1 /*$Id: ezmlm-gate.c,v 1.18 1999/10/09 16:49:56 lindberg Exp $*/
2 /*$Name: ezmlm-idx-040 $*/
19 #include "subscribe.h"
21 #define FATAL "ezmlm-gate: fatal: "
25 strerr_die1x(100,"ezmlm-gate: usage: ezmlm-gate [-cCmMpPqrRsSvV] "
26 "dir [moddir [...]]");
28 void die_nomem() { strerr_die2x(111,FATAL,ERR_NOMEM); }
33 stralloc sendopt = {0};
34 stralloc storeopt = {0};
35 void *psql = (void *) 0;
48 sendargs[0] = "/bin/sh"; /* 100 perm error, 111 temp, 99 dom ok */
49 sendargs[1] = "-c"; /* 0 rec ok, others bounce */
51 sendargs[3] = (char *)0;
52 switch(child = fork()) {
54 strerr_die2sys(111,FATAL,ERR_FORK);
56 execv(*sendargs,sendargs);
57 if (errno == error_txtbsy || errno == error_nomem ||
59 strerr_die5sys(111,FATAL,ERR_EXECUTE,
60 "/bin/sh -c ",sendargs[2],": ");
62 strerr_die5sys(100,FATAL,ERR_EXECUTE,
63 "/bin/sh -c ",sendargs[2],": ");
66 wait_pid(&wstat,child);
67 if (wait_crashed(wstat))
68 strerr_die2x(111,FATAL,ERR_CHILD_CRASHED);
69 switch((r = wait_exitcode(wstat))) {
70 case 0: case 99: case 100: break;
71 case 111: /* temp error */
72 strerr_die2x(111,FATAL,ERR_CHILD_TEMP);
74 strerr_die2x(100,FATAL,ERR_REJECT); /* other errors => bounce */
76 if (seek_begin(0) == -1) /* rewind */
77 strerr_die2sys(111,FATAL,ERR_SEEK_INPUT);
88 char *queryext = (char *) 0;
95 /* storeopts to ezmlm-store only. Others to both (ezmlm-store may */
96 /* pass them on to ezmlm-send. */
97 if (!stralloc_copys(&sendopt," -")) die_nomem();
98 if (!stralloc_copys(&storeopt," -")) die_nomem();
100 while ((opt = getopt(argc,argv,
101 "cCmMpPq:Q:sSrRt:T:vV")) != opteof)
102 switch(opt) { /* pass on unrecognized options */
103 case 'c': /* ezmlm-send flags */
108 if (!stralloc_append(&sendopt,szchar)) die_nomem();
110 case 'm': /* ezmlm-store flags */
117 if (!stralloc_append(&storeopt,szchar)) die_nomem();
119 case 'q': /* allow both qQ to be nice */
120 case 'Q': if (optarg) queryext = optarg; break;
122 case 'V': strerr_die2x(0,"ezmlm-gate version: ",EZIDX_VERSION);
123 default: /* ezmlm-store flags */
127 dir = argv[optind++];
128 if (!dir) die_usage();
129 if (chdir(dir) == -1)
130 strerr_die4sys(111,FATAL,ERR_SWITCH,dir,": ");
132 sender = env_get("SENDER");
137 getconf(&cmds,queryext,1,FATAL,dir);
139 for (j = 0;j < cmds.len; ++j)
142 case '\0': case '#': break; /* ignore blank/comment */
144 ret = mailprog(cmds.s + i + 1); break;
146 ret = mailprog(cmds.s + i); break;
151 if (!ret || ret == 99) /* 111 => temp error */
152 pmod = ""; /* 0, 99 => post */
153 /* other => moderate */
155 moddir = argv[optind++];
156 if (moddir && !ret) { /* if exit 0 and moddir, add issub */
158 while (moddir && !pmod && sender) {
159 pmod = issub(moddir,sender,(char *) 0,FATAL);
161 moddir = argv[optind++];
167 if (!stralloc_copys(&send,auto_bin)) die_nomem();
169 if (!stralloc_cats(&send,"/ezmlm-send")) die_nomem();
171 if (!stralloc_cat(&send,&sendopt)) die_nomem();
174 if (!stralloc_cats(&send,"/ezmlm-store")) die_nomem();
175 if (storeopt.len > 2)
176 if (!stralloc_cat(&send,&storeopt)) die_nomem();
178 if (!stralloc_cat(&send,&sendopt)) die_nomem();
180 if (!stralloc_cats(&send," '")) die_nomem();
181 if (!stralloc_cats(&send,dir)) die_nomem();
182 if (!stralloc_cats(&send,"'")) die_nomem();
183 if (!stralloc_0(&send)) die_nomem();
184 sendargs[2] = send.s;
187 switch(child = fork()) {
189 strerr_die2sys(111,FATAL,ERR_FORK);
191 execvp(*sendargs,sendargs);
192 if (errno == error_txtbsy || errno == error_nomem ||
194 strerr_die4sys(111,FATAL,ERR_EXECUTE,sendargs[2],": ");
196 strerr_die4sys(100,FATAL,ERR_EXECUTE,sendargs[2],": ");
199 wait_pid(&wstat,child);
200 if (wait_crashed(wstat))
201 strerr_die2x(111,FATAL,ERR_CHILD_CRASHED);
202 switch(wait_exitcode(wstat)) {
204 strerr_die2x(100,FATAL,ERR_CHILD_FATAL);
206 strerr_die2x(111,FATAL,ERR_CHILD_TEMP);
210 strerr_die2x(111,FATAL,ERR_CHILD_UNKNOWN);