quote.c - rohrpost - A commandline mail client to change the world as we see it.
 (HTM) git clone git://r-36.net/rohrpost
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       quote.c (2212B)
       ---
            1 /*
            2  * Copy me if you can.
            3  * by 20h
            4  */
            5 
            6 #include <unistd.h>
            7 #include <stdlib.h>
            8 #include <stdio.h>
            9 #include <string.h>
           10 
           11 #include "ind.h"
           12 
           13 char *
           14 qpenc(char *str, int len, int ishdr)
           15 {
           16         char *ret, add[6];
           17         int i, rlen, alen, llen;
           18 
           19         ret = NULL;
           20         for (i = 0, llen = 0, rlen = 0; i < len; i++) {
           21                 if (str[i] < 0x20 || str[i] > 0x7E)
           22                         snprintf(add, sizeof(add), "=%02x", str[i] & 0xFF);
           23                 else {
           24                         switch(str[i]) {
           25                         case ' ':
           26                                 if (ishdr) {
           27                                         add[0] = '_';
           28                                         add[1] = '\0';
           29                                         break;
           30                                 }
           31                         case '?':
           32                         case '_':
           33                         case '=':
           34                         case '(':
           35                         case ')':
           36                         case '<':
           37                         case '>':
           38                         case '@':
           39                         case ',':
           40                         case ';':
           41                         case '\\':
           42                         case '"':
           43                         case '/':
           44                         case '[':
           45                         case ']':
           46                                 snprintf(add, sizeof(add), "=%02x",
           47                                                 str[i] & 0xFF);
           48                                 break;
           49                         case '\n':
           50                                 if (i > 0 && strchr("\t\r\v\f", str[i-1])) {
           51                                         add[0] = '=';
           52                                         add[1] = str[i];
           53                                         add[2] = '\0';
           54                                         break;
           55                                 }
           56                         default:
           57                                 add[0] = str[i];
           58                                 add[1] = '\0';
           59                                 break;
           60                         }
           61                 }
           62                 alen = strlen(add);
           63                 if (llen + alen > 76) {
           64                         ret = memdupcat(ret, rlen, "=\n", 3);
           65                         rlen += 2;
           66                         llen = alen;
           67                 }
           68                 ret = memdupcat(ret, rlen, add, alen+1);
           69                 rlen += alen;
           70                 llen += alen;
           71         }
           72 
           73         return ret;
           74 }
           75 
           76 char *
           77 qpdec(char *str, int *len, int ishdr)
           78 {
           79         char *ret, add, abuf[3], *eabuf;
           80         int i, rlen, pbreak;
           81         long nval;
           82 
           83         ret = NULL;
           84         for (i = 0, rlen = 0; i < *len; i++) {
           85                 add = '\0';
           86                 switch (str[i]) {
           87                 case '_':
           88                         add = (ishdr)? ' ' : '_';
           89                         break;
           90                 case '=':
           91                         pbreak = 0;
           92                         if (str[i+1] == '\r') {
           93                                 i++;
           94                                 pbreak = 1;
           95                         }
           96                         if (str[i+1] == '\n') {
           97                                 i++;
           98                                 pbreak = 1;
           99                         }
          100                         if (str[i+1] == '\0') {
          101                                 i++;
          102                                 pbreak = 1;
          103                         }
          104                         if (pbreak)
          105                                 break;
          106 
          107                         memmove(&abuf, &str[i+1], 2);
          108                         abuf[2] = '\0';
          109 
          110                         eabuf = NULL;
          111                         nval = strtol((char *)&abuf, &eabuf, 16);
          112                         if (eabuf != NULL && *eabuf != '\0')
          113                                 break;
          114 
          115                         add = (char)(nval & 0xFF);
          116                         i += 2;
          117                         break;
          118                 default:
          119                         /*
          120                          * Convert CRLF to LF.
          121                          */
          122                         if (str[i] == '\r' && i < (*len)-1 && str[i+1] == '\n')
          123                                 add = '\0';
          124                         else
          125                                 add = str[i];
          126                         break;
          127                 }
          128                 if (add == '\0')
          129                         continue;
          130 
          131                 ret = reallocz(ret, (++rlen)+1, 0);
          132                 ret[rlen-1] = add;
          133                 ret[rlen] = '\0';
          134         }
          135 
          136         *len = rlen;
          137         return ret;
          138 }
          139