This is main.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 * ************************************** * * main.c * * REVISIONS: * 02-27-90 [ks] original implementation * 1.000 03-04-90 [ks] * 1.001 06-24-90 [ks] 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!) * -- set umask() value explicitly (Thanks to * Vikas Aggarwal, JvNCnet, Princeton, NJ * for suggesting this) * 1.003 03-92 [ks] close mailbox before return from main() * 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 <signal.h> #include <ctype.h> #include <sys/param.h> #include "pop3.h" #define VERSION "1.004" #define REVDATE "January, 1992" char *svr_hostname; /* Hostname of POP3 server */ char svr_buf[SVR_BUFSIZ+2]; /* Buffer for server I/O */ char cli_user[CLI_BUFSIZ]; /* Save client username */ static char *svr_invalid = "-ERR Invalid command; valid commands:"; #ifdef DEBUG FILE *logfp = NULL; /* File for recording session */ #endif /* Routines in this file */ static void initialize(); static void svr_timeout(); static void int_hangup(); static void int_progerr(); static int svr_auth(); static int svr_pass(); static int svr_trans(); static int svr_fold(); static int svr_shutdown(); /**************************************************************************/ /* Initialize POP3 server */ static void initialize() { char buf[MAXHOSTNAMELEN+1]; /* File permissions for owner only */ umask(077); /* [1.002] */ #ifdef DEBUG /* Prepare log file */ logfp = fopen(LOGFILE,"w"); fprintf(logfp,"POP3 server startup; version %s (%s)\n", VERSION,REVDATE); #endif /* Get our hostname */ gethostname(buf,MAXHOSTNAMELEN); svr_hostname = malloc(strlen(buf) + 1); if (svr_hostname == NULL) fail(FAIL_OUT_OF_MEMORY); strcpy(svr_hostname,buf); /* Handle process signals ourself */ signal(SIGALRM, svr_timeout); /* timer expiration */ signal(SIGHUP, int_hangup); /* socket signals */ signal(SIGURG, int_hangup); signal(SIGTERM, int_hangup); #ifdef LINUX # ifdef SIGBUS signal(SIGBUS, int_progerr); /* fatal program errors */ # endif #endif signal(SIGSEGV, int_progerr); signal(SIGILL, int_progerr); signal(SIGIOT, int_progerr); } /* Timeout while waiting for next client command */ static void svr_timeout() { fld_release(); /* Release mailbox folder */ fail(FAIL_LOST_CLIENT); /* Exit POP3 server */ } /* Timeout while waiting for next client command */ static void int_hangup() { fld_release(); /* Release mailbox folder */ fail(FAIL_HANGUP); /* Exit POP3 server */ } /* Timeout while waiting for next client command */ static void int_progerr() { fld_release(); /* Release mailbox folder */ fail(FAIL_PROGERR); /* Exit POP3 server */ } /**************************************************************************/ /* Server Authentification State; process client USER command */ static int svr_auth(state,inbuf) int state; char *inbuf; { if (strncmp(inbuf,"quit",4) == 0) return(svr_shutdown()); /* Expecting USER command */ if (strncmp(inbuf,"user",4) == 0) { inbuf += 4; EATSPACE(inbuf); strcpy(cli_user,inbuf); strcpy(svr_buf,"+OK please send PASS command\r\n"); state = SVR_PASS_STATE; } else { sprintf(svr_buf,"%s USER, QUIT\r\n",svr_invalid); } return(state); } /* Server Password State; process client PASS command */ static int svr_pass(state,inbuf) int state; char *inbuf; { int cnt; if (strncmp(inbuf,"quit",4) == 0) return(svr_shutdown()); /* Expecting PASS command */ if (strncmp(inbuf,"pass",4) != 0) { sprintf(svr_buf,"%s PASS, QUIT\r\n",svr_invalid); return(state); } /* Verify usercode/password pair */ inbuf += 4; EATSPACE(inbuf); if (verify_user(cli_user,inbuf) == -1) { strcpy(svr_buf,"-ERR invalid usercode or password, please try again\r\n"); return(SVR_AUTH_STATE); } strcpy(svr_buf,DEF_MAIL_DIR); strcat(svr_buf,cli_user); return(fld_fromsp(svr_buf)); } /* Server Transaction State; process client mailbox command */ static int svr_trans(state,inbuf) int state; char *inbuf; { int msgnum; if (strncmp(inbuf,"quit",4) == 0) return(svr_shutdown()); /* Expecting mailbox command */ if (strncmp(inbuf,"dele",4) == 0) { inbuf += 4; EATSPACE(inbuf); if (*inbuf == NULL_CHAR) sprintf(svr_buf,"-ERR message number required (e.g. DELE 1)\r\n"); else fld_delete(atoi(inbuf)); } else if (strncmp(inbuf,"host",4) == 0) { inbuf += 4; EATSPACE(inbuf); if (*inbuf == NULL_CHAR) sprintf(svr_buf,"-ERR must specify hostname\r\n"); else state = fld_bsmtp(inbuf); } else if (strncmp(inbuf,"last",4) == 0) { fld_last(); } else if (strncmp(inbuf,"list",4) == 0) { inbuf += 4; EATSPACE(inbuf); if (*inbuf == NULL_CHAR) fld_list(-1); else fld_list(atoi(inbuf)); } else if (strncmp(inbuf,"mbox",4) == 0) { inbuf += 4; EATSPACE(inbuf); if (*inbuf == NULL_CHAR) sprintf(svr_buf,"-ERR must specify mailbox filename\r\n"); else state = fld_fromsp(inbuf); } else if (strncmp(inbuf,"noop",4) == 0) { strcpy(svr_buf,"+OK\r\n"); } else if (strncmp(inbuf,"retr",4) == 0) { inbuf += 4; EATSPACE(inbuf); if (*inbuf == NULL_CHAR) { sprintf(svr_buf,"-ERR message number required (e.g. RETR 1)\r\n"); } else fld_retr(atoi(inbuf),-1); } else if (strncmp(inbuf,"rset",4) == 0) { fld_reset(); } else if (strncmp(inbuf,"stat",4) == 0) { fld_stat(); } else if (strncmp(inbuf,"top",3) == 0) { inbuf += 3; EATSPACE(inbuf); if (*inbuf == NULL_CHAR) { sprintf(svr_buf,"-ERR message number and line count required (e.g. TOP 1 7)\r\n"); } else { msgnum = atoi(inbuf); while (!isspace(*inbuf)) ++inbuf; EATSPACE(inbuf); if (*inbuf == NULL_CHAR) sprintf(svr_buf,"-ERR line count required (e.g. TOP 1 7)\r\n"); else fld_retr(msgnum,atoi(inbuf)); } } else { sprintf(svr_buf, "%s DELE, HOST, LAST, LIST, MBOX, NOOP, RETR, RSET, STAT, TOP or QUIT\r\n", svr_invalid); } return(state); } /* Server Folder State; need to open another folder */ static int svr_fold(state,inbuf) int state; char *inbuf; { if (strncmp(inbuf,"quit",4) == 0) return(svr_shutdown()); if (strncmp(inbuf,"host",4) == 0) { inbuf += 4; EATSPACE(inbuf); state = fld_bsmtp(inbuf); } else if (strncmp(inbuf,"mbox",4) == 0) { inbuf += 4; EATSPACE(inbuf); state = fld_fromsp(inbuf); } else if (strncmp(inbuf,"noop",4) == 0) { strcpy(svr_buf,"+OK\r\n"); } else { sprintf(svr_buf,"%s HOST, MBOX, NOOP or QUIT\r\n",svr_invalid); } return(state); } /* Prepare to shutdown POP3 server */ static int svr_shutdown() { fld_release(); sprintf(svr_buf,"+OK %s POP3 Server (Version %s) shutdown.\r\n", svr_hostname,VERSION); return(SVR_DONE_STATE); } /**************************************/ void svr_data_out(buf) char *buf; { /* Send out response to client */ alarm(SVR_TIMEOUT_SEND); fputs(buf,stdout); fflush(stdout); alarm(0); } /**************************************************************************/ main() { int svr_state = SVR_LISTEN_STATE; /* State of POP3 server */ char cli_buf[CLI_BUFSIZ]; /* Buffer for client cmds */ initialize(); fprintf(stdout,"+OK %s POP3 Server (Version %s) ready.\r\n", svr_hostname,VERSION); fflush(stdout); svr_state = SVR_AUTH_STATE; for ( ; ; ) { /* Wait for command from client */ alarm(SVR_TIMEOUT_CLI); if (fgetl(cli_buf,CLI_BUFSIZ,stdin) == NULL) break; alarm(0); /* Take action on client command */ cmd_prepare(cli_buf); #ifdef DEBUG if ((cli_buf[0] == 'p')||(cli_buf[0] == 'P')) fprintf(logfp,"CLI: PASS\n",cli_buf); else fprintf(logfp,"CLI: %s\n",cli_buf); #endif switch(svr_state) { case SVR_AUTH_STATE: /* Expecting USER command */ svr_state = svr_auth(svr_state,cli_buf); break; case SVR_PASS_STATE: /* Expecting PASS command */ svr_state = svr_pass(svr_state,cli_buf); break; case SVR_TRANS_STATE: /* Expecting mailbox command */ svr_state = svr_trans(svr_state,cli_buf); break; case SVR_FOLD_STATE: /* Need to open another mailbox */ svr_state = svr_fold(svr_state,cli_buf); break; default: fail(FAIL_CONFUSION); /* Wont return */ break; } #ifdef DEBUG fprintf(logfp,"SVR: %s",svr_buf); #endif /* Send out response to client */ alarm(SVR_TIMEOUT_SEND); fputs(svr_buf,stdout); fflush(stdout); alarm(0); if (ferror(stdout)) break; /* Exit when server has sent goodbye */ if (svr_state == SVR_DONE_STATE) break; } fld_release(); /* [1.003] Make sure folder is released */ exit(0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.