-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsplits.c
More file actions
134 lines (112 loc) · 3.65 KB
/
splits.c
File metadata and controls
134 lines (112 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
Split a file into multiple chunks
by John Walker
http://www.fourmilab.ch/
This program is in the public domain.
This program reads a file given by its first argument (or
standard input if the argument is "-") and writes files in the
current directory of the size given by the second argument
(default 100K). These files are named with the name of the
input file ("StdIn" if "-" was used) with a three digit chunk
number appended. You can reassemble the original file with
the command:
cat <fname>.??? ><fname>
or the equivalent COPY /B on MSDOS.
This program assumes that fread() and fwrite() take 4 byte
block length arguments and can read and write chunks as large
as the given specified output block size. Thus, it is
unlikely to work on 16 bit architectures. File open calls may
have to be modified on systems where binary files must be
identified at open time.
Release history:
April 12, 1993: Original release.
October 26, 1998: HTML documentation, WIN32 binary file
support and executable program, switch
to ZIP distribution format.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif
int main(int argc, char *argv[])
{
char splitfn[280];
long part = 0, chunk = 100 * 1024;
FILE *fp, *op;
char *fb;
char *ofn = "StdIn";
if (argc < 2 || argc > 3) {
fprintf(stderr, "Usage: splits [<filename>|-] [chunk(Kb)]\n");
return 2;
}
if (argc > 2) {
long lch = atol(argv[2]);
if (lch < 1) {
fprintf(stderr, "Invalid chunk size.\n");
return 2;
}
chunk = lch * 1024L;
}
fb = malloc((unsigned) chunk);
if (fb == NULL) {
fprintf(stderr, "Unable to allocate %ld byte I/O buffer.\n", chunk);
return 1;
}
if (strcmp(argv[1], "-") != 0) {
ofn = argv[1];
fp = fopen(argv[1], "rb");
if (fp == NULL) {
fprintf(stderr, "Cannot open file %s\n", argv[1]);
return 2;
}
} else {
/* Warning! Splits needs to read its input file and
write the output files in binary mode--without any
translation of end of line or end of file sequences.
On Unix, there is no distinction between text and
binary I/O, but on ill-conceived systems such as
MS-DOS/Windows and Mac OS, the default I/O mode
for C programs is text mode. Complicating the
matter further is the fact that, while almost all
modern implementations of C allow a "b" specification
in an fopen() call (on Unix it's just ignored), there
is no standard whatsoever for setting the mode of
automatically-opened streams such as stdin and
stdout.
This file contains code, conditional on _WIN32, which
sets binary mode using the method prescribed by
Microsoft Visual C 5.0 ("Monkey C"); this may
require modification if you're using a different
compiler or release of Monkey C. When opening files
explicitly, we also specify the "b" modifier so that
even if standard input doesn't work, reading explicitly
named files will still work. */
fp = stdin;
#ifdef _WIN32
_setmode(_fileno(fp), _O_BINARY);
#endif
}
while (1) {
long fl;
fl = fread(fb, 1, (int) chunk, fp);
if (fl > 0) {
sprintf(splitfn, "%03ld.%s", ++part, ofn);
op = fopen(splitfn, "wb");
if (op == NULL) {
fprintf(stderr, "Cannot create output file %s\n", splitfn);
return 2;
}
fwrite(fb, 1, (int) fl, op);
fclose(op);
} else {
break;
}
}
if (fp != stdin) {
fclose(fp);
}
return 0;
}