Marked some more applets NOEXEC/NOFORK
[oweals/busybox.git] / coreutils / dos2unix.c
1 /* vi: set sw=4 ts=4: */
2 /*
3  * dos2unix for BusyBox
4  *
5  * dos2unix '\n' convertor 0.5.0
6  * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997)
7  * Copyright 1997,.. by Peter Hanecak <hanecak@megaloman.sk>.
8  * All rights reserved.
9  *
10  * dos2unix filters reading input from stdin and writing output to stdout.
11  *
12  * Licensed under GPLv2 or later, see file LICENSE in this source tree.
13 */
14
15 #include "libbb.h"
16
17 /* This is a NOEXEC applet. Be very careful! */
18
19 enum {
20         CT_UNIX2DOS = 1,
21         CT_DOS2UNIX
22 };
23
24 /* if fn is NULL then input is stdin and output is stdout */
25 static void convert(char *fn, int conv_type)
26 {
27         FILE *in, *out;
28         int i;
29         char *temp_fn = temp_fn; /* for compiler */
30         char *resolved_fn = resolved_fn;
31
32         in = stdin;
33         out = stdout;
34         if (fn != NULL) {
35                 struct stat st;
36
37                 resolved_fn = xmalloc_follow_symlinks(fn);
38                 if (resolved_fn == NULL)
39                         bb_simple_perror_msg_and_die(fn);
40                 in = xfopen_for_read(resolved_fn);
41                 fstat(fileno(in), &st);
42
43                 temp_fn = xasprintf("%sXXXXXX", resolved_fn);
44                 i = mkstemp(temp_fn);
45                 if (i == -1
46                  || fchmod(i, st.st_mode) == -1
47                 ) {
48                         bb_simple_perror_msg_and_die(temp_fn);
49                 }
50                 out = xfdopen_for_write(i);
51         }
52
53         while ((i = fgetc(in)) != EOF) {
54                 if (i == '\r')
55                         continue;
56                 if (i == '\n')
57                         if (conv_type == CT_UNIX2DOS)
58                                 fputc('\r', out);
59                 fputc(i, out);
60         }
61
62         if (fn != NULL) {
63                 if (fclose(in) < 0 || fclose(out) < 0) {
64                         unlink(temp_fn);
65                         bb_perror_nomsg_and_die();
66                 }
67                 xrename(temp_fn, resolved_fn);
68                 free(temp_fn);
69                 free(resolved_fn);
70         }
71 }
72
73 int dos2unix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
74 int dos2unix_main(int argc UNUSED_PARAM, char **argv)
75 {
76         int o, conv_type;
77
78         /* See if we are supposed to be doing dos2unix or unix2dos */
79         conv_type = CT_UNIX2DOS;
80         if (applet_name[0] == 'd') {
81                 conv_type = CT_DOS2UNIX;
82         }
83
84         /* -u convert to unix, -d convert to dos */
85         opt_complementary = "u--d:d--u"; /* mutually exclusive */
86         o = getopt32(argv, "du");
87
88         /* Do the conversion requested by an argument else do the default
89          * conversion depending on our name.  */
90         if (o)
91                 conv_type = o;
92
93         argv += optind;
94         do {
95                 /* might be convert(NULL) if there is no filename given */
96                 convert(*argv, conv_type);
97         } while (*argv && *++argv);
98
99         return 0;
100 }