#include #include "line.h" #include "qp.h" unsigned char qp_atoh(unsigned char); unsigned char qp_hex2asc(unsigned char, unsigned char); int qp_decode(line_t *l, char *str) { unsigned char c = 0; unsigned long bytes = 0; char *h = NULL, *t = NULL; t = NULL; bytes = 0; for (h = str; *h;) { if (*h == '=') { if (t) line_inject(l, t, bytes); t = (h + 1); /* Require at least *one* byte after the equal sign (even though we should require two). */ if (!(*(h + 1))) return 0; /* Wrap? */ if ((*(h + 1) == '\n') || (*(h + 1) == '\r')) { /* Hope clients encode correctly... */ if ((*(h + 2) == '\n') || (*(h + 2) == '\r')) h += 3; /* ..but if they dont, we'll hafta accept that. */ else h += 2; t = NULL; bytes = 0; continue; } if (!(*(h + 2))) return 0; c = qp_hex2asc(*(h + 1), *(h + 2)); line_inject(l, &c, 1); t = NULL; bytes = 0; h += 3; continue; } else { if (!t) t = h; bytes++; h++; } } if (t) line_inject(l, t, bytes); return 1; } unsigned char qp_atoh(unsigned char x) { unsigned char c = 0; if ((x >= 'a') && (x <= 'f')) { c = x - 87; return c; } if ((x >= 'A') && (x <= 'F')) { c = x - 55; return c; } if ((x >= '0') && (x <= '9')) { c = x - 48; return c; } return 0; } unsigned char qp_hex2asc(unsigned char s, unsigned char f) { unsigned char val1 = 0, val2 = 0, val3 = 0; val1 = qp_atoh(f); val2 = qp_atoh(s); val3 = val1 + (val2 * 15) + val2; return val3; }