1 # include <ctype.h> 2 # include <wellknown.h> 3 # include <sysexits.h> 4 # include <stdio.h> 5 # include <useful.h> 6 7 static char SccsId[] = "@(#)usersmtp.c 3.2 11/07/81"; 8 9 /* 10 ** TCP -- TCP/Ethernet/ARPAnet mailer 11 ** 12 ** This arranges to send a message over the TCP connection. 13 */ 14 15 # define MAXLINE 200 16 17 char *MailCommand = "/usr/lib/sendmail"; 18 char *MailUser = "network"; 19 char *MailPassword = "mailhack"; 20 FILE *InConnection; 21 FILE *OutConnection; 22 bool Verbose; 23 bool Debug; 24 25 main(argc, argv) 26 int argc; 27 char **argv; 28 { 29 register int stat; 30 31 while (argc > 1 && argv[1][0] == '-') 32 { 33 register char *p = *++argv; 34 35 argc--; 36 switch (p[1]) 37 { 38 case 'v': 39 Verbose = TRUE; 40 break; 41 42 case 'd': 43 Debug = TRUE; 44 break; 45 } 46 } 47 48 if (argc < 4) 49 { 50 if (Debug) 51 printf("Usage\n"); 52 exit(EX_USAGE); 53 } 54 55 if (openconnection(argv[2]) < 0) 56 exit(EX_TEMPFAIL); 57 58 stat = runsmtp(argv[1], &argv[3]); 59 60 if (Debug) 61 printf("Finishing with stat %d\n", stat); 62 63 exit(stat); 64 } 65 /* 66 ** OPENCONNECTION -- open connection to SMTP socket 67 ** 68 ** Parameters: 69 ** none. 70 ** 71 ** Returns: 72 ** file pointer of connection. 73 ** NULL on error. 74 ** 75 ** Side Effects: 76 ** none. 77 */ 78 79 openconnection(host) 80 char *host; 81 { 82 char cmdbuf[100]; 83 register int fd; 84 85 /* create the command name */ 86 sprintf(cmdbuf, "%s -as%s%s", MailCommand, 87 Verbose ? " -v" : "", 88 Debug ? " -d" : ""); 89 90 if (Debug) 91 printf("Creating connection to \"%s\" on %s\n", cmdbuf, host); 92 93 /* create connection (we hope) */ 94 fd = rexec(&host, SHELLSERVER, cmdbuf, MailUser, MailPassword); 95 if (fd < 0) 96 return (-1); 97 InConnection = fdopen(fd, "r"); 98 OutConnection = fdopen(fd, "w"); 99 if (InConnection == NULL || OutConnection == NULL) 100 return (-1); 101 102 if (Debug) 103 printf("Connection open to %s\n", host); 104 105 return (0); 106 } 107 /* 108 ** RUNSMTP -- run the SMTP protocol over connection. 109 ** 110 ** Parameters: 111 ** fr -- from person. 112 ** tolist -- list of recipients. 113 ** 114 ** Returns: 115 ** none. 116 ** 117 ** Side Effects: 118 ** Sends the mail via SMTP. 119 */ 120 121 runsmtp(fr, tolist) 122 char *fr; 123 char **tolist; 124 { 125 register int r; 126 register char **t; 127 char buf[MAXLINE]; 128 129 /* get greeting message */ 130 r = reply(); 131 if (r / 100 != 2) 132 return (EX_TEMPFAIL); 133 134 /* send the mail command */ 135 message("MAIL From:<%s>\r\n", fr); 136 r = reply(); 137 if (r != 250) 138 return (EX_SOFTWARE); 139 140 /* send the recipients */ 141 for (t = tolist; *t != NULL; t++) 142 { 143 message("MRCP To:<%s>\r\n", *t); 144 r = reply(); 145 if (r != 250) 146 return (EX_NOUSER); 147 } 148 149 /* send the data */ 150 message("DATA\r\n"); 151 r = reply(); 152 if (r != 354) 153 return (EX_SOFTWARE); 154 while (fgets(buf, sizeof buf, stdin) != NULL) 155 { 156 /* change trailing newline to crlf */ 157 register char *p = index(buf, '\n'); 158 159 if (p != NULL) 160 *p = '\0'; 161 if (buf[0] == '.') 162 message("."); 163 message("%s\r\n", buf); 164 } 165 message(".\r\n"); 166 r = reply(); 167 if (r != 250) 168 return (EX_SOFTWARE); 169 170 /* force delivery */ 171 message("DOIT\r\n"); 172 r = reply(); 173 if (r != 250) 174 return (EX_TEMPFAIL); 175 176 message("QUIT\r\n"); 177 r = reply(); 178 if (r != 221) 179 return (EX_SOFTWARE); 180 181 return (EX_OK); 182 } 183 /* 184 ** REPLY -- read arpanet reply 185 ** 186 ** Parameters: 187 ** none. 188 ** 189 ** Returns: 190 ** reply code it reads. 191 ** 192 ** Side Effects: 193 ** flushes the mail file. 194 */ 195 196 reply() 197 { 198 fflush(OutConnection); 199 200 if (Debug) 201 printf("reply\n"); 202 203 /* read the input line */ 204 for (;;) 205 { 206 char buf[MAXLINE]; 207 register int r; 208 209 if (fgets(buf, sizeof buf, InConnection) == NULL) 210 return (-1); 211 if (Verbose) 212 fputs(buf, stdout); 213 if (buf[3] == '-' || !isdigit(buf[0])) 214 continue; 215 r = atoi(buf); 216 if (r < 100) 217 continue; 218 return (r); 219 } 220 } 221 /* 222 ** MESSAGE -- send message to server 223 ** 224 ** Parameters: 225 ** f -- format 226 ** a, b, c -- parameters 227 ** 228 ** Returns: 229 ** none. 230 ** 231 ** Side Effects: 232 ** writes message to OutChannel. 233 */ 234 235 message(f, a, b, c) 236 char *f; 237 { 238 char buf[100]; 239 240 sprintf(buf, f, a, b, c); 241 if (Debug) 242 fputs(buf, stdout); 243 fputs(buf, OutConnection); 244 } 245