/** request UIDL for single message \a num and stuff the result into the * buffer \a id which can hold \a idsize bytes */ static int pop3_getuidl(int sock, int num, char *id /** output */, size_t idsize) { int ok; char buf [POPBUFSIZE+1]; unsigned long gotnum; gen_send(sock, "UIDL %d", num); if ((ok = pop3_ok(sock, buf)) != 0) return(ok); if ((ok = parseuid(buf, &gotnum, id, idsize))) return ok; if (gotnum != (unsigned long)num) { report(stderr, GT_("Server responded with UID for wrong message.\n")); return PS_PROTOCOL; } return(PS_SUCCESS); }
static gint pop3_session_recv_msg(Session *session, const gchar *msg) { Pop3Session *pop3_session = POP3_SESSION(session); Pop3ErrorValue val = PS_SUCCESS; const gchar *body; body = msg; if (pop3_session->state != POP3_GETRANGE_UIDL_RECV && pop3_session->state != POP3_GETSIZE_LIST_RECV) { val = pop3_ok(pop3_session, msg); if (val != PS_SUCCESS) { if (val != PS_NOTSUPPORTED) { pop3_session->state = POP3_ERROR; return -1; } } if (*body == '+' || *body == '-') body++; while (g_ascii_isalpha(*body)) body++; while (g_ascii_isspace(*body)) body++; } switch (pop3_session->state) { case POP3_READY: case POP3_GREETING: pop3_greeting_recv(pop3_session, body); #ifdef USE_GNUTLS if (pop3_session->ac_prefs->ssl_pop == SSL_STARTTLS) val = pop3_stls_send(pop3_session); else #endif if (pop3_session->ac_prefs->use_apop_auth) val = pop3_getauth_apop_send(pop3_session); else val = pop3_getauth_user_send(pop3_session); break; #ifdef USE_GNUTLS case POP3_STLS: if (pop3_stls_recv(pop3_session) != PS_SUCCESS) return -1; if (pop3_session->ac_prefs->use_apop_auth) val = pop3_getauth_apop_send(pop3_session); else val = pop3_getauth_user_send(pop3_session); break; #endif case POP3_GETAUTH_USER: val = pop3_getauth_pass_send(pop3_session); break; case POP3_GETAUTH_PASS: case POP3_GETAUTH_APOP: if (!pop3_session->pop_before_smtp) val = pop3_getrange_stat_send(pop3_session); else val = pop3_logout_send(pop3_session); break; case POP3_GETRANGE_STAT: if (pop3_getrange_stat_recv(pop3_session, body) < 0) return -1; if (pop3_session->count > 0) val = pop3_getrange_uidl_send(pop3_session); else val = pop3_logout_send(pop3_session); break; case POP3_GETRANGE_LAST: if (val == PS_NOTSUPPORTED) pop3_session->error_val = PS_SUCCESS; else if (pop3_getrange_last_recv(pop3_session, body) < 0) return -1; if (pop3_session->cur_msg > 0) val = pop3_getsize_list_send(pop3_session); else val = pop3_logout_send(pop3_session); break; case POP3_GETRANGE_UIDL: if (val == PS_NOTSUPPORTED) { pop3_session->error_val = PS_SUCCESS; val = pop3_getrange_last_send(pop3_session); } else { pop3_session->state = POP3_GETRANGE_UIDL_RECV; session_recv_data(session, 0, ".\r\n"); } break; case POP3_GETSIZE_LIST: pop3_session->state = POP3_GETSIZE_LIST_RECV; session_recv_data(session, 0, ".\r\n"); break; case POP3_RETR: pop3_session->state = POP3_RETR_RECV; session_recv_data(session, 0, ".\r\n"); break; case POP3_TOP: if (val == PS_NOTSUPPORTED) { pop3_session->error_val = PS_SUCCESS; } else { pop3_session->state = POP3_TOP_RECV; session_recv_data(session, 0, ".\r\n"); } break; case POP3_DELETE: pop3_delete_recv(pop3_session); if (pop3_session->cur_msg == pop3_session->count) val = pop3_logout_send(pop3_session); else { pop3_session->cur_msg++; if (pop3_lookup_next(pop3_session) == POP3_ERROR) return -1; } break; case POP3_LOGOUT: pop3_session->state = POP3_DONE; session_disconnect(session); break; case POP3_ERROR: default: return -1; } return val == PS_SUCCESS?0:-1; }