X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=coreutils%2Fdos2unix.c;h=0464df76f5395cec4a86b3bd68942206b47d7233;hb=2454ebd85ddbbdc0971e9b848032f66e23245ebe;hp=e97c3ba9aa90852a190f10f25d148bd85690d381;hpb=5a9d441b2cfb4f3614971f918bb69b5e7a5ea2c9;p=oweals%2Fbusybox.git diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index e97c3ba9a..0464df76f 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c @@ -28,110 +28,151 @@ */ #include -#include +#include +#include +#include +#include #include "busybox.h" -// if fn is NULL then input is stdin and output is stdout -static int convert(char *fn, int ConvType) { - int c; - char *tempFn = NULL; - FILE *in = stdin, *out = stdout; +#define CT_UNIX2DOS 1 +#define CT_DOS2UNIX 2 + +/* We are making a lame pseudo-random string generator here. in + * convert(), each pass through the while loop will add more and more + * stuff into value, which is _supposed_ to wrap. We don't care about + * it being accurate. We care about it being messy, since we use it + * to pick a random letter to add to out temporary file. */ +typedef unsigned long int bb_uint64_t; + +#define tempFn bb_common_bufsiz1 + +/* if fn is NULL then input is stdin and output is stdout */ +static int convert(char *fn, int ConvType) +{ + int c, fd; + struct timeval tv; + static bb_uint64_t value=0; + FILE *in, *out; if (fn != NULL) { - if ((in = wfopen(fn, "r")) == NULL) { - return -1; - } - if ((out = tmpfile()) == NULL) { - perror_msg(NULL); - return -2; + in = bb_xfopen(fn, "rw"); + safe_strncpy(tempFn, fn, sizeof(tempFn)); + c = strlen(tempFn); + tempFn[c] = '.'; + while(1) { + /* tempFn is BUFSIZ so the last addressable spot it BUFSIZ-1. + * The loop increments by 2. So this must check for BUFSIZ-3. */ + if (c >=BUFSIZ-3) + bb_error_msg_and_die("unique name not found"); + /* Get some semi random stuff to try and make a + * random filename based (and in the same dir as) + * the input file... */ + gettimeofday (&tv, NULL); + value += ((bb_uint64_t) tv.tv_usec << 16) ^ tv.tv_sec ^ getpid (); + tempFn[++c] = ((value%62) < 26)?(value%62)+97: + ((value%62) < 52)?(value%62)+39: + (value%62)-4; + tempFn[c+1] = '\0'; + value /= 62; + + if ((fd = open(tempFn, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0 ) { + continue; + } + out = fdopen(fd, "w+"); + if (!out) { + close(fd); + remove(tempFn); + continue; + } + break; } + } else { + in = stdin; + out = stdout; } while ((c = fgetc(in)) != EOF) { if (c == '\r') { if ((ConvType == CT_UNIX2DOS) && (fn != NULL)) { - // file is alredy in DOS format so it is not necessery to touch it + /* file is already in DOS format so it is + * not necessary to touch it. */ + remove(tempFn); if (fclose(in) < 0 || fclose(out) < 0) { - perror_msg(NULL); + bb_perror_nomsg(); return -2; } return 0; } - if (!ConvType) - ConvType = CT_DOS2UNIX; break; } if (c == '\n') { if ((ConvType == CT_DOS2UNIX) && (fn != NULL)) { - // file is alredy in UNIX format so it is not necessery to touch it + /* file is already in DOS format so it is + * not necessary to touch it. */ + remove(tempFn); if ((fclose(in) < 0) || (fclose(out) < 0)) { - perror_msg(NULL); + bb_perror_nomsg(); return -2; } return 0; } - if (!ConvType) { - ConvType = CT_UNIX2DOS; - } if (ConvType == CT_UNIX2DOS) { fputc('\r', out); } - fputc('\n', out); - break; } fputc(c, out); } - if (c != EOF) - while ((c = fgetc(in)) != EOF) { - if (c == '\r') - continue; - if (c == '\n') { - if (ConvType == CT_UNIX2DOS) - fputc('\r', out); - fputc('\n', out); - continue; - } + while (c != EOF && (c = fgetc(in)) != EOF) { + if (c == '\r') + continue; + if (c == '\n') { + if (ConvType == CT_UNIX2DOS) + fputc('\r', out); + fputc('\n', out); + continue; + } fputc(c, out); } if (fn != NULL) { - if (fclose(in) < 0 || fclose(out) < 0 || - (in = fopen(tempFn, "r")) == NULL || (out = fopen(fn, "w")) == NULL) { - perror_msg(NULL); - return -2; + if (fclose(in) < 0 || fclose(out) < 0) { + bb_perror_nomsg(); + remove(tempFn); + return -2; } - while ((c = fgetc(in)) != EOF) { - fputc(c, out); - } - - if ((fclose(in) < 0) || (fclose(out) < 0)) { - perror_msg(NULL); - return -2; + /* Assume they are both on the same filesystem (which + * should be true since we put them into the same directory + * so we _should_ be ok, but you never know... */ + if (rename(tempFn, fn) < 0) { + bb_perror_msg("unable to rename '%s' as '%s'", tempFn, fn); + return -1; } } return 0; } -int dos2unix_main(int argc, char *argv[]) { - int ConvType = CT_AUTO; +int dos2unix_main(int argc, char *argv[]) +{ + int ConvType; int o; - // process parameters - while ((o = getopt(argc, argv, "du")) != EOF) { - switch (o) { - case 'd': - ConvType = CT_UNIX2DOS; - break; - case 'u': - ConvType = CT_DOS2UNIX; - break; - default: - show_usage(); - } + /* See if we are supposed to be doing dos2unix or unix2dos */ + if (argv[0][0]=='d') { + ConvType = CT_DOS2UNIX; + } else { + ConvType = CT_UNIX2DOS; } + /* process parameters */ + o = bb_getopt_ulflags(argc, argv, "ud"); + + /* Do the conversion requested by an argument else do the default + * conversion depending on our name. */ + if (o) + ConvType = o; + if (optind < argc) { while(optind < argc) if ((o = convert(argv[optind++], ConvType)) < 0)