4 * (c) 2006 Martin Mares <mj@ucw.cz>
18 static char *local_user;
19 static char *local_domain;
20 static char *from_user;
21 static char *from_domain;
24 static struct tm *now_tm;
30 start_sendmail(char **oargv, int oargc)
32 char **argv = xmalloc(sizeof(char *) * (oargc+4));
34 argv[argc++] = "/usr/sbin/sendmail";
36 char from[strlen(from_user) + strlen(from_domain) + 16];
39 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);
42 verb(1, "Using -f %s", from);
45 memcpy(argv+argc, oargv, sizeof(char *) * oargc);
49 // for (uns i=0; argv[i]; i++) verb(2, "Option: <%s>", argv[i]);
53 die("pipe failed: %m");
57 die("fork failed: %m");
63 execvp(argv[0], argv);
64 die("Cannot exec %s: %m", argv[0]);
67 sm_fh = fdopen(pfd[1], "w");
69 die("fdopen() failed: %m");
70 verb(1, "Forked pid %d for %s", sm_pid, argv[0]);
76 if (ferror(sm_fh) || fclose(sm_fh))
77 die("Error occured when writing to sendmail pipe");
83 die("wait failed: %m");
86 verb(1, "Subprocess %d finished with status 0x%x", p, st);
90 die("Sendmail process failed with exit code %d", WEXITSTATUS(st));
94 die("Sendmail process died on signal %d", WIFSIGNALED(st));
95 die("Sendmail process died with unknown status 0x%x", st);
107 if (!fgets(hdr, sizeof(hdr), stdin))
108 die("Malformed mail headers: unexpected EOF");
109 char *nl = strchr(hdr, '\n');
111 die("Malformed mail headers: line too long");
112 if (hdr[0] == '\r' || hdr[0] == '\n')
114 if (strncasecmp(hdr, "Message-ID:", 11))
124 if (gethostname(hostname, sizeof(hostname)))
127 hostname[sizeof(hostname)-1] = 0;
128 fprintf(sm_fh, "Message-ID: <%s+md-%04d%02d%02d.%02d%02d%02d.%d.%s@%s>\n",
130 now_tm->tm_year + 1900, now_tm->tm_mon + 1, now_tm->tm_mday,
131 now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec,
143 while ((n = fread(buf, 1, sizeof(buf), stdin)) > 0)
144 fwrite(buf, 1, n, sm_fh);
146 die("Malformed mail body: %m");
152 fprintf(stderr, "Usage: smail [<options>] -- <sendmail-options>\n\
155 -f<user>@<domain>\tGenerate envelope sender address for easy identification of bounces\n\
156 -l<user>@<domain>\tAdd Message-ID for detection of messages looped back\n\
157 -v\t\t\tIncrease verbosity\n\
159 MailDups " STR(VERSION) ", (c) " STR(YEAR) " Martin Mares <mj@ucw.cz>\n\
160 It can be freely distributed and used according to the GNU GPL v2.\n\
166 main(int argc, char **argv)
169 while ((c = getopt(argc, argv, "f:l:v")) >= 0)
174 char *c = strchr(optarg, '@');
184 char *c = strchr(optarg, '@');
200 if (!(now_tm = gmtime(&now)))
201 die("gmtime() failed: %m");
203 start_sendmail(argv+optind, argc-optind);