1*30126Sbostic static char *sccsid = "@(#)split.c 4.3 (Berkeley) 11/20/86"; 2*30126Sbostic 3*30126Sbostic #include <sys/param.h> 4*30126Sbostic #include <sys/file.h> 51101Sbill #include <stdio.h> 6*30126Sbostic #include <ctype.h> 71101Sbill 8*30126Sbostic #define DEFLINE 1000 /* default num lines per file */ 9*30126Sbostic #define ERR -1 /* general error */ 10*30126Sbostic #define ERREXIT 0 /* error exit */ 11*30126Sbostic #define NO 0 /* no/false */ 12*30126Sbostic #define OK 0 /* okay exit */ 13*30126Sbostic #define YES 1 /* yes/true */ 141101Sbill 15*30126Sbostic static long bytecnt, /* byte count to split on */ 16*30126Sbostic numlines; /* lines in each file */ 17*30126Sbostic static int ifd = ERR, /* input file descriptor */ 18*30126Sbostic ofd = ERR; /* output file descriptor */ 19*30126Sbostic static short file_open; /* if a file open */ 20*30126Sbostic static char bfr[MAXBSIZE], /* I/O buffer */ 21*30126Sbostic fname[MAXPATHLEN]; /* file name */ 22*30126Sbostic 23*30126Sbostic main(argc,argv) 24*30126Sbostic int argc; 25*30126Sbostic char **argv; 261101Sbill { 27*30126Sbostic register int cnt; /* general counter */ 28*30126Sbostic long atol(); 29*30126Sbostic char *strcpy(); 301101Sbill 31*30126Sbostic for (cnt = 1;cnt < argc;++cnt) { 32*30126Sbostic if (argv[cnt][0] == '-') 33*30126Sbostic switch(argv[cnt][1]) { 34*30126Sbostic case 0: /* stdin by request */ 35*30126Sbostic if (ifd != ERR) 36*30126Sbostic usage(); 37*30126Sbostic ifd = 0; 38*30126Sbostic break; 39*30126Sbostic case 'b': /* byte count split */ 40*30126Sbostic if (numlines) 41*30126Sbostic usage(); 42*30126Sbostic if (!argv[cnt][2]) 43*30126Sbostic bytecnt = atol(argv[++cnt]); 44*30126Sbostic else 45*30126Sbostic bytecnt = atol(argv[cnt] + 2); 46*30126Sbostic if (bytecnt <= 0) { 47*30126Sbostic fputs("split: byte count must be greater than zero.\n",stderr); 48*30126Sbostic usage(); 49*30126Sbostic } 50*30126Sbostic break; 51*30126Sbostic default: 52*30126Sbostic if (!isdigit(argv[cnt][1]) || bytecnt) 53*30126Sbostic usage(); 54*30126Sbostic if ((numlines = atol(argv[cnt] + 2)) <= 0) { 55*30126Sbostic fputs("split: line count must be greater than zero.\n",stderr); 56*30126Sbostic usage(); 57*30126Sbostic } 58*30126Sbostic break; 591101Sbill } 60*30126Sbostic else if (ifd == ERR) { /* input file */ 61*30126Sbostic if ((ifd = open(argv[cnt],O_RDONLY,0)) < 0) { 62*30126Sbostic perror(argv[cnt]); 63*30126Sbostic exit(ERREXIT); 64*30126Sbostic } 651101Sbill } 66*30126Sbostic else if (!*fname) /* output file prefix */ 67*30126Sbostic strcpy(fname,argv[cnt]); 68*30126Sbostic else 69*30126Sbostic usage(); 70*30126Sbostic } 71*30126Sbostic if (ifd == ERR) /* stdin by default */ 72*30126Sbostic ifd = 0; 73*30126Sbostic if (bytecnt) 74*30126Sbostic split1(); 75*30126Sbostic if (!numlines) 76*30126Sbostic numlines = DEFLINE; 77*30126Sbostic split2(); 78*30126Sbostic } 79*30126Sbostic 80*30126Sbostic /* 81*30126Sbostic * split1 -- 82*30126Sbostic * split by bytes 83*30126Sbostic */ 84*30126Sbostic static 85*30126Sbostic split1() 86*30126Sbostic { 87*30126Sbostic register long bcnt; /* byte counter */ 88*30126Sbostic register int dist, /* buffer offset */ 89*30126Sbostic len; /* read length */ 90*30126Sbostic register char *C; /* tmp pointer into buffer */ 91*30126Sbostic 92*30126Sbostic for (bcnt = 0;;) 93*30126Sbostic switch(len = read(ifd,bfr,MAXBSIZE)) { 94*30126Sbostic case 0: 95*30126Sbostic exit(OK); 96*30126Sbostic case ERR: 97*30126Sbostic perror("read"); 98*30126Sbostic exit(ERREXIT); 99*30126Sbostic default: 100*30126Sbostic if (!file_open) { 101*30126Sbostic newfile(); 102*30126Sbostic file_open = YES; 103*30126Sbostic } 104*30126Sbostic if (bcnt + len >= bytecnt) { 105*30126Sbostic dist = bytecnt - bcnt; 106*30126Sbostic write(ofd,bfr,dist); 107*30126Sbostic len -= dist; 108*30126Sbostic for (C = bfr + dist;len >= bytecnt;len -= bytecnt,C += bytecnt) { 109*30126Sbostic newfile(); 110*30126Sbostic write(ofd,C,(int)bytecnt); 111*30126Sbostic } 112*30126Sbostic if (len) { 113*30126Sbostic newfile(); 114*30126Sbostic write(ofd,C,len); 115*30126Sbostic } 116*30126Sbostic else 117*30126Sbostic file_open = NO; 118*30126Sbostic bcnt = len; 119*30126Sbostic } 120*30126Sbostic else { 121*30126Sbostic bcnt += len; 122*30126Sbostic write(ofd,bfr,len); 123*30126Sbostic } 1241101Sbill } 125*30126Sbostic } 1261101Sbill 127*30126Sbostic /* 128*30126Sbostic * split2 -- 129*30126Sbostic * split by lines 130*30126Sbostic */ 131*30126Sbostic static 132*30126Sbostic split2() 133*30126Sbostic { 134*30126Sbostic register char *Ce, /* start/end pointers */ 135*30126Sbostic *Cs; 136*30126Sbostic register long lcnt; /* line counter */ 137*30126Sbostic register int len; /* read length */ 138*30126Sbostic 139*30126Sbostic for (lcnt = 0;;) 140*30126Sbostic switch(len = read(ifd,bfr,MAXBSIZE)) { 141*30126Sbostic case 0: 142*30126Sbostic exit(0); 143*30126Sbostic case ERR: 144*30126Sbostic perror("read"); 145*30126Sbostic break; 146*30126Sbostic default: 147*30126Sbostic if (!file_open) { 148*30126Sbostic newfile(); 149*30126Sbostic file_open = YES; 150*30126Sbostic } 151*30126Sbostic for (Cs = Ce = bfr;len--;Ce++) 152*30126Sbostic if (*Ce == '\n' && ++lcnt == numlines) { 153*30126Sbostic write(ofd,Cs,(int)(Ce - Cs) + 1); 154*30126Sbostic lcnt = 0; 155*30126Sbostic Cs = Ce + 1; 156*30126Sbostic if (len) 157*30126Sbostic newfile(); 158*30126Sbostic else 159*30126Sbostic file_open = NO; 160*30126Sbostic } 161*30126Sbostic if (Cs < Ce) 162*30126Sbostic write(ofd,Cs,(int)(Ce - Cs)); 1631101Sbill } 164*30126Sbostic } 165*30126Sbostic 166*30126Sbostic /* 167*30126Sbostic * newfile -- 168*30126Sbostic * open a new file 169*30126Sbostic */ 170*30126Sbostic static 171*30126Sbostic newfile() 172*30126Sbostic { 173*30126Sbostic static long fnum; /* file name counter */ 174*30126Sbostic static short defname; /* using default name, "x" */ 175*30126Sbostic static char *fpnt; /* output file name pointer */ 176*30126Sbostic 177*30126Sbostic if (ofd == ERR) { 178*30126Sbostic if (fname[0]) { 179*30126Sbostic fpnt = fname + strlen(fname); 180*30126Sbostic defname = NO; 1811101Sbill } 182*30126Sbostic else { 183*30126Sbostic fname[0] = 'x'; 184*30126Sbostic fpnt = fname + 1; 185*30126Sbostic defname = YES; 186*30126Sbostic } 187*30126Sbostic ofd = fileno(stdout); 188*30126Sbostic } 189*30126Sbostic /* 190*30126Sbostic * hack to increase max files; original code just wandered through 191*30126Sbostic * magic characters. Maximum files is 3 * 26 * 26 == 2028 192*30126Sbostic */ 193*30126Sbostic #define MAXFILES 676 194*30126Sbostic if (fnum == MAXFILES) { 195*30126Sbostic if (!defname || fname[0] == 'z') { 196*30126Sbostic fputs("split: too many files.\n",stderr); 197*30126Sbostic exit(ERREXIT); 198*30126Sbostic } 199*30126Sbostic ++fname[0]; 200*30126Sbostic fnum = 0; 201*30126Sbostic } 202*30126Sbostic fpnt[0] = fnum / 26 + 'a'; 203*30126Sbostic fpnt[1] = fnum % 26 + 'a'; 204*30126Sbostic ++fnum; 205*30126Sbostic if (!freopen(fname,"w",stdout)) { 206*30126Sbostic fprintf(stderr,"split: unable to write to %s.\n",fname); 207*30126Sbostic exit(ERR); 208*30126Sbostic } 2091101Sbill } 210*30126Sbostic 211*30126Sbostic /* 212*30126Sbostic * usage -- 213*30126Sbostic * print usage message and die 214*30126Sbostic */ 215*30126Sbostic static 216*30126Sbostic usage() 217*30126Sbostic { 218*30126Sbostic fputs("usage: split [-] [-#] [-b byte_count] [file [prefix]]\n",stderr); 219*30126Sbostic exit(ERREXIT); 220*30126Sbostic } 221