4 * (c) 2006 Martin Mares <mj@ucw.cz>
18 const char progname[] = "smail";
20 static char *local_user;
21 static char *local_domain;
22 static char *from_user;
23 static char *from_domain;
26 static struct tm *now_tm;
32 start_sendmail(char **oargv, int oargc)
34 char **argv = xmalloc(sizeof(char *) * (oargc+4));
36 argv[argc++] = "/usr/sbin/sendmail";
38 char from[strlen(from_user) + strlen(from_domain) + 16];
41 sprintf(from, "%s+f-%04d%02d%02d@%s", from_user, now_tm->tm_year + 1900, now_tm->tm_mon + 1, now_tm->tm_mday, from_domain);
44 verb(1, "Using -f %s", from);
47 memcpy(argv+argc, oargv, sizeof(char *) * oargc);
51 // for (uns i=0; argv[i]; i++) verb(2, "Option: <%s>", argv[i]);
55 die("pipe failed: %m");
59 die("fork failed: %m");
65 execvp(argv[0], argv);
66 die("Cannot exec %s: %m", argv[0]);
69 sm_fh = fdopen(pfd[1], "w");
71 die("fdopen() failed: %m");
72 verb(1, "Forked pid %d for %s", sm_pid, argv[0]);
78 if (ferror(sm_fh) || fclose(sm_fh))
79 die("Error occured when writing to sendmail pipe");
85 die("wait failed: %m");
88 verb(1, "Subprocess %d finished with status 0x%x", p, st);
92 die("Sendmail process failed with exit code %d", WEXITSTATUS(st));
96 die("Sendmail process died on signal %d", WIFSIGNALED(st));
97 die("Sendmail process died with unknown status 0x%x", st);
109 if (!fgets(hdr, sizeof(hdr), stdin))
110 die("Malformed mail headers: unexpected EOF");
111 char *nl = strchr(hdr, '\n');
113 die("Malformed mail headers: line too long");
114 if (hdr[0] == '\r' || hdr[0] == '\n')
116 if (strncasecmp(hdr, "Message-ID:", 11))
126 if (gethostname(hostname, sizeof(hostname)))
129 hostname[sizeof(hostname)-1] = 0;
130 fprintf(sm_fh, "Message-ID: <%s+md-%04d%02d%02d.%02d%02d%02d.%d.%s@%s>\n",
132 now_tm->tm_year + 1900, now_tm->tm_mon + 1, now_tm->tm_mday,
133 now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec,
145 while ((n = fread(buf, 1, sizeof(buf), stdin)) > 0)
146 fwrite(buf, 1, n, sm_fh);
148 die("Malformed mail body: %m");
154 fprintf(stderr, "Usage: smail [<options>] -- <sendmail-options>\n\
157 -f<user>@<domain>\tGenerate envelope sender address for easy identification of bounces\n\
158 -l<user>@<domain>\tAdd Message-ID for detection of messages looped back\n\
159 -v\t\t\tIncrease verbosity\n\
161 MailDups " STR(VERSION) ", (c) " STR(YEAR) " Martin Mares <mj@ucw.cz>\n\
162 It can be freely distributed and used according to the GNU GPL v2.\n\
168 main(int argc, char **argv)
171 while ((c = getopt(argc, argv, "f:l:v")) >= 0)
176 char *c = strchr(optarg, '@');
186 char *c = strchr(optarg, '@');
202 if (!(now_tm = gmtime(&now)))
203 die("gmtime() failed: %m");
205 start_sendmail(argv+optind, argc-optind);