diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-09-05 20:14:53 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-09-08 16:11:37 +0300 |
commit | d22b2199ab813bf994afc2dbe8e033ffcc01d045 (patch) | |
tree | f91efb88eb92e8e700d25c16283941454b69c9d4 /examples | |
parent | b94a6d3cd2112e9b06f069e6ef9789cf6bc0d4e2 (diff) | |
download | mailutils-d22b2199ab813bf994afc2dbe8e033ffcc01d045.tar.gz mailutils-d22b2199ab813bf994afc2dbe8e033ffcc01d045.tar.bz2 |
Minor change in stream API. Improve POP3 client interface.
* include/mailutils/sys/stream.h (_MU_STR_EVENT_SET)
(_MU_STR_EVENT_CLR): New defines.
(_mu_stream) <event_cb, event_mask>: New members.
* mailbox/stream.c (_stream_setflag, _stream_clrflag): New static
functions.
All functions use these instead of setting/clearing flags directly.
(_mu_stream_cleareof, _mu_stream_seteof): New extern functions.
(_stream_cleareof): Remove define, use _mu_stream_cleareof instead.
(_stream_fill_buffer): Set EOF marker when end of stream is reached.
* mailbox/fltstream.c (filter_read): Call _mu_stream_seteof to set
EOF flag.
* include/mailutils/pop3.h: Get rid of the superfluous "extern" in
front of function prototypes.
Add new prototypes.
Remove extra whitespace.
* libproto/pop/pop3_capatst.c: New file.
* libproto/pop/pop3_list_cmd.c: New file.
* libproto/pop/pop3_listas.c: New file.
* libproto/pop/pop3_rdlist.c: New file.
* libproto/pop/pop3_uidl_cmd.c: New file.
* libproto/pop/pop3_uidlas.c: New file.
* libproto/pop/Makefile.am: Add new files.
* libproto/pop/pop3_capa.c (_mu_pop3_fill_list): Remove.
Use mu_pop3_read_list instead.
(capa_comp): New comparator for capa lists.
* libproto/pop/pop3_list.c (mu_pop3_list): Fix format specifier.
* libproto/pop/pop3_lista.c (mu_pop3_list_all): Rewrite.
* libproto/pop/pop3_retr.c (mu_pop3_retr) <MU_POP3_RETR_RX>: do not
reset state, this is done by the EOF event callback.
* libproto/pop/pop3_top.c (mu_pop3_top) <MU_POP3_TOP_RX>: Likewise.
* libproto/pop/pop3_stream.c (pop3_decode_state): New state pds_char.
Change semantics of pds_init.
(newstate, _pop3_decoder): Handle .\r\n in the initial state.
(_pop3_event_cb): New event callback.
(mu_pop3_filter_create): Set event callback on the filter stream.
* libproto/pop/pop3_uidla.c (mu_pop3_uidl_all): Rewrite.
* examples/Makefile.am (pop3client_CPPFLAGS): Add MU_APP_COMMON_INCLUDES.
* examples/pop3client.c: Rewrite command parser.
Diffstat (limited to 'examples')
-rw-r--r-- | examples/Makefile.am | 1 | ||||
-rw-r--r-- | examples/pop3client.c | 647 |
2 files changed, 364 insertions, 284 deletions
diff --git a/examples/Makefile.am b/examples/Makefile.am index 2db72b44b..b0911b57d 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -111,6 +111,7 @@ sfrom_LDADD =\ @MU_AUTHLIBS@\ ${MU_LIB_MAILUTILS} +pop3client_CPPFLAGS = @MU_APP_COMMON_INCLUDES@ pop3client_LDADD = \ ../lib/libmuaux.la\ ${MU_LIB_POP}\ diff --git a/examples/pop3client.c b/examples/pop3client.c index 3751c0a0e..24f621147 100644 --- a/examples/pop3client.c +++ b/examples/pop3client.c @@ -34,6 +34,7 @@ #include <stdlib.h> #include <termios.h> #include <signal.h> +#include <xalloc.h> #ifdef WITH_READLINE # include <readline/readline.h> @@ -56,64 +57,81 @@ typedef struct { const char *name; /* User printable name of the function. */ - int (*func) (char *); /* Function to call to do the job. */ + int argmin; + int argmax; + int (*func) (int, char **); /* Function to call to do the job. */ const char *doc; /* Documentation for this function. */ } COMMAND; /* The names of functions that actually do the manipulation. */ -int com_apop (char *); -int com_capa (char *); -int com_disconnect (char *); -int com_dele (char *); -int com_exit (char *); -int com_help (char *); -int com_list (char *); -int com_noop (char *); -int com_connect (char *); -int com_pass (char *); -int com_quit (char *); -int com_retr (char *); -int com_rset (char *); -int com_stat (char *); -int com_top (char *); -int com_uidl (char *); -int com_user (char *); -int com_verbose (char *); -int com_prompt (char *); -int com_stls (char *); - -void initialize_readline (void); -COMMAND *find_command (char *); -char *dupstr (const char *); -int execute_line (char *); -int valid_argument (const char *, char *); +int com_apop (int, char **); +int com_capa (int, char **); +int com_disconnect (int, char **); +int com_dele (int, char **); +int com_exit (int, char **); +int com_help (int, char **); +int com_list (int, char **); +int com_noop (int, char **); +int com_connect (int, char **); +int com_pass (int, char **); +int com_quit (int, char **); +int com_retr (int, char **); +int com_rset (int, char **); +int com_stat (int, char **); +int com_top (int, char **); +int com_uidl (int, char **); +int com_user (int, char **); +int com_verbose (int, char **); +int com_prompt (int, char **); +int com_stls (int, char **); -void sig_int (int); +COMMAND *find_command (char *); COMMAND commands[] = { - { "apop", com_apop, "Authenticate with APOP: APOP user secret" }, - { "capa", com_capa, "List capabilities: capa" }, - { "disconnect", com_disconnect, "Close connection: disconnect" }, - { "dele", com_dele, "Mark message: DELE msgno" }, - { "exit", com_exit, "exit program" }, - { "help", com_help, "Display this text" }, - { "?", com_help, "Synonym for `help'" }, - { "list", com_list, "List messages: LIST [msgno]" }, - { "noop", com_noop, "Send no operation: NOOP" }, - { "pass", com_pass, "Send passwd: PASS [passwd]" }, - { "prompt", com_prompt, "Set command prompt" }, - { "connect", com_connect, "Open connection: connect hostname [port]" }, - { "quit", com_quit, "Go to Update state : QUIT" }, - { "retr", com_retr, "Dowload message: RETR msgno" }, - { "rset", com_rset, "Unmark all messages: RSET" }, - { "stat", com_stat, "Get the size and count of mailbox : STAT [msgno]" }, - { "stls", com_stls, "Start TLS negotiation" }, - { "top", com_top, "Get the header of message: TOP msgno [lines]" }, - { "uidl", com_uidl, "Get the unique id of message: UIDL [msgno]" }, - { "user", com_user, "send login: USER user" }, - { "verbose", com_verbose, "Enable Protocol tracing: verbose [on|off]" }, - { NULL, NULL, NULL } + { "apop", 3, 3, com_apop, + "Authenticate with APOP: APOP user secret" }, + { "capa", 1, -1, com_capa, + "List capabilities: capa [-reread] [names...]" }, + { "disconnect", 1, 1, + com_disconnect, "Close connection: disconnect" }, + { "dele", 2, 2, com_dele, + "Mark message: DELE msgno" }, + { "exit", 1, 1, com_exit, + "exit program" }, + { "help", 1, 1, com_help, + "Display this text" }, + { "?", 1, 1, com_help, + "Synonym for `help'" }, + { "list", 1, 2, com_list, + "List messages: LIST [msgno]" }, + { "noop", 1, 1, com_noop, + "Send no operation: NOOP" }, + { "pass", 1, 2, com_pass, + "Send passwd: PASS [passwd]" }, + { "prompt", -1, -1, com_prompt, + "Set command prompt" }, + { "connect", 1, 4, com_connect, + "Open connection: connect [-tls] hostname port" }, + { "quit", 1, 1, com_quit, + "Go to Update state : QUIT" }, + { "retr", 2, 2, com_retr, + "Dowload message: RETR msgno" }, + { "rset", 1, 1, com_rset, + "Unmark all messages: RSET" }, + { "stat", 1, 1, com_stat, + "Get the size and count of mailbox : STAT" }, + { "stls", 1, 1, com_stls, + "Start TLS negotiation" }, + { "top", 2, 3, com_top, + "Get the header of message: TOP msgno [lines]" }, + { "uidl", 1, 2, com_uidl, + "Get the unique id of message: UIDL [msgno]" }, + { "user", 2, 2, com_user, + "send login: USER user" }, + { "verbose", 1, 2, com_verbose, + "Enable Protocol tracing: verbose [on|off]" }, + { NULL } }; /* Global handle for pop3. */ @@ -189,20 +207,6 @@ expand_prompt () return str; } -char * -dupstr (const char *s) -{ - char *r; - - r = malloc (strlen (s) + 1); - if (!r) - { - mu_error ("Memory exhausted"); - exit (1); - } - strcpy (r, s); - return r; -} #ifdef WITH_READLINE @@ -269,7 +273,7 @@ command_generator (const char *text, int state) list_index++; if (strncmp (name, text, len) == 0) - return (dupstr (name)); + return xstrdup (name); } /* If no names matched, then return NULL. */ @@ -304,73 +308,103 @@ add_history (const char *s MU_ARG_UNUSED) } #endif +int +get_bool (const char *str, int *pb) +{ + if (mu_c_strcasecmp (str, "yes") == 0 + || mu_c_strcasecmp (str, "on") == 0 + || mu_c_strcasecmp (str, "true") == 0) + *pb = 1; + else if (mu_c_strcasecmp (str, "no") == 0 + || mu_c_strcasecmp (str, "off") == 0 + || mu_c_strcasecmp (str, "false") == 0) + *pb = 0; + else + { + mu_error ("not a boolean: %s", str); + return 1; + } + return 0; +} int -main (int argc MU_ARG_UNUSED, char **argv) +get_port (const char *port_str, int *pn) { - char *line, *s; - - mu_set_program_name (argv[0]); - prompt = strdup (DEFAULT_PROMPT); - initialize_readline (); /* Bind our completer. */ -#ifdef WITH_TLS - mu_init_tls_libs (); -#endif - /* Loop reading and executing lines until the user quits. */ - while (!done) + short port_num; + long num; + char *p; + + num = port_num = strtol (port_str, &p, 0); + if (*p == 0) { - char *p = expand_prompt (); - line = readline (p); - free (p); - - if (!line) - break; - - /* Remove leading and trailing whitespace from the line. - Then, if there is anything left, add it to the history list - and execute it. */ - s = mu_str_stripws (line); - - if (*s) + if (num != port_num) { - int status; - add_history (s); - status = execute_line (s); - if (status != 0) - mu_error ("Error: %s", mu_strerror (status)); + mu_error ("bad port number: %s", port_str); + return 1; } - - free (line); } - exit (0); + else + { + struct servent *sp = getservbyname (port_str, "tcp"); + if (!sp) + { + mu_error ("unknown port name"); + return 1; + } + port_num = ntohs (sp->s_port); + } + *pn = port_num; + return 0; } - + /* Parse and execute a command line. */ int execute_line (char *line) { - COMMAND *command; - char *word, *arg; + int argc; + char **argv; + int status = 0; - /* Isolate the command word. */ - word = mu_str_skip_class (line, MU_CTYPE_SPACE); - arg = mu_str_skip_class_comp (word, MU_CTYPE_SPACE); - if (*arg) + if (mu_argcv_get (line, NULL, "#", &argc, &argv)) { - *arg++ = 0; - arg = mu_str_skip_class (arg, MU_CTYPE_SPACE); + mu_error("cannot parse input line"); + return 0; } - - command = find_command (word); - if (!command) + if (argc >= 0) { - mu_error ("%s: No such command.", word); - return 0; + COMMAND *command = find_command (argv[0]); + + if (!command) + mu_error ("%s: no such command.", argv[0]); + else if (command->argmin > 0 && argc < command->argmin) + mu_error ("%s: too few arguments", argv[0]); + else if (command->argmax > 0 && argc > command->argmax) + mu_error ("%s: too many arguments", argv[0]); + else + { + if (command->argmin <= 0 && argc != 2) + { + char *word = mu_str_skip_class (line, MU_CTYPE_SPACE); + char *arg = mu_str_skip_class_comp (word, MU_CTYPE_SPACE); + if (*arg) + { + *arg++ = 0; + arg = mu_str_skip_class (arg, MU_CTYPE_SPACE); + } + + mu_argcv_free (argc, argv); + argc = 2; + argv = xcalloc (argc + 1, sizeof (argv[0])); + argv[0] = xstrdup (word); + argv[1] = xstrdup (arg); + argv[2] = NULL; + } + status = command->func (argc, argv); + } } - - /* Call the function. */ - return ((*(command->func)) (arg)); + mu_argcv_free (argc, argv); + return status; } /* Look up NAME as the name of a command, and return a pointer to that @@ -378,106 +412,139 @@ execute_line (char *line) COMMAND * find_command (char *name) { - register int i; + COMMAND *cp; - for (i = 0; commands[i].name; i++) - if (strcmp (name, commands[i].name) == 0) - return (&commands[i]); + for (cp = commands; cp->name; cp++) + if (strcmp (cp->name, name) == 0) + return cp; - return ((COMMAND *) NULL); + return NULL; } int -com_verbose (char *arg) +com_verbose (int argc, char **argv) { - int status = 0; - if (!valid_argument ("verbose", arg)) - return EINVAL; - - verbose = (strcmp (arg, "on") == 0); - if (pop3 != NULL) + if (argc == 1) { - if (verbose == 1) - mu_pop3_trace (pop3, MU_POP3_TRACE_SET); + if (verbose) + printf ("verbose is on\n"); else - mu_pop3_trace (pop3, MU_POP3_TRACE_CLR); + printf ("verbose is off\n"); } - return status; + else + { + int bv; + + if (get_bool (argv[1], &bv) == 0) + { + verbose = bv; + if (pop3 != NULL) + { + if (verbose == 1) + mu_pop3_trace (pop3, MU_POP3_TRACE_SET); + else + mu_pop3_trace (pop3, MU_POP3_TRACE_CLR); + } + } + } + return 0; } int -com_user (char *arg) +com_user (int argc, char **argv) { int status; - if (!valid_argument ("user", arg)) - return EINVAL; - status = mu_pop3_user (pop3, arg); + status = mu_pop3_user (pop3, argv[1]); if (status == 0) - username = strdup (arg); + username = strdup (argv[1]); return status; } int -com_apop (char *arg) +com_apop (int argc, char **argv) { int status; - char *user, *digest; - - if (!valid_argument ("apop", arg)) - return EINVAL; - user = strtok (arg, " "); - digest = strtok (NULL, " "); - if (!valid_argument ("apop", user) || !valid_argument ("apop", digest)) - return EINVAL; - status = mu_pop3_apop (pop3, user, digest); + + status = mu_pop3_apop (pop3, argv[1], argv[2]); if (status == 0) { - username = strdup (user); + username = strdup (argv[1]); pop_session_status = pop_session_logged_in; } return status; } int -com_capa (char *arg) +com_capa (int argc, char **argv) { mu_iterator_t iterator = NULL; - int status; + int status = 0; int reread = 0; - - if (arg && *arg) + int i = 1; + + for (i = 1; i < argc; i++) { - if (strcmp (arg, "reread") == 0) + if (strcmp (argv[i], "-reread") == 0) reread = 1; else + break; + } + + if (i < argc) + { + if (reread) { - mu_error ("%s: unknown argument", "capa"); - return 0; + status = mu_pop3_capa (pop3, 1, NULL); + if (status) + return status; + } + for (; i < argc; i++) + { + const char *elt; + int rc = pop3_capa_test (pop3, argv[i], &elt); + switch (rc) + { + case 0: + if (*elt) + printf ("%s: %s\n", argv[i], elt); + else + printf ("%s is set\n", argv[i]); + break; + + case MU_ERR_NOENT: + printf ("%s is not set\n", argv[i]); + break; + + default: + return rc; + } } } - - status = mu_pop3_capa (pop3, reread, &iterator); - - if (status == 0) + else { - for (mu_iterator_first (iterator); - !mu_iterator_is_done (iterator); mu_iterator_next (iterator)) + status = mu_pop3_capa (pop3, reread, &iterator); + + if (status == 0) { - char *capa = NULL; - mu_iterator_current (iterator, (void **) &capa); - printf ("Capa: %s\n", (capa) ? capa : ""); + for (mu_iterator_first (iterator); + !mu_iterator_is_done (iterator); mu_iterator_next (iterator)) + { + char *capa = NULL; + mu_iterator_current (iterator, (void **) &capa); + printf ("CAPA: %s\n", capa ? capa : ""); + } + mu_iterator_destroy (&iterator); } - mu_iterator_destroy (&iterator); } return status; } int -com_uidl (char *arg) +com_uidl (int argc, char **argv) { int status = 0; - if (arg == NULL || *arg == '\0') + if (argc == 1) { mu_iterator_t uidl_iterator = NULL; status = mu_pop3_uidl_all (pop3, &uidl_iterator); @@ -489,7 +556,7 @@ com_uidl (char *arg) { char *uidl = NULL; mu_iterator_current (uidl_iterator, (void **) &uidl); - printf ("UIDL: %s\n", (uidl) ? uidl : ""); + printf ("UIDL: %s\n", uidl ? uidl : ""); } mu_iterator_destroy (&uidl_iterator); } @@ -497,20 +564,20 @@ com_uidl (char *arg) else { char *uidl = NULL; - unsigned int msgno = strtoul (arg, NULL, 10); + unsigned int msgno = strtoul (argv[1], NULL, 10); status = mu_pop3_uidl (pop3, msgno, &uidl); if (status == 0) - printf ("Msg: %d UIDL: %s\n", msgno, (uidl) ? uidl : ""); + printf ("Msg: %d UIDL: %s\n", msgno, uidl ? uidl : ""); free (uidl); } return status; } int -com_list (char *arg) +com_list (int argc, char **argv) { int status = 0; - if (arg == NULL || *arg == '\0') + if (argc == 1) { mu_iterator_t list_iterator; status = mu_pop3_list_all (pop3, &list_iterator); @@ -530,7 +597,7 @@ com_list (char *arg) else { size_t size = 0; - unsigned int msgno = strtoul (arg, NULL, 10); + unsigned int msgno = strtoul (argv[1], NULL, 10); status = mu_pop3_list (pop3, msgno, &size); if (status == 0) printf ("Msg: %u Size: %lu\n", msgno, (unsigned long) size); @@ -539,7 +606,7 @@ com_list (char *arg) } int -com_noop (char *arg MU_ARG_UNUSED) +com_noop (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) { return mu_pop3_noop (pop3); } @@ -561,33 +628,31 @@ echo_on (struct termios *stored_settings) } int -com_prompt (char *arg) +com_prompt (int argc, char **argv) { int quote; size_t size; - if (!valid_argument ("prompt", arg)) - return EINVAL; - free (prompt); - size = mu_argcv_quoted_length (arg, "e); + size = mu_argcv_quoted_length (argv[1], "e); prompt = malloc (size + 1); if (!prompt) { mu_error ("Memory exhausted"); exit (1); } - mu_argcv_unquote_copy (prompt, arg, size); + mu_argcv_unquote_copy (prompt, argv[1], size); return 0; } int -com_pass (char *arg) +com_pass (int argc, char **argv) { int status; char pass[256]; + char *pwd; - if (!arg || *arg == '\0') + if (argc == 1) { struct termios stored_settings; @@ -599,16 +664,18 @@ com_pass (char *arg) putchar ('\n'); fflush (stdout); pass[strlen (pass) - 1] = '\0'; /* nuke the trailing line. */ - arg = pass; + pwd = pass; } - status = mu_pop3_pass (pop3, arg); + else + pwd = argv[1]; + status = mu_pop3_pass (pop3, pwd); if (status == 0) pop_session_status = pop_session_logged_in; return status; } int -com_stat (char *arg MU_ARG_UNUSED) +com_stat (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) { unsigned count = 0; size_t size = 0; @@ -621,32 +688,31 @@ com_stat (char *arg MU_ARG_UNUSED) } int -com_stls (char *arg MU_ARG_UNUSED) +com_stls (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) { return mu_pop3_stls (pop3); } int -com_dele (char *arg) +com_dele (int argc, char **argv) { unsigned msgno; - if (!valid_argument ("dele", arg)) - return EINVAL; - msgno = strtoul (arg, NULL, 10); + msgno = strtoul (argv[1], NULL, 10); return mu_pop3_dele (pop3, msgno); } /* Print out help for ARG, or for all of the commands if ARG is not present. */ int -com_help (char *arg) +com_help (int argc, char **argv) { int i; int printed = 0; - + char *name = argv[1]; + for (i = 0; commands[i].name; i++) { - if (!*arg || (strcmp (arg, commands[i].name) == 0)) + if (!name || (strcmp (name, commands[i].name) == 0)) { printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); printed++; @@ -655,7 +721,7 @@ com_help (char *arg) if (!printed) { - printf ("No commands match `%s'. Possibilties are:\n", arg); + printf ("No commands match `%s'. Possibilties are:\n", name); for (i = 0; commands[i].name; i++) { @@ -677,32 +743,24 @@ com_help (char *arg) } int -com_rset (char *arg MU_ARG_UNUSED) +com_rset (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) { return mu_pop3_rset (pop3); } int -com_top (char *arg) +com_top (int argc, char **argv) { mu_stream_t stream; unsigned int msgno; unsigned int lines; - char *space; int status; - if (!valid_argument ("top", arg)) - return EINVAL; - - space = strchr (arg, ' '); - if (space) - { - *space++ = '\0'; - lines = strtoul (space, NULL, 10); - } + msgno = strtoul (argv[1], NULL, 10); + if (argc == 3) + lines = strtoul (argv[2], NULL, 10); else - lines = 0; - msgno = strtoul (arg, NULL, 10); + lines = 5; status = mu_pop3_top (pop3, msgno, lines, &stream); @@ -718,16 +776,13 @@ com_top (char *arg) } int -com_retr (char *arg) +com_retr (int argc, char **argv) { mu_stream_t stream; unsigned int msgno; int status; - if (!valid_argument ("retr", arg)) - return EINVAL; - - msgno = strtoul (arg, NULL, 10); + msgno = strtoul (argv[1], NULL, 10); status = mu_pop3_retr (pop3, msgno, &stream); if (status == 0) @@ -742,73 +797,44 @@ com_retr (char *arg) } int -get_port (const char *port_str, int *pn) +com_connect (int argc, char **argv) { - short port_num; - long num; - char *p; + int status; + int n = 0; + int tls = 0; + int i = 1; - num = port_num = strtol (port_str, &p, 0); - if (*p == 0) - { - if (num != port_num) - { - mu_error ("bad port number: %s", port_str); - return 1; - } - } - else + for (i = 1; i < argc; i++) { - struct servent *sp = getservbyname (port_str, "tcp"); - if (!sp) + if (strcmp (argv[i], "-tls") == 0) { - mu_error ("unknown port name"); - return 1; + if (WITH_TLS) + tls = 1; + else + { + mu_error ("TLS not supported"); + return 0; + } } - port_num = ntohs (sp->s_port); + else + break; } - *pn = port_num; - return 0; -} -int -com_connect (char *arg) -{ - int status; - int n = 110; - int argc; - char **argv; - - if (!valid_argument ("connect", arg)) - return 1; + argc -= i; + argv += i; - if (mu_argcv_get (arg, NULL, NULL, &argc, &argv)) + if (argc >= 2) { - mu_error ("Cannot parse arguments"); - return 0; - } - - if (!valid_argument ("connect", argv[0])) - { - mu_argcv_free (argc, argv); - return EINVAL; - } - - if (argc > 2) - { - mu_error ("Too many arguments"); - mu_argcv_free (argc, argv); - return 0; - } - - if (argc == 2 && get_port (argv[1], &n)) - { - mu_argcv_free (argc, argv); - return 0; + if (get_port (argv[1], &n)) + return 0; } + else if (tls) + n = MU_POP3_DEFAULT_SSL_PORT; + else + n = MU_POP3_DEFAULT_PORT; if (pop_session_status != pop_session_disconnected) - com_disconnect (NULL); + com_disconnect (0, NULL); status = mu_pop3_create (&pop3); if (status == 0) @@ -816,10 +842,35 @@ com_connect (char *arg) mu_stream_t tcp; if (verbose) - com_verbose ("on"); + mu_pop3_trace (pop3, MU_POP3_TRACE_SET); status = mu_tcp_stream_create (&tcp, argv[0], n, MU_STREAM_READ); if (status == 0) { +#ifdef WITH_TLS + if (tls) + { + mu_stream_t tlsstream; + + status = mu_stream_open (tcp); + if (status) + { + mu_error ("cannot open connection: %s", + mu_stream_strerror (tcp, status)); + mu_stream_destroy (&tcp); + return 0; + } + + status = mu_tls_client_stream_create (&tlsstream, tcp, tcp, 0); + mu_stream_unref (tcp); + if (status) + { + mu_error ("cannot create TLS stream: %s", + mu_strerror (status)); + return 0; + } + tcp = tlsstream; + } +#endif mu_pop3_set_carrier (pop3, tcp); status = mu_pop3_connect (pop3); } @@ -831,14 +882,14 @@ com_connect (char *arg) } if (status) - { - mu_error ("Failed to create pop3: %s", mu_strerror (status)); - mu_argcv_free (argc, argv); - } + mu_error ("Failed to create pop3: %s", mu_strerror (status)); else { connect_argc = argc; - connect_argv = argv; + connect_argv = xcalloc (argc, sizeof (*connect_argv)); + for (i = 0; i < argc; i++) + connect_argv[i] = xstrdup (argv[i]); + connect_argv[i] = NULL; port = n; pop_session_status = pop_session_connected; } @@ -847,7 +898,7 @@ com_connect (char *arg) } int -com_disconnect (char *arg MU_ARG_UNUSED) +com_disconnect (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) { if (pop3) { @@ -864,14 +915,14 @@ com_disconnect (char *arg MU_ARG_UNUSED) } int -com_quit (char *arg MU_ARG_UNUSED) +com_quit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) { int status = 0; if (pop3) { if (mu_pop3_quit (pop3) == 0) { - status = com_disconnect (arg); + status = com_disconnect (0, NULL); } else { @@ -884,7 +935,7 @@ com_quit (char *arg MU_ARG_UNUSED) } int -com_exit (char *arg MU_ARG_UNUSED) +com_exit (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) { if (pop3) { @@ -895,16 +946,44 @@ com_exit (char *arg MU_ARG_UNUSED) return 0; } -/* Return non-zero if ARG is a valid argument for CALLER, else print - an error message and return zero. */ + int -valid_argument (const char *caller, char *arg) +main (int argc MU_ARG_UNUSED, char **argv) { - if (!arg || !*arg) + char *line, *s; + + mu_set_program_name (argv[0]); + prompt = strdup (DEFAULT_PROMPT); + initialize_readline (); /* Bind our completer. */ +#ifdef WITH_TLS + mu_init_tls_libs (); +#endif + /* Loop reading and executing lines until the user quits. */ + while (!done) { - mu_error ("%s: Argument required", caller); - return 0; - } + char *p = expand_prompt (); + line = readline (p); + free (p); + + if (!line) + break; + + /* Remove leading and trailing whitespace from the line. + Then, if there is anything left, add it to the history list + and execute it. */ + s = mu_str_stripws (line); - return 1; + if (*s) + { + int status; + add_history (s); + status = execute_line (s); + if (status != 0) + mu_error ("Error: %s", mu_strerror (status)); + } + + free (line); + } + exit (0); } + |