As per subject. While here I couldn't resist simplifying the "From " check too, although it is indipendent from the rest of the diff. (could commit separately if preferred.)
ok? diff /usr/src commit - 79631e141468cced94e502d777a484fa0eb1f60f path + /usr/src blob - 815fe58323c8b912f5676a7d5a29cc90b5bb434c file + libexec/mail.local/mail.local.c --- libexec/mail.local/mail.local.c +++ libexec/mail.local/mail.local.c @@ -111,9 +111,10 @@ storemail(char *from) { FILE *fp = NULL; time_t tval; - int fd, eline; - size_t len; - char *line, *tbuf; + int fd, eline = 1; + char *tbuf, *line = NULL; + size_t linesize = 0; + ssize_t linelen; if ((tbuf = strdup(_PATH_LOCTMP)) == NULL) merr(EX_OSERR, "unable to allocate memory"); @@ -125,23 +126,13 @@ storemail(char *from) (void)time(&tval); (void)fprintf(fp, "From %s %s", from, ctime(&tval)); - for (eline = 1, tbuf = NULL; (line = fgetln(stdin, &len));) { - /* We have to NUL-terminate the line since fgetln does not */ - if (line[len - 1] == '\n') - line[len - 1] = '\0'; - else { - /* No trailing newline, so alloc space and copy */ - if ((tbuf = malloc(len + 1)) == NULL) - merr(EX_OSERR, "unable to allocate memory"); - memcpy(tbuf, line, len); - tbuf[len] = '\0'; - line = tbuf; - } + while ((linelen = getline(&line, &linesize, stdin)) != -1) { + if (line[linelen - 1] == '\n') + line[linelen - 1] = '\0'; if (line[0] == '\0') eline = 1; else { - if (eline && line[0] == 'F' && len > 5 && - !memcmp(line, "From ", 5)) + if (eline && !strncmp(line, "From ", 5)) (void)putc('>', fp); eline = 0; } @@ -149,7 +140,7 @@ storemail(char *from) if (ferror(fp)) break; } - free(tbuf); + free(line); /* Output a newline; note, empty messages are allowed. */ (void)putc('\n', fp);