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