4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
24 * Copyright 1999 Sun Microsystems, Inc. All rights reserved.
25 * Use is subject to license terms.
28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 /* All Rights Reserved */
31 #pragma ident "%Z%%M% %I% %E% SMI"
34 #include <sys/types.h>
35 #include <sys/statvfs.h>
39 #include <sys/param.h>
47 #define DEFAULT_LINES 1000
49 #define ONE_M ONE_K*ONE_K
57 static void next_file_name();
60 static char *progname
;
61 static int suffix_length
= 2;
64 main(int argc
, char **argv
)
66 long long line_count
= 0;
67 long long byte_count
= 0;
70 char head
[MAXPATHLEN
];
71 char *output_file_name
;
75 FILE *out_file
= NULL
;
82 int non_standard_line_count
= FALSE
;
85 (void) setlocale(LC_ALL
, "");
86 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
87 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
89 (void) textdomain(TEXT_DOMAIN
);
93 /* check for explicit stdin "-" option */
94 for (i
= 1; i
< argc
; i
++) {
95 if (strcmp(argv
[i
], "-") == 0) {
98 argv
[i
] = argv
[i
+ 1];
100 /* a "-" before "--" is an error */
101 if ((argv
[i
] != NULL
) &&
102 (strcmp(argv
[i
], "--") == 0)) {
111 /* check for non-standard "-line-count" option */
112 for (i
= 1; i
< argc
; i
++) {
113 if (strcmp(argv
[i
], "--") == 0)
116 if ((argv
[i
][0] == '-') && isdigit(argv
[i
][1])) {
117 if (strlen(&argv
[i
][1]) !=
118 strspn(&argv
[i
][1], "0123456789")) {
119 (void) fprintf(stderr
, gettext(
120 "%s: Badly formed number\n"), progname
);
124 line_count
= (long long) strtoll(&argv
[i
][1],
127 non_standard_line_count
= TRUE
;
129 argv
[i
] = argv
[i
+ 1];
137 while ((opt
= getopt(argc
, argv
, "a:b:l:")) != EOF
) {
140 if (strcmp(optarg
, "--") == 0) {
143 suffix_length
= (long long) strtoll(optarg
,
145 if (suffix_length
<= 0) {
146 (void) fprintf(stderr
, gettext(
147 "%s: Invalid \"-a %s\" option\n"),
154 if (strcmp(optarg
, "--") == 0) {
157 byte_count
= (long long) strtoll(optarg
,
159 if (*(optarg
+ strspn(optarg
, "0123456789")) == 'k')
161 if (*(optarg
+ strspn(optarg
, "0123456789")) == 'm')
166 if (strcmp(optarg
, "--") == 0) {
169 if (non_standard_line_count
== TRUE
) {
172 line_count
= (long long) strtoll(optarg
,
182 if ((in_file
== NULL
) && (optind
< argc
)) {
183 if ((in_file
= fopen(argv
[optind
++], "r")) == NULL
) {
184 (void) perror("split");
188 if (in_file
== NULL
) {
192 /* get output file name */
194 output_file_name
= argv
[optind
];
195 if ((tail
= strrchr(output_file_name
, '/')) == NULL
) {
196 tail
= output_file_name
;
197 (void) getcwd(head
, sizeof (head
));
200 (void) strcpy(head
, output_file_name
);
201 last
= strrchr(head
, '/');
205 if (statvfs(head
, &stbuf
) < 0) {
210 if (strlen(tail
) > (stbuf
.f_namemax
- suffix_length
)) {
211 (void) fprintf(stderr
, gettext(
212 "%s: More than %d characters in file name\n"),
213 progname
, stbuf
.f_namemax
- suffix_length
);
217 output_file_name
= "x";
220 if (((int)strlen(output_file_name
) + suffix_length
) > FILENAME_MAX
) {
221 (void) fprintf(stderr
, gettext(
222 "%s: Output file name too long\n"), progname
);
226 if (line_count
&& byte_count
) {
230 /* use default line count if none specified */
231 if (line_count
== 0) {
232 line_count
= DEFAULT_LINES
;
236 * allocate buffer for the filenames we'll construct; it must be
237 * big enough to hold the name in 'output_file_name' + an n-char
238 * suffix + NULL terminator
240 if ((fname
= (char *)malloc(strlen(output_file_name
) +
241 suffix_length
+ 1)) == NULL
) {
242 (void) perror("split");
246 /* build first output file name */
247 for (i
= 0; output_file_name
[i
]; i
++) {
248 fname
[i
] = output_file_name
[i
];
250 while (i
< (int)strlen(output_file_name
) + suffix_length
) {
254 fname
[i
- 1] = 'a' - 1;
258 output_file_open
= FALSE
;
260 for (out
= 0; out
< byte_count
; out
++) {
266 (void) fprintf(stderr
, gettext(
267 "%s: Read error at file offset %lld: %s, "
269 progname
, ftello(in_file
),
271 if (output_file_open
== TRUE
)
272 (void) fclose(out_file
);
276 if (output_file_open
== TRUE
)
277 (void) fclose(out_file
);
281 if (output_file_open
== FALSE
) {
282 next_file_name(fname
);
283 if ((out_file
= fopen(fname
, "w")) == NULL
) {
284 (void) perror("split");
288 output_file_open
= TRUE
;
290 if (putc(c
, out_file
) == EOF
) {
292 if (output_file_open
== TRUE
)
293 (void) fclose(out_file
);
299 for (out
= 0; out
< line_count
; out
++) {
305 if (errno
== EILSEQ
) {
306 (void) fprintf(stderr
, gettext(
307 "%s: Invalid multibyte sequence "
308 "encountered at file offset %lld, "
310 progname
, ftello(in_file
));
312 (void) perror("split");
314 if (output_file_open
== TRUE
)
315 (void) fclose(out_file
);
319 if (output_file_open
== TRUE
)
320 (void) fclose(out_file
);
324 if (output_file_open
== FALSE
) {
325 next_file_name(fname
);
326 if ((out_file
= fopen(fname
, "w")) == NULL
) {
327 (void) perror("split");
331 output_file_open
= TRUE
;
333 if (putwc(wc
, out_file
) == WEOF
) {
334 (void) perror("split");
335 if (output_file_open
== TRUE
)
336 (void) fclose(out_file
);
340 } while (wc
!= '\n');
343 if (output_file_open
== TRUE
)
344 (void) fclose(out_file
);
352 next_file_name(char *name
)
356 i
= strlen(name
) - 1;
358 while (i
>= (int)(strlen(name
) - suffix_length
)) {
359 if (++name
[i
] <= 'z')
363 (void) fprintf(stderr
, gettext(
364 "%s: Exhausted output file names, aborting split\n"),
373 (void) fprintf(stderr
, gettext(
374 "Usage: %s [-l #] [-a #] [file [name]]\n"
375 " %s [-b #[k|m]] [-a #] [file [name]]\n"
376 " %s [-#] [-a #] [file [name]]\n"),
377 progname
, progname
, progname
);