/************************/ /* bsplit.c 1.01 */ /* by Adam M. Costello */ /* */ /* */ /* Splits a binary file */ /* into equally sized */ /* pieces (except for */ /* the last piece, of */ /* course). */ /************************/ /* This is ANSI C plus POSIX code. */ #include #include #include #include #define MYBUFSIZE 1024 void usage(int argc, char **argv) /* Prints a usage message on stderr, then exits unsuccessfully. */ { fprintf(stderr, "usage:\n%s [ -blocksize] infile [outprefix]\n", argc ? argv[0] : "bsplit"); exit(EXIT_FAILURE); } static const int CB_EOF=1; static const int CB_WROTE=2; int copyblock(int in, int out, long bytesleft) /* Copies bytesleft bytes from in to out, or until EOF */ /* on in. Returns bit flags CB_EOF and CB_WROTE to */ /* indicate eof on in and output to out, respectively. */ { static char buf[MYBUFSIZE]; char *bufp; int nbyte, numbytes, byteswritten, eof = 0, wrote = 0; do { nbyte = bytesleft < MYBUFSIZE ? bytesleft : MYBUFSIZE; numbytes = read(in,buf,nbyte); if (numbytes < 0) { fprintf(stderr, "read(%d,buf,%d", out, nbyte); perror(")"); exit(errno); } if (!numbytes) { eof = 1; break; } else { wrote = 1; bytesleft -= numbytes; bufp = buf; while (numbytes) { byteswritten = write(out,bufp,numbytes); if (byteswritten < 0) { fprintf(stderr, "write(%d,bufp,%d", out, numbytes); perror(")"); exit(errno); } bufp += byteswritten; numbytes -= byteswritten; } } } while (bytesleft); return eof * CB_EOF | wrote * CB_WROTE; } int main(int argc, char **argv) { char *infile = NULL, *outprefix = NULL, *outfile = NULL, *outsuf0, *outsuf1; long blocksize = 65536; int i,in,out,opl,cbresult; for (i = 1; i < argc; ++i) if (*argv[i] == '-') blocksize = atol(argv[i] + 1); else if (!infile) infile = argv[i]; else if (!outprefix) outprefix = argv[i]; else usage(argc,argv); if (blocksize <= 0) { fputs("blocksize must be greater than 0.\n", stderr); exit(EXIT_FAILURE); } if (!infile) usage(argc,argv); if (!outprefix) outprefix = ""; opl = strlen(outprefix); outfile = (char *) malloc(sizeof (char) * (opl + 3)); if (!outfile) { perror("malloc"); return errno; } strcpy(outfile,outprefix); outsuf0 = outfile + opl; outsuf1 = outsuf0 + 1; *outsuf0 = *outsuf1 = 'a'; outsuf1[1] = '\0'; in = open(infile,O_RDONLY); if (in < 0) { fprintf(stderr, "open(\"%s\"", infile); perror(",O_RDONLY)"); return errno; } for (;;) { if (*outsuf0 > 'z') { fputs("Too many output files.\n", stderr); exit(EXIT_FAILURE); } out = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0666); if (out < 0) { fprintf(stderr, "open(\"%s\"", outfile); perror(", O_WRONLY | O_CREAT | O_EXCL, 0666)"); return errno; } cbresult = copyblock(in,out,blocksize); if (close(out) == -1) { fprintf(stderr, "close(%d", out); perror(")"); return errno; } if (!(cbresult & CB_WROTE) && remove(outfile)) { fprintf(stderr, "remove(\"%s\"", outfile); perror(")"); return errno; } if (++*outsuf1 > 'z') { *outsuf1 = 'a'; ++*outsuf0; } if (cbresult & CB_EOF) { if (close(in) == -1) { fprintf(stderr, "close(%d", in); perror(")"); return errno; } exit(EXIT_SUCCESS); } } }