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
);