static size_t gettok (struct imap4d_tokbuf *tok, size_t off) { char *buf = tok->buffer; while (off < tok->level && mu_isblank (buf[off])) off++; if (tok->argc == tok->argmax) { if (tok->argmax == 0) tok->argmax = 16; else tok->argmax *= 2; tok->argp = realloc (tok->argp, tok->argmax * sizeof (tok->argp[0])); if (!tok->argp) imap4d_bye (ERR_NO_MEM); } if (buf[off] == '"') { char *start = buf + off + 1; char *p = NULL; while (*start && (p = strchr (start, '"'))) { if (p == start || p[-1] != '\\') break; start = p + 1; } if (p) { size_t len; off++; len = unquote (buf + off, p - (buf + off)); buf[off + len] = 0; tok->argp[tok->argc++] = off; return p - buf + 1; } } tok->argp[tok->argc++] = off; if (ISDELIM (buf[off])) return insert_nul (tok, off + 1); while (off < tok->level && !mu_isblank (buf[off])) { if (ISDELIM (buf[off])) return insert_nul (tok, off); off++; } insert_nul (tok, off); return off + 1; }
static void check_input_err (int rc, size_t sz) { if (rc) { const char *p = mu_stream_strerror (iostream, rc); if (!p) p = mu_strerror (rc); mu_diag_output (MU_DIAG_INFO, _("error reading from input file: %s"), p); imap4d_bye (ERR_NO_IFILE); } else if (sz == 0) { mu_diag_output (MU_DIAG_INFO, _("unexpected eof on input")); imap4d_bye (ERR_NO_IFILE); } }
static void imap4d_tokbuf_expand (struct imap4d_tokbuf *tok, size_t size) { if (tok->size - tok->level < size) { tok->size = tok->level + size; tok->buffer = realloc (tok->buffer, tok->size); if (!tok->buffer) imap4d_bye (ERR_NO_MEM); } }
struct imap4d_tokbuf * imap4d_tokbuf_from_string (char *str) { struct imap4d_tokbuf *tok = imap4d_tokbuf_init (); tok->buffer = mu_strdup (str); if (!tok->buffer) imap4d_bye (ERR_NO_MEM); tok->level = strlen (str); tok->size = tok->level + 1; imap4d_tokbuf_tokenize (tok, 0); return tok; }
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); } }
void auth_add (char *name, imap4d_auth_handler_fp handler) { struct imap_auth *p = malloc (sizeof (*p)); if (!p) imap4d_bye (ERR_NO_MEM); p->name = name; p->handler = handler; if (!imap_auth_list) { mu_list_create (&imap_auth_list); mu_list_set_comparator (imap_auth_list, comp); mu_list_set_destroy_item (imap_auth_list, mu_list_free_item); } mu_list_append (imap_auth_list, (void*)p); }
int imap4d_init_tls_server () { mu_stream_t tlsstream, stream[2]; int rc; rc = mu_stream_ioctl (iostream, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, stream); if (rc) { mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM", mu_stream_strerror (iostream, rc)); return 1; } rc = mu_tls_server_stream_create (&tlsstream, stream[0], stream[1], 0); if (rc) { mu_diag_output (MU_DIAG_ERROR, _("cannot open TLS stream: %s"), mu_stream_strerror (tlsstream, rc)); return 1; } mu_stream_unref (stream[0]); mu_stream_unref (stream[1]); stream[0] = stream[1] = tlsstream; rc = mu_stream_ioctl (iostream, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_SET, stream); if (rc) { mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM", mu_stream_strerror (iostream, rc)); imap4d_bye (ERR_STREAM_CREATE); } mu_stream_unref (stream[0]); mu_stream_unref (stream[1]); return 0; }
void io_setio (int ifd, int ofd, int tls) { mu_stream_t str, istream, ostream; if (ifd == -1) imap4d_bye (ERR_NO_IFILE); if (ofd == -1) imap4d_bye (ERR_NO_OFILE); if (mu_stdio_stream_create (&istream, ifd, MU_STREAM_READ)) imap4d_bye (ERR_STREAM_CREATE); mu_stream_set_buffer (istream, mu_buffer_line, 0); if (mu_stdio_stream_create (&ostream, ofd, MU_STREAM_WRITE)) imap4d_bye (ERR_STREAM_CREATE); mu_stream_set_buffer (ostream, mu_buffer_line, 0); /* Combine the two streams into an I/O one. */ #ifdef WITH_TLS if (tls) { int rc = mu_tls_server_stream_create (&str, istream, ostream, 0); if (rc) { mu_stream_unref (istream); mu_stream_unref (ostream); mu_error (_("failed to create TLS stream: %s"), mu_strerror (rc)); imap4d_bye (ERR_STREAM_CREATE); } } else #endif if (mu_iostream_create (&str, istream, ostream)) imap4d_bye (ERR_STREAM_CREATE); /* Convert all writes to CRLF form. There is no need to convert reads, as the code ignores extra \r anyway. */ if (mu_filter_create (&iostream, str, "CRLF", MU_FILTER_ENCODE, MU_STREAM_WRITE | MU_STREAM_RDTHRU)) imap4d_bye (ERR_STREAM_CREATE); /* Change buffering scheme: filter streams are fully buffered by default. */ mu_stream_set_buffer (iostream, mu_buffer_line, 0); if (imap4d_transcript) { int rc; mu_stream_t dstr, xstr; rc = mu_dbgstream_create (&dstr, MU_DIAG_DEBUG); if (rc) mu_error (_("cannot create debug stream; transcript disabled: %s"), mu_strerror (rc)); else { rc = mu_xscript_stream_create (&xstr, iostream, dstr, NULL); mu_stream_unref (dstr); if (rc) mu_error (_("cannot create transcript stream: %s"), mu_strerror (rc)); else { mu_stream_unref (iostream); iostream = xstr; } } } }