* Input string from socket - implemented in terms of sock_read()
*
*/
-int sock_gets(int sock, char *buf)
+int sock_getln(int sock, char *buf, int bufsize)
{
int i;
*/
for (i = 0;; i++) {
if (sock_read(sock, &buf[i], 1) < 0) return(-1);
- if (buf[i] == '\n' || i == (SIZ-1))
+ if (buf[i] == '\n' || i == (bufsize-1))
break;
}
/* If we got a long line, discard characters until the newline.
*/
- if (i == (SIZ-1))
+ if (i == (bufsize-1))
while (buf[i] != '\n')
if (sock_read(sock, &buf[i], 1) < 0) return(-1);
char bigbuf[1024];
int g;
- g = sock_gets(sock, buf);
+ g = sock_getln(sock, buf, SIZ);
if (g < 4) return(g);
if (buf[3] != '-') return(g);
do {
- g = sock_gets(sock, bigbuf);
+ g = sock_getln(sock, bigbuf, SIZ);
if (g < 0) return(g);
} while ( (g >= 4) && (bigbuf[3] == '-') );
int sock_read(int sock, char *buf, int bytes);
int sock_write(int sock, char *buf, int nbytes);
int ml_sock_gets(int sock, char *buf);
-int sock_gets(int sock, char *buf);
+int sock_getln(int sock, char *buf, int bufsize);
int sock_puts(int sock, char *buf);
extract_token(confname, argbuf, 1, '|', sizeof confname);
unbuffer_output();
cprintf("%d %s\n", SEND_LISTING, confname);
- confptr = CtdlReadMessageBody("000",
- config.c_maxmsglen, NULL, 0);
+ confptr = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
CtdlPutSysConfig(confname, confptr);
free(confptr);
}
}
cprintf("%d Transmit data now\n", SEND_LISTING);
- calstream = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0);
+ calstream = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
if (calstream == NULL) {
return;
}
/* Response */
lprintf(CTDL_DEBUG, "Awaiting response\n");
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
goto bail;
}
lprintf(CTDL_DEBUG, "<%s\n", buf);
CtdlMakeTempFileName(tempfilename, sizeof tempfilename);
if (sock_puts(sock, "NDOP") < 0) return;
- if (sock_gets(sock, buf) < 0) return;
+ if (sock_getln(sock, buf, sizeof buf) < 0) return;
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (buf[0] != '2') {
return;
unlink(tempfilename);
return;
}
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
fclose(fp);
unlink(tempfilename);
return;
unlink(tempfilename);
return;
}
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
unlink(tempfilename);
return;
}
char sfname[128];
if (sock_puts(sock, "NUOP") < 0) return;
- if (sock_gets(sock, buf) < 0) return;
+ if (sock_getln(sock, buf, sizeof buf) < 0) return;
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (buf[0] != '2') {
return;
close(fd);
return;
}
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
close(fd);
return;
}
ABORTUPL:
close(fd);
if (sock_puts(sock, "UCLS 1") < 0) return;
- if (sock_gets(sock, buf) < 0) return;
+ if (sock_getln(sock, buf, sizeof buf) < 0) return;
lprintf(CTDL_NOTICE, "Sent %ld octets to <%s>\n",
bytes_written, remote_nodename);
lprintf(CTDL_DEBUG, "<%s\n", buf);
lprintf(CTDL_DEBUG, "Connected!\n");
/* Read the server greeting */
- if (sock_gets(sock, buf) < 0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
lprintf(CTDL_DEBUG, ">%s\n", buf);
/* Identify ourselves */
snprintf(buf, sizeof buf, "NETP %s|%s", config.c_nodename, secret);
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (sock_puts(sock, buf) <0) goto bail;
- if (sock_gets(sock, buf) < 0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
lprintf(CTDL_DEBUG, ">%s\n", buf);
if (buf[0] != '2') goto bail;
#include "room_ops.h"
#include "ctdl_module.h"
#include "clientsocket.h"
+#include "msgbase.h"
+#include "internet_addressing.h"
struct pop3aggr {
struct pop3aggr *next;
{
int sock;
char buf[SIZ];
+ int msg_to_fetch = 0;
+ int *msglist = NULL;
+ int num_msgs = 0;
+ int alloc_msgs = 0;
+ int i;
+ char *body = NULL;
+ struct CtdlMessage *msg = NULL;
+ long msgnum = 0;
lprintf(CTDL_DEBUG, "POP3: %s %s %s %s\n", roomname, pop3host, pop3user, pop3pass);
lprintf(CTDL_NOTICE, "Connecting to <%s>\n", pop3host);
lprintf(CTDL_DEBUG, "Connected!\n");
/* Read the server greeting */
- if (sock_gets(sock, buf) < 0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
lprintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
snprintf(buf, sizeof buf, "USER %s", pop3user);
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (sock_puts(sock, buf) <0) goto bail;
- if (sock_gets(sock, buf) < 0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
lprintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
snprintf(buf, sizeof buf, "PASS %s", pop3pass);
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (sock_puts(sock, buf) <0) goto bail;
- if (sock_gets(sock, buf) < 0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
lprintf(CTDL_DEBUG, ">%s\n", buf);
if (strncasecmp(buf, "+OK", 3)) goto bail;
- sock_puts(sock, "QUIT");
+ /* Get the list of messages */
+ snprintf(buf, sizeof buf, "LIST");
+ lprintf(CTDL_DEBUG, "<%s\n", buf);
+ if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+ lprintf(CTDL_DEBUG, ">%s\n", buf);
+ if (strncasecmp(buf, "+OK", 3)) goto bail;
+
+ do {
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+ lprintf(CTDL_DEBUG, ">%s\n", buf);
+ msg_to_fetch = atoi(buf);
+ if (msg_to_fetch > 0) {
+ if (alloc_msgs == 0) {
+ alloc_msgs = 100;
+ msglist = malloc((alloc_msgs * (sizeof(int))));
+ }
+ else if (num_msgs >= alloc_msgs) {
+ alloc_msgs = alloc_msgs * 2;
+ msglist = realloc(msglist, (alloc_msgs * sizeof(int)));
+ }
+ if (msglist == NULL) goto bail;
+ msglist[num_msgs++] = msg_to_fetch;
+ }
+ } while (buf[0] != '.');
+
+ if (num_msgs) for (i=0; i<num_msgs; ++i) {
+
+ /* Tell the server to fetch the message */
+ snprintf(buf, sizeof buf, "RETR %d", msglist[i]);
+ lprintf(CTDL_DEBUG, "<%s\n", buf);
+ if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+ lprintf(CTDL_DEBUG, ">%s\n", buf);
+ if (strncasecmp(buf, "+OK", 3)) goto bail;
+
+ /* If we get to this point, the message is on its way. Read it. */
+ body = CtdlReadMessageBody(".", config.c_maxmsglen, NULL, 1, sock);
+ if (body == NULL) goto bail;
+
+ lprintf(CTDL_DEBUG, "Converting message...\n");
+ msg = convert_internet_message(body);
+ body = NULL; /* yes, this should be dereferenced, NOT freed */
+
+ /* Do Something With It (tm) */
+ msgnum = CtdlSubmitMsg(msg, NULL, roomname);
+ if (msgnum > 0L) {
+ /* Message has been committed to the store, so delete it from the remote server */
+ snprintf(buf, sizeof buf, "DELE %d", msglist[i]);
+ lprintf(CTDL_DEBUG, "<%s\n", buf);
+ if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+ lprintf(CTDL_DEBUG, ">%s\n", buf);
+ if (strncasecmp(buf, "+OK", 3)) goto bail;
+ }
+ CtdlFreeMessage(msg);
+ }
+
+ /* Log out */
+ snprintf(buf, sizeof buf, "QUIT");
+ lprintf(CTDL_DEBUG, "<%s\n", buf);
+ if (sock_puts(sock, buf) <0) goto bail;
+ if (sock_getln(sock, buf, sizeof buf) < 0) goto bail;
+ lprintf(CTDL_DEBUG, ">%s\n", buf);
bail: sock_close(sock);
+ if (msglist) free(msglist);
}
extract_token(script_name, argbuf, 1, '|', sizeof script_name);
if (!IsEmptyStr(script_name)) {
cprintf("%d Transmit script now\n", SEND_LISTING);
- script_content = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0);
+ script_content = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
msiv_putscript(&u, script_name, script_content);
changes_made = 1;
}
config.c_fqdn,
nowstamp);
- body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1);
+ body = CtdlReadMessageBody(".", config.c_maxmsglen, body, 1, 0);
if (body == NULL) {
cprintf("550 5.6.5 "
"Unable to save message: internal error.\r\n");
/* Response */
lprintf(CTDL_DEBUG, "Awaiting response\n");
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
goto bail;
}
lprintf(CTDL_DEBUG, "<%s\n", buf);
if (strncasecmp(buf, "SPAMD", 5)) {
goto bail;
}
- if (sock_gets(sock, buf) < 0) {
+ if (sock_getln(sock, buf, sizeof buf) < 0) {
goto bail;
}
lprintf(CTDL_DEBUG, "<%s\n", buf);
#include "euidindex.h"
#include "journaling.h"
#include "citadel_dirs.h"
+#include "clientsocket.h"
long config_msgnum;
size_t maxlen, /* maximum message length */
char *exist, /* if non-null, append to it;
exist is ALWAYS freed */
- int crlf /* CRLF newlines instead of LF */
+ int crlf, /* CRLF newlines instead of LF */
+ int sock /* socket handle or 0 for this session's client socket */
) {
char buf[1024];
int linelen;
/* read in the lines of message text one by one */
do {
- if (client_getln(buf, (sizeof buf - 3)) < 1) finished = 1;
+ if (sock > 0) {
+ if (sock_getln(sock, buf, (sizeof buf - 3)) < 0) finished = 1;
+ }
+ else {
+ if (client_getln(buf, (sizeof buf - 3)) < 1) finished = 1;
+ }
if (!strcmp(buf, terminator)) finished = 1;
if (crlf) {
strcat(buf, "\r\n");
msg->cm_fields['M'] = preformatted_text;
}
else {
- msg->cm_fields['M'] = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0);
+ msg->cm_fields['M'] = CtdlReadMessageBody("000", config.c_maxmsglen, NULL, 0, 0);
}
return(msg);
int CtdlSaveMsgPointersInRoom(char *roomname, long newmsgidlist[], int num_newmsgs,
int do_repl_check, struct CtdlMessage *supplied_msg);
int CtdlSaveMsgPointerInRoom(char *roomname, long msgid, int do_repl_check, struct CtdlMessage *msg);
-char *CtdlReadMessageBody(char *terminator, size_t maxlen, char *exist, int crlf);
+char *CtdlReadMessageBody(char *terminator, size_t maxlen, char *exist, int crlf, int sock);
char *CtdlGetSysConfig(char *sysconfname);
void CtdlPutSysConfig(char *sysconfname, char *sysconfdata);
int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */