blob: 68aee13c582bd3e496cb9788eaa558a680330a2c [file] [log] [blame]
Eric Andersencff3fe32000-09-20 19:22:26 +00001/*
Eric Andersen544891d2001-02-22 23:37:30 +00002 * 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 */
Eric Andersencff3fe32000-09-20 19:22:26 +000029
Glenn L McGratha6ce6702001-04-12 02:26:04 +000030#include <string.h>
Eric Andersen544891d2001-02-22 23:37:30 +000031#include <getopt.h>
Eric Andersen655584b2001-07-25 07:22:55 +000032#include <unistd.h>
33#include <fcntl.h>
34#include <sys/time.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000035#include "busybox.h"
Eric Andersencff3fe32000-09-20 19:22:26 +000036
Eric Andersen655584b2001-07-25 07:22:55 +000037static const char letters[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
38
Glenn L McGratha6ce6702001-04-12 02:26:04 +000039// if fn is NULL then input is stdin and output is stdout
Eric Andersen655584b2001-07-25 07:22:55 +000040static int convert(char *fn, int ConvType)
41{
42 int c, fd;
43 struct timeval tv;
44 char tempFn[BUFSIZ];
45 static uint64_t value=0;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000046 FILE *in = stdin, *out = stdout;
47
48 if (fn != NULL) {
Eric Andersen655584b2001-07-25 07:22:55 +000049 if ((in = wfopen(fn, "rw")) == NULL) {
Glenn L McGratha6ce6702001-04-12 02:26:04 +000050 return -1;
51 }
Eric Andersen655584b2001-07-25 07:22:55 +000052 strcpy(tempFn, fn);
53 c = strlen(tempFn);
54 tempFn[c] = '.';
55 while(1) {
56 if (c >=BUFSIZ)
57 error_msg_and_die("unique name not found");
58 /* Get some semi random stuff to try and make a
59 * random filename based (and in the same dir as)
60 * the input file... */
61 gettimeofday (&tv, NULL);
62 value += ((uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid ();
63 tempFn[++c] = letters[value % 62];
64 tempFn[c+1] = '\0';
65 value /= 62;
66
67 if ((fd = open(tempFn, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0 ) {
68 continue;
69 }
70 out = fdopen(fd, "w+");
71 if (!out) {
72 close(fd);
73 remove(tempFn);
74 continue;
75 }
76 break;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000077 }
78 }
79
80 while ((c = fgetc(in)) != EOF) {
81 if (c == '\r') {
82 if ((ConvType == CT_UNIX2DOS) && (fn != NULL)) {
83 // file is alredy in DOS format so it is not necessery to touch it
Eric Andersen655584b2001-07-25 07:22:55 +000084 remove(tempFn);
Glenn L McGratha6ce6702001-04-12 02:26:04 +000085 if (fclose(in) < 0 || fclose(out) < 0) {
86 perror_msg(NULL);
87 return -2;
88 }
89 return 0;
90 }
91 if (!ConvType)
92 ConvType = CT_DOS2UNIX;
93 break;
94 }
95 if (c == '\n') {
96 if ((ConvType == CT_DOS2UNIX) && (fn != NULL)) {
97 // file is alredy in UNIX format so it is not necessery to touch it
Eric Andersen655584b2001-07-25 07:22:55 +000098 remove(tempFn);
Glenn L McGratha6ce6702001-04-12 02:26:04 +000099 if ((fclose(in) < 0) || (fclose(out) < 0)) {
100 perror_msg(NULL);
101 return -2;
102 }
103 return 0;
104 }
105 if (!ConvType) {
106 ConvType = CT_UNIX2DOS;
107 }
108 if (ConvType == CT_UNIX2DOS) {
109 fputc('\r', out);
110 }
111 fputc('\n', out);
112 break;
113 }
114 fputc(c, out);
115 }
116 if (c != EOF)
117 while ((c = fgetc(in)) != EOF) {
118 if (c == '\r')
119 continue;
120 if (c == '\n') {
121 if (ConvType == CT_UNIX2DOS)
122 fputc('\r', out);
123 fputc('\n', out);
124 continue;
125 }
126 fputc(c, out);
127 }
128
129 if (fn != NULL) {
Eric Andersen655584b2001-07-25 07:22:55 +0000130 if (fclose(in) < 0 || fclose(out) < 0) {
131 perror_msg(NULL);
132 remove(tempFn);
133 return -2;
Glenn L McGratha6ce6702001-04-12 02:26:04 +0000134 }
135
Eric Andersen655584b2001-07-25 07:22:55 +0000136 /* Assume they are both on the same filesystem */
137 if (rename(tempFn, fn) < 0) {
138 perror_msg("unable to rename '%s' as '%s'", tempFn, fn);
139 return -1;
Glenn L McGratha6ce6702001-04-12 02:26:04 +0000140 }
141 }
142
143 return 0;
144}
145
Eric Andersen655584b2001-07-25 07:22:55 +0000146int dos2unix_main(int argc, char *argv[])
147{
Eric Andersen544891d2001-02-22 23:37:30 +0000148 int ConvType = CT_AUTO;
149 int o;
150
Eric Andersen655584b2001-07-25 07:22:55 +0000151 //See if we are supposed to be doing dos2unix or unix2dos
152 if (argv[0][0]=='d') {
153 ConvType = CT_DOS2UNIX;
154 }
155 if (argv[0][0]=='u') {
156 ConvType = CT_UNIX2DOS;
157 }
158
Eric Andersen544891d2001-02-22 23:37:30 +0000159 // process parameters
160 while ((o = getopt(argc, argv, "du")) != EOF) {
161 switch (o) {
162 case 'd':
163 ConvType = CT_UNIX2DOS;
164 break;
165 case 'u':
166 ConvType = CT_DOS2UNIX;
167 break;
168 default:
169 show_usage();
170 }
Eric Andersencff3fe32000-09-20 19:22:26 +0000171 }
Eric Andersen544891d2001-02-22 23:37:30 +0000172
173 if (optind < argc) {
174 while(optind < argc)
175 if ((o = convert(argv[optind++], ConvType)) < 0)
176 break;
177 }
178 else
179 o = convert(NULL, ConvType);
180
181 return o;
182}
183