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.