Add in kent robotti's updated dos2unix.c
[platform/upstream/busybox.git] / coreutils / dos2unix.c
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 <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <getopt.h>
35 #include "busybox.h"
36
37 #define CT_AUTO 0
38 #define CT_UNIX2DOS     1
39 #define CT_DOS2UNIX     2
40
41 int convert(char *fn, int ConvType);
42
43 int dos2unix_main(int argc, char *argv[]) {
44         int ConvType = CT_AUTO;
45         int o;
46
47         // process parameters
48         while ((o = getopt(argc, argv, "du")) != EOF) {
49                 switch (o) {
50                 case 'd':
51                         ConvType = CT_UNIX2DOS;
52                         break;
53                 case 'u':
54                         ConvType = CT_DOS2UNIX;
55                         break;
56                 default:
57                         show_usage();
58                 }
59         }
60
61         if (optind < argc) {
62                 while(optind < argc)
63                         if ((o = convert(argv[optind++], ConvType)) < 0)
64                                 break;
65         }
66         else
67                 o = convert(NULL, ConvType);
68
69         return o;
70 }
71
72 // if fn is NULL then input is stdin and output is stdout
73 int convert(char *fn, int ConvType) {
74         char c;
75         char *tempFn = NULL;
76         FILE *in = stdin, *out = stdout;
77
78         if (fn != NULL) {
79                 if ((in = fopen(fn, "r")) == NULL) {
80                         perror_msg(fn);
81                         return -1;
82                 }
83                 tempFn = tmpnam(NULL);
84                 if (tempFn == NULL || (out = fopen(tempFn, "w")) == NULL) {
85                         perror_msg(NULL);
86                         return -2;
87                 }
88         }
89
90         while ((c = fgetc(in)) != EOF) {
91                 if (c == '\r') {
92                         if ((ConvType == CT_UNIX2DOS) && (fn != NULL)) {
93                                 // file is alredy in DOS format so it is not necessery to touch it
94                                 if (fclose(in) < 0 || fclose(out) < 0 || remove(tempFn) < 0) {
95                                         perror_msg(NULL);
96                                         return -2;
97                                 }
98                                 return 0;
99                         }
100                         if (!ConvType)
101                                 ConvType = CT_DOS2UNIX;
102                         break;
103                 }
104                 if (c == '\n') {
105                         if ((ConvType == CT_DOS2UNIX) && (fn != NULL)) {
106                                 // file is alredy in UNIX format so it is not necessery to touch it
107                                 if (fclose(in) < 0 || fclose(out) < 0 || remove(tempFn) < 0) {
108                                         perror_msg(NULL);
109                                         return -2;
110                                 }
111                                 return 0;
112                         }
113                         if (!ConvType)
114                                 ConvType = CT_UNIX2DOS;
115                         if (ConvType == CT_UNIX2DOS)
116                                 fputc('\r', out);
117                         fputc('\n', out);
118                         break;
119                 }
120                 fputc(c, out);
121         }
122         if (c != EOF)
123                 while ((c = fgetc(in)) != EOF) {
124                         if (c == '\r')
125                                 continue;
126                         if (c == '\n') {
127                                 if (ConvType == CT_UNIX2DOS)
128                                         fputc('\r', out);
129                                 fputc('\n', out);
130                                 continue;
131                         }
132                 fputc(c, out);
133         }
134
135         if (fn != NULL) {
136             if (fclose(in) < 0 || fclose(out) < 0 || 
137                     (in = fopen(tempFn, "r")) == NULL || (out = fopen(fn, "w")) == NULL) {
138                 perror_msg(NULL);
139                 return -2;
140             }
141
142             while ((c = fgetc(in)) != EOF)
143                 fputc(c, out);
144
145             if (fclose(in) < 0 || fclose(out) < 0 || remove(tempFn) < 0) {
146                 perror_msg(NULL);
147                 return -2;
148             }
149         }
150
151         return 0;
152 }