static int _whatnow (struct mh_whatnow_env *wh, struct action_tab *tab) { int rc, status = 0; do { char *line = NULL; size_t size = 0; int argc; char **argv; handler_fp fun; printf ("%s ", wh->prompt); getline (&line, &size, stdin); if (!line) continue; rc = mu_argcv_get (line, "", "#", &argc, &argv); free (line); if (rc) { mu_argcv_free (argc, argv); break; } fun = func (tab, argv[0]); if (fun) rc = fun (wh, argc, argv, &status); else rc = 0; mu_argcv_free (argc, argv); } while (rc == 0); return status; }
static int _construct_attr_array (size_t *pargc, char ***pargv) { size_t count, i; char **argv; mu_iterator_t itr = NULL; mu_assoc_count (ldap_param.field_map, &count); if (count == 0) return MU_ERR_FAILURE; argv = calloc (count + 1, sizeof argv[0]); mu_assoc_get_iterator (ldap_param.field_map, &itr); for (i = 0, mu_iterator_first (itr); !mu_iterator_is_done (itr); mu_iterator_next (itr), i++) { char **str; mu_iterator_current (itr, (void**) &str); if ((argv[i] = strdup (*str)) == NULL) { mu_argcv_free (i, argv); return ENOMEM; } } mu_iterator_destroy (&itr); argv[i] = NULL; *pargc = count; *pargv = argv; return 0; }
int main (int argc, char **argv) { char *delim = ""; char *comment = "#"; char buf[512]; while (fgets (buf, sizeof buf, stdin)) { int status, c; char **v; char *s; status = mu_argcv_get (buf, delim, comment, &c, &v); if (status) { fprintf (stderr, "cannot parse: %s\n", mu_strerror (status)); continue; } status = mu_argcv_string (c, v, &s); if (status) fprintf (stderr, "cannot create string: %s\n", mu_strerror (status)); else { printf ("%d: %s\n", c, s); free (s); } mu_argcv_free (c, v); } exit (0); }
int mu_url_aget_query (const mu_url_t url, size_t *qc, char ***qv) { size_t qargc, i; char **qargv; char **qcopy; int rc = mu_url_sget_fvpairs (url, &qargc, &qargv); if (rc) return rc; qcopy = calloc (qargc + 1, sizeof (qcopy[0])); if (!qcopy) return errno; for (i = 0; i < qargc; i++) { if (!(qcopy[i] = strdup (qargv[i]))) { mu_argcv_free (i, qcopy); return errno; } } qcopy[i] = NULL; *qc = qargc; *qv = qcopy; return 0; }
int mu_url_aget_fvpairs (const mu_url_t url, size_t *pfvc, char ***pfvp) { size_t fvc, i; char **fvp; char **fvcopy; int rc = mu_url_sget_fvpairs (url, &fvc, &fvp); if (rc) return rc; fvcopy = calloc (fvc + 1, sizeof (fvcopy[0])); if (!fvcopy) return errno; for (i = 0; i < fvc; i++) { if (!(fvcopy[i] = strdup (fvp[i]))) { mu_argcv_free (i, fvcopy); return errno; } } fvcopy[i] = NULL; *pfvc = fvc; *pfvp = fvcopy; return 0; }
int main (int argc, char **argv) { int c; char buf[512]; char **prevv; int prevc = 0; interactive = isatty (0); while ((c = getopt (argc, argv, "f:h")) != EOF) { switch (c) { case 'f': file = optarg; break; case 'h': printf ("usage: header [-f file]\n"); exit (0); default: exit (1); } } if (file) { if (load_file (file)) exit (1); } else { int status = mu_header_create (&header, NULL, 0, NULL); if (status) { mu_error ("cannot create header: %s", mu_strerror (status)); exit (1); } } while (prompt(0), fgets(buf, sizeof buf, stdin)) { int c; char **v; int status; line_num++; status = mu_argcv_get (buf, NULL, "#", &c, &v); if (status) { mu_error ("%u: cannot parse: %s", line_num, mu_strerror (status)); continue; } if (c == 0) { if (prevc) docmd (prevc, prevv); else mu_argcv_free (c, v); } else { docmd (c, v); mu_argcv_free (prevc, prevv); prevc = c; prevv = v; } } exit (0); }
static int _mu_ldap_search (LDAP *ld, const char *filter_pat, const char *key, struct mu_auth_data **return_data) { int rc; char **attrs; size_t nattrs; LDAPMessage *res, *msg; ber_int_t msgid; const char *env[3]; struct mu_wordsplit ws; rc = _construct_attr_array (&nattrs, &attrs); if (rc) return rc; env[0] = "user"; env[1] = key; env[2] = NULL; ws.ws_env = env; if (mu_wordsplit (filter_pat, &ws, MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | MU_WRDSF_ENV | MU_WRDSF_ENV_KV)) { mu_error (_("cannot expand line `%s': %s"), filter_pat, mu_wordsplit_strerror (&ws)); return MU_ERR_FAILURE; } else if (ws.ws_wordc == 0) { mu_error (_("expanding %s yields empty string"), filter_pat); mu_wordsplit_free (&ws); mu_argcv_free (nattrs, attrs); return MU_ERR_FAILURE; } rc = ldap_search_ext (ld, ldap_param.base, LDAP_SCOPE_SUBTREE, ws.ws_wordv[0], attrs, 0, NULL, NULL, NULL, -1, &msgid); mu_wordsplit_free (&ws); mu_argcv_free (nattrs, attrs); if (rc != LDAP_SUCCESS) { mu_error ("ldap_search_ext: %s", ldap_err2string (rc)); if (rc == LDAP_NO_SUCH_OBJECT) return MU_ERR_NOENT; else return MU_ERR_FAILURE; } rc = ldap_result (ld, msgid, LDAP_MSG_ALL, NULL, &res ); if (rc < 0) { mu_error ("ldap_result failed"); return MU_ERR_FAILURE; } rc = ldap_count_entries (ld, res); if (rc == 0) { mu_error ("not enough entires"); return MU_ERR_NOENT; } if (rc > 1) mu_error ("LDAP: too many entries for key %s", key); msg = ldap_first_entry (ld, res); rc = _mu_entry_to_auth_data (ld, msg, return_data); ldap_msgfree (res); return rc; }
/* Treat arg as a name of user-defined sequence and attempt to expand it. Return 0 if succeeded, non-zero otherwise. */ int expand_user_seq (mu_mailbox_t mbox, mh_msgset_t *msgset, char *arg) { int argc; char **argv; char *p; const char *listp; int rc = 1; int negate = 0; p = strchr (arg, ':'); if (p) *p++ = 0; listp = mh_global_sequences_get (arg, NULL); if (!listp) { int len; const char *neg = mh_global_profile_get ("Sequence-Negation", NULL); if (!neg) return 1; len = strlen (neg); if (strncmp (arg, neg, len)) return 1; negate = 1; listp = mh_global_sequences_get (arg + len, NULL); if (!listp) return 1; } if (mu_argcv_get (listp, "", NULL, &argc, &argv) == 0) rc = _mh_msgset_parse (mbox, msgset, argc, argv); mu_argcv_free (argc, argv); if (rc) return rc; if (negate) mh_msgset_negate (mbox, msgset); if (p) { int first, num; num = strtoul (p, &p, 0); if (*p) { mh_msgset_free (msgset); return 1; } if (num < 0) { first = num + msgset->count; num = - num; } else first = 0; if (num > msgset->count) { mh_msgset_free (msgset); return 1; } if (first > 0) memmove (msgset->list, &msgset->list[first], sizeof (msgset->list[0]) * num); msgset->count = num; } return rc; }
int argcv_get_np (const char *command, int len, const char *delim, const char *cmnt, int flags, int *pargc, char ***pargv, char **endp) { int i = 0; struct argcv_info info; int argc; char **argv; if (!delim) delim = ""; if (!cmnt) cmnt = ""; init_argcv_info (&info, flags, len, command, delim, cmnt); /* Count number of arguments */ argc = 0; while (argcv_scan (&info) <= len) argc++; argv = calloc ((argc + 1), sizeof (char *)); if (argv == NULL) return ENOMEM; i = 0; info.save = 0; for (i = 0; i < argc; i++) { int n; int unquote; argcv_scan (&info); if ((command[info.start] == '"' || command[info.end] == '\'') && command[info.end] == command[info.start]) { if (info.start < info.end) { info.start++; info.end--; } unquote = 0; } else unquote = 1; n = info.end - info.start + 1; argv[i] = calloc (n + 1, sizeof (char)); if (argv[i] == NULL) { mu_argcv_free (i, argv); return ENOMEM; } if (unquote) argcv_unquote_copy (argv[i], &command[info.start], n); else memcpy (argv[i], &command[info.start], n); argv[i][n] = 0; } argv[i] = NULL; *pargc = argc; *pargv = argv; if (endp) *endp = (char*) (command + info.finish_pos); return 0; }
void smtp (int fd) { int state, c; char *buf = NULL; size_t size = 0; mu_mailbox_t mbox; mu_message_t msg; char *tempfile; char *rcpt_addr; in = fdopen (fd, "r"); out = fdopen (fd, "w"); SETVBUF (in, NULL, _IOLBF, 0); SETVBUF (out, NULL, _IOLBF, 0); smtp_reply (220, "Ready"); for (state = STATE_INIT; state != STATE_QUIT; ) { int argc; char **argv; int kw, len; if (getline (&buf, &size, in) == -1) exit (1); len = strlen (buf); while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r')) len --; buf[len] = 0; if (mu_argcv_get (buf, "", NULL, &argc, &argv)) exit (1); kw = smtp_kw (argv[0]); if (kw == KW_QUIT) { smtp_reply (221, "Done"); state = STATE_QUIT; mu_argcv_free (argc, argv); continue; } switch (state) { case STATE_INIT: switch (kw) { case KW_EHLO: case KW_HELO: if (argc == 2) { smtp_reply (250, "pleased to meet you"); state = STATE_EHLO; } else smtp_reply (501, "%s requires domain address", argv[0]); break; default: smtp_reply (503, "Polite people say HELO first"); break; } break; case STATE_EHLO: switch (kw) { case KW_MAIL: if (argc == 2) from_person = check_prefix (argv[1], "from:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "from:") == 0) from_person = argv[2]; else from_person = NULL; if (from_person) { from_person = strdup (from_person); smtp_reply (250, "Sender OK"); state = STATE_MAIL; } else smtp_reply (501, "Syntax error"); break; default: smtp_reply (503, "Need MAIL command"); } break; case STATE_MAIL: switch (kw) { case KW_RCPT: if (argc == 2) rcpt_addr = check_prefix (argv[1], "to:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0) rcpt_addr = argv[2]; else rcpt_addr = NULL; if (rcpt_addr) { if (add_recipient (rcpt_addr)) smtp_reply (451, "Recipient not accepted"); else { smtp_reply (250, "Recipient OK"); state = STATE_RCPT; } } else smtp_reply (501, "Syntax error"); break; default: smtp_reply (503, "Need RCPT command"); } break; case STATE_RCPT: switch (kw) { case KW_RCPT: if (argc == 2) rcpt_addr = check_prefix (argv[1], "to:"); else if (argc == 3 && mu_c_strcasecmp (argv[1], "to:") == 0) rcpt_addr = argv[2]; else rcpt_addr = NULL; if (rcpt_addr) { if (add_recipient (rcpt_addr)) smtp_reply (451, "Recipient not accepted"); else { smtp_reply (250, "Recipient OK"); state = STATE_RCPT; } } else smtp_reply (501, "Syntax error"); break; case KW_DATA: smtp_reply (354, "Enter mail, end with \".\" on a line by itself"); make_tmp (in, from_person, &tempfile); if ((c = mu_mailbox_create_default (&mbox, tempfile)) != 0) { mu_error ("%s: can't create mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); exit (1); } if ((c = mu_mailbox_open (mbox, MU_STREAM_RDWR)) != 0) { mu_error ("%s: can't open mailbox %s: %s", progname, tempfile, mu_strerror (c)); unlink (tempfile); exit (1); } mu_mailbox_get_message (mbox, 1, &msg); if (message_finalize (msg, 0) == 0) mta_send (msg); else smtp_reply (501, "can't send message"); /*FIXME: code?*/ unlink (tempfile); mu_address_destroy (&recipients); from_person = NULL; smtp_reply (250, "Message accepted for delivery"); state = STATE_EHLO; break; default: smtp_reply (503, "Invalid command"); break; } break; } mu_argcv_free (argc, argv); } close (fd); }