dmg/dmg.c (127 lines of code) (raw):
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <dmg/dmg.h>
#include <dmg/filevault.h>
char endianness;
void TestByteOrder()
{
short int word = 0x0001;
char *byte = (char *) &word;
endianness = byte[0] ? IS_LITTLE_ENDIAN : IS_BIG_ENDIAN;
}
int buildInOut(const char* source, const char* dest, AbstractFile** in, AbstractFile** out) {
*in = createAbstractFileFromFile(fopen(source, "rb"));
if(!(*in)) {
printf("cannot open source: %s\n", source);
return FALSE;
}
*out = createAbstractFileFromFile(strcmp(dest, "-") == 0 ? stdout : fopen(dest, "wb"));
if(!(*out)) {
(*in)->close(*in);
printf("cannot open destination: %s\n", dest);
return FALSE;
}
return TRUE;
}
void usage(const char *name) {
printf("usage: %s [OPTIONS] [extract|build|build2048|res|iso|dmg|attribute] <in> <out> (partition)\n", name);
printf("OPTIONS:\n");
printf("\t--key, -k key\n");
printf("\t--compression, -c compressor name (%s)\n", compressionNames());
printf("\t--level, -l compression level\n");
printf("\t--run-sectors, -r run size (in sectors)\n");
exit(2);
}
int main(int argc, char* argv[]) {
int partNum;
AbstractFile* in;
AbstractFile* out;
int opt;
char *cmd, *infile, *outfile;
char *key = NULL;
Compressor comp = {.level = COMPRESSION_LEVEL_DEFAULT };
int ret;
int runSectors = DEFAULT_SECTORS_AT_A_TIME;
TestByteOrder();
initDefaultCompressor(&comp);
const char *optstring = "k:c:l:r:";
const struct option longopts[] = {
{"key", required_argument, NULL, 'k'},
{"compression", required_argument, NULL, 'c'},
{"level", required_argument, NULL, 'l'},
{"run-sectors", required_argument, NULL, 'r'},
{NULL, 0, NULL, 0},
};
while ((opt = getopt_long(argc, argv, optstring, longopts, NULL)) != -1) {
switch (opt) {
case 'k':
key = optarg;
break;
case 'c':
ret = getCompressor(&comp, optarg);
if (ret != 0) {
fprintf(stderr, "Unknown compressor \"%s\"\nAllowed options are: %s\n", optarg, compressionNames());
return 2;
}
break;
case 'l':
sscanf(optarg, "%d", &comp.level);
break;
case 'r':
sscanf(optarg, "%d", &runSectors);
if (runSectors < DEFAULT_SECTORS_AT_A_TIME) {
fprintf(stderr, "Run size must be at least %d sectors\n", DEFAULT_SECTORS_AT_A_TIME);
return 2;
}
break;
default:
usage(argv[0]);
}
}
if (argc < optind + 3) {
usage(argv[0]);
}
cmd = argv[optind++];
infile = argv[optind++];
outfile = argv[optind++];
if(!buildInOut(infile, outfile, &in, &out)) {
return -1;
}
if(key != NULL) {
in = createAbstractFileFromFileVault(in, key);
}
if(strcmp(cmd, "extract") == 0) {
partNum = -1;
if (optind < argc) {
sscanf(argv[optind++], "%d", &partNum);
}
extractDmg(in, out, partNum);
} else if(strcmp(cmd, "build") == 0) {
char *anchor = NULL;
if (optind < argc) {
anchor = argv[optind++];
}
buildDmg(in, out, SECTOR_SIZE, anchor, &comp, runSectors);
} else if(strcmp(cmd, "build2048") == 0) {
buildDmg(in, out, 2048, NULL, &comp, runSectors);
} else if(strcmp(cmd, "res") == 0) {
outResources(in, out);
} else if(strcmp(cmd, "iso") == 0) {
convertToISO(in, out);
} else if(strcmp(cmd, "dmg") == 0) {
convertToDMG(in, out, &comp, runSectors);
} else if(strcmp(cmd, "attribute") == 0) {
char *anchor, *data;
if(argc < optind + 2) {
printf("Not enough arguments: attribute <in> <out> <sentinel> <string>");
return 2;
}
anchor = argv[optind++];
data = argv[optind++];
updateAttribution(in, out, anchor, data, strlen(data));
}
return 0;
}