📄 par.c
字号:
free(data); if (x != 0) return -1; } } return n;}static intappend_stream(prc_t* prc, char** argv){ int n; for (n = 0; argv[n] != NULL; n++) { prc_byte_t* data; prc_uint32_t datalen; char* filename = argv[n]; data = file_to_data(filename, &datalen); if (!data) return -1; if (prcstreamwrite(prc, data, datalen) != datalen) return -1; free(data); } return n;}static intprcappend(prc_t* prc, char** argv){ if (PRC_IS_RESOURCE(prc)) { return append_resources(prc, argv); } else if (PRC_IS_STREAM(prc)) { return append_stream(prc, argv); } else { int n = append_info(prc, argv); if (n == -1) return n; return append_records(prc, &argv[n]); }}typedef struct type_id_t{ prc_uint32_t old_type; prc_uint16_t old_id; prc_uint32_t new_type; prc_uint16_t new_id;} type_id_t;static inttouch_resource_mappee(prc_resource_t* resource, void* arg){ type_id_t* info = (type_id_t*)arg; if (resource->type == info->old_type && resource->id == info->old_id) { resource->type = info->new_type; resource->id = info->new_id; return 1; } return 0;}static inttouch_resources(prc_t* prc, char** argv){ /* [-T type id] type id */ int n; type_id_t info; info.new_type = 0; info.new_id = 0; for (n = 0; argv[n] != NULL;) { if (strcmp("-T", argv[n]) == 0) { n++; info.new_type = prcstrtotype(argv[n++]); info.new_id = prcstrtoid(argv[n++]); continue; } info.old_type = prcstrtotype(argv[n++]); info.old_id = prcstrtoid(argv[n++]); if (info.new_type != 0) prcmapresources(prc, touch_resource_mappee, &info); } return n;}static inttouch_records(prc_t* prc, char** argv){ /* [-c category] [-a attr] [-i uid] index ... */ int n; prc_uint32_t uid = 0; unsigned flags = 0; unsigned category = 0; for (n = 0; argv[n] != NULL; n++) { int delta; prc_record_t* record; prc_uint16_t index; unsigned isPrc; delta = parse_record_args(&argv[n], &category, &flags, &uid, &isPrc); if (!delta) continue; n += delta; index = atoi(argv[n]); record = prcgetrecord(prc, index); if (record->id == uid && record->flags == (flags | category)) continue; record->flags = (flags | category); record->id = uid; } return n;}/* * records: [-c catagory] [-a attrs] index * resources: [-T type id] type id */static intprctouch(prc_t* prc, char** argv){ if (PRC_IS_RESOURCE(prc)) return touch_resources(prc, argv); else return touch_records(prc, argv);}static voidusage(){ fprintf(stderr, "usage:\n" "par t dbfile - list\n" "par h dbfile - header\n" "par x dbfile [ioptions] [records ..] - extract\n" "par c [hoptions] dbfile name type cid [ioptions] [files ..] - create\n" "par u [hoptions] dbfile [ioptions] [updates ..] - touch\n" "par a [hoptions] dbfile [ioptions] [files ..] - append\n" "par d [hoptions] dbfile [doptions] [records ..] - delete\n" "par version - version\n" "where dbfile is a pdb:\n" "ioptions = [-A appinfo] [-S sortinfo]\n" "doptions = [-A] [-S]\n" "file = [-c category] [-a attrs] [-u uid] filename |\n" " [-p databasefile] | resource.pdb\n" "record = [-f filename] index\n" "update = [-c category] [-a attrs] [-u uid] index\n" "where dbfile is a prc:\n" "file = [-T type id] filename |\n" " [-p resourcefile] | resource.prc\n" "record = [-f filename] type id\n" "update = [-T type id] type id\n" "hoptions:\n" "-n name - database name\n" "-T type - PRC creator type\n" "-I cid - PRC creator id\n" "-a attrs - PRC attribute flags, bit-ORed symbolic or numeric:\n" " resource|readonly|dirty|backup|newer|reset|copyprevent|\n" " stream|hidden|launchable|recyclable|bundle|open|<numeric>\n" "-v vers - 16 bit PRC version number, numeric (default is 1)\n" "-C ctime - creation time [[CC]YY]MMDDHHMM\n" "-m mtime - modification time\n" "-b btime - backup time\n" "");}#define HOPTIONS_NAME (0x1<<0)#define HOPTIONS_TYPE (0x1<<1)#define HOPTIONS_CID (0x1<<2)#define HOPTIONS_ATTR (0x1<<3)#define HOPTIONS_VERSION (0x1<<4)#define HOPTIONS_CTIME (0x1<<5)#define HOPTIONS_MTIME (0x1<<6)#define HOPTIONS_BTIME (0x1<<7)static intparse_hoptions(char** argv, prc_t* options, unsigned* options_set){ int n = 0; prc_attr_t a = 0; prc_time_t t = 0; for (n = 0; argv[n] != NULL;) { if (strcmp(argv[n], "-n") == 0) { prcsetname(options, argv[n+1]); n += 2; *options_set |= HOPTIONS_NAME; } else if (strcmp(argv[n], "-T") == 0) { options->type = prcstrtotype(argv[n+1]); n += 2; *options_set |= HOPTIONS_TYPE; } else if (strcmp(argv[n], "-I") == 0) { options->cid = prcstrtotype(argv[n+1]); n += 2; *options_set |= HOPTIONS_CID; } else if (strcmp(argv[n], "-a") == 0) { a = prcstrpattr(argv[n+1]); options->flags = a; n += 2; *options_set |= HOPTIONS_ATTR; } else if (strcmp(argv[n], "-v") == 0) { options->version = atoi(argv[n+1]); n += 2; *options_set |= HOPTIONS_VERSION; } else if (strcmp(argv[n], "-C") == 0) { t = prcstrtotime(argv[n+1]); options->ctime = t; n += 2; *options_set |= HOPTIONS_CTIME; } else if (strcmp(argv[n], "-m") == 0) { t = prcstrtotime(argv[n+1]); options->mtime = t; n += 2; *options_set |= HOPTIONS_MTIME; } else if (strcmp(argv[n], "-b") == 0) { t = prcstrtotime(argv[n+1]); options->btime = t; n += 2; *options_set |= HOPTIONS_BTIME; } else { break; } if (t == (prc_time_t)-1) { fprintf(stderr, "invalid time specification: %s\n", argv[n-1]); return -1; } if (a == (prc_attr_t)-1) { fprintf(stderr, "invalid attribute specification: %s\n", argv[n-1]); return -1; } } return n;}static voidset_hoptions(prc_t* prc, prc_t* options, unsigned options_set){ if (!prc || !options) return; if ((options_set & HOPTIONS_NAME) != 0) memcpy(prc->name, options->name, PRC_MAX_NAMESIZE); /* not so great */ if ((options_set & HOPTIONS_TYPE) != 0) prc->type = options->type; if ((options_set & HOPTIONS_CID) != 0) prc->cid = options->cid; if ((options_set & HOPTIONS_ATTR) != 0) prc->flags = options->flags; if ((options_set & HOPTIONS_VERSION) != 0) prc->version = options->version; if ((options_set & HOPTIONS_CTIME) != 0) prc->ctime = options->ctime; if ((options_set & HOPTIONS_MTIME) != 0) prc->mtime = options->mtime; if ((options_set & HOPTIONS_BTIME) != 0) prc->btime = options->btime;}typedef enum { PAR_NONE = (unsigned)-1, PAR_LIST = 0, PAR_INFO, PAR_EXTRACT, PAR_CREATE, PAR_TOUCH, PAR_DELETE, PAR_APPEND, PAR_VERSION} par_mode_t;static par_mode_tparse_mode(const char* s){ if (strcmp(s, "-l") == 0 || strcmp(s, "l") == 0 || strcmp(s, "-t") == 0 || strcmp(s, "t") == 0) return PAR_LIST; else if (strcmp(s, "-h") == 0 || strcmp(s, "h") == 0 || strcmp(s, "-i") == 0 || strcmp(s, "i") == 0) return PAR_INFO; else if (strcmp(s, "-x") == 0 || strcmp(s, "x") == 0) return PAR_EXTRACT; else if (strcmp(s, "-c") == 0 || strcmp(s, "c") == 0) return PAR_CREATE; else if (strcmp(s, "-u") == 0 || strcmp(s, "u") == 0) return PAR_TOUCH; else if (strcmp(s, "-d") == 0 || strcmp(s, "d") == 0) return PAR_DELETE; else if (strcmp(s, "-a") == 0 || strcmp(s, "a") == 0) return PAR_APPEND; else if (strcmp(s, "-V") == 0 || strcmp(s, "V") == 0 || strcmp(s, "-version") == 0 || strcmp(s, "version") == 0) return PAR_VERSION; else return PAR_NONE;}intmain(int argc, char** argv){ char* dbname; prc_t* prc; par_mode_t mode; int n = 1; prc_t optionsBuf; unsigned optionsSet; int rv = 0; char* mode_s; if (argc < 2) { fprintf(stderr, "not enough args!\n"); usage(); return 2; } /* init hoptions */ memset(&optionsBuf, 0, sizeof(prc_t)); optionsSet = 0; mode_s = argv[n++]; if (strcmp(mode_s, "-r") == 0 || strcmp(mode_s, "r") == 0) { /* hack */ optionsBuf.flags = PRC_FLAGS_RESOURCE; optionsSet |= HOPTIONS_ATTR; mode_s = "-c"; } mode = parse_mode(mode_s); if (mode == PAR_NONE) { fprintf(stderr, "invalid mode\n"); usage(); return 2; } if (mode == PAR_VERSION) { printf("%02ld.%02ld", LIBPRC_VERSION_MAJOR, LIBPRC_VERSION_MINOR); if (LIBPRC_VERSION_MICRO != 0UL) printf(".%02ld", LIBPRC_VERSION_MICRO); printf("\n"); return 0; } if (argc < 3) { fprintf(stderr, "not enough args!\n"); usage(); return 2; } if (mode == PAR_CREATE || mode == PAR_TOUCH || mode == PAR_DELETE || mode == PAR_APPEND) { int rv; /* always touch the mod time for writable modes */ optionsBuf.mtime = prctime(NULL); /* now */ optionsSet |= HOPTIONS_MTIME; rv = parse_hoptions(&argv[n], &optionsBuf, &optionsSet); if (rv == -1) { usage(); return 2; } n += rv; } dbname = argv[n++]; switch (mode) { case PAR_CREATE: /* create */ { const char* name; prc_type_t type; prc_type_t cid; if (argc < n + 3) { fprintf(stderr, "not enough args!\n"); usage(); return 2; } if (strlen(argv[n+1]) != 4) { fprintf(stderr, "type must be 4 chars\n"); usage(); return 2; } if (strlen(argv[n+2]) != 4) { fprintf(stderr, "creator id must be 4 chars\n"); usage(); return 2; } name = argv[n++]; type = prcstrtotype(argv[n++]); cid = prcstrtotype(argv[n++]); prc = prccreate(dbname, name, type, cid, optionsBuf.flags); if ((optionsSet & (HOPTIONS_NAME|HOPTIONS_TYPE|HOPTIONS_CID)) != 0) fprintf(stderr, "warning: -n,-T,-I ignored with -c mode\n"); optionsSet &= ~(HOPTIONS_NAME|HOPTIONS_TYPE|HOPTIONS_CID); } break; case PAR_DELETE: /* update */ case PAR_APPEND: prc = prcopen(dbname, PRC_OPEN_UPDATE); break; case PAR_TOUCH: /* touch */ prc = prcopen(dbname, PRC_OPEN_TOUCH); break; case PAR_LIST: /* read only */ case PAR_INFO: case PAR_EXTRACT: prc = prcopen(dbname, PRC_OPEN_READ); break; default: fprintf(stderr, "mode not implimented\n"); return 3; } if (!prc) { prc_errno_t err = prcgeterrno(); const char* e_string = prcstrerror(err); fprintf(stderr, "failed to open %s: %s\n", dbname, e_string); return 1; } if ((prc->flags & PRC_FLAGS_RESOURCE) == 0 && (optionsBuf.flags & PRC_FLAGS_RESOURCE) != 0) { fprintf(stderr, "'resource' attribute can only be set at create time\n"); return 2; } if (optionsSet != 0) { set_hoptions(prc, &optionsBuf, optionsSet); } switch (mode) { case PAR_CREATE: /* create become append */ case PAR_APPEND: rv = prcappend(prc, &argv[n]); break; case PAR_TOUCH: /* touch */ rv = prctouch(prc, &argv[n]); break; case PAR_LIST: /* read only */ rv = prclist(prc); break; case PAR_INFO: rv = prcinfo(prc); break; case PAR_EXTRACT: rv = prcextract(prc, &argv[n]); break; case PAR_DELETE: /* delete */ rv = prcdelete(prc, &argv[n]); break; default: fprintf(stderr, "mode not implimented\n"); return 3; } prcclose(prc); if (rv == -1) return 1; else return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -