dos2unix.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * dos2unix for BusyBox
  4. *
  5. * dos2unix '\n' converter 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. //config:config DOS2UNIX
  15. //config: bool "dos2unix (5.2 kb)"
  16. //config: default y
  17. //config: help
  18. //config: dos2unix is used to convert a text file from DOS format to
  19. //config: UNIX format, and vice versa.
  20. //config:
  21. //config:config UNIX2DOS
  22. //config: bool "unix2dos (5.2 kb)"
  23. //config: default y
  24. //config: help
  25. //config: unix2dos is used to convert a text file from UNIX format to
  26. //config: DOS format, and vice versa.
  27. //applet:IF_DOS2UNIX(APPLET_NOEXEC(dos2unix, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, dos2unix))
  28. //applet:IF_UNIX2DOS(APPLET_NOEXEC(unix2dos, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, unix2dos))
  29. //kbuild:lib-$(CONFIG_DOS2UNIX) += dos2unix.o
  30. //kbuild:lib-$(CONFIG_UNIX2DOS) += dos2unix.o
  31. //usage:#define dos2unix_trivial_usage
  32. //usage: "[-ud] [FILE]"
  33. //usage:#define dos2unix_full_usage "\n\n"
  34. //usage: "Convert FILE in-place from DOS to Unix format.\n"
  35. //usage: "When no file is given, use stdin/stdout.\n"
  36. //usage: "\n -u dos2unix"
  37. //usage: "\n -d unix2dos"
  38. //usage:
  39. //usage:#define unix2dos_trivial_usage
  40. //usage: "[-ud] [FILE]"
  41. //usage:#define unix2dos_full_usage "\n\n"
  42. //usage: "Convert FILE in-place from Unix to DOS format.\n"
  43. //usage: "When no file is given, use stdin/stdout.\n"
  44. //usage: "\n -u dos2unix"
  45. //usage: "\n -d unix2dos"
  46. #include "libbb.h"
  47. /* This is a NOEXEC applet. Be very careful! */
  48. enum {
  49. CT_UNIX2DOS = 1,
  50. CT_DOS2UNIX
  51. };
  52. /* if fn is NULL then input is stdin and output is stdout */
  53. static void convert(char *fn, int conv_type)
  54. {
  55. FILE *in, *out;
  56. int ch;
  57. char *temp_fn = temp_fn; /* for compiler */
  58. char *resolved_fn = resolved_fn;
  59. in = stdin;
  60. out = stdout;
  61. if (fn != NULL) {
  62. struct stat st;
  63. int fd;
  64. resolved_fn = xmalloc_follow_symlinks(fn);
  65. if (resolved_fn == NULL)
  66. bb_simple_perror_msg_and_die(fn);
  67. in = xfopen_for_read(resolved_fn);
  68. xfstat(fileno(in), &st, resolved_fn);
  69. temp_fn = xasprintf("%sXXXXXX", resolved_fn);
  70. fd = xmkstemp(temp_fn);
  71. if (fchmod(fd, st.st_mode) == -1)
  72. bb_simple_perror_msg_and_die(temp_fn);
  73. fchown(fd, st.st_uid, st.st_gid);
  74. out = xfdopen_for_write(fd);
  75. }
  76. while ((ch = fgetc(in)) != EOF) {
  77. if (ch == '\r')
  78. continue;
  79. if (ch == '\n')
  80. if (conv_type == CT_UNIX2DOS)
  81. fputc('\r', out);
  82. fputc(ch, out);
  83. }
  84. if (fn != NULL) {
  85. if (fclose(in) < 0 || fclose(out) < 0) {
  86. unlink(temp_fn);
  87. bb_perror_nomsg_and_die();
  88. }
  89. xrename(temp_fn, resolved_fn);
  90. free(temp_fn);
  91. free(resolved_fn);
  92. }
  93. }
  94. int dos2unix_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  95. int dos2unix_main(int argc UNUSED_PARAM, char **argv)
  96. {
  97. int o, conv_type;
  98. /* See if we are supposed to be doing dos2unix or unix2dos */
  99. if (ENABLE_DOS2UNIX
  100. && (!ENABLE_UNIX2DOS || applet_name[0] == 'd')
  101. ) {
  102. conv_type = CT_DOS2UNIX;
  103. } else {
  104. conv_type = CT_UNIX2DOS;
  105. }
  106. /* -u convert to unix, -d convert to dos */
  107. o = getopt32(argv, "^" "du" "\0" "u--d:d--u"); /* mutually exclusive */
  108. /* Do the conversion requested by an argument else do the default
  109. * conversion depending on our name. */
  110. if (o)
  111. conv_type = o;
  112. argv += optind;
  113. do {
  114. /* might be convert(NULL) if there is no filename given */
  115. convert(*argv, conv_type);
  116. } while (*argv && *++argv);
  117. return 0;
  118. }