« Return to Thread: sendbug(1) patch

Re: sendbug(1) patch

by Dasn-6 :: Rate this Message:

Reply to Author | View in Thread

On 12/04/08 23:50 -0400, Ray wrote:
>Sendbug was rewritten some time ago, so your patch doesn't apply, sorry.
>
>I was unaware of problems people had with sendmail, is this a  
>widespread problem?
>
>-Ray-
>

I'm still in obsd 4.1, thanks for your pointer.

When I use the sendmail to deliver messages to some mail servers, I got
the message returned with errors like:

> Diagnostic-Code: SMTP; 550 The IP address x.x.x.x has been listed on a
> realtime blacklist ...

I suppose my ISP's NAT allocated a notorious address for me. So I have
to use an alternative SMTP server to send the mail.

The following patch against the new (rewritten) sendbug (v4.2), with the
PR_AGENT feature and a few minor fixes.

Anyway, another use of the 'PR_AGENT' feature is, to help test sendbug's
send-outs, like:

$ export PR_AGENT="tee mail.out"
$ ./sendbug

:)

diff -u /usr/src/usr.bin/sendbug/sendbug.1 sendbug/sendbug.1
--- /usr/src/usr.bin/sendbug/sendbug.1 Fri Jun  1 03:20:16 2007
+++ sendbug/sendbug.1 Tue Apr 15 18:47:53 2008
@@ -91,6 +91,8 @@
 Filename of PR form to use instead of using the built-in form.
 Such a PR form can be partially pre-completed to make the
 process faster.
+.It Ev PR_AGENT
+Specifies an alternate Mail Transfer Agent to send the PR
 .It Ev TMPDIR
 Specifies a directory for temporary files to be created.
 The default is
@@ -103,7 +105,8 @@
 .El
 .Sh SEE ALSO
 .Xr crash 8 ,
-.Xr dmesg 8
+.Xr dmesg 8 ,
+.Xr sendmail 8
 .Sh AUTHORS
 .Nm
 was written from scratch for the public domain by

diff -u /usr/src/usr.bin/sendbug/sendbug.c sendbug/sendbug.c
--- /usr/src/usr.bin/sendbug/sendbug.c Fri Jan  4 08:50:09 2008
+++ sendbug/sendbug.c Tue Apr 15 18:53:29 2008
@@ -303,39 +303,81 @@
 sendmail(const char *pathname)
 {
  int filedes[2];
+ pid_t pid;
 
  if (pipe(filedes) == -1) {
  warn("pipe: unsent report in %s", pathname);
  return (-1);
  }
- switch (fork()) {
+
+ pid = fork();
+
+ switch (pid) {
  case -1:
  warn("fork error: unsent report in %s",
     pathname);
  return (-1);
  case 0:
  close(filedes[1]);
- if (dup2(filedes[0], STDIN_FILENO) == -1) {
- warn("dup2 error: unsent report in %s",
-    pathname);
- return (-1);
+
+ if (filedes[0] != STDIN_FILENO) { /* defensive measure */
+ if (dup2(filedes[0], STDIN_FILENO) == -1) {
+ warn("dup2 error: unsent report in %s",
+ pathname);
+ return (-1);
+ }
+ close(filedes[0]);
  }
+
+ char *mta_cmd;
+
+ if ( (mta_cmd = getenv("PR_AGENT")) == NULL ) {
+ execl("/usr/sbin/sendmail", "sendmail",
+ "-oi", "-t", (void *)NULL);
+ } else {
+ execl(_PATH_BSHELL, "sh", "-c", mta_cmd,
+ (void *) NULL);
+ }
+
+ /* shouldn't reach here */
+ warn("exec error: unsent report in %s", pathname);
+ _exit(127);
+
+ default:
  close(filedes[0]);
- execl("/usr/sbin/sendmail", "sendmail",
-    "-oi", "-t", (void *)NULL);
- warn("sendmail error: unsent report in %s",
-    pathname);
- return (-1);
- default:
- close(filedes[0]);
  /* Pipe into sendmail. */
  if (send_file(pathname, filedes[1]) == -1) {
+ wantcleanup = 0;
  warn("send_file error: unsent report in %s",
     pathname);
  return (-1);
  }
+
  close(filedes[1]);
- wait(NULL);
+
+ /* We should check the return value of MTA to see whether the
+ * PR has been sent successfully, if not, save the user's work
+ * (unsent report).
+ */
+
+ int status, ret_child = 0; /* the return value of MTA */
+ while (waitpid(pid, &status, 0) == -1)
+ if (errno != EINTR)
+ return(-1);
+
+ ret_child = WIFEXITED(status) ? WEXITSTATUS(status) : -1;
+
+ if (ret_child != 0) {
+ wantcleanup = 0;
+                        /*
+ * warn("sendmail error: unsent report in %s",
+ *                 pathname);
+                         */
+ fprintf(stderr, "MTA error (%d returned):"
+      " unsent report in %s", ret_child,
+ pathname);
+ return(-1);
+ }
  break;
  }
  return (0);
@@ -467,7 +509,9 @@
  if (ep)
  copylen = sp - buf;
  else
- copylen = len;
+ /* The final newline has been stripped,
+ * so minus 1.  */
+ copylen = len - 1;
  if (atomicio(vwrite, dst, buf, copylen) != copylen ||
     atomicio(vwrite, dst, "\n", 1) != 1)
  goto end;

--
Dasn

 « Return to Thread: sendbug(1) patch