1*4796Seric # include <ctype.h> 24684Seric # include <wellknown.h> 34684Seric # include <sysexits.h> 44684Seric # include <stdio.h> 54684Seric # include <useful.h> 64684Seric 7*4796Seric static char SccsId[] = "@(#)usersmtp.c 3.2 11/07/81"; 84684Seric 94684Seric /* 104684Seric ** TCP -- TCP/Ethernet/ARPAnet mailer 114684Seric ** 124684Seric ** This arranges to send a message over the TCP connection. 134684Seric */ 144684Seric 154684Seric # define MAXLINE 200 164684Seric 174684Seric char *MailCommand = "/usr/lib/sendmail"; 184684Seric char *MailUser = "network"; 19*4796Seric char *MailPassword = "mailhack"; 20*4796Seric FILE *InConnection; 21*4796Seric FILE *OutConnection; 224684Seric bool Verbose; 23*4796Seric bool Debug; 244684Seric 254684Seric main(argc, argv) 264684Seric int argc; 274684Seric char **argv; 284684Seric { 294684Seric register int stat; 304684Seric 31*4796Seric while (argc > 1 && argv[1][0] == '-') 32*4796Seric { 33*4796Seric register char *p = *++argv; 34*4796Seric 35*4796Seric argc--; 36*4796Seric switch (p[1]) 37*4796Seric { 38*4796Seric case 'v': 39*4796Seric Verbose = TRUE; 40*4796Seric break; 41*4796Seric 42*4796Seric case 'd': 43*4796Seric Debug = TRUE; 44*4796Seric break; 45*4796Seric } 46*4796Seric } 47*4796Seric 484684Seric if (argc < 4) 49*4796Seric { 50*4796Seric if (Debug) 51*4796Seric printf("Usage\n"); 524684Seric exit(EX_USAGE); 53*4796Seric } 544684Seric 55*4796Seric if (openconnection(argv[2]) < 0) 564684Seric exit(EX_TEMPFAIL); 574684Seric 584684Seric stat = runsmtp(argv[1], &argv[3]); 594684Seric 60*4796Seric if (Debug) 61*4796Seric printf("Finishing with stat %d\n", stat); 62*4796Seric 634684Seric exit(stat); 644684Seric } 654684Seric /* 664684Seric ** OPENCONNECTION -- open connection to SMTP socket 674684Seric ** 684684Seric ** Parameters: 694684Seric ** none. 704684Seric ** 714684Seric ** Returns: 724684Seric ** file pointer of connection. 734684Seric ** NULL on error. 744684Seric ** 754684Seric ** Side Effects: 764684Seric ** none. 774684Seric */ 784684Seric 794684Seric openconnection(host) 804684Seric char *host; 814684Seric { 824684Seric char cmdbuf[100]; 83*4796Seric register int fd; 844684Seric 854684Seric /* create the command name */ 86*4796Seric sprintf(cmdbuf, "%s -as%s%s", MailCommand, 87*4796Seric Verbose ? " -v" : "", 88*4796Seric Debug ? " -d" : ""); 894684Seric 90*4796Seric if (Debug) 91*4796Seric printf("Creating connection to \"%s\" on %s\n", cmdbuf, host); 92*4796Seric 934684Seric /* create connection (we hope) */ 94*4796Seric fd = rexec(&host, SHELLSERVER, cmdbuf, MailUser, MailPassword); 95*4796Seric if (fd < 0) 96*4796Seric return (-1); 97*4796Seric InConnection = fdopen(fd, "r"); 98*4796Seric OutConnection = fdopen(fd, "w"); 99*4796Seric if (InConnection == NULL || OutConnection == NULL) 100*4796Seric return (-1); 1014684Seric 102*4796Seric if (Debug) 103*4796Seric printf("Connection open to %s\n", host); 104*4796Seric 105*4796Seric return (0); 1064684Seric } 1074684Seric /* 1084684Seric ** RUNSMTP -- run the SMTP protocol over connection. 1094684Seric ** 1104684Seric ** Parameters: 1114684Seric ** fr -- from person. 1124684Seric ** tolist -- list of recipients. 1134684Seric ** 1144684Seric ** Returns: 1154684Seric ** none. 1164684Seric ** 1174684Seric ** Side Effects: 1184684Seric ** Sends the mail via SMTP. 1194684Seric */ 1204684Seric 121*4796Seric runsmtp(fr, tolist) 1224684Seric char *fr; 1234684Seric char **tolist; 1244684Seric { 1254684Seric register int r; 1264684Seric register char **t; 1274684Seric char buf[MAXLINE]; 1284684Seric 1294684Seric /* get greeting message */ 130*4796Seric r = reply(); 1314684Seric if (r / 100 != 2) 1324684Seric return (EX_TEMPFAIL); 1334684Seric 1344684Seric /* send the mail command */ 135*4796Seric message("MAIL From:<%s>\r\n", fr); 136*4796Seric r = reply(); 1374684Seric if (r != 250) 1384684Seric return (EX_SOFTWARE); 1394684Seric 1404684Seric /* send the recipients */ 1414684Seric for (t = tolist; *t != NULL; t++) 1424684Seric { 143*4796Seric message("MRCP To:<%s>\r\n", *t); 144*4796Seric r = reply(); 1454684Seric if (r != 250) 1464684Seric return (EX_NOUSER); 1474684Seric } 1484684Seric 1494684Seric /* send the data */ 150*4796Seric message("DATA\r\n"); 151*4796Seric r = reply(); 1524684Seric if (r != 354) 1534684Seric return (EX_SOFTWARE); 1544684Seric while (fgets(buf, sizeof buf, stdin) != NULL) 1554684Seric { 1564684Seric /* change trailing newline to crlf */ 1574684Seric register char *p = index(buf, '\n'); 1584684Seric 1594684Seric if (p != NULL) 1604684Seric *p = '\0'; 1614684Seric if (buf[0] == '.') 162*4796Seric message("."); 163*4796Seric message("%s\r\n", buf); 1644684Seric } 165*4796Seric message(".\r\n"); 166*4796Seric r = reply(); 1674684Seric if (r != 250) 1684684Seric return (EX_SOFTWARE); 1694684Seric 1704684Seric /* force delivery */ 171*4796Seric message("DOIT\r\n"); 172*4796Seric r = reply(); 1734684Seric if (r != 250) 1744684Seric return (EX_TEMPFAIL); 1754684Seric 176*4796Seric message("QUIT\r\n"); 177*4796Seric r = reply(); 1784684Seric if (r != 221) 1794684Seric return (EX_SOFTWARE); 1804684Seric 1814684Seric return (EX_OK); 1824684Seric } 1834684Seric /* 1844684Seric ** REPLY -- read arpanet reply 1854684Seric ** 1864684Seric ** Parameters: 187*4796Seric ** none. 1884684Seric ** 1894684Seric ** Returns: 1904684Seric ** reply code it reads. 1914684Seric ** 1924684Seric ** Side Effects: 1934684Seric ** flushes the mail file. 1944684Seric */ 1954684Seric 196*4796Seric reply() 1974684Seric { 198*4796Seric fflush(OutConnection); 1994684Seric 200*4796Seric if (Debug) 201*4796Seric printf("reply\n"); 202*4796Seric 2034684Seric /* read the input line */ 2044684Seric for (;;) 2054684Seric { 2064684Seric char buf[MAXLINE]; 2074684Seric register int r; 2084684Seric 209*4796Seric if (fgets(buf, sizeof buf, InConnection) == NULL) 2104684Seric return (-1); 2114684Seric if (Verbose) 2124684Seric fputs(buf, stdout); 213*4796Seric if (buf[3] == '-' || !isdigit(buf[0])) 2144684Seric continue; 2154684Seric r = atoi(buf); 2164684Seric if (r < 100) 2174684Seric continue; 2184684Seric return (r); 2194684Seric } 2204684Seric } 221*4796Seric /* 222*4796Seric ** MESSAGE -- send message to server 223*4796Seric ** 224*4796Seric ** Parameters: 225*4796Seric ** f -- format 226*4796Seric ** a, b, c -- parameters 227*4796Seric ** 228*4796Seric ** Returns: 229*4796Seric ** none. 230*4796Seric ** 231*4796Seric ** Side Effects: 232*4796Seric ** writes message to OutChannel. 233*4796Seric */ 234*4796Seric 235*4796Seric message(f, a, b, c) 236*4796Seric char *f; 237*4796Seric { 238*4796Seric char buf[100]; 239*4796Seric 240*4796Seric sprintf(buf, f, a, b, c); 241*4796Seric if (Debug) 242*4796Seric fputs(buf, stdout); 243*4796Seric fputs(buf, OutConnection); 244*4796Seric } 245