diff options
Diffstat (limited to 'busybox/coreutils/dos2unix.c')
-rw-r--r-- | busybox/coreutils/dos2unix.c | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/busybox/coreutils/dos2unix.c b/busybox/coreutils/dos2unix.c new file mode 100644 index 000000000..df0b4f977 --- /dev/null +++ b/busybox/coreutils/dos2unix.c | |||
@@ -0,0 +1,198 @@ | |||
1 | /* | ||
2 | * dos2unix for BusyBox | ||
3 | * | ||
4 | * dos2unix '\n' convertor 0.5.0 | ||
5 | * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997) | ||
6 | * Copyright 1997,.. by Peter Hanecak <hanecak@megaloman.sk>. | ||
7 | * All rights reserved. | ||
8 | * | ||
9 | * dos2unix filters reading input from stdin and writing output to stdout. | ||
10 | * Without arguments it reverts the format (e.i. if source is in UNIX format, | ||
11 | * output is in DOS format and vice versa). | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This program is distributed in the hope that it will be useful, | ||
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | * GNU General Public License for more details. | ||
22 | * | ||
23 | * You should have received a copy of the GNU General Public License | ||
24 | * along with this program; if not, write to the Free Software | ||
25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
26 | * | ||
27 | * See the COPYING file for license information. | ||
28 | */ | ||
29 | |||
30 | #include <string.h> | ||
31 | #include <getopt.h> | ||
32 | #include <unistd.h> | ||
33 | #include <stdint.h> | ||
34 | #include <fcntl.h> | ||
35 | #include <sys/time.h> | ||
36 | #include "busybox.h" | ||
37 | |||
38 | #define CT_AUTO 0 | ||
39 | #define CT_UNIX2DOS 1 | ||
40 | #define CT_DOS2UNIX 2 | ||
41 | |||
42 | /* We are making a lame pseudo-random string generator here. in | ||
43 | * convert(), each pass through the while loop will add more and more | ||
44 | * stuff into value, which is _supposed_ to wrap. We don't care about | ||
45 | * it being accurate. We care about it being messy, since we then mod | ||
46 | * it by the sizeof(letters) and then use that as an index into letters | ||
47 | * to pick a random letter to add to out temporary file. */ | ||
48 | typedef unsigned long int bb_uint64_t; | ||
49 | |||
50 | static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||
51 | |||
52 | // if fn is NULL then input is stdin and output is stdout | ||
53 | static int convert(char *fn, int ConvType) | ||
54 | { | ||
55 | int c, fd; | ||
56 | struct timeval tv; | ||
57 | char tempFn[BUFSIZ]; | ||
58 | static bb_uint64_t value=0; | ||
59 | FILE *in = stdin, *out = stdout; | ||
60 | |||
61 | if (fn != NULL) { | ||
62 | in = bb_xfopen(fn, "rw"); | ||
63 | safe_strncpy(tempFn, fn, sizeof(tempFn)); | ||
64 | c = strlen(tempFn); | ||
65 | tempFn[c] = '.'; | ||
66 | while(1) { | ||
67 | /* tempFn is BUFSIZ so the last addressable spot it BUFSIZ-1. | ||
68 | * The loop increments by 2. So this must check for BUFSIZ-3. */ | ||
69 | if (c >=BUFSIZ-3) | ||
70 | bb_error_msg_and_die("unique name not found"); | ||
71 | /* Get some semi random stuff to try and make a | ||
72 | * random filename based (and in the same dir as) | ||
73 | * the input file... */ | ||
74 | gettimeofday (&tv, NULL); | ||
75 | value += ((bb_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); | ||
76 | tempFn[++c] = letters[value % 62]; | ||
77 | tempFn[c+1] = '\0'; | ||
78 | value /= 62; | ||
79 | |||
80 | if ((fd = open(tempFn, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0 ) { | ||
81 | continue; | ||
82 | } | ||
83 | out = fdopen(fd, "w+"); | ||
84 | if (!out) { | ||
85 | close(fd); | ||
86 | remove(tempFn); | ||
87 | continue; | ||
88 | } | ||
89 | break; | ||
90 | } | ||
91 | } | ||
92 | |||
93 | while ((c = fgetc(in)) != EOF) { | ||
94 | if (c == '\r') { | ||
95 | if ((ConvType == CT_UNIX2DOS) && (fn != NULL)) { | ||
96 | // file is alredy in DOS format so it is not necessery to touch it | ||
97 | remove(tempFn); | ||
98 | if (fclose(in) < 0 || fclose(out) < 0) { | ||
99 | bb_perror_nomsg(); | ||
100 | return -2; | ||
101 | } | ||
102 | return 0; | ||
103 | } | ||
104 | if (!ConvType) | ||
105 | ConvType = CT_DOS2UNIX; | ||
106 | break; | ||
107 | } | ||
108 | if (c == '\n') { | ||
109 | if ((ConvType == CT_DOS2UNIX) && (fn != NULL)) { | ||
110 | // file is alredy in UNIX format so it is not necessery to touch it | ||
111 | remove(tempFn); | ||
112 | if ((fclose(in) < 0) || (fclose(out) < 0)) { | ||
113 | bb_perror_nomsg(); | ||
114 | return -2; | ||
115 | } | ||
116 | return 0; | ||
117 | } | ||
118 | if (!ConvType) { | ||
119 | ConvType = CT_UNIX2DOS; | ||
120 | } | ||
121 | if (ConvType == CT_UNIX2DOS) { | ||
122 | fputc('\r', out); | ||
123 | } | ||
124 | fputc('\n', out); | ||
125 | break; | ||
126 | } | ||
127 | fputc(c, out); | ||
128 | } | ||
129 | if (c != EOF) | ||
130 | while ((c = fgetc(in)) != EOF) { | ||
131 | if (c == '\r') | ||
132 | continue; | ||
133 | if (c == '\n') { | ||
134 | if (ConvType == CT_UNIX2DOS) | ||
135 | fputc('\r', out); | ||
136 | fputc('\n', out); | ||
137 | continue; | ||
138 | } | ||
139 | fputc(c, out); | ||
140 | } | ||
141 | |||
142 | if (fn != NULL) { | ||
143 | if (fclose(in) < 0 || fclose(out) < 0) { | ||
144 | bb_perror_nomsg(); | ||
145 | remove(tempFn); | ||
146 | return -2; | ||
147 | } | ||
148 | |||
149 | /* Assume they are both on the same filesystem (which | ||
150 | * should be true since we put them into the same directory | ||
151 | * so we _should_ be ok, but you never know... */ | ||
152 | if (rename(tempFn, fn) < 0) { | ||
153 | bb_perror_msg("unable to rename '%s' as '%s'", tempFn, fn); | ||
154 | return -1; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | int dos2unix_main(int argc, char *argv[]) | ||
162 | { | ||
163 | int ConvType = CT_AUTO; | ||
164 | int o; | ||
165 | |||
166 | //See if we are supposed to be doing dos2unix or unix2dos | ||
167 | if (argv[0][0]=='d') { | ||
168 | ConvType = CT_DOS2UNIX; | ||
169 | } | ||
170 | if (argv[0][0]=='u') { | ||
171 | ConvType = CT_UNIX2DOS; | ||
172 | } | ||
173 | |||
174 | // process parameters | ||
175 | while ((o = getopt(argc, argv, "du")) != EOF) { | ||
176 | switch (o) { | ||
177 | case 'd': | ||
178 | ConvType = CT_UNIX2DOS; | ||
179 | break; | ||
180 | case 'u': | ||
181 | ConvType = CT_DOS2UNIX; | ||
182 | break; | ||
183 | default: | ||
184 | bb_show_usage(); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | if (optind < argc) { | ||
189 | while(optind < argc) | ||
190 | if ((o = convert(argv[optind++], ConvType)) < 0) | ||
191 | break; | ||
192 | } | ||
193 | else | ||
194 | o = convert(NULL, ConvType); | ||
195 | |||
196 | return o; | ||
197 | } | ||
198 | |||