75 log1s(
"alert: qmail-send lost connection to qmail-clean ... exiting\n");
83 log1s(
"alert: oh no! qmail-send lost spawn connection! dying...\n");
88#define REPORTMAX 10000
124 if (str_equal(
sender + i - 4,
"-@[]")) {
125 j = byte_rchr(
sender,i - 4,
'@');
127 if (
recip[
k] && (
j + 5 <= i)) {
131 while (!stralloc_cats(
sa,
"="))
nomem();
133 while (!stralloc_cats(
sa,
"@"))
nomem();
148 static stralloc
line = {0};
154 fdnumber = open_read(
fn.s);
155 if (fdnumber == -1)
return 0;
156 if (fstat(fdnumber,&st) == -1) { close(fdnumber);
return 0; }
157 buffer_init(&
b,buffer_unixread,fdnumber,
buf,
sizeof(
buf));
158 if (getln(&
b,&
line,&
match,
'\0') == -1) { close(fdnumber);
return 0; }
160 if (!
match)
return 0;
161 if (
line.s[0] !=
'F')
return 0;
165 while (!stralloc_0(
sa))
nomem();
243 if ((w == -1) && (errno == EPIPE))
293 if (stat(
fn.s,&st) == -1)
return;
297 if (stat(
fn.s,&st) == 0)
return;
298 if (errno != ENOENT)
return;
301 if (stat(
fn.s,&st) == 0)
return;
302 if (errno != ENOENT)
return;
308 log3s(
"warning: qmail-clean is unable to clean up ",
fn.s,
"\n");
328#define CHECKSTAT if (errno != ENOENT) goto FAIL;
331 if (stat(
fn.s,&st) == -1) {
337 if (stat(
fn.s,&st) != -1)
return;
342 if (stat(
fn.s,&st) == -1) { flagchan[
c] = 0;
CHECKSTAT }
343 else { flagchan[
c] = 1; pechan[
c].
id =
id; pechan[
c].
dt = st.st_mtime; }
351 if (flagchan[
c])
break;
361 log3s(
"warning: qmail-send send is unable to stat ",
fn.s,
"; will try again later\n");
375 if (x > 0)
pqadd(
id);
389 ut.actime =
ut.modtime = pe.
dt;
390 if (utime(
fn.s,&
ut) == -1)
391 log3s(
"warning: qmail-send is unable to utime ",
fn.s,
"; message will be retried too soon\n");
403 for (i = 0; i <
pqchan[
c].len; ++i)
466 if (0 < --
jo[
j].refs)
return;
471 if (
jo[
j].flaghiteof && !
jo[
j].numtodo) {
473 if (unlink(
fn.s) == -1) {
474 log3s(
"warning: qmail-send is unable to unlink ",
fn.s,
"; will try again later\n");
479 if (stat(
fn.s,&st) == 0)
return;
480 if (errno != ENOENT) {
481 log3s(
"warning: qmail-send is unable to stat ",
fn.s,
"\n");
504 i = str_rchr(
recip,
'@');
507 domainlen = str_len(
domain);
509 for (i = 0; i <= domainlen; ++i)
510 if ((i == 0) || (i == domainlen) || (
domain[i] ==
'.'))
512 if (!*prepend)
break;
513 i = str_len(prepend);
514 if (str_diffn(
recip,prepend,i))
break;
515 if (
recip[i] !=
'-')
break;
516 return recip + i + 1;
544 for (pos =
bouncetext.len - 2; pos > 0; --pos)
553 fd = open_append(
fn2.s);
555 log1s(
"alert: qmail-send is unable to append to bounce message; HELP! sleeping...\n");
564 log1s(
"alert: qmail-send is unable to append to bounce message; HELP! sleeping...\n");
584 static stralloc
sender = {0};
585 static stralloc
quoted = {0};
603 if (stat(
fn2.s,&st) == -1) {
604 if (errno == ENOENT)
return 1;
605 log3s(
"warning: qmail-send is unable to stat ",
fn2.s,
"\n");
609 if (str_equal(
sender.s,
"#@[]"))
610 log3s(
"triple bounce: discarding ",
fn2.s,
"\n");
612 log3s(
"double bounce: discarding ",
fn2.s,
"\n");
615 {
log1s(
"warning: qmail-send is unable to start qmail-queue, will try later\n");
return 0; }
618 if (*
sender.s) { bouncesender =
""; bouncerecip =
sender.s; }
632Subject: failure notice\n\
634Hi. This is the qmail-send program at ");
637I'm afraid I wasn't able to deliver your message to the following addresses.\n\
638This is a permanent error; I've given up. Sorry it didn't work out.\n\
641I tried to deliver a bounce message to this address, but the bounce bounced!\n\
645 fd = open_read(
fn2.s);
650 while ((r = buffer_get(&
bi,
buf,
sizeof(
buf))) > 0)
657 qmail_puts(&
qqt,*
sender.s ?
"--- Below this line is a copy of the message.\n\n" :
"--- Below this line is the original bounce.\n\n");
663 fd = open_read(
fn.s);
669 bytestoget = (bytestogo <
sizeof(
buf)) ? bytestogo :
sizeof(
buf);
673 while (bytestoget > 0 && (r = buffer_get(&
bi,
buf,bytestoget)) > 0) {
675 bytestogo -= bytestoget;
676 bytestoget = (bytestogo <
sizeof(
buf)) ? bytestogo :
sizeof(
buf);
683 while ((r = buffer_get(&
bi,
buf,
sizeof(
buf))) > 0)
694 log1s(
"warning: qmail-send has trouble injecting bounce message, will try later\n");
704 if (unlink(
fn2.s) != 0) {
705 log3s(
"warning: qmail-send is unable to unlink ",
fn2.s,
"\n");
817 fd = open_write(
fn.s);
819 if (fstat(
fd,&st) == -1) { close(
fd);
break; }
820 if (seek_set(
fd,pos) == -1) { close(
fd);
break; }
821 if (
write(
fd,
"D",1) != 1) { close(
fd);
break; }
826 log3s(
"warning: qmail-send has trouble marking ",
fn.s,
"; message will be delivered twice!\n");
840 for (i = 0; i < r; ++i) {
849 if (!ch && (
dline[
c].len > 1)) {
852 log1s(
"warning: qmail-send's internal error: delivery report out of range\n");
859 while (!stralloc_cats(&
dline[
c],
"I'm not going to try again; this message has been in the queue too long.\n"))
nomem();
885 log3s(
"delivery ",
strnum3,
": report mangled, will defer\n");
950 { *wakeup = 0;
return; }
956 if (*wakeup > pe.
dt) *wakeup = pe.
dt;
963 if (*wakeup > pe.
dt)*wakeup = pe.
dt;
974 for (
j = 15;
j >= 0; --
j) {
975 y21 = (y << (
j + 1)) + (1 << (
j +
j));
976 if (y21 <= x - yy) { y += (1 <<
j); yy += y21; }
989 return birth + n * n;
996 static stralloc
line = {0};
1010 if (
pass[
c].
fd == -1)
goto trouble;
1024 log3s(
"warning: qmail-send has trouble reading ",
fn.s,
"; will try again later\n");
1039 switch (
line.s[0]) {
1048 log3s(
"warning: qmail-send recognizes unknown record type in ",
fn.s,
"!\n");
1059 log3s(
"warning: qmail-send has trouble opening ",
fn.s,
"; will try again later\n");
1073 if (stat(
fn.s,&st) == 0)
return;
1074 if (errno != ENOENT) {
1075 log3s(
"warning: qmail-send is unable to stat ",
fn.s,
"; will try again later\n");
1081 if (stat(
fn.s,&st) == 0)
return;
1082 if (errno != ENOENT) {
1083 log3s(
"warning: qmail-send is unable to stat ",
fn.s,
"; will try again later\n");
1088 if (stat(
fn.s,&st) == -1) {
1089 if (errno == ENOENT)
return;
1090 log3s(
"warning: qmail-send is unable to stat ",
fn.s,
"; will try again later\n");
1103 if (unlink(
fn.s) == -1) {
1104 log3s(
"warning: qmail-send is unable to unlink ",
fn.s,
"; will try again later\n");
1112 if (ch !=
'+')
log3s(
"warning: qmail-clean unable to clean up ",
fn.s,
"\n");
1152 log1s(
"alert: qmail-send lost connection to qmail-todo ... exiting\n");
1207 log1s(
"warning: qmail-send is unable to understand qmail-todo\n");
1211 len = scan_ulong(s,&
id);
1212 if (!len || s[len]) {
1213 log1s(
"warning: qmail-send is unable to understand qmail-todo\n");
1223 if (flagchan[
c])
break;
1238 if (!FD_ISSET(
todofdin,rfds))
return;
1241 if (r == -1)
return;
1250 for (i = 0; i < r; ++i) {
1272 log1s(
"warning: qmail-send is unable to understand qmail-todo: report mangled\n");
1320 {
log1s(
"alert: qmail-send is unable to reread control/locals\n");
return; }
1322 {
log1s(
"alert: qmail-send is unable to reread control/concurrencylocal\n");
return; }
1324 {
log1s(
"alert: qmail-send is unable to reread control/concurrencyremote\n");
return; }
1326 {
log1s(
"alert: qmail-send is unable to reread control/queuelifetime\n");
return; }
1329 if (r == -1) {
log1s(
"alert: qmail-send is unable to reread control/virtualdomains\n");
return; }
1347 log1s(
"alert: qmail-send is unable to reread controls: unable to switch to home directory\n");
1354 log1s(
"alert: qmail-send is unable to switch back to queue directory; HELP! sleeping...\n");
1378 if (chdir(
queuedir.s) == -1) {
log3s(
"alert: qmail-send cannot start and is unable to switch to queue directory ",
queuedir.s,
"\n");
_exit(110); }
1386 fd = open_write(
"lock/sendmutex");
1387 if (
fd == -1) {
log1s(
"alert: qmail-send is unable to open mutex\n");
_exit(111); }
1388 if (lock_exnb(
fd) == -1) {
log1s(
"alert: qmail-send is already running\n");
_exit(111); }
1395 while ((r == -1) && (errno == EINTR));
1396 if (r < 1) {
log1s(
"alert: cannot start: hath the daemon spawn no fire?\n");
_exit(111); }
1398 u = (
unsigned int) (
unsigned char) ch;
1431 if (wakeup <=
recent) tv.tv_sec = 0;
1435 if (select(nfds,&rfds,&wfds,(fd_set *) 0,&tv) == -1)
1439 log1s(
"warning: qmail-send has trouble in select\n");
1452 log1s(
"status: qmail-send exiting\n");
void constmap_free(struct constmap *cm)
int constmap_init(struct constmap *cm, char *s, int len, int flagcolon)
int control_readint(unsigned long *i, char *fn)
int control_rldef(stralloc *sa, char *fn, int flagme, char *def)
int control_readfile(stralloc *sa, char *fn, int flagme)
int stralloc_copys(stralloc *, char const *)
unsigned int fmtqfn(char *s, char *dirslash, unsigned long id, int flagsplit)
void c(char *, char *, char *, int, int, int)
void p(char *, char *, int, int, int)
int newfield_datemake(datetime_sec newfield_date)
struct prioq_elt *int prioq_min(prioq *, struct prioq_elt *)
void prioq_delmin(prioq *)
void report(buffer *log, int wstat, char *s, int len)
char fnmake_strnum[FMT_ULONG]
void pqadd(unsigned long id)
void fnmake_todo(unsigned long id)
void fnmake_foop(unsigned long id)
void messdone(unsigned long id)
void fnmake_info(unsigned long id)
int job_open(unsigned long id, int channel)
int getinfo(stralloc *sa, datetime_sec *dt, unsigned long id)
void markdone(int c, unsigned long id, seek_pos pos)
stralloc doublebouncehost
unsigned long concurrencyused[CHANNELS]
char * chanaddr[CHANNELS]
void fnmake_split(unsigned long id)
void cleanup_selprep(datetime_sec *wakeup)
int injectbounce(unsigned long id)
void addbounce(unsigned long id, char *recip, char *report)
char toqcbuf[BUFSIZE_LINE]
char fromqcbuf[BUFSIZE_LINE]
struct constmap mappercenthack
void del_do(fd_set *rfds)
void comm_write(int c, int delnum, unsigned long id, char *sender, char *recip)
void fnmake_mess(unsigned long id)
void todo_do(fd_set *rfds)
void pass_selprep(datetime_sec *wakeup)
int flagspawnalive[CHANNELS]
unsigned long concurrency[CHANNELS]
void comm_do(fd_set *wfds)
void comm_selprep(int *nfds, fd_set *wfds)
void todo_selprep(int *nfds, fd_set *rfds, datetime_sec *wakeup)
void senderadd(stralloc *sa, char *sender, char *recip)
char * stripvdomprepend(char *recip)
unsigned long masterdelid
void del_start(int j, seek_pos mpos, char *recip)
char * chanstatusmsg[CHANNELS]
datetime_sec nextretry(datetime_sec birth, int c)
struct constmap maplocals
stralloc comm_buf[CHANNELS]
void fnmake_chanaddr(unsigned long id, int c)
void del_selprep(int *nfds, fd_set *rfds)
void fnmake2_bounce(unsigned long id)
void qmail_to(struct qmail *, char *)
void qmail_from(struct qmail *, char *)
void qmail_put(struct qmail *, char *, int)
char * qmail_close(struct qmail *)
unsigned long qmail_qp(struct qmail *)
void qmail_puts(struct qmail *, char *)
int qmail_open(struct qmail *)
void qmail_fail(struct qmail *)
void log2s(char *, char *)
void log3s(char *, char *, char *)
int quote(stralloc *, stralloc *)
int quote2(stralloc *, char *)
void readsubdir_init(readsubdir *, char *, void(*)())
int readsubdir_next(readsubdir *, unsigned long *)