-void smtp_do_bounce(char *instr) {
- int i;
- int lines;
- int status;
- char buf[1024];
- char key[1024];
- char addr[1024];
- char dsn[1024];
- char bounceto[1024];
- StrBuf *boundary;
- int num_bounces = 0;
- int bounce_this = 0;
- long bounce_msgid = (-1);
- time_t submitted = 0L;
- struct CtdlMessage *bmsg = NULL;
- int give_up = 0;
- struct recptypes *valid;
- int successful_bounce = 0;
- static int seq = 0;
- StrBuf *BounceMB;
- long omsgid = (-1);
-
- CtdlLogPrintf(CTDL_DEBUG, "smtp_do_bounce() called\n");
- strcpy(bounceto, "");
- boundary = NewStrBufPlain(HKEY("=_Citadel_Multipart_"));
- StrBufAppendPrintf(boundary, "%s_%04x%04x", config.c_fqdn, getpid(), ++seq);
- lines = num_tokens(instr, '\n');
-
- /* See if it's time to give up on delivery of this message */
- for (i=0; i<lines; ++i) {
- extract_token(buf, instr, i, '\n', sizeof buf);
- extract_token(key, buf, 0, '|', sizeof key);
- extract_token(addr, buf, 1, '|', sizeof addr);
- if (!strcasecmp(key, "submitted")) {
- submitted = atol(addr);
- }
- }
-
- if ( (time(NULL) - submitted) > SMTP_GIVE_UP ) {
- give_up = 1;
- }
-
- /* Start building our bounce message */
-
- bmsg = (struct CtdlMessage *) malloc(sizeof(struct CtdlMessage));
- if (bmsg == NULL) return;
- memset(bmsg, 0, sizeof(struct CtdlMessage));
- BounceMB = NewStrBufPlain(NULL, 1024);
-
- bmsg->cm_magic = CTDLMESSAGE_MAGIC;
- bmsg->cm_anon_type = MES_NORMAL;
- bmsg->cm_format_type = FMT_RFC822;
- bmsg->cm_fields['A'] = strdup("Citadel");
- bmsg->cm_fields['O'] = strdup(MAILROOM);
- bmsg->cm_fields['N'] = strdup(config.c_nodename);
- bmsg->cm_fields['U'] = strdup("Delivery Status Notification (Failure)");
- StrBufAppendBufPlain(BounceMB, HKEY("Content-type: multipart/mixed; boundary=\""), 0);
- StrBufAppendBuf(BounceMB, boundary, 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\"\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("MIME-Version: 1.0\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("X-Mailer: " CITADEL "\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\r\nThis is a multipart message in MIME format.\r\n\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("--"), 0);
- StrBufAppendBuf(BounceMB, boundary, 0);
- StrBufAppendBufPlain(BounceMB, HKEY("\r\n"), 0);
- StrBufAppendBufPlain(BounceMB, HKEY("Content-type: text/plain\r\n\r\n"), 0);
-
- if (give_up) StrBufAppendBufPlain(BounceMB, HKEY(
-"A message you sent could not be delivered to some or all of its recipients\n"
-"due to prolonged unavailability of its destination(s).\n"
-"Giving up on the following addresses:\n\n"
- ), 0);
-
- else StrBufAppendBufPlain(BounceMB, HKEY(
-"A message you sent could not be delivered to some or all of its recipients.\n"
-"The following addresses were undeliverable:\n\n"
- ), 0);
-
- /*
- * Now go through the instructions checking for stuff.
- */
- for (i=0; i<lines; ++i) {
- long addrlen;
- long dsnlen;
- extract_token(buf, instr, i, '\n', sizeof buf);
- extract_token(key, buf, 0, '|', sizeof key);
- addrlen = extract_token(addr, buf, 1, '|', sizeof addr);
- status = extract_int(buf, 2);
- dsnlen = extract_token(dsn, buf, 3, '|', sizeof dsn);
- bounce_this = 0;
-
- CtdlLogPrintf(CTDL_DEBUG, "key=<%s> addr=<%s> status=%d dsn=<%s>\n",
- key, addr, status, dsn);
-
- if (!strcasecmp(key, "bounceto")) {
- strcpy(bounceto, addr);
- }
-
- if (!strcasecmp(key, "msgid")) {
- omsgid = atol(addr);
- }
-
- if (!strcasecmp(key, "remote")) {
- if (status == 5) bounce_this = 1;
- if (give_up) bounce_this = 1;
- }
-
- if (bounce_this) {
- ++num_bounces;