mail-dm.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 427 行
C
427 行
#include <arpa/netopen.h>#include "srvrftp.h"#include <statbuf.h>#include <arpa/hostnames.h>#include <io_buf.h>#include <arpa/mail.h>#include <ident.h>#include <signal.h>#include <log.h>extern int fout;static char SccsId[] = "@(#)mail-dm.c 4.1 7/25/83";/*Name: mailFunction: handle the MAIL <user> command over the command connectionAlgorithm: see if we have a known user if mailbox file can't be gotten return tell him it is ok to go ahead with mail while he doesn't type a period read and write data say completedParameters: username in argReturns: nothingGlobals: arg username=Calls: strmove getuser loguser openmail closemail getline chown (sys) time (sys) printf (sys) getch (util) putch (util)Called by: main thru command arrayHistory: initial coding Mark Kampe UCLA-ATS modified 4/13/76 by S. F. Holmgren for Illinois version modified 6/30/76 by S. F. Holmgren to call getmbox modified 10/18/76 by J. S. Kravitz to improve net mail header chown removed by R. Balocca @ CAC, Sunday 1977 February 20 getline removed and limit on line length removed by using getch and putch added by R. Balocca @ CAC, 1977 March 8 Tuesday Fixed oversight in above (forgot to translate <crlf> to <lf>) 1977 March 10 Thursday by Rick Balocca @ CAC Added openmail & closemail, added logging, and fixed several bugs on or about 12/21/79 by Eric Allman, UCB/INGRES. Changed to always accept mail -- bad mail will be sent back -- 1/9/80 by Eric Allman, UCB/INGRES. Don't print out 350 enter mail or 256 mail accepted messages -- sendmail will do that. 8/19/81 Eric Allman UCB/INGRES.*/#define gt (c = getch())mail(){ register char *p; /* general use */ register int c; int i; /* extern struct io_buf obuf; */ /* get to open mailbox file descriptor */ fflush(&fout); if( (fout = openmail(arg, 0)) < 0 ) return; for(;;) /* while no error or <crlf>.<crlf> */ { /* we are at beginning of line */ if(gt=='.') /*"."*/ { if(gt=='\r') /*".\r"*/ { if(gt=='\n') /*".\r\n"*/ { /* end of message */ break; } else { /*".\r"c*/ putch('.'); putch('\r'); } } else /*"."c"*/ putch('.'); } /*"-"*/ /* c */ for(;;) { for(; c != '\r'; gt) { if( c < 0 ) { fflush(&fout); write(fout, "\n***** Sender aborted connection *****\n", 39); goto out; } else putch(c); } /*"\r"*/ if( gt == '\n' ) { /*"\r\n"*/crlf: putch('\n'); break; } else { /*"\r"c*/crc: putch('\r'); if(c=='\0') gt; /* "\r\0" */ /* is arpa escape for "\r" */ } } }out: fflush(&fout); closemail(fout);}/*Name: datamailFunction: handle the MLFL commandAlgorithm: fork make sure we have a valid user say bad user and exit send sock command open data connection get open mailbox file descriptor call rcvdata to receive mailParameters: username in argReturns: nothingGlobals: argCalls: fork (sys) strmove netreply sendsock dataconnection getmbox rcvdata printf (sys) time (sys)Called by: main thru command array History: initial coding 4/13/76 by S. F. Holmgren modified 10/18/76 by J. S. Kravitz to put net mail header chown removed by R. Balocca @ CAC, Sunday 1977 February 20*/datamail(){ register netdata; /* register mboxfid; */ register int i; i = fork(); if (i < 0) { netreply("455 Mail server temporarily unavailable\r\n"); return; } else if (i == 0) { fflush(&fout); if ((fout = openmail(arg, 1)) < 0) exit(3); /* send sock command */ sendsock( U4 ); /* open data connection */ netdata = dataconnection( U4 ); /* say its ok to proceed */ numreply( NUM250 ); /* get data from net connection and copy to mail file */ /* rcvdata( netdata,mboxfid ); */ if (rcvdata(netdata, fout) < 0) exit(1); /* close the mail, see if ok; if so say ok */ fflush(&fout); closemail(fout); exit( 0 ); }}/*** OPENMAIL -- Open a channel to the mail server**** Gets the mail server started up ready to handle our** mail.**** Algorithm:** See if the user is specified.** If not, send to user "root".** See if the user exists.** If not, signal error 450 and return.** Fork.** Create a pipe** Signal "unavailable" and exit on failure.** Fork.** Signal "unavailable" and exit on failure** In child:** Call mailer: /etc/delivermail is preferred.** In parent:** Avoid pipe signals in case delivermail dies.** Save the childs pid.** Return file descriptor.**** Notes:** The check to see if the user actually exists should** go away so that we can do real mail forwarding.**** Parameters:** who -- the user to send the mail to.** mode -- 0 -- called from mail** 1 -- called from mlfl**** Returns:** File descriptor to send mail to.** -1 on failure.**** Side Effects:** Forks /etc/delivermail or /bin/mail or /usr/bin/mail.** Becomes "network" in the child.**** Requires:** strmove** getuser** netreply** pipe (sys)** fork (sys)** close (sys)** dup (sys)** execl (sys)** signal (sys)** exit (sys)**** Called By:** mail** datamail**** History:** 1/9/80 -- Added 050 & 455 reply messages if execl's** fail. Eric Allman UCB/INGRES.** 11/26/79 -- Modified to map upper case to lower** case. Eric Allman UCB/INGRES.** 11/10/79 -- Written by Eric Allman UCB/INGRES** 3/6/80 -- Dropped case mapping; delivermail does** that now. EPA UCB/INGRES.** 8/19/81 -- Added "mode" parameter; call sendmail** instead of delivermail. EPA*/int Mail_pid;char *Mail_user;openmail(who, mode) char *who; int mode;{ register char *w; register int i; int pvect[2]; register char *p; w = who; if (w == 0) w = "root"; Mail_user = w; /* see if the user exists */ strmove(w, username); /* try to get a pipe to the mailer */ if (pipe(pvect) < 0) { unavailable: netreply("455 Mail server temporarily unavailable\r\n"); return (-1); } /* fork */ i = fork(); if (i < 0) { /* failure */ close(pvect[0]); close(pvect[1]); goto unavailable; } else if (i == 0) { /* child */ close(pvect[1]); close(0); dup(pvect[0]); close(pvect[0]); setuid(NETUID); /* try to call something to deliver the mail */ execl("/etc/sendmail", "sendmail", "-v", mode == 1 ? "-af" : "-am", w, 0); /* doesn't seem to be anything around */ netreply("455 Mail server unavailable\r\n"); exit(3); } /* else parent */ signal(SIGPIPE, SIG_IGN); Mail_pid = i; close(pvect[0]); return (pvect[1]);}/*** CLOSEMAIL -- Close the mail file and get actual status**** The mail file is closed.**** Algorithm:** Wait for the mailer to die.** If it wasn't there, be non-comittal.** If it died a violent death, give error.**** Parameters:** fd -- the file descriptor of the mail file.**** Returns:** none.**** Side Effects:** mailer is soaked up.**** Requires:** close (sys)** wait (sys)**** Called By:** mail** datamail**** History:** 1/9/80 -- Changed to not check for errors in mailing,** since these will be mailed back.** 11/10/79 -- Written by Eric Allman UCB/INGRES.*/closemail(fd) int fd;{ auto int st; register int i; /* close the pipe -- mail should go away */ close(fd); /* wait for its body */ while ((i = wait(&st)) != Mail_pid) { if (i < 0) { /* how did this happen? */ logmsg(LOG_ERR, "mail from host %d to %s: no child", openparams.o_frnhost & 0377, Mail_user); goto unavailable; } } /* 'st' is now the status of the mailer */ if ((st & 0377) != 0) { logmsg(LOG_ERR, "mail from host %d to %s: status %o", openparams.o_frnhost & 0377, Mail_user, st);unavailable: netreply("455 Mail not delivered -- local system error\r\n"); return (-1); } return (0);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?