Hello everyone,

With mailx(1) in mind and resurrecting the few I know about C I wrote
the code pasted below.  It encodes mail headers in MIME quoted-printable
format.  Unless I'm missing something it complies with all stated here:

https://www.ietf.org/rfc/rfc2047.txt

You can pipe to it a line or the whole meassage, it only processes
headers leaving the body untouched.  The problem is, so far, it assumes
all 8bit chars are utf8.  Even when openbsd now only supports utf8
locale you can still enter iso-latin characters while your LC_CTYPE is
set to C, what means if eventually you judge it could be adapted to
patch mailx some non valid utf8 characters check would be mandatory.

So at this point I'm not sure it'll be a good deal since, as far as I
know, to make it able to check for non valid UTF-8 characters would take
more lines of code than the program itself.

I wrote also an encoder to the body, a base64 version and some decoders
but for now I'll show you only this one to not clutter the message.

I'd appreciate your opinion and advice about what can I do from now
(don't hesitate in being frank if you think it's useless).


/*
 * MIME encode mail headers quoted-printable.
 *
 * BUG: it assumes all non ascii characters are UTF-8.
 */

#include <stdio.h>

#define ASCII   0x7f
#define IN      1
#define OUT     0

int
main()
{
        int c, i, n, nl, eightbit, encode, body;
        unsigned char s[256];

        i = n = nl = 0;
        encode = eightbit = body = OUT;

        while ((c = getchar()) != EOF) {
                if (body == IN)
                        putchar(c);
                else if (c == '\n' || c == ' ') {
                        s[i] = '\0';
                        if (eightbit == IN) {
                                if (encode == IN)
                                        printf("=20?= ");
                                printf("=?UTF-8?Q?");
                                while (n < i) {
                                        if (s[n] > ASCII ||
                                                s[n] == '=' ||
                                                s[n] == '?' ||
                                                s[n] == '\t') {
                                                printf("=%02X", s[n]);
                                        } else
                                                printf("%c", s[n]);
                                        ++n;
                                }
                                n = 0;
                                encode = IN;

                                if (c == '\n') {
                                        printf("?=");
                                        putchar(c);
                                        encode = OUT;
                                }

                                eightbit = OUT;
                        } else {
                                if (encode == IN)
                                        printf("?= ");
                                printf("%s", s);
                                putchar(c);
                                encode = OUT;
                        }
                        i = 0;
                        if (c == '\n')
                                ++nl;
                        else
                                nl = 0;
                        if (nl > 1)
                                body = IN;
                } else {
                        if (c > ASCII)
                                eightbit = IN;
                        s[i] = c;
                        ++i;
                }
        }

        return 0;
}

Reply via email to