📄 zipsplit.c
字号:
init_upper(); /* build case map table */ /* Go through args */ signal(SIGINT, handler);#ifdef SIGTERM /* Amiga has no SIGTERM */ signal(SIGTERM, handler);#endif k = h = x = d = u = 0; c = DEFSIZ; for (r = 1; r < argc; r++) if (*argv[r] == '-') if (argv[r][1]) for (q = argv[r]+1; *q; q++) switch(*q) { case 'b': /* Specify path for output files */ if (k) err(ZE_PARMS, "options are separate and precede zip file"); else k = 1; /* Next non-option is path */ break; case 'h': /* Show help */ help(); exit(0); case 'i': /* Make an index file */ x = 1; break; case 'l': case 'L': /* Show copyright and disclaimer */ license(); exit(0); case 'n': /* Specify maximum size of resulting zip files */ if (k) err(ZE_PARMS, "options are separate and precede zip file"); else k = 2; /* Next non-option is size */ break; case 'p': u = 1; case 's': h = 1; /* Only try simple */ break; case 't': /* Just report number of disks */ d = 1; break; default: err(ZE_PARMS, "Use option -h for help."); } else err(ZE_PARMS, "zip file cannot be stdin"); else if (k == 0) if (zipfile == NULL) { if ((zipfile = ziptyp(argv[r])) == NULL) err(ZE_MEM, "was processing arguments"); } else err(ZE_PARMS, "can only specify one zip file"); else if (k == 1) { tempath = argv[r]; k = 0; } else /* k must be 2 */ { if ((c = (ulg)atol(argv[r])) < 100) /* 100 is smallest zip file */ err(ZE_PARMS, "invalid size given. Use option -h for help."); k = 0; } if (zipfile == NULL) err(ZE_PARMS, "need to specify zip file"); /* Read zip file */ if ((r = readzipfile()) != ZE_OK) err(r, zipfile); if (zfiles == NULL) err(ZE_NAME, zipfile); /* Make a list of sizes and check against capacity. Also compute the size of the index file. */ c -= ENDHEAD + 4; /* subtract overhead/zipfile */ if ((a = (ulg *)malloc(zcount * sizeof(ulg))) == NULL || (w = (struct zlist far **)malloc(zcount * sizeof(struct zlist far *))) == NULL) { if (a != NULL) free((voidp *)a); err(ZE_MEM, "was computing split"); return 1; } i = t = 0; for (j = 0, z = zfiles; j < zcount; j++, z = z->nxt) { w[j] = z; if (x) i += z->nam + 6 + NL; t += a[j] = 8 + LOCHEAD + CENHEAD + 2 * (ulg)z->nam + 2 * (ulg)z->ext + z->com + z->siz; if (a[j] > c) { free((voidp *)w); free((voidp *)a); err(ZE_BIG, z->zname); } } /* Decide on split to use, report number of files */ if (h) s = simple(a, zcount, c, i); else { if ((p = (ulg *)malloc(zcount * sizeof(ulg))) == NULL) { free((voidp *)w); free((voidp *)a); err(ZE_MEM, "was computing split"); } memcpy((char *)p, (char *)a, zcount * sizeof(ulg)); s = simple(a, zcount, c, i); g = greedy(p, zcount, c, i); if (s <= g) free((voidp *)p); else { free((voidp *)a); a = p; s = g; } } printf("%d zip files w%s be made (%d%% efficiency)\n", s, d ? "ould" : "ill", ((200 * ((t + c - 1)/c)) / s + 1) >> 1); if (d) { free((voidp *)w); free((voidp *)a); free((voidp *)zipfile); zipfile = NULL; exit(0); } /* Set up path for output files */ if ((path = malloc(tempath == NULL ? 13 : strlen(tempath) + 14)) == NULL) err(ZE_MEM, "was making output file names"); if (tempath == NULL) name = path; else { strcpy(path, tempath);#ifdef AMIGA tailchar = path[strlen(path) - 1]; /* last character */ if (path[0] && (tailchar != '/') && (tailchar != ':')) strcat(path, "/"); name = path + strlen(path);#else if (path[0] && path[strlen(path) - 1] != '/') strcat(path, "/"); name = path + strlen(path);#endif /* ?AMIGA */ } /* Write the index file */ if (u) { char m[10]; fputs("Insert first disk and hit return: ", stderr); fgets(m, 10, stdin); } if (x) { strcpy(name, INDEX); printf("creating: %s\n", path); indexmade = 1; if ((f = fopen(path, "w")) == NULL) { free((voidp *)w); free((voidp *)a); err(ZE_CREAT, path); } for (j = 0; j < zcount; j++) fprintf(f, "%5ld %s\n", a[j] + 1, w[j]->zname); if ((j = ferror(f)) != 0 || fclose(f)) { if (j) fclose(f); free((voidp *)w); free((voidp *)a); err(ZE_WRITE, path); } } /* Make linked lists of results */ if ((b = (extent *)malloc(s * sizeof(extent))) == NULL) { free((voidp *)w); free((voidp *)a); err(ZE_MEM, "was computing split"); } for (j = 0; j < s; j++) b[j] = (extent)-1; j = zcount; while (j--) { g = (extent)a[j]; a[j] = b[g]; b[g] = j; } /* Make a name template for the zip files that is eight or less characters before the .zip, and that will not overwrite the original zip file. */ for (k = 1, j = s; j >= 10; j /= 10) k++; if (k > 7) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_PARMS, "way too many zip files must be made"); }#ifdef VMS if ((q = strrchr(zipfile, ']')) != NULL)#else /* !VMS */# ifdef AMIGA if (((q = strrchr(zipfile, '/')) != NULL) || ((q = strrchr(zipfile, ':'))) != NULL)# else /* !AMIGA */ if ((q = strrchr(zipfile, '/')) != NULL)# endif /* ?AMIGA */#endif /* ?VMS */ q++; else q = zipfile; r = 0; while ((g = *q++) != 0 && g != '.' && r < 8 - k) template[r++] = (char)g; if (r == 0) template[r++] = '_'; else if (g >= '0' && g <= '9') template[r - 1] = (char)(template[r - 1] == '_' ? '-' : '_'); sprintf(template + r, "%%0%dd.zip", k); /* Make the zip files from the linked lists of entry numbers */ if ((e = fopen(zipfile, FOPR)) == NULL) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_NAME, zipfile); } free((voidp *)zipfile); zipfile = NULL; for (j = 0; j < s; j++) { if (u && j) { char m[10]; fputs("Insert next disk and hit return: ", stderr); fgets(m, 10, stdin); } sprintf(name, template, j + 1); printf("creating: %s\n", path); zipsmade = j + 1; if ((f = fopen(path, FOPW)) == NULL) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_CREAT, path); } tempzn = 0; for (g = b[j]; g != (extent)-1; g = (extent)a[g]) { if (fseek(e, w[g]->off, SEEK_SET)) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ferror(e) ? ZE_READ : ZE_EOF, zipfile); } if ((r = zipcopy(w[g], e, f)) != ZE_OK) { free((voidp *)b); free((voidp *)w); free((voidp *)a); if (r == ZE_TEMP) err(ZE_WRITE, path); else err(r, zipfile); } } if ((c = ftell(f)) == -1L) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_WRITE, path); } for (g = b[j], k = 0; g != (extent)-1; g = (extent)a[g], k++) if ((r = putcentral(w[g], f)) != ZE_OK) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_WRITE, path); } if ((t = ftell(f)) == -1L) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_WRITE, path); } if ((r = putend(k, t - c, c, (extent)0, (char *)NULL, f)) != ZE_OK) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_WRITE, path); } if (ferror(f) || fclose(f)) { free((voidp *)b); free((voidp *)w); free((voidp *)a); err(ZE_WRITE, path); } } free((voidp *)b); free((voidp *)w); free((voidp *)a); fclose(e); /* Done! */ exit(0); return 0; /* avoid warning */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -