|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1987 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that: (1) source distributions retain this entire copyright ! 7: * notice and comment, and (2) distributions including binaries display ! 8: * the following acknowledgement: ``This product includes software ! 9: * developed by the University of California, Berkeley and its contributors'' ! 10: * in the documentation or other materials provided with the distribution ! 11: * and in all advertising materials mentioning features or use of this ! 12: * software. Neither the name of the University nor the names of its ! 13: * contributors may be used to endorse or promote products derived ! 14: * from this software without specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: char copyright[] = ! 22: "@(#) Copyright (c) 1987 Regents of the University of California.\n\ ! 23: All rights reserved.\n"; ! 24: #endif /* not lint */ ! 25: ! 26: #ifndef lint ! 27: static char sccsid[] = "@(#)split.c 4.8 (Berkeley) 6/1/90"; ! 28: #endif /* not lint */ ! 29: ! 30: #include <sys/param.h> ! 31: #include <sys/file.h> ! 32: #include <stdio.h> ! 33: #include <ctype.h> ! 34: ! 35: #define DEFLINE 1000 /* default num lines per file */ ! 36: #define ERR -1 /* general error */ ! 37: #define NO 0 /* no/false */ ! 38: #define OK 0 /* okay exit */ ! 39: #define YES 1 /* yes/true */ ! 40: ! 41: static long bytecnt, /* byte count to split on */ ! 42: numlines; /* lines in each file */ ! 43: static int ifd = ERR, /* input file descriptor */ ! 44: ofd = ERR; /* output file descriptor */ ! 45: static short file_open; /* if a file open */ ! 46: static char bfr[MAXBSIZE], /* I/O buffer */ ! 47: fname[MAXPATHLEN]; /* file name */ ! 48: ! 49: main(argc, argv) ! 50: int argc; ! 51: char **argv; ! 52: { ! 53: register int cnt; ! 54: long atol(); ! 55: char *strcpy(); ! 56: ! 57: for (cnt = 1; cnt < argc; ++cnt) { ! 58: if (argv[cnt][0] == '-') ! 59: switch(argv[cnt][1]) { ! 60: case 0: /* stdin by request */ ! 61: if (ifd != ERR) ! 62: usage(); ! 63: ifd = 0; ! 64: break; ! 65: case 'b': /* byte count split */ ! 66: if (numlines) ! 67: usage(); ! 68: if (!argv[cnt][2]) ! 69: bytecnt = atol(argv[++cnt]); ! 70: else ! 71: bytecnt = atol(argv[cnt] + 2); ! 72: if (bytecnt <= 0) { ! 73: fputs("split: byte count must be greater than zero.\n", stderr); ! 74: usage(); ! 75: } ! 76: break; ! 77: default: ! 78: if (!isdigit(argv[cnt][1]) || bytecnt) ! 79: usage(); ! 80: if ((numlines = atol(argv[cnt] + 1)) <= 0) { ! 81: fputs("split: line count must be greater than zero.\n", stderr); ! 82: usage(); ! 83: } ! 84: break; ! 85: } ! 86: else if (ifd == ERR) { /* input file */ ! 87: if ((ifd = open(argv[cnt], O_RDONLY, 0)) < 0) { ! 88: perror(argv[cnt]); ! 89: exit(1); ! 90: } ! 91: } ! 92: else if (!*fname) /* output file prefix */ ! 93: strcpy(fname, argv[cnt]); ! 94: else ! 95: usage(); ! 96: } ! 97: if (ifd == ERR) /* stdin by default */ ! 98: ifd = 0; ! 99: if (bytecnt) ! 100: split1(); ! 101: if (!numlines) ! 102: numlines = DEFLINE; ! 103: split2(); ! 104: exit(0); ! 105: } ! 106: ! 107: /* ! 108: * split1 -- ! 109: * split by bytes ! 110: */ ! 111: split1() ! 112: { ! 113: register long bcnt; ! 114: register int dist, len; ! 115: register char *C; ! 116: ! 117: for (bcnt = 0;;) ! 118: switch(len = read(ifd, bfr, MAXBSIZE)) { ! 119: case 0: ! 120: exit(OK); ! 121: case ERR: ! 122: perror("read"); ! 123: exit(1); ! 124: default: ! 125: if (!file_open) { ! 126: newfile(); ! 127: file_open = YES; ! 128: } ! 129: if (bcnt + len >= bytecnt) { ! 130: dist = bytecnt - bcnt; ! 131: if (write(ofd, bfr, dist) != dist) ! 132: wrerror(); ! 133: len -= dist; ! 134: for (C = bfr + dist; len >= bytecnt; len -= bytecnt, C += bytecnt) { ! 135: newfile(); ! 136: if (write(ofd, C, (int)bytecnt) != bytecnt) ! 137: wrerror(); ! 138: } ! 139: if (len) { ! 140: newfile(); ! 141: if (write(ofd, C, len) != len) ! 142: wrerror(); ! 143: } ! 144: else ! 145: file_open = NO; ! 146: bcnt = len; ! 147: } ! 148: else { ! 149: bcnt += len; ! 150: if (write(ofd, bfr, len) != len) ! 151: wrerror(); ! 152: } ! 153: } ! 154: } ! 155: ! 156: /* ! 157: * split2 -- ! 158: * split by lines ! 159: */ ! 160: split2() ! 161: { ! 162: register char *Ce, *Cs; ! 163: register long lcnt; ! 164: register int len, bcnt; ! 165: ! 166: for (lcnt = 0;;) ! 167: switch(len = read(ifd, bfr, MAXBSIZE)) { ! 168: case 0: ! 169: exit(0); ! 170: case ERR: ! 171: perror("read"); ! 172: exit(1); ! 173: default: ! 174: if (!file_open) { ! 175: newfile(); ! 176: file_open = YES; ! 177: } ! 178: for (Cs = Ce = bfr; len--; Ce++) ! 179: if (*Ce == '\n' && ++lcnt == numlines) { ! 180: bcnt = Ce - Cs + 1; ! 181: if (write(ofd, Cs, bcnt) != bcnt) ! 182: wrerror(); ! 183: lcnt = 0; ! 184: Cs = Ce + 1; ! 185: if (len) ! 186: newfile(); ! 187: else ! 188: file_open = NO; ! 189: } ! 190: if (Cs < Ce) { ! 191: bcnt = Ce - Cs; ! 192: if (write(ofd, Cs, bcnt) != bcnt) ! 193: wrerror(); ! 194: } ! 195: } ! 196: } ! 197: ! 198: /* ! 199: * newfile -- ! 200: * open a new file ! 201: */ ! 202: newfile() ! 203: { ! 204: static long fnum; ! 205: static short defname; ! 206: static char *fpnt; ! 207: ! 208: if (ofd == ERR) { ! 209: if (fname[0]) { ! 210: fpnt = fname + strlen(fname); ! 211: defname = NO; ! 212: } ! 213: else { ! 214: fname[0] = 'x'; ! 215: fpnt = fname + 1; ! 216: defname = YES; ! 217: } ! 218: ofd = fileno(stdout); ! 219: } ! 220: /* ! 221: * hack to increase max files; original code just wandered through ! 222: * magic characters. Maximum files is 3 * 26 * 26 == 2028 ! 223: */ ! 224: #define MAXFILES 676 ! 225: if (fnum == MAXFILES) { ! 226: if (!defname || fname[0] == 'z') { ! 227: fputs("split: too many files.\n", stderr); ! 228: exit(1); ! 229: } ! 230: ++fname[0]; ! 231: fnum = 0; ! 232: } ! 233: fpnt[0] = fnum / 26 + 'a'; ! 234: fpnt[1] = fnum % 26 + 'a'; ! 235: ++fnum; ! 236: if (!freopen(fname, "w", stdout)) { ! 237: fprintf(stderr, "split: unable to write to %s.\n", fname); ! 238: exit(ERR); ! 239: } ! 240: } ! 241: ! 242: /* ! 243: * usage -- ! 244: * print usage message and die ! 245: */ ! 246: usage() ! 247: { ! 248: fputs("usage: split [-] [-#] [-b byte_count] [file [prefix]]\n", stderr); ! 249: exit(1); ! 250: } ! 251: ! 252: /* ! 253: * wrerror -- ! 254: * write error ! 255: */ ! 256: wrerror() ! 257: { ! 258: perror("split: write"); ! 259: exit(1); ! 260: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.