ascii.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /*
  2. * Part of Very Secure FTPd
  3. * Licence: GPL v2
  4. * Author: Chris Evans
  5. * ascii.c
  6. *
  7. * Routines to handle ASCII mode tranfers. Yuk.
  8. */
  9. #include "ascii.h"
  10. struct ascii_to_bin_ret
  11. vsf_ascii_ascii_to_bin(char* p_buf, unsigned int in_len, int prev_cr)
  12. {
  13. /* Task: translate all \r\n into plain \n. A plain \r not followed by \n must
  14. * not be removed.
  15. */
  16. struct ascii_to_bin_ret ret;
  17. unsigned int indexx = 0;
  18. unsigned int written = 0;
  19. char* p_out = p_buf + 1;
  20. ret.last_was_cr = 0;
  21. if (prev_cr && (!in_len || p_out[0] != '\n'))
  22. {
  23. p_buf[0] = '\r';
  24. ret.p_buf = p_buf;
  25. written++;
  26. }
  27. else
  28. {
  29. ret.p_buf = p_out;
  30. }
  31. while (indexx < in_len)
  32. {
  33. char the_char = p_buf[indexx + 1];
  34. if (the_char != '\r')
  35. {
  36. *p_out++ = the_char;
  37. written++;
  38. }
  39. else if (indexx == in_len - 1)
  40. {
  41. ret.last_was_cr = 1;
  42. }
  43. else if (p_buf[indexx + 2] != '\n')
  44. {
  45. *p_out++ = the_char;
  46. written++;
  47. }
  48. indexx++;
  49. }
  50. ret.stored = written;
  51. return ret;
  52. }
  53. struct bin_to_ascii_ret
  54. vsf_ascii_bin_to_ascii(const char* p_in,
  55. char* p_out,
  56. unsigned int in_len,
  57. int prev_cr)
  58. {
  59. /* Task: translate all \n not preceeded by \r into \r\n.
  60. * Note that \r\n stays as \r\n. We used to map it to \r\r\n like wu-ftpd
  61. * but have switched to leaving it, like the more popular proftpd.
  62. */
  63. struct bin_to_ascii_ret ret = { 0, 0 };
  64. unsigned int indexx = 0;
  65. unsigned int written = 0;
  66. char last_char = 0;
  67. if (prev_cr)
  68. {
  69. last_char = '\r';
  70. ret.last_was_cr = 1;
  71. }
  72. while (indexx < in_len)
  73. {
  74. char the_char = p_in[indexx];
  75. if (the_char == '\n' && last_char != '\r')
  76. {
  77. *p_out++ = '\r';
  78. written++;
  79. }
  80. *p_out++ = the_char;
  81. written++;
  82. indexx++;
  83. last_char = the_char;
  84. if (the_char == '\r')
  85. {
  86. ret.last_was_cr = 1;
  87. }
  88. else
  89. {
  90. ret.last_was_cr = 0;
  91. }
  92. }
  93. ret.stored = written;
  94. return ret;
  95. }