static int top0 (msgset_t *mspec, mu_message_t msg, void *data) { mu_stream_t stream; char *buf = NULL; size_t size = 0, n; int lines; if (mailvar_get (&lines, "toplines", mailvar_type_number, 1) || lines < 0) return 1; mu_message_get_streamref (msg, &stream); for (; lines > 0; lines--) { int status = mu_stream_getline (stream, &buf, &size, &n); if (status != 0 || n == 0) break; mu_printf ("%s", buf); } free (buf); mu_stream_destroy (&stream); set_cursor (mspec->msg_part[0]); util_mark_read (msg); return 0; }
/* If we did not grap the ack already, call pop3_readline() but handle Nonblocking also. */ int mu_pop3_response (mu_pop3_t pop3, size_t *pnread) { size_t n = 0; int status = 0; if (pop3 == NULL) return EINVAL; if (!MU_POP3_FISSET (pop3, MU_POP3_ACK)) { status = mu_stream_getline (pop3->carrier, &pop3->ackbuf, &pop3->acksize, NULL); if (status == 0) { n = mu_rtrim_class (pop3->ackbuf, MU_CTYPE_SPACE); MU_POP3_FSET (pop3, MU_POP3_ACK); /* Flag that we have the ack. */ } } else if (pop3->ackbuf) n = strlen (pop3->ackbuf); if (n < 3) status = MU_ERR_BADREPLY; else if (strncmp (pop3->ackbuf, "-ERR", 4) == 0) status = MU_ERR_REPLY; else if (strncmp (pop3->ackbuf, "+OK", 3)) status = MU_ERR_BADREPLY; if (pnread) *pnread = n; return status; }
int pop_header_blurb (mu_stream_t stream, size_t maxlines, char **pbuf, size_t *plen) { int status; mu_opool_t opool; size_t size = 0; char *buf = NULL; size_t n; size_t nlines = 0; status = mu_opool_create (&opool, 0); if (status) return status; while ((status = mu_stream_getline (stream, &buf, &size, &n)) == 0 && n > 0) { size_t len = mu_rtrim_class (buf, MU_CTYPE_ENDLN); if (len == 0) break; mu_opool_append (opool, buf, len); mu_opool_append_char (opool, '\n'); if (maxlines && ++nlines >= maxlines) break; } if (status == 0) { n = mu_opool_size (opool); if (n > size) { char *p = realloc (buf, n); if (!p) { free (buf); status = ENOMEM; } else buf = p; } } if (status == 0) { mu_opool_copy (opool, buf, n); *pbuf = buf; *plen = n; } else free (buf); mu_opool_destroy (&opool); return 0; }
/* If we did not grap the ack already, call pop3_readline() but handle Nonblocking also. */ int mu_pop3_response (mu_pop3_t pop3, size_t *pnread) { size_t n = 0; int status = 0; if (pop3 == NULL) return EINVAL; if (!MU_POP3_FISSET (pop3, MU_POP3_ACK)) { status = mu_stream_getline (pop3->carrier, &pop3->ackbuf, &pop3->acksize, NULL); if (status == 0) { n = mu_rtrim_class (pop3->ackbuf, MU_CTYPE_SPACE); MU_POP3_FSET (pop3, MU_POP3_ACK); /* Flag that we have the ack. */ } else { /* Provide them with an error. */ if (pop3->acksize < sizeof (POP3_DEFERR)) { char *p = realloc (pop3->ackbuf, sizeof (POP3_DEFERR)); if (p) { pop3->ackbuf = p; pop3->acksize = sizeof (POP3_DEFERR); } } if (pop3->ackbuf) strncpy (pop3->ackbuf, POP3_DEFERR, pop3->acksize); } } else if (pop3->ackbuf) n = strlen (pop3->ackbuf); if (n < 3) status = MU_ERR_BADREPLY; else if (strncmp (pop3->ackbuf, "-ERR", 4) == 0) status = MU_ERR_REPLY; else if (strncmp (pop3->ackbuf, "+OK", 3)) status = MU_ERR_BADREPLY; if (pnread) *pnread = n; return status; }
void ioloop (char *id, mu_stream_t in, mu_stream_t out) { char *buf = NULL; size_t size = 0, n; int rc; while ((rc = mu_stream_getline (in, &buf, &size, &n)) == 0 && n > 0) { if (rc) { mu_error("%s: read error: %s", id, mu_stream_strerror (in, rc)); exit (1); } MU_ASSERT (mu_stream_write (out, buf, n, NULL)); } mu_stream_flush (out); if (verbose) fprintf (stderr, "%s exited\n", id); }
/* FIXME: Is it needed? */ int mu_pop3_getline (mu_pop3_t pop3) { size_t n; int status = mu_stream_getline (pop3->carrier, &pop3->rdbuf, &pop3->rdsize, &n); if (status == 0) { if (n == 0) return EIO; n = mu_rtrim_class (pop3->rdbuf, MU_CTYPE_SPACE); /* When examining a multi-line response, the client checks to see if the line begins with the termination octet "."(DOT). If yes and if octets other than CRLF follow, the first octet of the line (the termination octet) is stripped away. */ if (n >= 2 && pop3->rdbuf[0] == '.' && pop3->rdbuf[1] != '\n') memmove (pop3->rdbuf, pop3->rdbuf + 1, n); } return status; }
int mu_pop3_stream_to_list (mu_pop3_t pop3, mu_stream_t stream, mu_list_t list) { int status; size_t n; while ((status = mu_stream_getline (stream, &pop3->rdbuf, &pop3->rdsize, &n)) == 0 && n > 0) { char *np = strdup (pop3->rdbuf); if (!np) { status = ENOMEM; break; } mu_rtrim_class (np, MU_CTYPE_SPACE); status = mu_list_append (list, np); if (status) break; } return status; }
void io_getline (char **pbuf, size_t *psize, size_t *pnbytes) { size_t len; int rc = mu_stream_getline (iostream, pbuf, psize, &len); if (rc == 0) { char *s = *pbuf; if (len == 0) { imap4d_bye (ERR_NO_IFILE); /*FIXME rc = ECONNABORTED;*/ } len = mu_rtrim_class (s, MU_CTYPE_ENDLN); if (pnbytes) *pnbytes = len; } else { mu_error (_("read error: %s"), mu_strerror (rc)); imap4d_bye (ERR_NO_IFILE); } }
int mu_imapio_getline (struct _mu_imapio *io) { int rc; char *last_arg; int xlev = MU_XSCRIPT_NORMAL; if (io->_imap_reply_ready) { mu_wordsplit_free_words (&io->_imap_ws); io->_imap_reply_ready = 0; } for (;;) { rc = mu_stream_getline (io->_imap_stream, &io->_imap_buf_base, &io->_imap_buf_size, &io->_imap_buf_level); if (rc) break; if (io->_imap_buf_level == 0) break; io->_imap_buf_level = mu_rtrim_class (io->_imap_buf_base, MU_CTYPE_ENDLN); rc = initial_parse (io); if (rc == IMAPIO_ERR) { rc = MU_ERR_PARSE; break; } else if (rc == IMAPIO_RESP) { rc = 0; break; } rc = mu_wordsplit_len (io->_imap_buf_base + io->_imap_ws.ws_endp, io->_imap_buf_level - io->_imap_ws.ws_endp, &io->_imap_ws, io->_imap_ws_flags); if (rc) { rc = MU_ERR_PARSE; break; } if (io->_imap_ws.ws_wordc == 0) break; last_arg = io->_imap_ws.ws_wordv[io->_imap_ws.ws_wordc - 1]; if (last_arg[0] == '{' && last_arg[strlen (last_arg)-1] == '}') { int rc; unsigned long number; char *sp = NULL; if (!io->_imap_trace_payload) xlev = mu_imapio_set_xscript_level (io, MU_XSCRIPT_PAYLOAD); number = strtoul (last_arg + 1, &sp, 10); /* Client can ask for non-synchronised literal, if a '+' is appended to the octet count. */ if (*sp == '}') { if (io->_imap_server) mu_stream_printf (io->_imap_stream, "+ GO AHEAD\n"); } else if (*sp != '+') break; if (number + 1 > io->_imap_buf_size) { size_t newsize = number + 1; void *newp = realloc (io->_imap_buf_base, newsize); if (!newp) { rc = ENOMEM; break; } io->_imap_buf_base = newp; io->_imap_buf_size = newsize; } for (io->_imap_buf_level = 0; io->_imap_buf_level < number; ) { size_t sz; rc = mu_stream_read (io->_imap_stream, io->_imap_buf_base + io->_imap_buf_level, number - io->_imap_buf_level, &sz); if (rc || sz == 0) break; io->_imap_buf_level += sz; } mu_imapio_set_xscript_level (io, xlev); if (rc) break; io->_imap_buf_base[io->_imap_buf_level++] = 0; free (last_arg); io->_imap_ws.ws_wordv[--io->_imap_ws.ws_wordc] = NULL; if (mu_wordsplit_len (io->_imap_buf_base, io->_imap_buf_level, &io->_imap_ws, io->_imap_ws_flags|MU_WRDSF_NOSPLIT)) { rc = MU_ERR_PARSE; break; } } else break; } if (!io->_imap_trace_payload) mu_imapio_set_xscript_level (io, xlev); io->_imap_reply_ready = 1; return rc; }