20#define WHO "ezmlm-dispatch"
28static void die_usage(
void) {
logmsg(
WHO,100,USAGE,
"ezmlm-dispatch dir [list]"); }
31static const char *sender;
32static const char *basedir;
33static const char *listdir;
36static stralloc path = {0};
37static char strnum[FMT_ULONG];
38static int did_program;
39static int did_forward;
41static void make_path(
const char *
fn)
43 if (!stralloc_copys(&path,basedir))
die_nomem();
45 if (!stralloc_cats(&path,
"/"))
die_nomem();
46 if (!stralloc_cats(&path,listdir))
die_nomem();
49 if (!stralloc_cats(&path,
"/"))
die_nomem();
55static int is_dir(
const char *
fn)
60 && S_ISDIR(st.st_mode);
63static int is_file(
const char *
fn)
67 return (
wrap_stat(path.s,&st) == 0 && S_ISREG(st.st_mode));
70static void forward(
const char *rcpt)
79 if ((
dtline = env_get(
"DTLINE")) != 0)
81 while ((r = read(0,
buf,
sizeof buf)) > 0)
90 buffer_puts(buffer_2,
"qp ");
91 buffer_puts(buffer_2,strnum);
92 buffer_putsflush(buffer_2,
"\n");
96static void execute_line(
const char *line)
100 if (seek_begin(0) == -1)
102 while (*line && (*line ==
'\t' || *line ==
' '))
108 ++did_program;
break;
110 case '.':
logmsg(
WHO,100,FATAL,B(
"Delivery to files is not supported for: ",path.s));
break;
111 default:
if (*line ==
'&') ++line;
116static void execute_file(stralloc *file)
121 for (start = 0; start < file->len; start =
end + 1) {
122 len = byte_chr(file->s+start,file->len-start,
'\n');
125 execute_line(file->s+start);
131static void execute(
const char *
fn,
const char *def)
133 stralloc file = {0, 0, 0};
135 env_put2(
"DEFAULT",def);
137 env_unset(
"DEFAULT");
139 if (openreadclose(path.s,&file,256) != 1)
142 buffer_puts(buffer_2,
"did 0+");
143 buffer_put(buffer_2,strnum,fmt_ulong(strnum,did_forward));
144 buffer_puts(buffer_2,
"+");
145 buffer_put(buffer_2,strnum,fmt_ulong(strnum,did_program));
146 buffer_putsflush(buffer_2,
"\n");
152static void try_dispatch(
const char *def,
const char *
prefix,
unsigned int len,
const char *
fn)
160static void dispatch(
const char *
dir,
const char *def)
166 else if (str_diff(def,
"owner") == 0)
168 else if (str_diff(def,
"digest-owner") == 0)
171 try_dispatch(def,
"digest-return-",14,
"bouncer");
172 try_dispatch(def,
"return-",7,
"bouncer");
173 try_dispatch(def,
"confirm-",8,
"confirmer");
174 try_dispatch(def,
"discard-",8,
"confirmer");
175 try_dispatch(def,
"accept-",7,
"moderator");
176 try_dispatch(def,
"reject-",7,
"moderator");
178 execute(
"manager",def);
188 while ((
opt = getoptb(argc,argv,
"vV")) != opteof)
192 default: die_usage();
195 if ((basedir = argv[optind++]) == 0)
198 logmsg(
WHO,100,FATAL,B(
"Not a directory: ",basedir));
200 sender = env_get(
"SENDER");
203 def = env_get(
"DEFAULT");
207 if ((listdir = argv[optind++]) != 0) {
209 logmsg(
WHO,100,FATAL,B(
"Not a directory: ",path.s));
213 if (def[str_chr(def,
'/')] != 0)
214 logmsg(
WHO,100,FATAL,
"Recipient address may not contain '/'");
222 if (def[dash] ==
'-')
228 dispatch(def,def+dash+1);
231 logmsg(
WHO,100,FATAL,B(
"Could not match recipient name to any list: ",def));
const char auto_version[]
void wrap_execsh(const char *command)
int wrap_waitpid(int pid)
int wrap_stat(const char *fn, struct stat *st)
Error messages. If you translate these, I would urge you to keep the English version as well....
#define ERR_TMP_QMAIL_QUEUE
const char * qmail_close(struct qmail *)
void qmail_puts(struct qmail *, const char *)
void qmail_put(struct qmail *, const char *, int)
void qmail_from(struct qmail *, const char *)
void qmail_to(struct qmail *, const char *)
unsigned long qmail_qp(struct qmail *)
int qmail_open(struct qmail *, const stralloc *)
const char * logmsg(const char *dir, unsigned long num, unsigned long listno, unsigned long subs, int done)