-
-#ifdef MPOP
-
-int
-sm_bulk (char *file)
-{
- int cc, i, j, k, result;
- long pos;
- char *dp, *bp, *cp, s;
- char buffer[BUFSIZ], sender[BUFSIZ];
- FILE *fp, *gp;
-
- gp = NULL;
- k = strlen (file) - sizeof(".bulk");
- if ((fp = fopen (file, "r")) == NULL) {
- return sm_perror("unable to read %s: ", file);
- }
- if (sm_debug) {
- printf ("reading file %s\n", file);
- fflush (stdout);
- }
-
- i = j = 0;
- while (fgets (buffer, sizeof(buffer), fp)) {
- if (j++ == 0)
- strncpy (sender, buffer + sizeof("MAIL FROM:") - 1, sizeof(sender));
- if (strcmp (buffer, "DATA\r\n") == 0) {
- i = 1;
- break;
- }
- }
- if (i == 0) {
- if (sm_debug) {
- printf ("no DATA...\n");
- fflush (stdout);
- }
-losing0:
- snprintf (buffer, sizeof(buffer), "%s.bad", file);
- rename (file, buffer);
- if (gp) {
- snprintf (buffer, sizeof(buffer), "%*.*sA.bulk", k, k, file);
- unlink (buffer);
- fclose (gp);
- }
- fclose (fp);
- return RP_OK;
- }
- if (j < 3) {
- if (sm_debug) {
- printf ("no %srecipients...\n", j < 1 ? "sender or " : "");
- fflush (stdout);
- }
- goto losing0;
- }
-
- if ((cp = malloc ((size_t) (cc = (pos = ftell (fp)) + 1))) == NULL) {
- sm_reply.length = strlen (strcpy (sm_reply.text, "out of memory"));
-losing1: ;
- sm_reply.code = NOTOK;
- fclose (fp);
- return RP_BHST;
- }
- fseek (fp, 0L, SEEK_SET);
- for (dp = cp, i = 0; i++ < j; dp += strlen (dp))
- if (fgets (dp, cc - (dp - cp), fp) == NULL) {
- sm_reply.length = strlen (strcpy (sm_reply.text, "premature eof"));
-losing2:
- free (cp);
- goto losing1;
- }
- *dp = NULL;
-
- for (dp = cp, i = cc - 1; i > 0; dp += cc, i -= cc)
- if ((cc = write (fileno (sm_wfp), dp, i)) == NOTOK) {
- int len;
-losing3:
- sm_perror("error writing to server: ");
- goto losing2;
- }
- else
- if (sm_debug) {
- printf ("wrote %d octets to server\n", cc);
- fflush (stdout);
- }
-
- for (dp = cp, i = 0; i++ < j; dp = strchr(dp, '\n'), dp++) {
- if (sm_debug) {
- if (bp = strchr(dp, '\r'))
- *bp = NULL;
- printf ("=> %s\n", dp);
- fflush (stdout);
- if (bp)
- *bp = '\r';
- }
-
- switch (smhear () + (i == 1 ? 1000 : i != j ? 2000 : 3000)) {
- case 1000 + 250:
- sm_addrs = 0;
- result = RP_OK;
- break;
-
- case 1000 + 500:
- case 1000 + 501:
- case 1000 + 552:
- case 2000 + 500:
- case 2000 + 501:
- result = RP_PARM;
- smtalk (SM_RSET, "RSET");
- free (cp);
- goto losing0;
-
- case 2000 + 250:
- case 2000 + 251:
- sm_addrs++;
- result = RP_OK;
- break;
-
- case 2000 + 451:
-#ifdef SENDMAILBUG
- sm_addrs++;
- result = RP_OK;
- break;
-#endif
- case 2000 + 421:
- case 2000 + 450:
- case 2000 + 452:
- result = RP_NO;
- goto bad_addr;
-
- case 2000 + 550:
- case 2000 + 551:
- case 2000 + 552:
- case 2000 + 553:
- result = RP_USER;
-bad_addr:
- if (k <= 0 || strcmp (sender, "<>\r\n") == 0)
- break;
- if (gp == NULL) {
- int l;
- snprintf (buffer, sizeof(buffer), "%*.*sA.bulk", k, k, file);
- if ((gp = fopen (buffer, "w+")) == NULL)
- goto bad_data;
- fprintf (gp, "MAIL FROM:<>\r\nRCPT TO:%sDATA\r\n", sender);
- l = strlen (sender);
- fprintf (gp,
- "To: %*.*s\r\nSubject: Invalid addresses (%s)\r\n",
- l - 4, l - 4, sender + 1, file);
- fprintf (gp, "Date: %s\r\nFrom: Postmaster@%s\r\n\r\n",
- dtimenow (0), LocalName ());
- }
- if (bp = strchr(dp, '\r'))
- *bp = NULL;
- fprintf (gp, "=> %s\r\n", dp);
- if (bp)
- *bp = '\r';
- fprintf (gp, "<= %s\r\n", rp_string (result));
- fflush (gp);
- break;
-
- case 3000 + 354:
-#ifdef SENDMAILBUG
-ok_data:
-#endif
- result = RP_OK;
- break;
-
- case 3000 + 451:
-#ifdef SENDMAILBUG
- goto ok_data;
-#endif
- case 3000 + 421:
- result = RP_NO;
-bad_data:
- smtalk (SM_RSET, "RSET");
- free (cp);
- if (gp) {
- snprintf (buffer, sizeof(buffer), "%*.*sA.bulk", k, k, file);
- unlink (buffer);
- fclose (gp);
- }
- fclose (fp);
- return result;
-
- case 3000 + 500:
- case 3000 + 501:
- case 3000 + 503:
- case 3000 + 554:
- smtalk (SM_RSET, "RSET");
- free (cp);
- goto no_dice;
-
- default:
- result = RP_RPLY;
- goto bad_data;
- }
- }
- free (cp);
-
- {
-#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
- struct stat st;
-
- if (fstat (fileno (sm_wfp), &st) == NOTOK || (cc = st.st_blksize) < BUFSIZ)
- cc = BUFSIZ;
-#else
- cc = BUFSIZ;
-#endif
- if ((cp = malloc ((size_t) cc)) == NULL) {
- smtalk (SM_RSET, "RSET");
- sm_reply.length = strlen (strcpy (sm_reply.text, "out of memory"));
- goto losing1;
- }
- }
-
- fseek (fp, pos, SEEK_SET);
- for (;;) {
- int eof = 0;
-
- for (dp = cp, i = cc; i > 0; dp += j, i -= j)
- if ((j = fread (cp, sizeof(*cp), i, fp)) == OK) {
- if (ferror (fp)) {
- sm_perror("error reading %s: ", file);
- goto losing2;
- }
- cc = dp - cp;
- eof = 1;
- break;
- }
-
- for (dp = cp, i = cc; i > 0; dp += j, i -= j)
- if ((j = write (fileno (sm_wfp), dp, i)) == NOTOK)
- goto losing3;
- else
- if (sm_debug) {
- printf ("wrote %d octets to server\n", j);
- fflush (stdout);
- }
-
- if (eof)
- break;
- }
- free (cp);
-
- switch (smhear ()) {
- case 250:
- case 251:
-#ifdef SENDMAILBUG
-ok_dot:
-#endif
- result = RP_OK;
- unlink (file);
- break;
-
- case 451:
-#ifdef SENDMAILBUG
- goto ok_dot;
-#endif
- case 452:
- default:
- result = RP_NO;
- if (gp) {
- snprintf (buffer, sizeof(buffer), "%*.*sA.bulk", k, k, file);
- unlink (buffer);
- fclose (gp);
- gp = NULL;
- }
- break;
-
- case 552:
- case 554:
-no_dice:
- result = RP_NDEL;
- if (k <= 0 || strcmp (sender, "<>\r\n") == 0) {
- unlink (file);
- break;
- }
- if (gp) {
- fflush (gp);
- ftruncate (fileno (gp), 0L);
- fseek (gp, 0L, SEEK_SET);
- }
- else {
- snprintf (buffer, sizeof(buffer), "%*.*sA.bulk", k, k, file);
- if ((gp = fopen (buffer, "w")) == NULL)
- break;
- }
- fprintf (gp, "MAIL FROM:<>\r\nRCPT TO:%sDATA\r\n", sender);
- i = strlen (sender);
- fprintf (gp, "To: %*.*s\r\nSubject: Failed mail (%s)\r\n",
- i - 4, i - 4, sender + 1, file);
- fprintf (gp, "Date: %s\r\nFrom: Postmaster@%s\r\n\r\n",
- dtimenow (0), LocalName ());
- break;
- }
-
- if (gp) {
- fputs ("\r\n------- Begin Returned message\r\n\r\n", gp);
- fseek (fp, pos, SEEK_SET);
- while (fgets (buffer, sizeof(buffer), fp)) {
- if (buffer[0] == '-')
- fputs ("- ", gp);
- if (strcmp (buffer, ".\r\n"))
- fputs (buffer, gp);
- }
- fputs ("\r\n------- End Returned Message\r\n\r\n.\r\n", gp);
- fflush (gp);
- if (!ferror (gp))
- unlink (file);
- fclose (gp);
- }
- fclose (fp);
-
- return result;
-}
-#endif /* MPOP */
-
-