home *** CD-ROM | disk | FTP | other *** search
- /* SMTP Server state machine - see RFC 821
- * Very simple implementation; no forwarding allowed
- * (who wants to re-create "sendmail" ??)
- * enhanced 12/87 Dave Trulli nn2z
- */
- #include <stdio.h>
- #include <ctype.h>
- #include <time.h>
- #include "global.h"
- #include "mbuf.h"
- #include "netuser.h"
- #include "timer.h"
- #include "tcp.h"
- #include "smtp.h"
-
- #ifndef DFLT_MODE
- #define DFLT_MODE 0660 /* use this instead of user's umask */
- #endif
-
- char *ptime(), *getname();
- void mail_delete(), del_rcpt();
- static int queuejob(),checkaddress();
- int32 get_msgid();
-
- /* Command table */
- static char *commands[] = {
- "helo",
- #define HELO_CMD 0
- "noop",
- #define NOOP_CMD 1
- "mail from:",
- #define MAIL_CMD 2
- "quit",
- #define QUIT_CMD 3
- "rcpt to:",
- #define RCPT_CMD 4
- "help",
- #define HELP_CMD 5
- "data",
- #define DATA_CMD 6
- "rset",
- #define RSET_CMD 7
- NULLCHAR
- };
-
- /* Reply messages */
- static char help[] = "214-Commands:\r\n214-HELO NOOP MAIL QUIT RCPT HELP DATA RSET\r\n214 End\r\n";
- static char banner[] = "220 %s SMTP ready\r\n";
- static char closing[] = "221 Closing\r\n";
- static char ok[] = "250 Ok\r\n";
- static char reset[] = "250 Reset state\r\n";
- static char sent[] = "250 Sent\r\n";
- static char ourname[] = "250 %s, \"Gateway to the universe!\"\r\n"; /*Share and Enjoy!\r\n";*/
- static char enter[] = "354 Enter mail, end with .\r\n";
- static char ioerr[] = "452 Temp file write error\r\n";
- static char mboxerr[] = "452 Mailbox %s write error\r\n";
- static char badcmd[] = "500 Command unrecognized\r\n";
- static char syntax[] = "501 Syntax error\r\n";
- static char needrcpt[] = "503 Need RCPT (recipient)\r\n";
- static char badname[] = "550 Can't open mailbox for %s\r\n";
-
- static struct tcb *smtp_tcb;
- /* Start up SMTP receiver service */
- smtp_start(argc,argv)
- int argc;
- char *argv[];
- {
- struct socket lsocket;
- void r_mail(),s_mail();
-
- lsocket.address = ip_addr;
- if(argc < 2)
- lsocket.port = SMTP_PORT;
- else
- lsocket.port = atoi(argv[1]);
-
- smtp_tcb = open_tcp(&lsocket,NULLSOCK,
- TCP_SERVER,0,r_mail,NULLVFP,s_mail,0,(char *)NULL);
- }
-
- /* Shutdown SMTP service (existing connections are allowed to finish) */
- smtp_stop()
- {
- if(smtp_tcb != NULLTCB)
- close_tcp(smtp_tcb);
- }
-
- /* SMTP connection state change upcall handler */
- static void
- s_mail(tcb,old,new)
- struct tcb *tcb;
- char old,new;
- {
- struct mail *mp,*mail_create();
-
- switch(new){
- #ifdef QUICKSTART
- case SYN_RECEIVED:
- #else
- case ESTABLISHED:
- #endif
- if((mp = mail_create(tcb)) == NULLMAIL){
- close_tcp(tcb);
- break;
- }
- (void) tprintf(mp->tcb,banner,hostname);
- log(tcb,"open SMTP");
- break;
- case CLOSE_WAIT:
- close_tcp(tcb);
- break;
- case CLOSED:
- log(tcb,"close SMTP");
- mp = (struct mail *)tcb->user;
- mail_delete(mp);
- del_tcp(tcb);
- /* Check if server is being shut down */
- if(tcb == smtp_tcb)
- smtp_tcb = NULLTCB;
- break;
- }
- }
-
- /* SMTP receiver upcall handler */
- static void
- r_mail(tcb,cnt)
- struct tcb *tcb;
- int16 cnt;
- {
- register struct mail *mp;
- char *inet_ntoa(),c;
- struct mbuf *bp;
- void docommand(),deliver(),doline();
-
- if((mp = (struct mail *)tcb->user) == NULLMAIL){
- /* Unknown sessioo */
- close_tcp(tcb);
- return;
- }
- recv_tcp(tcb,&bp,cnt);
- /* Assemble an input line in the session buffer.
- * Return if incomplete
- */
- while(pullup(&bp,&c,1) == 1){
- switch(c){
- case '\r': /* Strip cr's */
- #ifdef MSDOS
- case '\032': /* Strip ctrl/Z's */
- #endif
- continue;
- case '\n': /* Complete line; process it */
- mp->buf[mp->cnt] = '\0';
- doline(mp);
- break;
- default: /* Assemble line */
- if(mp->cnt != LINELEN-1)
- mp->buf[mp->cnt++] = c;
- break;
- }
- }
- }
- /* Process Process Process Process Process