#endif /* OPIE */
ok = 0;
}
- else if (strcmp(buf,"-ERR") == 0)
+ else if (strncmp(buf,"-ERR", 4) == 0)
{
if (phase > PHASE_GETAUTH)
ok = PS_PROTOCOL;
* CompuServe has changed its RPA behavior. Used to be they didn't
* accept PASS, but I'm told this changed in mid-November 1997.
*/
- if (strstr(greeting, "csi.com"))
+ if (strstr(greeting, "csi.com")
+ && (start = strchr(ctl->remotename, '@'))
+ && !strcmp("@compuserve.com", start))
{
/* temporary fix to get back out of cleartext authentication */
gen_transact(sock, "PASS %s", "dummypass");
int i;
i = opiegenerator(challenge, !strcmp(ctl->password, "opie") ? "" : ctl->password, response);
- if ((i == -2) && (cmd_daemon == -1)) {
+ if ((i == -2) && !run.poll_interval) {
char secret[OPIE_SECRET_MAX+1];
fprintf(stderr, "Secret pass phrase: ");
if (opiereadpass(secret, sizeof(secret), 0))
*/
sleep(3); /* to be _really_ safe, probably need sleep(5)! */
+ /* we're peek-capable if use of TOP is enabled */
+ peek_capable = !(ctl->fetchall || ctl->keep);
+
/* we're approved */
return(PS_SUCCESS);
}
static int pop3_getrange(int sock,
struct query *ctl,
const char *folder,
- int *countp, int *newp)
+ int *countp, int *newp, int *bytes)
/* get range of messages to be fetched */
{
int ok;
gen_send(sock, "STAT");
ok = pop3_ok(sock, buf);
if (ok == 0)
- sscanf(buf,"%d %*d", countp);
+ sscanf(buf,"%d %d", countp, bytes);
else
return(ok);
new = save_str(&ctl->newsaved, id, UID_UNSEEN);
new->val.status.num = num;
- /* note: ID comparison is caseblind */
- if (str_in_list(&ctl->oldsaved, id))
+ if (str_in_list(&ctl->oldsaved, id, FALSE)) {
new->val.status.mark = UID_SEEN;
+ str_set_mark(&ctl->oldsaved, id, UID_SEEN);
+ }
else
(*newp)++;
}
}
}
- return(0);
+ return(PS_SUCCESS);
}
static int pop3_getsizes(int sock, int count, int *sizes)
if (!ctl->oldsaved)
return (num <= last);
else
- /* note: ID comparison is caseblind */
return (str_in_list(&ctl->oldsaved,
- str_find (&ctl->newsaved, num)));
+ str_find(&ctl->newsaved, num), FALSE));
}
+#ifdef UNUSED
+/*
+ * We could use this to fetch headers only as we do for IMAP. The trouble
+ * is that there's no way to fetch the body only. So the following RETR
+ * would have to re-fetch the header. Enough messages have longer headers
+ * than bodies to make this a net loss.
+ */
+static int pop_fetch_headers(int sock, struct query *ctl,int number,int *lenp)
+/* request headers of nth message */
+{
+ int ok;
+ char buf[POPBUFSIZE+1];
+
+ /* phase = PHASE_FETCH */
+
+ gen_send(sock, "TOP %d 0", number);
+ if ((ok = pop3_ok(sock, buf)) != 0)
+ return(ok);
+
+ *lenp = -1; /* we got sizes from the LIST response */
+
+ return(PS_SUCCESS);
+}
+#endif /* UNUSED */
+
static int pop3_fetch(int sock, struct query *ctl, int number, int *lenp)
/* request nth message */
{
int ok;
- char buf [POPBUFSIZE+1];
+ char buf[POPBUFSIZE+1];
/* phase = PHASE_FETCH */
- gen_send(sock, "RETR %d", number);
+ /*
+ * Though the POP RFCs don't document this fact, on every POP3 server
+ * I know of messages are marked "seen" only at the time the OK
+ * response to a RETR is issued.
+ *
+ * This means we can use TOP to fetch the message without setting its
+ * seen flag. This is good! It means that if the protocol exchange
+ * craps out during the message, it will still be marked `unseen' on
+ * the server.
+ *
+ * However...*don't* do this if we're using keep to suppress deletion!
+ * In that case, marking the seen flag is the only way to prevent the
+ * message from being re-fetched on subsequent runs.
+ *
+ * Also use RETR if fetchall is on. This gives us a workaround
+ * for servers like usa.net's that bungle TOP. It's pretty
+ * harmless because fetchall guarantees that any message dropped
+ * by an interrupted RETR will be picked up on the next poll of the
+ * site.
+ *
+ * We take advantage here of the fact that, according to all the
+ * POP RFCs, "if the number of lines requested by the POP3 client
+ * is greater than than the number of lines in the body, then the
+ * POP3 server sends the entire message.").
+ *
+ * The line count passed (99999999) is the maximum value CompuServe will
+ * accept; it's much lower than the natural value 2147483646 (the maximum
+ * twos-complement signed 32-bit integer minus 1)
+ */
+ if (ctl->keep || ctl->fetchall)
+ gen_send(sock, "RETR %d", number);
+ else
+ gen_send(sock, "TOP %d 99999999", number);
if ((ok = pop3_ok(sock, buf)) != 0)
return(ok);
*lenp = -1; /* we got sizes from the LIST response */
- return(0);
+ return(PS_SUCCESS);
}
static int pop3_delete(int sock, struct query *ctl, int number)
FALSE, /* this is not a tagged protocol */
TRUE, /* this uses a message delimiter */
pop3_ok, /* parse command response */
+ NULL, /* no password canonicalization */
pop3_getauth, /* get authorization */
pop3_getrange, /* query range of messages */
pop3_getsizes, /* we can get a list of sizes */