qsmhook.c
author "Tomas Zeman <tomas.zeman@sun.com>"
Fri, 19 Oct 2007 14:06:22 +0200
changeset 0 068428edee47
permissions -rw-r--r--
Imported qmail-1.03
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     1
#include "fd.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     2
#include "stralloc.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     3
#include "readwrite.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     4
#include "sgetopt.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     5
#include "wait.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     6
#include "env.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     7
#include "byte.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     8
#include "str.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
     9
#include "alloc.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    10
#include "exit.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    11
#include "fork.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    12
#include "case.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    13
#include "subfd.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    14
#include "error.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    15
#include "substdio.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    16
#include "sig.h"
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    17
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    18
void die(e,s) int e; char *s; { substdio_putsflush(subfderr,s); _exit(e); }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    19
void die_usage() { die(100,"qsmhook: fatal: incorrect usage\n"); }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    20
void die_temp() { die(111,"qsmhook: fatal: temporary problem\n"); }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    21
void die_read() { die(111,"qsmhook: fatal: unable to read message\n"); }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    22
void die_badcmd() { die(100,"qsmhook: fatal: command not found\n"); }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    23
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    24
int flagrpline = 0; char *rpline;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    25
int flagufline = 1; char *ufline;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    26
int flagdtline = 0; char *dtline;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    27
char *host;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    28
char *sender;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    29
char *recip;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    30
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    31
stralloc newarg = {0};
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    32
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    33
substdio ssout;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    34
char outbuf[SUBSTDIO_OUTSIZE];
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    35
substdio ssin;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    36
char inbuf[SUBSTDIO_INSIZE];
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    37
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    38
void main(argc,argv)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    39
int argc;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    40
char **argv;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    41
{
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    42
 int pid;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    43
 int wstat;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    44
 int pi[2];
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    45
 int opt;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    46
 char **arg;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    47
 char *x;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    48
 int i;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    49
 int flagesc;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    50
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    51
 sig_pipeignore();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    52
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    53
 if (!(dtline = env_get("DTLINE"))) die_usage();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    54
 if (!(rpline = env_get("RPLINE"))) die_usage();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    55
 if (!(ufline = env_get("UFLINE"))) die_usage();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    56
 if (!(recip = env_get("LOCAL"))) die_usage();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    57
 if (!(host = env_get("HOST"))) die_usage();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    58
 if (!(sender = env_get("SENDER"))) die_usage();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    59
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    60
 while ((opt = getopt(argc,argv,"DFlMmnPsx:")) != opteof)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    61
   switch(opt)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    62
    {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    63
     case 'D': case 'F': case 'M': break; /* be serious */
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    64
     case 'l': flagdtline = 1; break; /* also return-receipt-to? blech */
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    65
     case 'm': break; /* we only handle one recipient anyway */
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    66
     case 'n': flagufline = 0; break;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    67
     case 's': break; /* could call quote() otherwise, i suppose... */
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    68
     case 'P': flagrpline = 1; break;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    69
     case 'x':
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    70
       if (case_starts(recip,optarg))
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    71
	 recip += str_len(optarg);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    72
       break;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    73
     default:
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    74
       _exit(100);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    75
    }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    76
 argc -= optind;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    77
 argv += optind;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    78
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    79
 if (!*argv) die_usage();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    80
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    81
 for (arg = argv;x = *arg;++arg)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    82
  {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    83
   if (!stralloc_copys(&newarg,"")) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    84
   flagesc = 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    85
   for (i = 0;x[i];++i)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    86
     if (flagesc)
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    87
      {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    88
       switch(x[i])
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    89
	{
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    90
	 case '%': if (!stralloc_cats(&newarg,"%")) die_temp(); break;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    91
	 case 'g': if (!stralloc_cats(&newarg,sender)) die_temp(); break;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    92
	 case 'h': if (!stralloc_cats(&newarg,host)) die_temp(); break;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    93
	 case 'u': if (!stralloc_cats(&newarg,recip)) die_temp(); break;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    94
	}
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    95
       flagesc = 0;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    96
      }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    97
     else
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    98
       if (x[i] == '%')
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
    99
	 flagesc = 1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   100
       else
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   101
	 if (!stralloc_append(&newarg,&x[i])) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   102
   if (!stralloc_0(&newarg)) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   103
   i = str_len(newarg.s) + 1;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   104
   if (!(x = alloc(i))) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   105
   byte_copy(x,i,newarg.s);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   106
   *arg = x;
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   107
  }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   108
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   109
 if (pipe(pi) == -1) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   110
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   111
 switch(pid = fork())
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   112
  {
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   113
   case -1:
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   114
     die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   115
   case 0:
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   116
     close(pi[1]);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   117
     if (fd_move(0,pi[0]) == -1) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   118
     sig_pipedefault();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   119
     execvp(*argv,argv);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   120
     if (error_temp(errno)) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   121
     die_badcmd();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   122
  }
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   123
 close(pi[0]);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   124
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   125
 substdio_fdbuf(&ssout,write,pi[1],outbuf,sizeof(outbuf));
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   126
 substdio_fdbuf(&ssin,read,0,inbuf,sizeof(inbuf));
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   127
 if (flagufline) substdio_bputs(&ssout,ufline);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   128
 if (flagrpline) substdio_bputs(&ssout,rpline);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   129
 if (flagdtline) substdio_bputs(&ssout,dtline);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   130
 if (substdio_copy(&ssout,&ssin) == -2) die_read();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   131
 substdio_flush(&ssout);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   132
 close(pi[1]);
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   133
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   134
 if (wait_pid(&wstat,pid) == -1) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   135
 if (wait_crashed(wstat)) die_temp();
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   136
 _exit(wait_exitcode(wstat));
068428edee47 Imported qmail-1.03
"Tomas Zeman <tomas.zeman@sun.com>"
parents:
diff changeset
   137
}