/* $MirOS: src/usr.bin/splitb/splitb.c,v 1.7 2013/10/31 20:07:10 tg Exp $ */ /*- * Copyright © 2005, 2013 * Thorsten Glaser * * Provided that these terms and disclaimer and all copyright notices * are retained or reproduced in an accompanying document, permission * is granted to deal in this work without restriction, including un‐ * limited rights to use, publicly perform, distribute, sell, modify, * merge, give away, or sublicence. * * This work is provided “AS IS” and WITHOUT WARRANTY of any kind, to * the utmost extent permitted by applicable law, neither express nor * implied; without malicious intent or gross negligence. In no event * may a licensor, author or contributor be held liable for indirect, * direct, other damage, loss, or other issues arising in any way out * of dealing in the work, even if advised of the possibility of such * damage or existence of a defect, except proven that it results out * of said person’s immediate fault when using the work as intended. *- * Inspired by work done for Telefax 400, Deutsche Telekom AG. */ #ifdef linux #define _FILE_OFFSET_BITS 64 #ifndef __dead #define __dead __attribute__((__noreturn__)) #endif #endif #include #include #include #include #include #include #include #include int main(int, char **); __dead void usage(int); int main(int argc, char **argv) { int i, ifd, ofd, ch, pfl = 3; long l = 1, lw = 0, bufsiz = 1024 * 1024; ssize_t k; bool quiet = false, dec = false; char *ft = strdup("split"), fn[PATH_MAX], *buf; int64_t sum = 0; while ((ch = getopt(argc, argv, "B:b:dhkqt:w:")) != -1) { switch (ch) { case 'h': usage(1); break; case 'B': if ((bufsiz = strtol(optarg, NULL, 0)) <=0) errx(1, "bufsize cannot be negative"); else if ((bufsiz == 1) && !quiet) warnx("bufsize 1 provides low performance"); else if (bufsiz > 1024 * 1024 * 1024) errx(1, "bufsize > 1 GiB makes no sense"); break; case 'b': if ((l = strtol(optarg, NULL, 0)) <= 0) usage(0); break; case 'd': dec = !dec; break; case 'k': bufsiz = 1024; break; case 'q': quiet = true; break; case 't': ft = strdup(optarg); break; case 'w': if ((pfl = (int)strtol(optarg, NULL, 0)) < 1) usage(0); break; default: usage(0); break; } } argc -= optind; argv += optind; if ((size_t)pfl > (PATH_MAX - 2 - strlen(ft))) usage(0); if (argc) { if ((ifd = open(*argv, O_RDONLY)) == -1) err(1, "cannot open input file"); } else ifd = STDIN_FILENO; if ((buf = malloc((size_t)bufsiz)) == NULL) err(1, "cannot allocate memory"); i = 0; ofd = -1; while ((k = read(ifd, buf, (size_t)bufsiz)) > 0) { sum += k; if (ofd == -1) { snprintf(fn, sizeof(fn), dec ? "%s.%0*d" : "%s.%0*X", ft, pfl, i); if ((ofd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0666)) == -1) err(1, "cannot open output file"); lw = 0; if (!quiet) printf("Writing to %s...", fn); fflush(stdout); } if (write(ofd, buf, (size_t)k) != k) err(1, "cannot write to output file"); if (k != bufsiz) { close(ofd); break; } if (++lw == l) { close(ofd); ofd = -1; if (!quiet) printf("done\n"); fflush(stdout); ++i; } } if (ofd != -1) { close(ofd); if (!quiet) printf("done\n"); ++i; } printf("%lld bytes written to %d output files.\n", sum, i); return 0; } __dead void usage(int loud) { extern const char *__progname; printf("Usage: %s [-dhkq] [-B bufsiz] [-b blocks] [-t template]\n" " [-w width] [inputfile]\n%s", __progname, loud ? "A buffer consists of bufsiz Bytes, or 1 KiB (1024 Bytes)\n" "if -k is given, or 1 MiB (1048576 Bytes) if neither -B\n" "nor -k is used on the command line. Default width for\n" "the file postfix is 3; stdin is the default inputfile.\n" : ""); exit(loud ? 0 : 1); }