regex: updates from neatvi
[neatmail.git] / me.c
blob2e6500f3c443caa85ec6f61190f4ca1c3b6ae5e1
1 /* encode a mime message */
2 #include <stdio.h>
3 #include <string.h>
4 #include <ctype.h>
6 #define LNSZ 1024
8 static char out[LNSZ * 2]; /* collected characters */
9 static int out_n; /* number of characters in out */
10 static int out_mime; /* set if inside a mime encoded word */
11 static int out_mbuf; /* buffered characters */
12 static int out_mlen; /* number of buffered characters */
13 static int out_mhdr; /* header type; 's' for subject 'a' for address */
15 static char *b64_chr =
16 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
18 /* encode 3 bytes in base64 */
19 static void b64_word(char *s, unsigned num)
21 s[3] = b64_chr[num & 0x3f];
22 num >>= 6;
23 s[2] = b64_chr[num & 0x3f];
24 num >>= 6;
25 s[1] = b64_chr[num & 0x3f];
26 num >>= 6;
27 s[0] = b64_chr[num & 0x3f];
30 static void q_beg(void)
32 out[out_n++] = '=';
33 out[out_n++] = '?';
34 out[out_n++] = 'U';
35 out[out_n++] = 'T';
36 out[out_n++] = 'F';
37 out[out_n++] = '-';
38 out[out_n++] = '8';
39 out[out_n++] = '?';
40 out[out_n++] = 'B';
41 out[out_n++] = '?';
42 out_mime = 1;
45 static void q_put(int c)
47 out_mlen++;
48 out_mbuf = (out_mbuf << 8) | c;
49 if (out_mlen == 3) {
50 b64_word(out + out_n, out_mbuf);
51 out_n += 4;
52 out_mlen = 0;
53 out_mbuf = 0;
57 static void q_end(void)
59 int i;
60 for (i = 0; out_mlen; i++)
61 q_put(0);
62 while (--i >= 0)
63 out[out_n - i - 1] = '=';
64 out_mime = 0;
65 out[out_n++] = '?';
66 out[out_n++] = '=';
69 static void out_flush(void)
71 if (out_mime)
72 q_end();
73 out[out_n] = '\0';
74 fputs(out, stdout);
75 out_n = 0;
78 static void out_chr(int c)
80 if (out_mime) {
81 if (c == '\r' || c == '\n') {
82 q_end();
83 } else if (out_mhdr == 'a' && c != ' ' && ~c & 0x80) {
84 q_end();
85 } else if (out_n > 65 && (c & 0xc0) != 0x80) {
86 q_end();
87 out_flush();
88 out[out_n++] = '\n';
89 out[out_n++] = ' ';
90 q_beg();
93 if (c == '\n' || out_n > 75) {
94 out[out_n++] = c;
95 out_flush();
96 } else {
97 if (out_mhdr && (c & 0x80) && !out_mime)
98 q_beg();
99 if (out_mime)
100 q_put(c);
101 else
102 out[out_n++] = c;
106 static int startswith(char *r, char *s)
108 while (*s)
109 if (tolower((unsigned char) *s++) != tolower((unsigned char) *r++))
110 return 0;
111 return 1;
114 int me(char *argv[])
116 char ln[LNSZ];
117 while (fgets(ln, sizeof(ln), stdin)) {
118 char *s = ln;
119 if (ln[0] != ' ' && ln[0] != '\t')
120 out_mhdr = 0;
121 if (startswith(ln, "from:") || startswith(ln, "to:") ||
122 startswith(ln, "cc:") || startswith(ln, "bcc:"))
123 out_mhdr = 'a';
124 if (startswith(ln, "subject:"))
125 out_mhdr = 's';
126 while (*s)
127 out_chr((unsigned char) *s++);
128 if (ln[0] == '\n' || ln[0] == '\r')
129 break;
131 while (fgets(ln, sizeof(ln), stdin))
132 fputs(ln, stdout);
133 return 0;