On Mon, 25 Sep 2023 21:31:08 +0200, Walter wrote:
> Yours are the first technical, functional corrections I got about the
> code.  Thanks!  Let's go back in time, then.  I think that what you're
> telling me can be done by simply replacing "break" for "return" in my
> original function.  Tell me what you think, please.

Yesterday I was so tired that I told you nonsense, there's no difference
between puting break or return there, my original funtion already did
what you told me.


--- send.c.orig 2023-09-25 21:01:34.780102611 +0200
+++ send.c      2023-09-25 21:17:11.120117761 +0200
@@ -33,6 +33,10 @@
 #include "rcv.h"
 #include "extern.h"
 
++/* To check charset of the message and add the appropiate MIME headers  */
++static char nutf8;
++static int not_utf8(FILE *s, int len);
+
 static volatile sig_atomic_t sendsignal;       /* Interrupted by a signal? */
 
 /*
@@ -341,6 +345,17 @@
                else
                        puts("Null message body; hope that's ok");
        }
+
+       /* Check non valid UTF-8 characters in the message */
+       nutf8 = not_utf8(mtf, fsize(mtf));
+       rewind(mtf);
+       if (nutf8 > 1) {
+               savedeadletter(mtf);
+               puts("Invalid or incomplete multibyte or wide character");
+               fputs(". . . message not sent.\n", stderr);
+               exit(1);
+       }
+
        /*
         * Now, take the user names from the combined
         * to and cc lists and do all the alias
@@ -369,7 +384,7 @@
        }
        if ((cp = value("record")) != NULL)
                (void)savemail(expand(cp), mtf);
-       
+
        /* Setup sendmail arguments. */
         *ap++ = "sendmail";
         *ap++ = "-i";
@@ -525,6 +540,16 @@
                fmt("To:", hp->h_to, fo, w&GCOMMA), gotcha++;
        if (hp->h_subject != NULL && w & GSUBJECT)
                fprintf(fo, "Subject: %s\n", hp->h_subject), gotcha++;
+       if (nutf8 == 0)
+               fprintf(fo, "MIME-Version: 1.0\n"
+                   "Content-Type: text/plain; charset=us-ascii\n"
+                   "Content-Transfer-Encoding: 7bit\n"),
+                   gotcha++;
+       else if (nutf8 == 1)
+               fprintf(fo, "MIME-Version: 1.0\n"
+                   "Content-Type: text/plain; charset=utf-8\n"
+                   "Content-Transfer-Encoding: 8bit\n"),
+                   gotcha++;
        if (hp->h_cc != NULL && w & GCC)
                fmt("Cc:", hp->h_cc, fo, w&GCOMMA), gotcha++;
        if (hp->h_bcc != NULL && w & GBCC)
@@ -610,3 +635,59 @@
 
        sendsignal = s;
 }
+
+/* Search non valid UTF-8 characters in the message */
+static int
+not_utf8(FILE *fp, int len)
+{
+       int i, n, nonascii;
+       char c;
+       unsigned char s[len];
+
+       i = 0;
+        while ((c = getc(fp)) != EOF)
+               s[i++] = c;
+
+       s[i] = '\0';
+
+       i = n = nonascii = 0;
+       while (s[i] != '\0')
+               if (s[i] <= 0x7f) {
+                       i++;
+               /* Two bytes case */
+               } else if (s[i] >= 0xc2 && s[i] < 0xe0 &&
+                   s[i + 1] >= 0x80 && s[i + 1] <= 0xbf) {
+                       i += 2;
+                       nonascii++;
+               /* Special three bytes case */
+               } else if ((s[i] == 0xe0 &&
+                   s[i + 1] >= 0xa0 && s[i + 1] <= 0xbf &&
+                   s[i + 2] >= 0x80 && s[i + 2] <= 0xbf) ||
+                   /* Three bytes case */
+                   (s[i] > 0xe0 && s[i] < 0xf0 &&
+                   s[i + 1] >= 0x80 && s[i + 1] <= 0xbf &&
+                   s[i + 2] >= 0x80 && s[i + 2] <= 0xbf)) {
+                       i += 3;
+                       nonascii++;
+               /* Special four bytes case */
+               } else if ((s[i] == 0xf0 &&
+                   s[i + 1] >= 0x90 && s[i + 1] <= 0xbf &&
+                   s[i + 2] >= 0x80 && s[i + 2] <= 0xbf &&
+                   s[i + 3] >= 0x80 && s[i + 3] <= 0xbf) ||
+                   /* Four bytes case */
+                   (s[i] > 0xf0 &&
+                   s[i + 1] >= 0x80 && s[i + 1] <= 0xbf &&
+                   s[i + 2] >= 0x80 && s[i + 2] <= 0xbf &&
+                   s[i + 3] >= 0x80 && s[i + 3] <= 0xbf)) {
+                       i += 4;
+                       nonascii++;
+               } else {
+                       n = i + 1;
+                       break;
+               }
+
+       if (nonascii)
+               n++;
+
+       return n;
+}


-- 
Walter

Reply via email to