diff options
Diffstat (limited to 'mail')
-rw-r--r-- | mail/Makefile.am | 106 | ||||
-rw-r--r-- | mail/mail.c | 623 |
2 files changed, 75 insertions, 654 deletions
diff --git a/mail/Makefile.am b/mail/Makefile.am index e9d859c3d..ffc0db571 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -1,107 +1,5 @@ -## Process this file with GNU Automake to create Makefile.in - -## Copyright (C) 1999,2000,2001,2002,2005,2007 Free Software Foundation, Inc. -## -## GNU Mailutils is free software; you can redistribute it and/or -## modify it under the terms of the GNU General Public License as -## published by the Free Software Foundation; either version 2, or (at -## your option) any later version. -## -## This program is distributed in the hope that it will be useful, but -## WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA -## 02110-1301 USA - -AM_YFLAGS=-vt -INCLUDES = @MU_COMMON_INCLUDES@ @MU_AUTHINCS@ -AM_CFLAGS = -DSITE_MAIL_RC=\"@SITE_MAIL_RC@\" +CPPFLAGS = -I$(top_srcdir)/libmailbox bin_PROGRAMS = mail -mail_LDADD = \ - ${MU_APP_LIBRARIES}\ - ${MU_LIB_MBOX}\ - ${MU_LIB_IMAP}\ - ${MU_LIB_POP}\ - ${MU_LIB_NNTP}\ - ${MU_LIB_MH}\ - ${MU_LIB_MAILDIR}\ - ${MU_LIB_MAILER}\ - ${MU_LIB_AUTH}\ - @MU_AUTHLIBS@\ - ${MU_LIB_MAILUTILS}\ - @READLINE_LIBS@ @MU_COMMON_LIBRARIES@ - -EXTRA_DIST = msgset.c - -mail_SOURCES = \ - alias.c\ - alt.c\ - cd.c\ - copy.c\ - decode.c\ - delete.c\ - dp.c\ - echo.c\ - edit.c\ - eq.c\ - escape.c\ - exit.c\ - file.c\ - folders.c\ - followup.c\ - from.c\ - headers.c\ - help.c\ - hold.c\ - if.c\ - inc.c\ - list.c\ - mail.c\ - mail.h\ - mailline.c\ - mbox.c\ - msgset.y\ - next.c\ - page.c\ - pipe.c\ - previous.c\ - print.c\ - quit.c\ - reply.c\ - retain.c\ - save.c\ - send.c\ - set.c\ - setenv.c\ - shell.c\ - size.c\ - source.c\ - summary.c\ - table.c\ - tag.c\ - top.c\ - touch.c\ - unalias.c\ - undelete.c\ - unset.c\ - util.c\ - version.c\ - visual.c\ - write.c\ - z.c - -SUBDIRS = testsuite - -CFLOW_FLAGS=-i^s --brief -v -mail_CFLOW_INPUT=$(mail_OBJECTS:.$(OBJEXT)=.c) -mail.cflow: $(mail_CFLOW_INPUT) Makefile - cflow -o$@ $(CFLOW_FLAGS) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) \ - $(mail_CFLOW_INPUT) +mail_LDADD = ../libmailbox/libmailbox.la diff --git a/mail/mail.c b/mail/mail.c index 553448f42..daa0e5c8e 100644 --- a/mail/mail.c +++ b/mail/mail.c @@ -1,571 +1,94 @@ -/* GNU Mailutils -- a suite of utilities for electronic mail - Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007 Free Software Foundation, Inc. +/* copyright and license info go here */ - GNU Mailutils is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. +#include <mailbox.h> +#include <stdio.h> +#include <stdlib.h> - GNU Mailutils is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with GNU Mailutils; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - MA 02110-1301 USA */ - -#include "mail.h" -#include "mailutils/libargp.h" - -/* Global variables and constants*/ -mu_mailbox_t mbox; /* Mailbox being operated upon */ -size_t total; /* Total number of messages in the mailbox */ -FILE *ofile; /* Output file */ -int interactive; /* Is the session interactive */ - -static mu_list_t command_list; /* List of commands to be executed after parsing - command line */ - -const char *program_version = "mail (" PACKAGE_STRING ")"; -static char doc[] = N_("GNU mail -- the standard /bin/mail interface"); -static char args_doc[] = N_("[address...]"); - -static struct argp_option options[] = { - {"exist", 'e', 0, 0, N_("Return true if mail exists"), 0}, - {"file", 'f', N_("URL"), OPTION_ARG_OPTIONAL, - N_("Operate on given mailbox URL (default ~/mbox)"), 0}, - {"byname", 'F', 0, 0, N_("Save messages according to sender"), 0}, - {"headers", 'H', 0, 0, N_("Write a header summary and exit"), 0}, - {"ignore", 'i', 0, 0, N_("Ignore interrupts"), 0}, - {"norc", 'n', 0, 0, N_("Do not read the system mailrc file"), 0}, - {"nosum", 'N', 0, 0, N_("Do not display initial header summary"), 0}, - {"print", 'p', 0, 0, N_("Print all mail to standard output"), 0}, - {"quit", 'q', 0, 0, N_("Cause interrupts to terminate program"), 0}, - {"read", 'r', 0, 0, N_("Same as -p"), 0}, - {"subject", 's', N_("SUBJ"), 0, N_("Send a message with a Subject of SUBJ"), 0}, - {"to", 't', 0, 0, N_("Precede message by a list of addresses"), 0}, - {"user", 'u', N_("USER"), 0, N_("Operate on USER's mailbox"), 0}, - {"append", 'a', N_("HEADER: VALUE"), 0, - N_("Append given header to the message being sent"), 0}, - {"exec", 'E', N_("COMMAND"), 0, - N_("Execute COMMAND"), 0 }, - { NULL, 0, NULL, 0, NULL, 0 } -}; - - -struct arguments -{ - char **args; - char *file; - char *user; - int send_mode; -}; - -static error_t -parse_opt (int key, char *arg, struct argp_state *state) -{ - struct arguments *args = state->input; - - switch (key) - { - case 'a': - args->send_mode = 1; - send_append_header (arg); - break; - - case 'e': - util_cache_command (&command_list, "set mode=exist"); - break; - - case 'f': - if (arg != NULL) - args->file = arg; - /* People often tend to separate -f option from its argument - with a whitespace. This heuristics tries to catch the - error: */ - else if (state->next < state->argc - && state->argv[state->next][0] != '-') - args->file = state->argv[state->next++]; - else - { - int len; - char *home = getenv("HOME"); - len = strlen (home) + strlen ("/mbox") + 1; - args->file = xmalloc(len * sizeof (char)); - strcpy (args->file, home); - strcat (args->file, "/mbox"); - } - break; - - case 'p': - case 'r': - util_cache_command (&command_list, "set mode=print"); - break; - - case 'q': - util_cache_command (&command_list, "set quit"); - break; - - case 't': - util_cache_command (&command_list, "set mode=send"); - break; - - case 'H': - util_cache_command (&command_list, "set mode=headers"); - break; - - case 'i': - util_cache_command (&command_list, "set ignore"); - break; - - case 'n': - util_do_command ("set norc"); - break; - - case 'N': - util_cache_command (&command_list, "set noheader"); - break; - - case 's': - send_append_header2 (MU_HEADER_SUBJECT, arg, COMPOSE_REPLACE); - util_cache_command (&command_list, "set noasksub"); - args->send_mode = 1; - break; - - case 'u': - args->user = arg; - break; - - case 'E': - util_cache_command (&command_list, arg); - break; - - case 'F': - util_cache_command (&command_list, "set byname"); - break; - - case ARGP_KEY_ARG: - args->args = realloc (args->args, - sizeof (char *) * (state->arg_num + 2)); - args->args[state->arg_num] = arg; - args->args[state->arg_num + 1] = NULL; - args->send_mode = 1; - break; - - case ARGP_KEY_FINI: - if (args->send_mode) - util_cache_command (&command_list, "set mode=send"); - break; - - default: - return ARGP_ERR_UNKNOWN; - } - return 0; -} - -static struct argp argp = { - options, - parse_opt, - args_doc, - doc, - NULL, - NULL, NULL -}; - -static const char *mail_capa[] = { - "common", - "debug", - "license", - "mailbox", - "locking", - NULL -}; - -static char * -mail_cmdline (void *closure, int cont MU_ARG_UNUSED) -{ - char *prompt = (char*) closure; - char *rc; - - while (1) - { - if (util_getenv (NULL, "autoinc", Mail_env_boolean, 0) == 0 - && !mu_mailbox_is_updated (mbox)) - { - mu_mailbox_messages_count (mbox, &total); - page_invalidate (0); - fprintf (ofile, _("New mail has arrived.\n")); - } - - rc = ml_readline (prompt); - - if (ml_got_interrupt ()) - { - util_error (_("Interrupt")); - continue; - } - - if (!rc && util_getenv (NULL, "ignoreeof", Mail_env_boolean, 0) == 0) - { - util_error (_("Use \"quit\" to quit.")); - continue; - } - - break; - } - return rc; -} - -static char *default_setup[] = { - "set noallnet", - "set noappend", - "set asksub", - "set crt", - "set noaskbcc", - "set askcc", - "set noautoprint", - "set nobang", - "set nocmd", - "set nodebug", - "set nodot", - "set escape=~", - "set noflipr", - "set nofolder", - "set header", - "set nohold", - "set noignore", - "set noignoreeof", - "set indentprefix=\"\t\"", - "set nokeep", - "set nokeepsave", - "set nometoo", - "set noonehop", - "set nooutfolder", - "set nopage", - "set prompt=\"? \"", - "set norecord", - "set save", - "set nosendmail", - "set nosendwait", - "set noshowto", - "set nosign", - "set noSign", - "set toplines=5", - "set autoinc", - "set regex", - "set replyprefix=\"Re: \"", - "set charset=auto", - "set xmailer", - "unfold subject", - "sender mail-followup-to reply-to from", - "set nocmd", - "set metamail", - "set recursivealiases", - "set noinplacealiases", - - /* Start in mail reading mode */ - "set mode=read", - "set noquit", - "set rc", - - "set noflipr", - "set noshowto", - "set nobang", +#ifdef HAVE_PATHS_H +#include <paths.h> +#endif - "set nullbody", /* Null message body is traditionally allowed */ - "set nullbodymsg=\"" N_("Null message body; hope that's ok") "\"", - - /* These settings are not yet used */ - "set nodebug", - "set noonehop", - "set nosendwait", -}; +#ifndef _PATH_MAILDIR +#define _PATH_MAILDIR "/var/spool/mail" +#endif int main (int argc, char **argv) { - char *mode = NULL, *prompt = NULL; - struct arguments args; - int i, rc; - - ofile = stdout; - set_cursor (1); - - /* Native Language Support */ - MU_APP_INIT_NLS (); - - /* Register the desired formats. */ - mu_register_all_formats (); - - interactive = isatty (fileno(stdin)); -#ifdef HAVE_SIGACTION - { - struct sigaction act; - act.sa_handler = SIG_IGN; - sigemptyset (&act.sa_mask); - act.sa_flags = 0; - sigaction (SIGPIPE, &act, NULL); - } -#else - signal (SIGPIPE, SIG_IGN); -#endif + char *foo, bar[80]; + int i = 0; + char c = 0; + char *mboxname; + mailbox *mbox; - /* set up the default environment */ - if (!getenv ("HOME")) + if (argc != 1) { - char *p = util_get_homedir (); - setenv ("HOME", p, 0); + fprintf (stderr, "Usage: %s\n", argv[0]); + return 1; } - /* Set up the default environment */ - setenv ("DEAD", util_fullpath("~/dead.letter"), 0); - setenv ("EDITOR", "ed", 0); - setenv ("LISTER", "ls", 0); - setenv ("MAILRC", util_fullpath("~/.mailrc"), 0); - setenv ("MBOX", util_fullpath("~/mbox"), 0); - setenv ("PAGER", "more", 0); - setenv ("SHELL", "sh", 0); - setenv ("VISUAL", "vi", 0); - setenv ("COLUMNS", "80", 0); - setenv ("LINES", "24", 0); - - /* set defaults for execution */ - for (i = 0; i < sizeof(default_setup)/sizeof(default_setup[0]); i++) - util_do_command (default_setup[i]); - util_do_command ("set screen=%d", util_getlines ()); - util_do_command ("set columns=%d", util_getcols ()); - - /* Set the default mailer to sendmail. */ - { - char *mailer_name = alloca (strlen ("sendmail:") - + strlen (_PATH_SENDMAIL) + 1); - sprintf (mailer_name, "sendmail:%s", _PATH_SENDMAIL); - util_setenv ("sendmail", mailer_name, Mail_env_string, 1); - } - - - args.args = NULL; - args.file = NULL; - args.user = NULL; - args.send_mode = 0; - - /* argument parsing */ -#ifdef WITH_TLS - mu_gocs_register ("tls", mu_tls_module_init); -#endif - mu_argp_init (program_version, NULL); - if (mu_app_init (&argp, mail_capa, NULL, argc, argv, 0, NULL, &args)) - exit (1); - - /* read system-wide mail.rc and user's .mailrc */ - if (util_getenv (NULL, "rc", Mail_env_boolean, 0) == 0) - util_do_command ("source %s", SITE_MAIL_RC); - util_do_command ("source %s", getenv ("MAILRC")); - - util_run_cached_commands (&command_list); - - if (!interactive) + mboxname = getenv ("MAIL"); + if (mboxname == NULL) { - util_do_command ("set nocrt"); - util_do_command ("set noasksub"); - util_do_command ("set noaskcc"); - util_do_command ("set noaskbcc"); + foo = getenv ("LOGNAME"); + mboxname = malloc ((strlen(foo) + strlen(_PATH_MAILDIR) + 2) * sizeof(char)); + strcpy (mboxname, _PATH_MAILDIR "/"); + strcat (mboxname, foo); + free (foo); } - /* how should we be running? */ - if (util_getenv (&mode, "mode", Mail_env_string, 1)) - exit (EXIT_FAILURE); - - /* Interactive mode */ - - ml_readline_init (); - mail_set_my_name(args.user); - - /* Mode is just sending */ - if (strcmp (mode, "send") == 0) - { - /* FIXME: set cmd to "mail [add1...]" */ - char *buf = NULL; - int num = 0; - int rc; - if (args.args != NULL) - while (args.args[num] != NULL) - num++; - mu_argcv_string (num, args.args, &buf); - rc = util_do_command ("mail %s", buf); - return util_getenv (NULL, "mailx", Mail_env_boolean, 0) ? rc : 0; - } - /* Or acting as a normal reader */ - else + mbox = mbox_open (mboxname); + printf ("Number of messages: %d\n", mbox->messages); + while (1) { - /* open the mailbox */ - if (args.file == NULL) - { - if (args.user) - { - char *p = xmalloc (strlen (args.user) + 2); - p[0] = '%'; - strcpy (p + 1, args.user); - rc = mu_mailbox_create_default (&mbox, p); - free (p); - } - else - rc = mu_mailbox_create_default (&mbox, NULL); - if (rc != 0) - { - util_error (_("Cannot create mailbox for %s: %s"), args.user, - mu_strerror (rc)); - exit (EXIT_FAILURE); - } - } - else if ((rc = mu_mailbox_create_default (&mbox, args.file)) != 0) + printf ("& "); + fflush (stdout); + fgets (bar, 80, stdin); + c = bar[0]; + if (c == 'd' || c == 'D' || c == 'b' || c == 'B' || c == 'h' || + c == 'H' || c == 'r' || c == 'R') { - util_error (_("Cannot create mailbox %s: %s"), args.file, - mu_strerror (rc)); - exit (EXIT_FAILURE); + printf ("# "); + fgets (bar, 80, stdin); } - - /* Could we enable this at runtime, via the a set environment? */ - if (0) + switch (c) { - mu_debug_t debug = NULL; - mu_mailbox_get_debug (mbox, &debug); - mu_debug_set_level (debug, MU_DEBUG_LEVEL_UPTO (MU_DEBUG_PROT)); - } - - if ((rc = mu_mailbox_open (mbox, MU_STREAM_RDWR|MU_STREAM_CREAT)) != 0) - { - mu_url_t url = NULL; - mu_mailbox_get_url (mbox, &url); - util_error (_("Cannot open mailbox %s: %s"), - mu_url_to_string (url), mu_strerror (rc)); - mu_mailbox_destroy (&mbox); - } - - if (rc) - total = 0; - else - { - if ((rc = mu_mailbox_scan (mbox, 1, &total)) != 0) - { - mu_url_t url = NULL; - mu_mailbox_get_url (mbox, &url); - util_error (_("Cannot read mailbox %s: %s"), - mu_url_to_string (url), mu_strerror (rc)); - exit (EXIT_FAILURE); - } - - if (strcmp (mode, "exist") == 0) - return (total < 1) ? 1 : 0; - else if (strcmp (mode, "print") == 0) - return util_do_command ("print *"); - else if (strcmp (mode, "headers") == 0) - return util_do_command ("from *"); - else if (strcmp (mode, "read")) - { - util_error(_("Unknown mode `%s'"), mode); - util_do_command ("quit"); - return 1; - } + case 'q': + case 'Q': + mbox_close (mbox); + return 0; + break; + case 'r': + case 'R': + foo = mbox_get_header (mbox, atoi (bar) - 1); + printf ("%s\n", foo); + free (foo); + foo = mbox_get_body (mbox, atoi (bar) - 1); + printf ("%s", foo); + free (foo); + break; + case 'h': + case 'H': + foo = mbox_get_header (mbox, atoi (bar) - 1); + printf ("%s", foo); + free (foo); + break; + case 'b': + case 'B': + foo = mbox_get_body (mbox, atoi (bar) - 1); + printf ("%s", foo); + free (foo); + break; + case 'd': + case 'D': + mbox_delete (mbox, atoi (bar) - 1); + break; + case 'x': + case 'X': + mbox_expunge (mbox); + break; + default: + break; } - - if (total == 0 - && (strcmp (mode, "read") - || util_getenv (NULL, "emptystart", Mail_env_boolean, 0))) - { - if (args.file) - fprintf (ofile, _("%s: 0 messages\n"), args.file); - else - fprintf (ofile, _("No mail for %s\n"), - args.user ? args.user : mail_whoami ()); - return 1; - } - - /* initial commands */ - if (util_getenv (NULL, "header", Mail_env_boolean, 0) == 0) - { - util_do_command ("summary"); - util_do_command ("z."); - } - - util_getenv (&prompt, "prompt", Mail_env_string, 0); - mail_mainloop (mail_cmdline, (void*) prompt, 1); - fprintf (ofile, "\n"); - util_do_command ("quit"); - return 0; } - /* We should never reach this point */ - return 1; } - - -void -mail_mainloop (char *(*input) (void *, int), - void *closure, int do_history) -{ - char *command, *cmd; - - while ((command = (*input)(closure, 0)) != NULL) - { - int len = strlen (command); - while (command[len-1] == '\\') - { - char *buf; - char *command2 = (*input) (closure, 1); - - if (!command2) - { - command[len-1] = 0; - break; - } - command[len-1] = '\0'; - buf = xmalloc ((len + strlen (command2)) * sizeof (char)); - strcpy (buf, command); - strcat (buf, command2); - free (command); - command = buf; - len = strlen (command); - } - cmd = util_stripwhite (command); - util_do_command ("%s", cmd); -#ifdef WITH_READLINE - if (do_history && !(isspace(cmd[0]) || cmd[0] == '#')) - add_history (cmd); -#endif - if (command) - free (command); - } -} - -int -mail_warranty (int argc MU_ARG_UNUSED, char **argv MU_ARG_UNUSED) -{ - fputs (_("GNU Mailutils -- a suite of utilities for electronic mail\n" - "Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,\n" - "2007 Free Software Foundation, Inc.\n\n"), - ofile); - fputs ( - _(" GNU Mailutils is free software; you can redistribute it and/or modify\n" - " it under the terms of the GNU General Public License as published by\n" - " the Free Software Foundation; either version 3 of the License, or\n" - " (at your option) any later version.\n" - "\n" - " GNU Mailutils is distributed in the hope that it will be useful,\n" - " but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - " MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - " GNU General Public License for more details.\n" - "\n" - " You should have received a copy of the GNU General Public License along\n" - " with GNU Mailutils; if not, write to the Free Software Foundation,\n" - " Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n" - "\n" - "\n" -), - ofile); - - return 0; -} - |