diff options
Diffstat (limited to 'src/qp-decode.c')
-rw-r--r-- | src/qp-decode.c | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/qp-decode.c b/src/qp-decode.c new file mode 100644 index 0000000..835dc1a --- /dev/null +++ b/src/qp-decode.c @@ -0,0 +1,102 @@ +/* public domain */ + +/* Quoted Printable on stdin -> converted data on stdout */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#ifdef _WIN32 +#ifndef WIN32 +#define WIN32 +#endif +#endif + +#ifdef WIN32 +#include <io.h> +#include <fcntl.h> +#endif + +char *hexdigits = "0123456789ABCDEF"; +char *hexdigits2 = "0123456789abcdef"; + +int +main() +{ + char line[2000], *start, *stop, *copy; + char *d1, *d2, c; + int lineno; + +#ifdef WIN32 + _setmode( _fileno(stdout), _O_BINARY); +#endif + + line[sizeof line - 1] = 0; + lineno = 1; + while (fgets(line, sizeof line - 1, stdin)) { + lineno++; + start = line; + keep_processing: + for (stop = start; *stop && *stop != '=' && *stop != '\n'; stop++) + ; + if (stop != line && *stop == '\n') { + copy = stop; + do { + copy--; + if (*copy != ' ' && *copy != '\t') { + copy++; + break; + } + } while (copy != line); + } else { + copy = stop; + } + while (start != copy) { + putchar(*start); + start++; + } + if (*stop == '\n') { + putchar(*stop); + lineno++; + continue; + } else if (*stop == 0) { + continue; + } else { /* *stop == '=' */ + stop++; + if ((d1 = strchr(hexdigits, *(stop))) && + (d2 = strchr(hexdigits, *(stop+1)))) { + c = (d1 - hexdigits) * 16 + (d2 - hexdigits); + putchar(c); + stop += 2; + } else if ((d1 = strchr(hexdigits2, *(stop))) && + (d2 = strchr(hexdigits2, *(stop+1)))) { + c = (d1 - hexdigits2) * 16 + (d2 - hexdigits2); + putchar(c); + stop += 2; + } else if (*stop == '\n') { + /* soft line break */ + stop++; + } else if (*stop == '\r') { + /* + * Assume the user's lousy delivery software + * didn't convert from Internet's CRLF newline + * convention to the local LF convention. + */ + stop++; + } else if (*stop == ' ' || *stop == '\t') { + /* garbage added in transit */ + for (stop++; *stop && (*stop == ' ' || *stop == '\t'); stop++) + ; + } else { + fprintf(stderr, "Error: line %d: '%c' is something other than line break or hex digit after = in quoted-printable encoding\n", lineno, *stop); + putchar('='); + putchar(*stop); + stop++; + /* exit(1); */ + } + start = stop; + goto keep_processing; + } + } + exit(0); +} |