This is folder.c in view mode; [Download] [Up]
/* * pop3d - IP/TCP/POP3 server for UNIX 4.3BSD * Post Office Protocol - Version 3 (RFC1225) * * (C) Copyright 1991 Regents of the University of California * * Permission to use, copy, modify, and distribute this program * for any purpose and without fee is hereby granted, provided * that this copyright and permission notice appear on all copies * and supporting documentation, the name of University of California * not be used in advertising or publicity pertaining to distribution * of the program without specific prior permission, and notice be * given in supporting documentation that copying and distribution is * by permission of the University of California. * The University of California makes no representations about * the suitability of this software for any purpose. It is provided * "as is" without express or implied warranty. * * Katie Stevens * dkstevens@ucdavis.edu * Information Technology -- Campus Access Point * University of California, Davis * ************************************** * * folder.c * * REVISIONS: * 02-27-90 [ks] original implementation * 1.000 03-04-90 [ks] * 1.001 06-24-90 [ks] allow TRANS state if 0 msgs in folder * implement optional TOP command * 1.002 07-22-91 [ks] reset index counter after folder rewind * in fld_release (Thanks to John Briggs, * vaxs09@vitro.com, Vitro Corporation, * Silver Spring, MD for finding this bug!) * 1.004 11-13-91 [ks] leave original mailbox intact during POP * session (Thanks to Dave Cooley, * dwcooley@colby.edu for suggesting this) */ #include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/file.h> #include "pop3.h" #ifdef LINUX # include <unistd.h> #endif /* In main.c */ extern char *svr_hostname; extern char svr_buf[]; extern char cli_user[]; /* In util.c */ extern char flash_buf[]; #ifdef DEBUG extern FILE *logfp; #endif /* Constants used when closing a folder after POP session */ #define REMOVE_MBOX 1 #define SAVE_NEW 2 #define SAVE_ALL 3 static char *svr_nomsg = "-ERR no messages in mailbox\r\n"; static char *cli_mbox = NULL; /* Filename of mailbox folder */ static char fld_fname[32]; /* Filename for working folder */ static FILE *fld_fp = NULL; /* Stream pointer for mailbox */ static struct fld_item *fld_msg; /* Struct for mailbox stats */ static int fld_max = -1; /* Actual # msgs in mailbox */ static int fld_highest = -1; /* Max msg accessed by client */ static int fld_hostmbox = 0; /* 0=FromSP mailbox; 1=BSMTP */ static int fld_write_ok = -1; /* -1=client doesnt have write privs */ static long fld_orig_size; /* [1.004] size of mbox when loaded */ static time_t fld_orig_mod_time; /* [1.004] timestamp on mbox file */ #define isfromsp_start(buf) (strncmp(buf,"From ",5) == 0) #define isbsmtp_helo(buf) (strncmp(buf,"helo",4) == 0) #define isbsmtp_end(buf) ((buf[0] == DOT_CHAR)&&(strlen(buf) == 2)) static int fld_select(); static void retr_fromsp(); static void retr_bsmtp(); static int msg_fromsp(); static int msg_bsmtp(); static char *bsmtp_rcpt(); /**************************************************************************/ /* Open a BSMTP wrapped mailbox */ int fld_bsmtp(hostname) char *hostname; { int cnt; /* Release previously opened mailbox */ if (fld_fp != NULL) fld_release(); /* Construct filename for new mailbox */ cli_mbox = malloc(strlen(hostname)+strlen(DEF_POP3_DIR)+1); if (cli_mbox == NULL) fail(FAIL_OUT_OF_MEMORY); strcpy(cli_mbox,DEF_POP3_DIR); strcat(cli_mbox,hostname); /* Open mailbox */ if ((cnt = fld_select(cli_mbox,1)) == -1) { sprintf(svr_buf,"-ERR cannot open mailbox %s\r\n", cli_mbox); free(cli_mbox); cli_mbox = NULL; return(SVR_FOLD_STATE); } else { sprintf(svr_buf,"+OK %d messages ready for %s in %s\r\n", cnt,cli_user,cli_mbox); return(SVR_TRANS_STATE); } } /* Open a FromSpace delimited mailbox */ int fld_fromsp(fname) char *fname; { int cnt; /* Release previously opened mailbox */ if (fld_fp != NULL) fld_release(); /* Construct filename for new mailbox */ cli_mbox = malloc(strlen(fname)+1); if (cli_mbox == NULL) fail(FAIL_OUT_OF_MEMORY); strcpy(cli_mbox,fname); /* Open mailbox */ if ((cnt = fld_select(cli_mbox,0)) == -1) { sprintf(svr_buf,"-ERR cannot open mailbox %s\r\n", cli_mbox); free(cli_mbox); cli_mbox = NULL; return(SVR_FOLD_STATE); } else { sprintf(svr_buf,"+OK %d messages ready for %s in %s\r\n", cnt,cli_user,cli_mbox); return(SVR_TRANS_STATE); } } /**************************************************************************/ /* Mark a message for deletion */ void fld_delete(msgnum) int msgnum; { if (fld_fp == NULL) { strcpy(svr_buf, svr_nomsg); return; } if ((msgnum < 1)||(msgnum > fld_max)) { sprintf(svr_buf,"-ERR invalid message; number out of range\r\n"); } else { fld_msg[msgnum-1].status |= MSG_DELETED; sprintf(svr_buf,"+OK message %d marked for deletion\r\n", msgnum); if ((msgnum-1) > fld_highest) fld_highest =(msgnum-1); } } /* Report the highest access number for this mailbox */ void fld_last() { sprintf(svr_buf,"+OK %d\r\n",(fld_highest+1)); } /* Give information about messages in mailbox folder */ void fld_list(msgnum) int msgnum; { int i; if (fld_fp == NULL) { strcpy(svr_buf, svr_nomsg); return; } if (msgnum == -1) { sprintf(svr_buf,"+OK %d messages; msg# and size (in octets) for undeleted messages:\r\n",fld_max); svr_data_out(svr_buf); for (i=0; i<fld_max; ++i) { if ((fld_msg[i].status & MSG_DELETED) == 0) { sprintf(svr_buf,"%d %ld\r\n", (i+1),fld_msg[i].bcount); svr_data_out(svr_buf); } } sprintf(svr_buf,".\r\n"); } else { if ((msgnum < 1)||(msgnum > fld_max)) sprintf(svr_buf,"-ERR invalid message; number out of range\r\n"); else if (fld_msg[msgnum-1].status & MSG_DELETED) sprintf(svr_buf,"-ERR message %d has been marked for deletion\r\n", msgnum); else sprintf(svr_buf,"+OK %d %ld\r\n", msgnum,fld_msg[msgnum-1].bcount); } } /* Reset deleted messages and highest access number */ void fld_reset() { int i; if (fld_fp == NULL) { strcpy(svr_buf, svr_nomsg); return; } /* Reset messages marked for deletion */ for (i=0; i<fld_max; ++i) { fld_msg[i].status &= ~MSG_DELETED; } /* Reset highest access number for this mailbox */ fld_highest = -1; sprintf(svr_buf,"+OK %d messages ready for %s in %s\r\n", fld_max,cli_user,cli_mbox); } /* Retrieve a message from mailbox */ void fld_retr(msgnum,linecnt) int msgnum; int linecnt; { if (fld_fp == NULL) { strcpy(svr_buf, svr_nomsg); return; } if ((msgnum < 1)||(msgnum > fld_max)) { sprintf(svr_buf,"-ERR invalid message; number out of range\r\n"); } else if (fld_msg[msgnum-1].status & MSG_DELETED) { sprintf(svr_buf,"-ERR message %d has been marked for deletion\r\n", msgnum); } else { sprintf(svr_buf,"+OK message %d (%ld octets):\r\n", msgnum,fld_msg[msgnum-1].bcount); svr_data_out(svr_buf); if (fld_hostmbox == 0) retr_fromsp(--msgnum,linecnt); else retr_bsmtp(--msgnum,linecnt); sprintf(svr_buf,".\r\n"); if ((linecnt != -1)&&(msgnum > fld_highest)) fld_highest = msgnum; } } /* Give message count and total size (in octets) of a mailbox folder */ void fld_stat() { int i; long total_cnt = 0L; if (fld_fp == NULL) { strcpy(svr_buf, "+OK 0 0\r\n"); return; } for (i=0; i<fld_max; ++i) { total_cnt += fld_msg[i].bcount; } sprintf(svr_buf,"+OK %d %ld\r\n",fld_max,total_cnt); } /**************************************************************************/ /* Attempt to load a mailbox folder */ static int fld_select(mbox,host_fld) char *mbox; int host_fld; { struct stat stat_buf; FILE *mboxfp; int lock; /* Reset folder variables */ fld_hostmbox = host_fld; fld_fp = NULL; fld_write_ok = -1; fld_highest = -1; /* Make sure mailbox is present and non-zero size */ if (stat(mbox,&stat_buf) == -1) return 0; if (stat_buf.st_size == 0L) return 0; /* Save current mailbox size and last-modified-timestamp */ fld_orig_size = stat_buf.st_size; /* [1.004] */ fld_orig_mod_time = stat_buf.st_mtime; /* [1.004] */ /* Create/save mailbox names */ strcpy(fld_fname, POP3_TMPFILE); if (mktemp(fld_fname) == NULL) return -1; /* Secure mailbox for POP3 session; copy to temporary file */ if ((mboxfp = fopen(mbox, "r")) == NULL) return -1; if ((lock = dup(fileno(mboxfp))) == -1) { fclose(mboxfp); return -1; } if (flock(lock, LOCK_EX) == -1) { fclose(mboxfp); close(lock); return -1; } if ((fld_fp = fopen(fld_fname,"w")) == NULL) { fclose(mboxfp); flock(lock, LOCK_UN); close(lock); return -1; } /* Load messages from folder */ if (fld_hostmbox == 0) fld_max = msg_fromsp(mboxfp, fld_fp); else fld_max = msg_bsmtp(mboxfp, fld_fp); if (fclose(mboxfp) == EOF) fld_max = -1; if (fclose(fld_fp) == EOF) fld_max = -1; #ifdef notdef /* [1.004] */ /* Zero out the mailbox so other processes can use it */ /* while we are using the temporary copy just made. */ fld_write_ok = access(mbox,W_OK); if ((fld_max > 0) && (fld_write_ok != -1)) { if ((mboxfp = fopen(mbox,"w")) == NULL) { fld_max = -1; } else if (fclose(mboxfp) == EOF) { fld_max = -1; } } #endif /* [1.004] */ /* Unlock mailbox */ flock(lock, LOCK_UN); close(lock); /* Prepare to use temporary file for POP3 session */ if (fld_max > 0) { if ((fld_fp = fopen(fld_fname,"r")) == NULL) { unlink(fld_fname); fld_max = -1; } } else { /* Either zero messages or error */ unlink(fld_fname); fld_fp = NULL; } return(fld_max); } /* Close a mailbox folder; remove messages marked for deletion */ void fld_release() { char temp_fname[32]; FILE *mboxfp; FILE *tempfp; int lock; int i = 0; int savemsg = 1; int zap_orig_mbox; int bsmtp_helo = 0; struct stat stat_buf; /* If no messages in folder, just free memory for filename */ if (fld_fp == NULL) { if (cli_mbox != NULL) { free(cli_mbox); cli_mbox = NULL; } return; } /* If user doesnt have write permission for this */ /* mailbox, just delete the working mailbox. */ if (fld_write_ok = 0) goto cleanup; /* [1.004] Check size and timestamp on the original mailbox file */ if (stat(cli_mbox, &stat_buf) == -1) { /* Another user agent removed it while we were working */ zap_orig_mbox = REMOVE_MBOX; } else { if ((stat_buf.st_mtime == fld_orig_mod_time) && (stat_buf.st_size == fld_orig_size)) { /* Nothing added to mailbox while we were working */ zap_orig_mbox = REMOVE_MBOX; } else { if (stat_buf.st_size > fld_orig_size) { /* More messages were added to end of mbox */ zap_orig_mbox = SAVE_NEW; /* If no messages were deleted, just remove */ /* the working mailbox file. */ for (i=0; i<fld_max; ++i) { if ((fld_msg[i].status & MSG_DELETED) != 0) break; } if (i == fld_max) goto cleanup; } else { /* Another user agent made changes while * we were working; save it all to be safe */ zap_orig_mbox = SAVE_ALL; } } } /* Save changes made to original mailbox folder during * this POP3 session */ if (zap_orig_mbox == REMOVE_MBOX) { /* No changes to save */ if ((mboxfp = fopen(cli_mbox, "w")) == NULL) fail(FAIL_FILE_ERROR); } else { /* Save parts of this mailbox */ if ((mboxfp = fopen(cli_mbox, "r")) == NULL) fail(FAIL_FILE_ERROR); } /* Lock original mailbox folder */ if ((lock = dup(fileno(mboxfp))) == -1) fail(FAIL_FILE_ERROR); if (flock(lock, LOCK_EX) == -1) fail(FAIL_FILE_ERROR); /* Adjust position in original mailbox file */ if (zap_orig_mbox == SAVE_NEW) { /* Save only the messages added while we were working */ if (fseek(mboxfp, fld_orig_size, 0) == -1) fail(FAIL_FILE_ERROR); } else if ((zap_orig_mbox == SAVE_ALL) && (fld_hostmbox != 0)) { /* BSMTP: Skip past HELO line in original mailbox file */ while (fgetl(svr_buf,SVR_BUFSIZ,mboxfp) != NULL) { cmd_prepare(svr_buf); if (isbsmtp_helo(svr_buf)) { break; } } if (ferror(mboxfp)) fail(FAIL_FILE_ERROR); } /* Transfer messages we want to save */ if (zap_orig_mbox == REMOVE_MBOX) { /* Nothing to save, close file we just openned for write */ if (fclose(mboxfp) == EOF) fail(FAIL_FILE_ERROR); temp_fname[0] = '\0'; } else { /* Copy from the original mailbox to a temp file */ strcpy(temp_fname, POP3_TMPFILE); if (mktemp(temp_fname) == NULL) fail(FAIL_FILE_ERROR); if ((tempfp = fopen(temp_fname,"w")) == NULL) fail(FAIL_FILE_ERROR); while (fgetl(svr_buf,SVR_BUFSIZ,mboxfp) != NULL) { fputs(svr_buf,tempfp); if (ferror(tempfp)) fail(FAIL_FILE_ERROR); } if (ferror(mboxfp)) fail(FAIL_FILE_ERROR); if (fclose(mboxfp) == EOF) fail(FAIL_FILE_ERROR); if (fclose(tempfp) == EOF) fail(FAIL_FILE_ERROR); } /* Transfer contents of working folder to original */ /* mailbox folder; dont copy deleted messages. */ if ((mboxfp = fopen(cli_mbox,"w")) == NULL) fail(FAIL_FILE_ERROR); /* If all messages were deleted, we don't need to look */ /* throught the working mailbox file. */ for (i=0; i<fld_max; ++i) { if ((fld_msg[i].status & MSG_DELETED) == 0) break; } if (i == fld_max) goto addnew; /* Transfer undeleted messages from the working mailbox */ rewind(fld_fp); i = 0; /* [1.002] reset index counter */ if (fld_hostmbox != 0) { /* BSMTP: Transfer all text upto and including HELO */ while (fgetl(svr_buf,SVR_BUFSIZ,fld_fp) != NULL) { fputs(svr_buf,mboxfp); if (ferror(mboxfp)) fail(FAIL_FILE_ERROR); cmd_prepare(svr_buf); if (isbsmtp_helo(svr_buf)) { bsmtp_helo = 1; break; } } /* Transfer first message, unless marked for deletion */ savemsg = !(fld_msg[i++].status & MSG_DELETED); } while (fgetl(svr_buf,SVR_BUFSIZ,fld_fp) != NULL) { if ((fld_hostmbox == 0) && (isfromsp_start(svr_buf))) { /* FromSPACE delimited mailbox */ /* Transfer next msg, unless deleted */ savemsg = !(fld_msg[i++].status & MSG_DELETED); } if (savemsg) { fputs(svr_buf,mboxfp); if (ferror(mboxfp)) fail(FAIL_FILE_ERROR); } if ((fld_hostmbox != 0) && (isbsmtp_end(svr_buf))) { /* BSMTP mailbox */ /* Transfer next msg, unless deleted */ savemsg = !(fld_msg[i++].status & MSG_DELETED); } } if (ferror(fld_fp)) fail(FAIL_FILE_ERROR); if (temp_fname[0] == '\0') { /* Nothing more to add, close the original mailbox file */ if (fclose(mboxfp) == EOF) fail(FAIL_FILE_ERROR); } addnew: if (temp_fname[0] != '\0') { /* There were changes to the original mailbox file * while we were working. Save the messages that * chnaged in the original mailbox file. */ if ((fld_hostmbox != 0) && (bsmtp_helo == 0)) { /* BSMTP: Transfer all text upto and including HELO */ rewind(fld_fp); while (fgetl(svr_buf,SVR_BUFSIZ,fld_fp) != NULL) { fputs(svr_buf,mboxfp); if (ferror(mboxfp)) fail(FAIL_FILE_ERROR); cmd_prepare(svr_buf); if (isbsmtp_helo(svr_buf)) { bsmtp_helo = 1; break; } } if (ferror(fld_fp)) fail(FAIL_FILE_ERROR); } /* Transfer contents of temp file (messages added */ /* to original mailbox during this POP3 session) */ /* back to mailbox folder */ if ((tempfp = fopen(temp_fname,"r")) == NULL) fail(FAIL_FILE_ERROR); while (fgets(svr_buf,SVR_BUFSIZ,tempfp) != NULL) { fputs(svr_buf,mboxfp); if (ferror(mboxfp)) fail(FAIL_FILE_ERROR); } if (ferror(tempfp)) fail(FAIL_FILE_ERROR); if (fclose(tempfp) == EOF) fail(FAIL_FILE_ERROR); unlink(temp_fname); if (fclose(mboxfp) == EOF) fail(FAIL_FILE_ERROR); } /* Unlock original mailbox folder */ flock(lock, LOCK_UN); close(lock); cleanup: /* Close and remove working copy of mailbox folder */ fclose(fld_fp); fld_fp = NULL; unlink(fld_fname); for (i=0; i<fld_max; ++i) { if (fld_msg[i].pop_hdr != NULL) free(fld_msg[i].pop_hdr); } free( (char *)fld_msg ); free(cli_mbox); cli_mbox = NULL; } /********************************************/ /* Send a BSMTP wrapped message to the POP3 client */ static void retr_bsmtp(msgnum,linecnt) int msgnum; int linecnt; { char *tp; int msgbody = 0; /* Locate start of message in mailbox file */ if (fseek(fld_fp, fld_msg[msgnum].fmsg_entry, 0) == -1) return; /* Display message text for the client */ if (fld_msg[msgnum].pop_hdr != NULL) svr_data_out(fld_msg[msgnum].pop_hdr); while (fgetl(svr_buf,SVR_BUFSIZ,fld_fp) != NULL) { if (isbsmtp_end(svr_buf)) break; /* Use CR-LF line terminator */ tp = strchr(svr_buf,LF_CHAR); if (tp != NULL) strcpy(tp,"\r\n"); svr_data_out(svr_buf); if ((msgbody)&&(--linecnt == 0)) { break; } else { if (*svr_buf == CR_CHAR) msgbody = 1; } } } /* Send a FromSP delimited message to the POP3 client */ static void retr_fromsp(msgnum,linecnt) int msgnum; int linecnt; { char *cp, *tp; int msgbody = 0; /* Locate start of message in mailbox file */ if (fseek(fld_fp, fld_msg[msgnum].fmsg_entry, 0) == -1) return; /* Setup for byte-stuff on lines that start with '.' */ cp = svr_buf; *cp = DOT_CHAR; ++cp; /* Display message for the client */ if (fld_msg[msgnum].pop_hdr != NULL) svr_data_out(fld_msg[msgnum].pop_hdr); while (fgetl(cp,SVR_BUFSIZ,fld_fp) != NULL) { if (isfromsp_start(cp)) break; /* Use CR-LF line terminator */ tp = strchr(cp,LF_CHAR); if (tp != NULL) strcpy(tp,"\r\n"); /* Byte-stuff lines that start with '.' */ if (*cp == DOT_CHAR) svr_data_out(svr_buf); else svr_data_out(cp); if ((msgbody)&&(--linecnt == 0)) { break; } else { if (*cp == CR_CHAR) msgbody = 1; } } } /**************************************************************************/ /* Load messages from a mailbox wrapped in BSMTP format */ /* Assume BSMTP mailbox starts with a HELO command. */ /* Assume BSMTP mailbox doesnt end with a QUIT command. */ static int msg_bsmtp(infp, outfp) FILE *infp; FILE *outfp; { register struct fld_item *mp; int i = 0; int mbox_state = BSMTP_HELO_STATE; /* Get an array for storing info about messages in folder */ get_e_array(fld_msg, FLD_ENTRY_BLOCK); if (fld_msg == NULL) fail(FAIL_OUT_OF_MEMORY); mp = &fld_msg[0]; mp->pop_hdr = NULL; /* Load messages from mailbox folder to temporary folder */ while (fgetl(svr_buf,SVR_BUFSIZ,infp) != NULL) { fputs(svr_buf, outfp); if (ferror(outfp)) return -1; switch(mbox_state) { case BSMTP_HELO_STATE: /* Look for HELO command */ cmd_prepare(svr_buf); if (strncmp(svr_buf,"helo",4) == 0) mbox_state = BSMTP_MAIL_STATE; break; case BSMTP_MAIL_STATE: /* Process MAIL command */ cmd_prepare(svr_buf); if (strncmp(svr_buf,"mail",4) == 0) mbox_state = BSMTP_RCPT_STATE; break; case BSMTP_RCPT_STATE: /* Process RCPT command(s) */ cmd_prepare(svr_buf); if (strncmp(svr_buf,"rcpt",4) == 0) { /* Save recipient for POP3 client */ sprintf(flash_buf,"%s %s\r\n", POP3_RCPT_HDR,bsmtp_rcpt(svr_buf)); if (mp->pop_hdr == NULL) { mp->bcount = 0L; mp->status = 0; mp->pop_hdr = malloc(strlen(flash_buf)+1); if (mp->pop_hdr == NULL) fail(FAIL_OUT_OF_MEMORY); strcpy(mp->pop_hdr,flash_buf); } else { mp->pop_hdr = realloc(mp->pop_hdr, (strlen(mp->pop_hdr)+strlen(flash_buf)+1)); if (mp->pop_hdr == NULL) fail(FAIL_OUT_OF_MEMORY); strcat(mp->pop_hdr,flash_buf); } mp->bcount += (long)strlen(flash_buf); } else if (strncmp(svr_buf,"data",4) == 0) { mbox_state = BSMTP_DATA_STATE; /* Save entry point of message text */ mp->fmsg_entry = ftell(outfp); } break; case BSMTP_DATA_STATE: /* Reading mail message */ if (isbsmtp_end(svr_buf)) { /* Prepare for next message in mailbox */ mbox_state = BSMTP_MAIL_STATE; ++i; /* Resize message array, if needed */ chk_e_size(fld_msg, FLD_ENTRY_BLOCK, i); if (fld_msg == NULL) fail(FAIL_OUT_OF_MEMORY); mp = &fld_msg[i]; mp->pop_hdr = NULL; } else { mp->bcount += ((long)strlen(svr_buf) + 1L); if (svr_buf[0] == DOT_CHAR) --mp->bcount; } break; default: /* Shouldnt happen */ fail(FAIL_CONFUSION); break; } } if (ferror(infp)) return -1; if (i == 0) free((char *)fld_msg); return(i); } /* Load messages from a mailbox delimited by FromSPACE */ static int msg_fromsp(infp, outfp) FILE *infp; FILE *outfp; { int i = 0; register struct fld_item *mp; /* Get an array for storing info about messages in folder */ get_e_array(fld_msg, FLD_ENTRY_BLOCK); if (fld_msg == NULL) fail(FAIL_OUT_OF_MEMORY); mp = &fld_msg[0]; /* Load messages from mailbox folder to temporary folder */ while (fgetl(svr_buf,SVR_BUFSIZ,infp) != NULL) { fputs(svr_buf, outfp); if (ferror(outfp)) return -1; if (isfromsp_start(svr_buf)) { /* Make sure there is room in array for this entry */ chk_e_size(fld_msg, FLD_ENTRY_BLOCK, i); if (fld_msg == NULL) fail(FAIL_OUT_OF_MEMORY); /* Reset stats for this message */ mp = &fld_msg[i]; mp->fmsg_entry = ftell(outfp); mp->status = 0; sprintf(flash_buf,"%s %s@%s\r\n",POP3_RCPT_HDR, cli_user,svr_hostname); mp->pop_hdr = malloc(strlen(flash_buf)+1); if (mp->pop_hdr == NULL) fail(FAIL_OUT_OF_MEMORY); strcpy(mp->pop_hdr,flash_buf); mp->bcount = strlen(mp->pop_hdr); ++i; } else { mp->bcount += ((long)strlen(svr_buf) + 1L); } } if (ferror(infp)) return -1; if (i == 0) free((char *)fld_msg); return(i); } /************************************************/ /* Isolate a recipient address in a BSMTP RCPT TO:<addr> command */ static char * bsmtp_rcpt(inbuf) char *inbuf; { char *cp; cp = strchr(inbuf,RANKLE_CHAR); if (cp == NULL) return("postmaster"); *cp = NULL_CHAR; cp = strchr(inbuf,LANKLE_CHAR); if (cp == NULL) return("postmaster"); return(cp+1); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.