summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-09-05 20:14:53 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-09-08 16:11:37 +0300
commitd22b2199ab813bf994afc2dbe8e033ffcc01d045 (patch)
treef91efb88eb92e8e700d25c16283941454b69c9d4 /examples
parentb94a6d3cd2112e9b06f069e6ef9789cf6bc0d4e2 (diff)
downloadmailutils-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.am1
-rw-r--r--examples/pop3client.c647
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, &quote);
+ size = mu_argcv_quoted_length (argv[1], &quote);
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);
}
+

Return to:

Send suggestions and report system problems to the System administrator.