update to use "person.root" login for kerberos
[unix-history] / usr / src / usr.bin / split / split.c
CommitLineData
86bcea21
KB
1/*
2 * Copyright (c) 1987 Regents of the University of California.
3 * All rights reserved.
4 *
cb956e54 5 * %sccs.include.redist.c%
86bcea21
KB
6 */
7
8#ifndef lint
9char copyright[] =
10"@(#) Copyright (c) 1987 Regents of the University of California.\n\
11 All rights reserved.\n";
12#endif /* not lint */
13
14#ifndef lint
cb956e54 15static char sccsid[] = "@(#)split.c 4.8 (Berkeley) %G%";
86bcea21 16#endif /* not lint */
460f3462
KB
17
18#include <sys/param.h>
19#include <sys/file.h>
f37d3151 20#include <stdio.h>
460f3462
KB
21#include <ctype.h>
22
23#define DEFLINE 1000 /* default num lines per file */
24#define ERR -1 /* general error */
460f3462
KB
25#define NO 0 /* no/false */
26#define OK 0 /* okay exit */
27#define YES 1 /* yes/true */
f37d3151 28
460f3462
KB
29static long bytecnt, /* byte count to split on */
30 numlines; /* lines in each file */
31static int ifd = ERR, /* input file descriptor */
32 ofd = ERR; /* output file descriptor */
33static short file_open; /* if a file open */
34static char bfr[MAXBSIZE], /* I/O buffer */
35 fname[MAXPATHLEN]; /* file name */
f37d3151 36
86bcea21 37main(argc, argv)
4bf5591e
KB
38 int argc;
39 char **argv;
f37d3151 40{
4bf5591e
KB
41 register int cnt;
42 long atol();
43 char *strcpy();
f37d3151 44
86bcea21 45 for (cnt = 1; cnt < argc; ++cnt) {
460f3462
KB
46 if (argv[cnt][0] == '-')
47 switch(argv[cnt][1]) {
86bcea21
KB
48 case 0: /* stdin by request */
49 if (ifd != ERR)
50 usage();
51 ifd = 0;
52 break;
53 case 'b': /* byte count split */
54 if (numlines)
55 usage();
56 if (!argv[cnt][2])
57 bytecnt = atol(argv[++cnt]);
58 else
59 bytecnt = atol(argv[cnt] + 2);
60 if (bytecnt <= 0) {
61 fputs("split: byte count must be greater than zero.\n", stderr);
62 usage();
63 }
64 break;
65 default:
66 if (!isdigit(argv[cnt][1]) || bytecnt)
67 usage();
68 if ((numlines = atol(argv[cnt] + 1)) <= 0) {
69 fputs("split: line count must be greater than zero.\n", stderr);
70 usage();
71 }
72 break;
460f3462
KB
73 }
74 else if (ifd == ERR) { /* input file */
86bcea21 75 if ((ifd = open(argv[cnt], O_RDONLY, 0)) < 0) {
460f3462 76 perror(argv[cnt]);
4bf5591e 77 exit(1);
f37d3151 78 }
f37d3151 79 }
460f3462 80 else if (!*fname) /* output file prefix */
86bcea21 81 strcpy(fname, argv[cnt]);
460f3462
KB
82 else
83 usage();
84 }
85 if (ifd == ERR) /* stdin by default */
86 ifd = 0;
87 if (bytecnt)
88 split1();
89 if (!numlines)
90 numlines = DEFLINE;
91 split2();
4bf5591e 92 exit(0);
460f3462
KB
93}
94
95/*
96 * split1 --
97 * split by bytes
98 */
460f3462
KB
99split1()
100{
4bf5591e
KB
101 register long bcnt;
102 register int dist, len;
103 register char *C;
460f3462
KB
104
105 for (bcnt = 0;;)
86bcea21
KB
106 switch(len = read(ifd, bfr, MAXBSIZE)) {
107 case 0:
108 exit(OK);
109 case ERR:
110 perror("read");
4bf5591e 111 exit(1);
86bcea21
KB
112 default:
113 if (!file_open) {
114 newfile();
115 file_open = YES;
116 }
117 if (bcnt + len >= bytecnt) {
118 dist = bytecnt - bcnt;
4bf5591e
KB
119 if (write(ofd, bfr, dist) != dist)
120 wrerror();
86bcea21
KB
121 len -= dist;
122 for (C = bfr + dist; len >= bytecnt; len -= bytecnt, C += bytecnt) {
460f3462 123 newfile();
4bf5591e
KB
124 if (write(ofd, C, (int)bytecnt) != bytecnt)
125 wrerror();
460f3462 126 }
86bcea21
KB
127 if (len) {
128 newfile();
4bf5591e
KB
129 if (write(ofd, C, len) != len)
130 wrerror();
460f3462 131 }
86bcea21
KB
132 else
133 file_open = NO;
134 bcnt = len;
135 }
136 else {
137 bcnt += len;
4bf5591e
KB
138 if (write(ofd, bfr, len) != len)
139 wrerror();
86bcea21 140 }
460f3462
KB
141 }
142}
143
144/*
145 * split2 --
146 * split by lines
147 */
460f3462
KB
148split2()
149{
4bf5591e
KB
150 register char *Ce, *Cs;
151 register long lcnt;
152 register int len, bcnt;
460f3462
KB
153
154 for (lcnt = 0;;)
86bcea21
KB
155 switch(len = read(ifd, bfr, MAXBSIZE)) {
156 case 0:
157 exit(0);
158 case ERR:
159 perror("read");
4bf5591e 160 exit(1);
86bcea21
KB
161 default:
162 if (!file_open) {
163 newfile();
164 file_open = YES;
165 }
166 for (Cs = Ce = bfr; len--; Ce++)
167 if (*Ce == '\n' && ++lcnt == numlines) {
4bf5591e
KB
168 bcnt = Ce - Cs + 1;
169 if (write(ofd, Cs, bcnt) != bcnt)
170 wrerror();
86bcea21
KB
171 lcnt = 0;
172 Cs = Ce + 1;
173 if (len)
174 newfile();
175 else
176 file_open = NO;
460f3462 177 }
4bf5591e
KB
178 if (Cs < Ce) {
179 bcnt = Ce - Cs;
180 if (write(ofd, Cs, bcnt) != bcnt)
181 wrerror();
182 }
f37d3151 183 }
460f3462 184}
f37d3151 185
460f3462
KB
186/*
187 * newfile --
188 * open a new file
189 */
460f3462
KB
190newfile()
191{
4bf5591e
KB
192 static long fnum;
193 static short defname;
194 static char *fpnt;
460f3462
KB
195
196 if (ofd == ERR) {
197 if (fname[0]) {
198 fpnt = fname + strlen(fname);
199 defname = NO;
f37d3151 200 }
460f3462
KB
201 else {
202 fname[0] = 'x';
203 fpnt = fname + 1;
204 defname = YES;
205 }
206 ofd = fileno(stdout);
207 }
208 /*
209 * hack to increase max files; original code just wandered through
210 * magic characters. Maximum files is 3 * 26 * 26 == 2028
211 */
212#define MAXFILES 676
213 if (fnum == MAXFILES) {
214 if (!defname || fname[0] == 'z') {
86bcea21 215 fputs("split: too many files.\n", stderr);
4bf5591e 216 exit(1);
f37d3151 217 }
460f3462
KB
218 ++fname[0];
219 fnum = 0;
220 }
221 fpnt[0] = fnum / 26 + 'a';
222 fpnt[1] = fnum % 26 + 'a';
223 ++fnum;
86bcea21
KB
224 if (!freopen(fname, "w", stdout)) {
225 fprintf(stderr, "split: unable to write to %s.\n", fname);
460f3462
KB
226 exit(ERR);
227 }
228}
229
230/*
231 * usage --
232 * print usage message and die
233 */
460f3462
KB
234usage()
235{
86bcea21 236 fputs("usage: split [-] [-#] [-b byte_count] [file [prefix]]\n", stderr);
4bf5591e
KB
237 exit(1);
238}
239
240/*
241 * wrerror --
242 * write error
243 */
244wrerror()
245{
246 perror("split: write");
247 exit(1);
f37d3151 248}