debian/rules: Use `git' potty wrapper.
[qmail] / preline.c
index 8e76485..1a4cef8 100644 (file)
--- a/preline.c
+++ b/preline.c
@@ -1,7 +1,7 @@
 #include "fd.h"
 #include "sgetopt.h"
 #include "readwrite.h"
-#include "subfd.h"
+#include "strerr.h"
 #include "substdio.h"
 #include "exit.h"
 #include "fork.h"
 #include "sig.h"
 #include "error.h"
 
-void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
-void die_usage() { die(100,"preline: fatal: incorrect usage\n"); }
-void die_temp() { die(111,"preline: fatal: temporary problem\n"); }
-void die_read() { die(111,"preline: fatal: unable to read message\n"); }
-void die_badcmd() { die(100,"preline: fatal: command not found\n"); }
+#define FATAL "preline: fatal: "
+
+void die_usage()
+{
+  strerr_die1x(100,"preline: usage: preline cmd [ arg ... ]");
+}
 
 int flagufline = 1; char *ufline;
 int flagrpline = 1; char *rpline;
 int flagdtline = 1; char *dtline;
 
-substdio ssout;
 char outbuf[SUBSTDIO_OUTSIZE];
-substdio ssin;
 char inbuf[SUBSTDIO_INSIZE];
+substdio ssout = SUBSTDIO_FDBUF(write,1,outbuf,sizeof outbuf);
+substdio ssin = SUBSTDIO_FDBUF(read,0,inbuf,sizeof inbuf);
 
 void main(argc,argv)
 int argc;
 char **argv;
 {
- int opt;
- int pi[2];
- int pid;
- int wstat;
-
- sig_pipeignore();
-
- if (!(ufline = env_get("UFLINE"))) die_usage();
- if (!(rpline = env_get("RPLINE"))) die_usage();
- if (!(dtline = env_get("DTLINE"))) die_usage();
-
- while ((opt = getopt(argc,argv,"frdFRD")) != opteof)
-   switch(opt)
-    {
-     case 'f': flagufline = 0; break;
-     case 'r': flagrpline = 0; break;
-     case 'd': flagdtline = 0; break;
-     case 'F': flagufline = 1; break;
-     case 'R': flagrpline = 1; break;
-     case 'D': flagdtline = 1; break;
-     default:
-       _exit(100);
+  int opt;
+  int pi[2];
+  int pid;
+  int wstat;
+  sig_pipeignore();
+  if (!(ufline = env_get("UFLINE"))) die_usage();
+  if (!(rpline = env_get("RPLINE"))) die_usage();
+  if (!(dtline = env_get("DTLINE"))) die_usage();
+  while ((opt = getopt(argc,argv,"frdFRD")) != opteof)
+    switch(opt) {
+      case 'f': flagufline = 0; break;
+      case 'r': flagrpline = 0; break;
+      case 'd': flagdtline = 0; break;
+      case 'F': flagufline = 1; break;
+      case 'R': flagrpline = 1; break;
+      case 'D': flagdtline = 1; break;
+      default: die_usage();
     }
- argc -= optind;
- argv += optind;
- if (!*argv) die_usage();
+  argc -= optind;
+  argv += optind;
+  if (!*argv) die_usage();
+  if (pipe(pi) == -1)
+    strerr_die2sys(111,FATAL,"unable to create pipe: ");
 
- if (pipe(pi) == -1) die_temp();
+  pid = fork();
+  if (pid == -1)
+    strerr_die2sys(111,FATAL,"unable to fork: ");
 
- switch(pid = fork())
-  {
-   case -1:
-     die_temp();
-   case 0:
-     close(pi[1]);
-     if (fd_move(0,pi[0])) die_temp();
-     sig_pipedefault();
-     execvp(*argv,argv);
-     if (error_temp(errno)) die_temp();
-     die_badcmd();
+  if (pid == 0) {
+    close(pi[1]);
+    if (fd_move(0,pi[0]) == -1)
+      strerr_die2sys(111,FATAL,"unable to set up fds: ");
+    sig_pipedefault();
+    execvp(*argv,argv);
+    strerr_die4sys(error_temp(errno) ? 111 : 100,FATAL,"unable to run ",*argv,": ");
   }
- close(pi[0]);
-
- substdio_fdbuf(&ssout,write,pi[1],outbuf,sizeof(outbuf));
- substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
- if (flagufline) substdio_bputs(&ssout,ufline);
- if (flagrpline) substdio_bputs(&ssout,rpline);
- if (flagdtline) substdio_bputs(&ssout,dtline);
- if (substdio_copy(&ssout,&ssin) == -2) die_read();
- substdio_flush(&ssout);
- close(pi[1]);
-
- if (wait_pid(&wstat,pid) == -1) die_temp();
- if (wait_crashed(wstat)) die_temp();
- _exit(wait_exitcode(wstat));
+  close(pi[0]);
+  if (fd_move(1,pi[1]) == -1)
+    strerr_die2sys(111,FATAL,"unable to set up fds: ");
+  if (flagufline) substdio_bputs(&ssout,ufline);
+  if (flagrpline) substdio_bputs(&ssout,rpline);
+  if (flagdtline) substdio_bputs(&ssout,dtline);
+  if (substdio_copy(&ssout,&ssin) != 0)
+    strerr_die2sys(111,FATAL,"unable to copy input: ");
+  substdio_flush(&ssout);
+  close(1);
+  if (wait_pid(&wstat,pid) == -1)
+    strerr_die2sys(111,FATAL,"wait failed: ");
+  if (wait_crashed(wstat))
+    strerr_die2x(111,FATAL,"child crashed");
+  _exit(wait_exitcode(wstat));
 }