|
|
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.