send use m_getfld2
authorPhilipp Takacs <philipp@bureaucracy.de>
Sun, 20 Aug 2023 07:49:46 +0000 (09:49 +0200)
committerPhilipp Takacs <philipp@bureaucracy.de>
Thu, 24 Aug 2023 19:35:17 +0000 (21:35 +0200)
uip/send.c

index 148c05b..f4169ee 100644 (file)
@@ -39,8 +39,6 @@ char *distfile = NULL;
 static char body_file_name[MAXPATHLEN + 1];
 /* name of mhbuild composition temporary file */
 static char composition_file_name[MAXPATHLEN + 1]; 
-static int field_size;  /* size of header field buffer */
-static char *field;  /* header field buffer */
 static FILE *draft_file;  /* draft file pointer */
 static FILE *body_file;  /* body file pointer */
 static FILE *composition_file;  /* composition file pointer */
@@ -54,7 +52,6 @@ static int sendaux(char **, int, char *, struct stat *);
 static int attach(char *);
 static int signandenc(char *);
 static void clean_up_temporary_files(void);
-static int get_line(void);
 static void make_mime_composition_file_entry(char *);
 static char* strexit(int status);
 
@@ -331,8 +328,11 @@ sendsbr(char **vec, int vecp, char *drft, struct stat *st)
 static int
 attach(char *draft_file_name)
 {
+       enum state state;
+       struct field f = {{0}};
+       int compnum;
+       int finished_header = 0;
        char buf[MAXPATHLEN + 6];
-       int c;
        int length = strlen(attach_hdr);
        char *p;
 
@@ -344,9 +344,6 @@ attach(char *draft_file_name)
                adios(EX_IOERR, NULL, "can't open draft file `%s'.", draft_file_name);
        }
 
-       /* We'll grow the buffer as needed. */
-       field = mh_xcalloc(field_size = 256, sizeof(char));
-
        /*
        ** MIMEify
        */
@@ -369,28 +366,42 @@ attach(char *draft_file_name)
 
        /* Copy non-attachment header fields to the temp composition file. */
        rewind(draft_file);
-       while (get_line() != EOF && *field && *field != '-') {
-               if (strncasecmp(field, VRSN_FIELD, strlen(VRSN_FIELD))==0 &&
-                               field[strlen(VRSN_FIELD)] == ':') {
-                       /*
-                       ** The draft is already in MIME format, thus
-                       ** back out and use the original draft file.
-                       */
-                       clean_up_temporary_files();
-                       return DONE;
-               }
-
-               if (strncasecmp(field, attach_hdr, length) != 0 ||
-                               field[length] != ':') {
-                       fprintf(composition_file, "%s\n", field);
+       for (compnum = 1, state = FLD2; state == FLD2 || state == BODY2;) {
+               switch (state = m_getfld2(state, &f, draft_file)) {
+               case LENERR2:
+                       state = FLD2;
+               case FLD2:
+                       compnum++;
+                       if (strncasecmp(f.name, VRSN_FIELD, sizeof(VRSN_FIELD) - 1)==0) {
+                               /*
+                               ** The draft is already in MIME format, thus
+                               ** back out and use the original draft file.
+                               */
+                               clean_up_temporary_files();
+                               return DONE;
+                       }
+                       if (strncasecmp(f.name, attach_hdr, length) != 0 ||
+                                       f.namelen != length) {
+                               fprintf(composition_file, "%s:%s", f.name, f.value);
+                       }
+                       break;
+               case BODY2:
+                       if (!finished_header) {
+                               fputs("--------\n", composition_file);
+                               finished_header++;
+                       }
+                       fputs(f.value, body_file);
+                       break;
+               case FILEEOF2:
+                       break;
+               case FMTERR2:
+                       adios(EX_DATAERR, NULL, "message format error in component #%d", compnum);
+               case IOERR2:
+                       adios(EX_IOERR, NULL, "error reading draft file: %s", draft_file_name);
+               default:
+                       adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
                }
        }
-       fputs("--------\n", composition_file);
-
-       /* Copy the message body to the temporary file. */
-       while ((c = getc(draft_file)) != EOF) {
-               putc(c, body_file);
-       }
        fclose(body_file);
 
        /* Add a mhbuild MIME composition file line for the body */
@@ -403,17 +414,33 @@ attach(char *draft_file_name)
        ** composition file for each.
        */
        rewind(draft_file);
-       while (get_line() != EOF && *field && *field != '-') {
-               if (strncasecmp(field, attach_hdr, length) == 0 &&
-                               field[length] == ':') {
-                       p = trim(field+length+1);
-                       if (*p == '+') {
-                               /* forwarded message */
-                               fprintf(composition_file, "#forw [forwarded message(s)] %s\n", p);
-                       } else {
-                               /* regular attachment */
-                               make_mime_composition_file_entry(p);
+       for (compnum = 1, state = FLD2; state == FLD2;) {
+               switch (state = m_getfld2(state, &f, draft_file)) {
+               case LENERR2:
+                       state = FLD2;
+               case FLD2:
+                       compnum++;
+                       if (strncasecmp(f.name, attach_hdr, length) == 0 &&
+                                       f.namelen == length) {
+                               p = trim(f.value);
+                               if (*p == '+') {
+                                       /* forwarded message */
+                                       fprintf(composition_file, "#forw [forwarded message(s)] %s\n", p);
+                               } else {
+                                       /* regular attachment */
+                                       make_mime_composition_file_entry(p);
+                               }
                        }
+                       break;
+               case BODY2:
+               case FILEEOF2:
+                       break;
+               case FMTERR2:
+                       adios(EX_DATAERR, NULL, "message format error in component #%d", compnum);
+               case IOERR2:
+                       adios(EX_IOERR, NULL, "error reading draft file: %s", draft_file_name);
+               default:
+                       adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
                }
        }
        fclose(composition_file);
@@ -437,6 +464,9 @@ attach(char *draft_file_name)
 static int
 signandenc(char *draft_file_name)
 {
+       enum state state;
+       int compnum;
+       struct field f = {{0}};
        char buf[BUFSIZ];
        int dosign = 0;
        int doenc = 0;
@@ -450,20 +480,32 @@ signandenc(char *draft_file_name)
                adios(EX_IOERR, NULL, "can't open draft file `%s'.", draft_file_name);
        }
 
-       /* We'll grow the buffer as needed. */
-       field = mh_xcalloc(field_size = 256, sizeof(char));
-
        /* Scan the draft file for an attachment header field name. */
-       while (get_line() != EOF && *field != '\0' && *field != '-') {
-               if (strncasecmp(field, sign_hdr, strlen(sign_hdr))==0 &&
-                               field[strlen(sign_hdr)] == ':') {
-                       dosign = 1;
-               }
-               if (strncasecmp(field, enc_hdr, strlen(enc_hdr))==0 &&
-                               field[strlen(enc_hdr)] == ':') {
-                       doenc = 1;
+       for (compnum = 1, state = FLD2; state == FLD2;) {
+               switch (state = m_getfld2(state, &f, draft_file)) {
+               case LENERR2:
+                       state = FLD2;
+               case FLD2:
+                       compnum++;
+                       if (strcasecmp(f.name, sign_hdr)==0) {
+                               dosign = 1;
+                       }
+                       if (strcasecmp(f.name, enc_hdr)==0) {
+                               doenc = 1;
+                       }
+                       break;
+               case BODY2:
+               case FILEEOF2:
+                       break;
+               case FMTERR2:
+                       adios(EX_DATAERR, NULL, "message format error in component #%d", compnum);
+               case IOERR2:
+                       adios(EX_IOERR, NULL, "error reading draft file: %s", draft_file_name);
+               default:
+                       adios(EX_SOFTWARE, NULL, "getfld() returned %d", state);
                }
        }
+
        if (!dosign && !doenc) {
                return DONE;
        }
@@ -500,35 +542,6 @@ clean_up_temporary_files(void)
        return;
 }
 
-static int
-get_line(void)
-{
-       int c;  /* current character */
-       int n;  /* number of bytes in buffer */
-       char *p;
-
-       /*
-       ** Get a line from the input file, growing the field buffer as
-       ** needed.  We do this so that we can fit an entire line in the
-       ** buffer making it easy to do a string comparison on both the
-       ** field name and the field body which might be a long path name.
-       */
-       for (n = 0, p = field; (c = getc(draft_file)) != EOF; *p++ = c) {
-               if (c == '\n' && (c = getc(draft_file)) != ' ' && c != '\t') {
-                       ungetc(c, draft_file);
-                       c = '\n';
-                       break;
-               }
-               if (++n >= field_size - 1) {
-                       field = mh_xrealloc(field, field_size += 256);
-                       p = field + n - 1;
-               }
-       }
-       *p = '\0';
-
-       return (c);
-}
-
 static void
 make_mime_composition_file_entry(char *file_name)
 {