* sock_write() - send binary to server.
* Returns the number of bytes written, or -1 for error.
*/
-int sock_write(int sock, char *buf, int nbytes)
+int sock_write(int *sock, char *buf, int nbytes)
{
int bytes_written = 0;
int retval;
- while (bytes_written < nbytes) {
- retval = write(sock, &buf[bytes_written],
+
+ while ((*sock != -1) &&
+ (bytes_written < nbytes))
+ {
+ retval = write(*sock, &buf[bytes_written],
nbytes - bytes_written);
if (retval < 1) {
+ sock_close(*sock);
+ *sock = -1;
return (-1);
}
bytes_written = bytes_written + retval;
* sock_puts() - send line to server - implemented in terms of serv_write()
* Returns the number of bytes written, or -1 for error.
*/
-int sock_puts(int sock, char *buf)
+int sock_puts(int *sock, char *buf)
{
int i, j;
int sock_connect(char *host, char *service, char *protocol);
int sock_read_to(int *sock, char *buf, int bytes, int timeout, int keep_reading_until_full);
int sock_read(int *sock, char *buf, int bytes, int keep_reading_until_full);
-int sock_write(int sock, char *buf, int nbytes);
+int sock_write(int *sock, char *buf, int nbytes);
int ml_sock_gets(int *sock, char *buf);
int sock_getln(int *sock, char *buf, int bufsize);
int CtdlSockGetLine(int *sock, StrBuf *Target);
-int sock_puts(int sock, char *buf);
+int sock_puts(int *sock, char *buf);
/*
/* Command */
CtdlLogPrintf(CTDL_DEBUG, "Transmitting STREAM command\n");
sprintf(buf, "STREAM\r\n");
- sock_write(sock, buf, strlen(buf));
+ sock_write(&sock, buf, strlen(buf));
CtdlLogPrintf(CTDL_DEBUG, "Waiting for PORT number\n");
if (sock_getln(&sock, buf, sizeof buf) < 0) {
CC->redirect_len = 0;
CC->redirect_alloc = 0;
- sock_write(streamsock, msgtext, msglen);
+ sock_write(&streamsock, msgtext, msglen);
free(msgtext);
/* Close the streamsocket connection; this tells clamd
* that we're done.
*/
- close(streamsock);
+ if (streamsock != -1)
+ close(streamsock);
/* Response */
CtdlLogPrintf(CTDL_DEBUG, "Awaiting response\n");
FILE *fp, *newfp;
CtdlMakeTempFileName(tempfilename, sizeof tempfilename);
- if (sock_puts(*sock, "NDOP") < 0) return;
+ if (sock_puts(sock, "NDOP") < 0) return;
if (sock_getln(sock, buf, sizeof buf) < 0) return;
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
if (buf[0] != '2') {
bytes_received,
((download_len - bytes_received > IGNET_PACKET_SIZE)
? IGNET_PACKET_SIZE : (download_len - bytes_received)));
- if (sock_puts(*sock, buf) < 0) {
+ if (sock_puts(sock, buf) < 0) {
fclose(fp);
unlink(tempfilename);
return;
unlink(tempfilename);
return;
}
- if (sock_puts(*sock, "CLOS") < 0) {
+ if (sock_puts(sock, "CLOS") < 0) {
unlink(tempfilename);
return;
}
int fd;
char sfname[128];
- if (sock_puts(*sock, "NUOP") < 0) return;
+ if (sock_puts(sock, "NUOP") < 0) return;
if (sock_getln(sock, buf, sizeof buf) < 0) return;
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
if (buf[0] != '2') {
}
snprintf(buf, sizeof buf, "WRIT %ld", bytes_to_write);
- if (sock_puts(*sock, buf) < 0) {
+ if (sock_puts(sock, buf) < 0) {
close(fd);
return;
}
}
thisblock = atol(&buf[4]);
if (buf[0] == '7') {
- if (sock_write(*sock, pbuf,
+ if (sock_write(sock, pbuf,
(int) thisblock) < 0) {
close(fd);
return;
if(CtdlThreadCheckStop())
return;
- if (sock_puts(*sock, "UCLS 1") < 0) return;
+ if (sock_puts(sock, "UCLS 1") < 0) return;
/**
* From here on we must complete or messages will get lost
*/
/* We're talking to the correct node. Now identify ourselves. */
snprintf(buf, sizeof buf, "NETP %s|%s", config.c_nodename, secret);
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
if (buf[0] != '2') goto bail;
transmit_spool(&sock, node);
}
- sock_puts(sock, "QUIT");
-bail: sock_close(sock);
+ sock_puts(&sock, "QUIT");
+bail:
+ if (sock != -1)
+ sock_close(sock);
network_talking_to(node, NTT_REMOVE);
}
*/
snprintf(buf, sizeof buf, "USER %s\r", pop3user);
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
/* Password */
snprintf(buf, sizeof buf, "PASS %s\r", pop3pass);
CtdlLogPrintf(CTDL_DEBUG, "<PASS <password>\n");
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
/* Get the list of messages */
snprintf(buf, sizeof buf, "LIST\r");
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
/* Find out the UIDL of the message, to determine whether we've already downloaded it */
snprintf(buf, sizeof buf, "UIDL %d\r", msglist[i]);
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
/* Message has not been seen. Tell the server to fetch the message... */
snprintf(buf, sizeof buf, "RETR %d\r", msglist[i]);
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
if (!keep) {
snprintf(buf, sizeof buf, "DELE %d\r", msglist[i]);
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf); /* errors here are non-fatal */
}
/* Log out */
snprintf(buf, sizeof buf, "QUIT\r");
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
- if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_puts(&sock, buf) <0) goto bail;
if (sock_getln(&sock, buf, sizeof buf) < 0) goto bail;
CtdlLogPrintf(CTDL_DEBUG, ">%s\n", buf);
-bail: sock_close(sock);
+bail:
+ if (sock != -1)
+ sock_close(sock);
if (msglist) free(msglist);
}
/* Do a EHLO command. If it fails, try the HELO command. */
snprintf(buf, sizeof buf, "EHLO %s\r\n", config.c_fqdn);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
+ sock_write(&sock, buf, strlen(buf));
if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP HELO");
if (buf[0] != '2') {
snprintf(buf, sizeof buf, "HELO %s\r\n", config.c_fqdn);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
+ sock_write(&sock, buf, strlen(buf));
if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP HELO");
CtdlEncodeBase64(encoded, buf, strlen(mx_user) + strlen(mx_user) + strlen(mx_pass) + 2, 0);
snprintf(buf, sizeof buf, "AUTH PLAIN %s\r\n", encoded);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
+ sock_write(&sock, buf, strlen(buf));
if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP AUTH");
/* previous command succeeded, now try the MAIL FROM: command */
snprintf(buf, sizeof buf, "MAIL FROM:<%s>\r\n", envelope_from);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
+ sock_write(&sock, buf, strlen(buf));
if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP MAIL");
/* MAIL succeeded, now try the RCPT To: command */
snprintf(buf, sizeof buf, "RCPT TO:<%s@%s>\r\n", user, node);
CtdlLogPrintf(CTDL_DEBUG, ">%s", buf);
- sock_write(sock, buf, strlen(buf));
+ sock_write(&sock, buf, strlen(buf));
if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP RCPT");
/* RCPT succeeded, now try the DATA command */
CtdlLogPrintf(CTDL_DEBUG, ">DATA\n");
- sock_write(sock, "DATA\r\n", 6);
+ sock_write(&sock, "DATA\r\n", 6);
if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP DATA");
}
/* If we reach this point, the server is expecting data.*/
- sock_write(sock, msgtext, msg_size);
+ sock_write(&sock, msgtext, msg_size);
if (msgtext[msg_size-1] != 10) {
CtdlLogPrintf(CTDL_WARNING, "Possible problem: message did not "
"correctly terminate. (expecting 0x10, got 0x%02x)\n",
buf[msg_size-1]);
- sock_write(sock, "\r\n", 2);
+ sock_write(&sock, "\r\n", 2);
}
- sock_write(sock, ".\r\n", 3);
+ sock_write(&sock, ".\r\n", 3);
if (ml_sock_gets(&sock, buf) < 0) {
*status = 4;
strcpy(dsn, "Connection broken during SMTP message transmit");
*status = 2;
CtdlLogPrintf(CTDL_DEBUG, ">QUIT\n");
- sock_write(sock, "QUIT\r\n", 6);
+ sock_write(&sock, "QUIT\r\n", 6);
ml_sock_gets(&sock, buf);
CtdlLogPrintf(CTDL_DEBUG, "<%s\n", buf);
CtdlLogPrintf(CTDL_INFO, "SMTP client: delivery to <%s> @ <%s> (%s) succeeded\n",
user, node, name);
bail: free(msgtext);
- sock_close(sock);
+ if (sock != -1)
+ sock_close(sock);
/* Write something to the syslog (which may or may not be where the
* rest of the Citadel logs are going; some sysadmins want LOG_MAIL).
/* Command */
CtdlLogPrintf(CTDL_DEBUG, "Transmitting command\n");
sprintf(buf, "CHECK SPAMC/1.2\r\n\r\n");
- sock_write(sock, buf, strlen(buf));
+ sock_write(&sock, buf, strlen(buf));
/* Message */
CC->redirect_buffer = malloc(SIZ);
CC->redirect_len = 0;
CC->redirect_alloc = 0;
- sock_write(sock, msgtext, msglen);
+ sock_write(&sock, msgtext, msglen);
free(msgtext);
/* Close one end of the socket connection; this tells SpamAssassin
* that we're done.
*/
- sock_shutdown(sock, SHUT_WR);
+ if (sock != -1)
+ sock_shutdown(sock, SHUT_WR);
/* Response */
CtdlLogPrintf(CTDL_DEBUG, "Awaiting response\n");
{
StrBuf *Message;
StrBuf *LineBuf;
- char buf[1024];
int flushing = 0;
int finished = 0;
int dotdot = 0;