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