[Apcupsd-commits] apcupsd/src smtp.c,1.8,1.9
Brought to you by:
adk0212
From: Adam K. <ad...@us...> - 2006-07-29 20:25:59
|
Update of /cvsroot/apcupsd/apcupsd/src In directory sc8-pr-cvs11.sourceforge.net:/tmp/cvs-serv8587 Modified Files: smtp.c Log Message: Rewrite for Win32 compatibility. The previous version assumed a socket could be treated as a normal fd, which is a perfectly valid assumption on any sane platform. But like I said, this is Win32. Index: smtp.c =================================================================== RCS file: /cvsroot/apcupsd/apcupsd/src/smtp.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- smtp.c 21 Feb 2006 01:03:37 -0000 1.8 +++ smtp.c 29 Jul 2006 20:25:49 -0000 1.9 @@ -58,8 +58,7 @@ # define MAXSTRING 254 #endif -static FILE *sfp; -static FILE *rfp; +static int s; static char *from_addr = NULL; static char *cc_addr = NULL; @@ -73,14 +72,31 @@ /* Needed by lib/apcconfig.c */ char argvalue[MAXSTRING]; +/* like fgets(3), but for a socket */ +static char *sockgets(char *buf, int len, int s) +{ + int i=0; + + /* Inefficient, but simple */ + while (i < len-1) { + if (recv(s, buf+i, 1, 0) != 1) + break; + i++; + if (buf[i-1] == '\n') + break; + } + buf[i] = '\0'; + return i==0 ? NULL : buf; +} + /* examine message from server */ static void get_response(void) { char buf[MAXSTRING]; - Dmsg0(50, "Calling fgets on read socket rfp.\n"); + Dmsg0(50, "Calling sockgets on read socket.\n"); - while (fgets(buf, sizeof(buf), rfp)) { + while (sockgets(buf, sizeof(buf), s)) { buf[strlen(buf) - 1] = 0; Dmsg2(10, "%s --> %s\n", mailhost, buf); @@ -94,20 +110,38 @@ } } +/* like vfprintf(3), but for a socket */ +static void vsockwrite(int s, const char *fmt, va_list ap) +{ + static char temp[MAXSTRING]; + + avsnprintf(temp, sizeof(temp), fmt, ap); + send(s, temp, strlen(temp), 0); +} + +/* like fprintf(3), but for a socket */ +static void sockwrite(int s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + vsockwrite(s, fmt, ap); + va_end(ap); +} + /* say something to server and check the response */ static void chat(char *fmt, ...) { va_list ap; va_start(ap, fmt); - vfprintf(sfp, fmt, ap); + vsockwrite(s, fmt, ap); if (debug_level >= 10) { fprintf(stdout, "%s --> ", my_hostname); vfprintf(stdout, fmt, ap); } va_end(ap); - fflush(sfp); if (debug_level >= 10) fflush(stdout); @@ -137,7 +171,7 @@ char buf[MAXSTRING]; struct sockaddr_in sin; struct hostent *hp; - int s, r, i, ch; + int i, ch; struct passwd *pwd; char *cp, *p; time_t now = time(NULL); @@ -206,12 +240,16 @@ mailhost = "localhost"; } +#ifdef HAVE_WIN32 + WSA_Init(); +#endif + /* * Find out my own host name for HELO; * if possible, get the fully qualified domain name */ - if (gethostname(my_hostname, sizeof(my_hostname) - 1) < 0) { - Pmsg1(0, "Fatal gethostname error: ERR=%s\n", strerror(errno)); + if (gethostname(my_hostname, sizeof(my_hostname) - 1) == -1) { + Pmsg2(0, "Fatal gethostname error: %s ERR=%s\n", my_hostname, strerror(errno)); exit(1); } @@ -272,21 +310,6 @@ Dmsg0(20, "Connected\n"); - if ((r = dup(s)) < 0) { - Pmsg1(0, "Fatal dup error: ERR=%s\n", strerror(errno)); - exit(1); - } - - if ((sfp = fdopen(s, "w")) == 0) { - Pmsg1(0, "Fatal fdopen error: ERR=%s\n", strerror(errno)); - exit(1); - } - - if ((rfp = fdopen(r, "r")) == 0) { - Pmsg1(0, "Fatal fdopen error: ERR=%s\n", strerror(errno)); - exit(1); - } - /* Send SMTP headers */ get_response(); /* banner */ chat("helo %s\r\n", my_hostname); @@ -304,43 +327,43 @@ chat("data\r\n"); /* Send message header */ - fprintf(sfp, "From: %s\r\n", from_addr); + sockwrite(s, "From: %s\r\n", from_addr); if (subject) - fprintf(sfp, "Subject: %s\r\n", subject); + sockwrite(s, "Subject: %s\r\n", subject); if (reply_addr) - fprintf(sfp, "Reply-To: %s\r\n", reply_addr); + sockwrite(s, "Reply-To: %s\r\n", reply_addr); if (err_addr) - fprintf(sfp, "Errors-To: %s\r\n", err_addr); + sockwrite(s, "Errors-To: %s\r\n", err_addr); if ((pwd = getpwuid(getuid())) == 0) - fprintf(sfp, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname); + sockwrite(s, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname); else - fprintf(sfp, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname); + sockwrite(s, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname); - fprintf(sfp, "To: %s", argv[0]); + sockwrite(s, "To: %s", argv[0]); for (i = 1; i < argc; i++) - fprintf(sfp, ",%s", argv[i]); - fprintf(sfp, "\r\n"); + sockwrite(s, ",%s", argv[i]); + sockwrite(s, "\r\n"); if (cc_addr) - fprintf(sfp, "Cc: %s\r\n", cc_addr); + sockwrite(s, "Cc: %s\r\n", cc_addr); /* Add RFC822 date */ localtime_r(&now, &tm); strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %z", &tm); - fprintf(sfp, "Date: %s\r\n", buf); + sockwrite(s, "Date: %s\r\n", buf); - fprintf(sfp, "\r\n"); + sockwrite(s, "\r\n"); /* Send message body */ while (fgets(buf, sizeof(buf), stdin)) { buf[strlen(buf) - 1] = 0; if (strcmp(buf, ".") == 0) /* quote lone dots */ - fprintf(sfp, "..\r\n"); + sockwrite(s, "..\r\n"); else /* pass body through unchanged */ - fprintf(sfp, "%s\r\n", buf); + sockwrite(s, "%s\r\n", buf); } /* Send SMTP quit command */ |