#include #include #include #include #include #include #include #include #include #include #include "common.hh" #include "TreFile.hh" void usage(char *argv0) { fprintf(stderr, "Usage: %s [-sh] [-d dest] tre-file [filenames/crcs...]\n", argv0); fprintf(stderr, "\t-s\tPrint the tre-file's structure\n"); fprintf(stderr, "\t-d dest\tDump files to dest/\n"); fprintf(stderr, "\t\tif dilenames/crcs are supplied, dump those object, else dump all\n"); fprintf(stderr, "\t-h\tPrint this help\n"); } int main(int argc, char *argv[]) { bool printStructure = false, dumpFiles = false; std::string dumpPath, treFile; std::vector fileSpecs; { int opt; while ((opt = getopt(argc, argv, "hsd:")) != -1) { switch (opt) { case 'h': usage(argv[0]); return 0; case 's': printStructure = true; break; case 'd': dumpPath = optarg; dumpFiles = true; break; default: usage(argv[0]); return 1; } } if (optind >= argc) { usage(argv[0]); return 1; } treFile = argv[optind]; for (int i = optind+1;i < argc;++i) fileSpecs.push_back(argv[i]); } try { TreFile file{treFile}; if (printStructure) file.printStructure(); if (dumpFiles) { if (fileSpecs.empty()) file.dumpAll(dumpPath); else { for (auto spec : fileSpecs) { try { unsigned long fileCRC = std::stoul(spec, nullptr, 16); if (fileCRC <= std::numeric_limits::max()) { file.dumpCRC(dumpPath, fileCRC); continue; } } catch (std::invalid_argument &ex) { } catch (std::out_of_range &ex) { } file.dumpName(dumpPath, spec); } } } } catch (POSIXException &ex) { fprintf(stderr, "%s\n", ex.toString().c_str()); return 2; } catch (FormatException &ex) { fprintf(stderr, "%s\n", ex.toString().c_str()); return 3; } return 0; }