blob: c5021f9d066487feb67434249ef6b0341e1817b1 [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
Rob Landley330ac852006-03-14 21:49:18 +00005 * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997)
Eric Andersen544891d2001-02-22 23:37:30 +00006 * 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.
Eric Andersen544891d2001-02-22 23:37:30 +000010 *
Rob Landley330ac852006-03-14 21:49:18 +000011 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
12*/
Eric Andersencff3fe32000-09-20 19:22:26 +000013
Glenn L McGratha6ce6702001-04-12 02:26:04 +000014#include <string.h>
Eric Andersen655584b2001-07-25 07:22:55 +000015#include <unistd.h>
Eric Andersen59443962001-08-22 05:06:29 +000016#include <stdint.h>
Eric Andersen655584b2001-07-25 07:22:55 +000017#include <fcntl.h>
18#include <sys/time.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000019#include "busybox.h"
Eric Andersencff3fe32000-09-20 19:22:26 +000020
Manuel Novoa III cad53642003-03-19 09:13:01 +000021#define CT_UNIX2DOS 1
22#define CT_DOS2UNIX 2
"Vladimir N. Oleynik"6f347ef2005-10-15 10:23:55 +000023#define tempFn bb_common_bufsiz1
24
Rob Landleyf8154692005-09-01 03:11:19 +000025/* if fn is NULL then input is stdin and output is stdout */
Eric Andersenc7bda1c2004-03-15 08:29:22 +000026static int convert(char *fn, int ConvType)
Eric Andersen655584b2001-07-25 07:22:55 +000027{
28 int c, fd;
Rob Landleyf8154692005-09-01 03:11:19 +000029 FILE *in, *out;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000030
31 if (fn != NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000032 in = bb_xfopen(fn, "rw");
Rob Landley330ac852006-03-14 21:49:18 +000033 /*
34 The file is then created with mode read/write and
35 permissions 0666 for glibc 2.0.6 and earlier or
36 0600 for glibc 2.0.7 and later.
37 */
38 snprintf(tempFn, sizeof(tempFn), "%sXXXXXX", fn);
39 /*
40 sizeof tempFn is 4096, so it should be big enough to hold the full
41 path. however if the output is truncated the subsequent call to
42 mkstemp would fail.
43 */
44 if ((fd = mkstemp(&tempFn[0])) == -1 || chmod(tempFn, 0600) == -1) {
45 bb_perror_nomsg_and_die();
46 }
47 out = fdopen(fd, "w+");
48 if (!out) {
Eric Andersen655584b2001-07-25 07:22:55 +000049 close(fd);
50 remove(tempFn);
Glenn L McGratha6ce6702001-04-12 02:26:04 +000051 }
Rob Landleyf8154692005-09-01 03:11:19 +000052 } else {
53 in = stdin;
54 out = stdout;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000055 }
56
57 while ((c = fgetc(in)) != EOF) {
Rob Landleyf8154692005-09-01 03:11:19 +000058 if (c == '\r')
59 continue;
60 if (c == '\n') {
61 if (ConvType == CT_UNIX2DOS)
62 fputc('\r', out);
63 fputc('\n', out);
64 continue;
65 }
Glenn L McGratha6ce6702001-04-12 02:26:04 +000066 fputc(c, out);
67 }
68
69 if (fn != NULL) {
Rob Landley330ac852006-03-14 21:49:18 +000070 if (fclose(in) < 0 || fclose(out) < 0) {
71 bb_perror_nomsg();
72 remove(tempFn);
73 return -2;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000074 }
Rob Landley330ac852006-03-14 21:49:18 +000075
76 /* Assume they are both on the same filesystem (which
77 * should be true since we put them into the same directory
78 * so we _should_ be ok, but you never know... */
79 if (rename(tempFn, fn) < 0) {
80 bb_perror_msg("cannot rename '%s' as '%s'", tempFn, fn);
81 return -1;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000082 }
83 }
84
85 return 0;
86}
87
Eric Andersenc7bda1c2004-03-15 08:29:22 +000088int dos2unix_main(int argc, char *argv[])
Eric Andersen655584b2001-07-25 07:22:55 +000089{
Rob Landleyf8154692005-09-01 03:11:19 +000090 int ConvType;
Eric Andersen544891d2001-02-22 23:37:30 +000091 int o;
92
Rob Landleyf8154692005-09-01 03:11:19 +000093 /* See if we are supposed to be doing dos2unix or unix2dos */
Eric Andersen655584b2001-07-25 07:22:55 +000094 if (argv[0][0]=='d') {
Bernhard Reutner-Fischer99a072d2006-03-18 23:05:37 +000095 ConvType = CT_DOS2UNIX; /*2*/
Rob Landleyf8154692005-09-01 03:11:19 +000096 } else {
Bernhard Reutner-Fischer99a072d2006-03-18 23:05:37 +000097 ConvType = CT_UNIX2DOS; /*1*/
Eric Andersen655584b2001-07-25 07:22:55 +000098 }
Rob Landley330ac852006-03-14 21:49:18 +000099 /* -u and -d are mutally exclusive */
100 bb_opt_complementally = "?:u--d:d--u";
Rob Landleyf8154692005-09-01 03:11:19 +0000101 /* process parameters */
Rob Landley330ac852006-03-14 21:49:18 +0000102 /* -u convert to unix */
103 /* -d convert to dos */
104 o = bb_getopt_ulflags(argc, argv, "du");
Rob Landleyf8154692005-09-01 03:11:19 +0000105
106 /* Do the conversion requested by an argument else do the default
107 * conversion depending on our name. */
108 if (o)
109 ConvType = o;
Eric Andersen544891d2001-02-22 23:37:30 +0000110
111 if (optind < argc) {
112 while(optind < argc)
113 if ((o = convert(argv[optind++], ConvType)) < 0)
114 break;
115 }
116 else
117 o = convert(NULL, ConvType);
118
119 return o;
120}