132747Sbostic /* 2*62254Sbostic * Copyright (c) 1987, 1993 3*62254Sbostic * The Regents of the University of California. All rights reserved. 432747Sbostic * 542768Sbostic * %sccs.include.redist.c% 632747Sbostic */ 730126Sbostic 832747Sbostic #ifndef lint 9*62254Sbostic static char copyright[] = 10*62254Sbostic "@(#) Copyright (c) 1987, 1993\n\ 11*62254Sbostic The Regents of the University of California. All rights reserved.\n"; 1232747Sbostic #endif /* not lint */ 1332747Sbostic 1432747Sbostic #ifndef lint 15*62254Sbostic static char sccsid[] = "@(#)split.c 8.1 (Berkeley) 06/06/93"; 1632747Sbostic #endif /* not lint */ 1732747Sbostic 1830126Sbostic #include <sys/param.h> 1930126Sbostic #include <sys/file.h> 201101Sbill #include <stdio.h> 2130126Sbostic #include <ctype.h> 221101Sbill 2330126Sbostic #define DEFLINE 1000 /* default num lines per file */ 2430126Sbostic #define ERR -1 /* general error */ 2530126Sbostic #define NO 0 /* no/false */ 2630126Sbostic #define OK 0 /* okay exit */ 2730126Sbostic #define YES 1 /* yes/true */ 281101Sbill 2930126Sbostic static long bytecnt, /* byte count to split on */ 3030126Sbostic numlines; /* lines in each file */ 3130126Sbostic static int ifd = ERR, /* input file descriptor */ 3230126Sbostic ofd = ERR; /* output file descriptor */ 3330126Sbostic static short file_open; /* if a file open */ 3430126Sbostic static char bfr[MAXBSIZE], /* I/O buffer */ 3530126Sbostic fname[MAXPATHLEN]; /* file name */ 3630126Sbostic 3732747Sbostic main(argc, argv) 3836598Sbostic int argc; 3936598Sbostic char **argv; 401101Sbill { 4136598Sbostic register int cnt; 4236598Sbostic long atol(); 4336598Sbostic char *strcpy(); 441101Sbill 4532747Sbostic for (cnt = 1; cnt < argc; ++cnt) { 4630126Sbostic if (argv[cnt][0] == '-') 4730126Sbostic switch(argv[cnt][1]) { 4832747Sbostic case 0: /* stdin by request */ 4932747Sbostic if (ifd != ERR) 5032747Sbostic usage(); 5132747Sbostic ifd = 0; 5232747Sbostic break; 5332747Sbostic case 'b': /* byte count split */ 5432747Sbostic if (numlines) 5532747Sbostic usage(); 5632747Sbostic if (!argv[cnt][2]) 5732747Sbostic bytecnt = atol(argv[++cnt]); 5832747Sbostic else 5932747Sbostic bytecnt = atol(argv[cnt] + 2); 6032747Sbostic if (bytecnt <= 0) { 6132747Sbostic fputs("split: byte count must be greater than zero.\n", stderr); 6232747Sbostic usage(); 6332747Sbostic } 6432747Sbostic break; 6532747Sbostic default: 6632747Sbostic if (!isdigit(argv[cnt][1]) || bytecnt) 6732747Sbostic usage(); 6832747Sbostic if ((numlines = atol(argv[cnt] + 1)) <= 0) { 6932747Sbostic fputs("split: line count must be greater than zero.\n", stderr); 7032747Sbostic usage(); 7132747Sbostic } 7232747Sbostic break; 731101Sbill } 7430126Sbostic else if (ifd == ERR) { /* input file */ 7532747Sbostic if ((ifd = open(argv[cnt], O_RDONLY, 0)) < 0) { 7630126Sbostic perror(argv[cnt]); 7736598Sbostic exit(1); 7830126Sbostic } 791101Sbill } 8030126Sbostic else if (!*fname) /* output file prefix */ 8132747Sbostic strcpy(fname, argv[cnt]); 8230126Sbostic else 8330126Sbostic usage(); 8430126Sbostic } 8530126Sbostic if (ifd == ERR) /* stdin by default */ 8630126Sbostic ifd = 0; 8730126Sbostic if (bytecnt) 8830126Sbostic split1(); 8930126Sbostic if (!numlines) 9030126Sbostic numlines = DEFLINE; 9130126Sbostic split2(); 9236598Sbostic exit(0); 9330126Sbostic } 9430126Sbostic 9530126Sbostic /* 9630126Sbostic * split1 -- 9730126Sbostic * split by bytes 9830126Sbostic */ 9930126Sbostic split1() 10030126Sbostic { 10136598Sbostic register long bcnt; 10236598Sbostic register int dist, len; 10336598Sbostic register char *C; 10430126Sbostic 10530126Sbostic for (bcnt = 0;;) 10632747Sbostic switch(len = read(ifd, bfr, MAXBSIZE)) { 10732747Sbostic case 0: 10832747Sbostic exit(OK); 10932747Sbostic case ERR: 11032747Sbostic perror("read"); 11136598Sbostic exit(1); 11232747Sbostic default: 11332747Sbostic if (!file_open) { 11432747Sbostic newfile(); 11532747Sbostic file_open = YES; 11632747Sbostic } 11732747Sbostic if (bcnt + len >= bytecnt) { 11832747Sbostic dist = bytecnt - bcnt; 11936598Sbostic if (write(ofd, bfr, dist) != dist) 12036598Sbostic wrerror(); 12132747Sbostic len -= dist; 12232747Sbostic for (C = bfr + dist; len >= bytecnt; len -= bytecnt, C += bytecnt) { 12330126Sbostic newfile(); 12436598Sbostic if (write(ofd, C, (int)bytecnt) != bytecnt) 12536598Sbostic wrerror(); 12630126Sbostic } 12732747Sbostic if (len) { 12832747Sbostic newfile(); 12936598Sbostic if (write(ofd, C, len) != len) 13036598Sbostic wrerror(); 13130126Sbostic } 13232747Sbostic else 13332747Sbostic file_open = NO; 13432747Sbostic bcnt = len; 13532747Sbostic } 13632747Sbostic else { 13732747Sbostic bcnt += len; 13836598Sbostic if (write(ofd, bfr, len) != len) 13936598Sbostic wrerror(); 14032747Sbostic } 1411101Sbill } 14230126Sbostic } 1431101Sbill 14430126Sbostic /* 14530126Sbostic * split2 -- 14630126Sbostic * split by lines 14730126Sbostic */ 14830126Sbostic split2() 14930126Sbostic { 15036598Sbostic register char *Ce, *Cs; 15136598Sbostic register long lcnt; 15236598Sbostic register int len, bcnt; 15330126Sbostic 15430126Sbostic for (lcnt = 0;;) 15532747Sbostic switch(len = read(ifd, bfr, MAXBSIZE)) { 15632747Sbostic case 0: 15732747Sbostic exit(0); 15832747Sbostic case ERR: 15932747Sbostic perror("read"); 16036598Sbostic exit(1); 16132747Sbostic default: 16232747Sbostic if (!file_open) { 16332747Sbostic newfile(); 16432747Sbostic file_open = YES; 16532747Sbostic } 16632747Sbostic for (Cs = Ce = bfr; len--; Ce++) 16732747Sbostic if (*Ce == '\n' && ++lcnt == numlines) { 16836598Sbostic bcnt = Ce - Cs + 1; 16936598Sbostic if (write(ofd, Cs, bcnt) != bcnt) 17036598Sbostic wrerror(); 17132747Sbostic lcnt = 0; 17232747Sbostic Cs = Ce + 1; 17332747Sbostic if (len) 17432747Sbostic newfile(); 17532747Sbostic else 17632747Sbostic file_open = NO; 17730126Sbostic } 17836598Sbostic if (Cs < Ce) { 17936598Sbostic bcnt = Ce - Cs; 18036598Sbostic if (write(ofd, Cs, bcnt) != bcnt) 18136598Sbostic wrerror(); 18236598Sbostic } 1831101Sbill } 18430126Sbostic } 18530126Sbostic 18630126Sbostic /* 18730126Sbostic * newfile -- 18830126Sbostic * open a new file 18930126Sbostic */ 19030126Sbostic newfile() 19130126Sbostic { 19236598Sbostic static long fnum; 19336598Sbostic static short defname; 19436598Sbostic static char *fpnt; 19530126Sbostic 19630126Sbostic if (ofd == ERR) { 19730126Sbostic if (fname[0]) { 19830126Sbostic fpnt = fname + strlen(fname); 19930126Sbostic defname = NO; 2001101Sbill } 20130126Sbostic else { 20230126Sbostic fname[0] = 'x'; 20330126Sbostic fpnt = fname + 1; 20430126Sbostic defname = YES; 20530126Sbostic } 20630126Sbostic ofd = fileno(stdout); 20730126Sbostic } 20830126Sbostic /* 20930126Sbostic * hack to increase max files; original code just wandered through 21030126Sbostic * magic characters. Maximum files is 3 * 26 * 26 == 2028 21130126Sbostic */ 21230126Sbostic #define MAXFILES 676 21330126Sbostic if (fnum == MAXFILES) { 21430126Sbostic if (!defname || fname[0] == 'z') { 21532747Sbostic fputs("split: too many files.\n", stderr); 21636598Sbostic exit(1); 21730126Sbostic } 21830126Sbostic ++fname[0]; 21930126Sbostic fnum = 0; 22030126Sbostic } 22130126Sbostic fpnt[0] = fnum / 26 + 'a'; 22230126Sbostic fpnt[1] = fnum % 26 + 'a'; 22330126Sbostic ++fnum; 22432747Sbostic if (!freopen(fname, "w", stdout)) { 22532747Sbostic fprintf(stderr, "split: unable to write to %s.\n", fname); 22630126Sbostic exit(ERR); 22730126Sbostic } 2281101Sbill } 22930126Sbostic 23030126Sbostic /* 23130126Sbostic * usage -- 23230126Sbostic * print usage message and die 23330126Sbostic */ 23430126Sbostic usage() 23530126Sbostic { 23632747Sbostic fputs("usage: split [-] [-#] [-b byte_count] [file [prefix]]\n", stderr); 23736598Sbostic exit(1); 23830126Sbostic } 23936598Sbostic 24036598Sbostic /* 24136598Sbostic * wrerror -- 24236598Sbostic * write error 24336598Sbostic */ 24436598Sbostic wrerror() 24536598Sbostic { 24636598Sbostic perror("split: write"); 24736598Sbostic exit(1); 24836598Sbostic } 249