blob: 5bf16e5af99c4127f16c98cfaf55cb2b478294f1 [file] [log] [blame]
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +00001/* vi: set sw=4 ts=4: */
Eric Andersencff3fe32000-09-20 19:22:26 +00002/*
Eric Andersen544891d2001-02-22 23:37:30 +00003 * dos2unix for BusyBox
4 *
5 * dos2unix '\n' convertor 0.5.0
Rob Landley330ac852006-03-14 21:49:18 +00006 * based on Unix2Dos 0.9.0 by Peter Hanecak (made 19.2.1997)
Eric Andersen544891d2001-02-22 23:37:30 +00007 * 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.
Eric Andersen544891d2001-02-22 23:37:30 +000011 *
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000012 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
Rob Landley330ac852006-03-14 21:49:18 +000013*/
Eric Andersencff3fe32000-09-20 19:22:26 +000014
Glenn L McGratha6ce6702001-04-12 02:26:04 +000015#include <string.h>
Eric Andersen655584b2001-07-25 07:22:55 +000016#include <unistd.h>
Eric Andersen59443962001-08-22 05:06:29 +000017#include <stdint.h>
Eric Andersen655584b2001-07-25 07:22:55 +000018#include <fcntl.h>
Eric Andersencbe31da2001-02-20 06:14:08 +000019#include "busybox.h"
Eric Andersencff3fe32000-09-20 19:22:26 +000020
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000021enum ConvType {
22 CT_UNIX2DOS = 1,
23 CT_DOS2UNIX
24} ConvType;
"Vladimir N. Oleynik"6f347ef2005-10-15 10:23:55 +000025
Rob Landleyf8154692005-09-01 03:11:19 +000026/* if fn is NULL then input is stdin and output is stdout */
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000027static int convert(char *fn)
Eric Andersen655584b2001-07-25 07:22:55 +000028{
Rob Landleyf8154692005-09-01 03:11:19 +000029 FILE *in, *out;
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000030 int i;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000031
32 if (fn != NULL) {
Manuel Novoa III cad53642003-03-19 09:13:01 +000033 in = bb_xfopen(fn, "rw");
Rob Landley330ac852006-03-14 21:49:18 +000034 /*
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000035 The file is then created with mode read/write and
36 permissions 0666 for glibc 2.0.6 and earlier or
37 0600 for glibc 2.0.7 and later.
38 */
39 snprintf(bb_common_bufsiz1, sizeof(bb_common_bufsiz1), "%sXXXXXX", fn);
Rob Landley330ac852006-03-14 21:49:18 +000040 /*
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000041 sizeof bb_common_bufsiz1 is 4096, so it should be big enough to
42 hold the full path. However if the output is truncated the
43 subsequent call to mkstemp would fail.
44 */
45 if ((i = mkstemp(&bb_common_bufsiz1[0])) == -1
46 || chmod(bb_common_bufsiz1, 0600) == -1) {
Rob Landley330ac852006-03-14 21:49:18 +000047 bb_perror_nomsg_and_die();
48 }
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000049 out = fdopen(i, "w+");
Rob Landley330ac852006-03-14 21:49:18 +000050 if (!out) {
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000051 close(i);
52 remove(bb_common_bufsiz1);
Glenn L McGratha6ce6702001-04-12 02:26:04 +000053 }
Rob Landleyf8154692005-09-01 03:11:19 +000054 } else {
55 in = stdin;
56 out = stdout;
Glenn L McGratha6ce6702001-04-12 02:26:04 +000057 }
58
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000059 while ((i = fgetc(in)) != EOF) {
60 if (i == '\r')
Rob Landleyf8154692005-09-01 03:11:19 +000061 continue;
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000062 if (i == '\n') {
Rob Landleyf8154692005-09-01 03:11:19 +000063 if (ConvType == CT_UNIX2DOS)
64 fputc('\r', out);
65 fputc('\n', out);
66 continue;
67 }
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000068 fputc(i, out);
Glenn L McGratha6ce6702001-04-12 02:26:04 +000069 }
70
71 if (fn != NULL) {
Rob Landley330ac852006-03-14 21:49:18 +000072 if (fclose(in) < 0 || fclose(out) < 0) {
73 bb_perror_nomsg();
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000074 remove(bb_common_bufsiz1);
Rob Landley330ac852006-03-14 21:49:18 +000075 return -2;
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000076 }
Rob Landley330ac852006-03-14 21:49:18 +000077 /* Assume they are both on the same filesystem (which
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000078 * should be true since we put them into the same directory
79 * so we _should_ be ok, but you never know... */
80 if (rename(bb_common_bufsiz1, fn) < 0) {
81 bb_perror_msg("cannot rename '%s' as '%s'", bb_common_bufsiz1, fn);
Rob Landley330ac852006-03-14 21:49:18 +000082 return -1;
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000083 }
Glenn L McGratha6ce6702001-04-12 02:26:04 +000084 }
85
86 return 0;
87}
88
Eric Andersenc7bda1c2004-03-15 08:29:22 +000089int dos2unix_main(int argc, char *argv[])
Eric Andersen655584b2001-07-25 07:22:55 +000090{
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 */
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +000094 if (bb_applet_name[0] == 'd') {
95 ConvType = CT_DOS2UNIX; /*2 */
Rob Landleyf8154692005-09-01 03:11:19 +000096 } else {
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +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) {
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +0000112 while (optind < argc)
113 if ((o = convert(argv[optind++])) < 0)
Eric Andersen544891d2001-02-22 23:37:30 +0000114 break;
Bernhard Reutner-Fischerb5353a22006-06-01 18:30:42 +0000115 } else
116 o = convert(NULL);
Eric Andersen544891d2001-02-22 23:37:30 +0000117
118 return o;
119}