summaryrefslogtreecommitdiff
path: root/mail
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2012-07-19 08:31:14 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2012-07-19 08:43:48 +0300
commit62e22dcc8419437e03225ae55223aaf97227b1e1 (patch)
treeb4ca558c2b90155199f0db98c4206d98390858ca /mail
parent8ad474712f6758cdff637c5391867706957dfd74 (diff)
downloadmailutils-62e22dcc8419437e03225ae55223aaf97227b1e1.tar.gz
mailutils-62e22dcc8419437e03225ae55223aaf97227b1e1.tar.bz2
mail: provide mechanism for listing and editing attachments from the shell
* NEWS: Update. * mail/escape.c (escape_check_args): Take two additional arguments specifying minimum and maximum number of parameters to expect. All uses updated. Remove static qualifier. * mail/mail.h (send_attach_file): Rename to send_attach_file_default (escape_check_args,escape_list_attachments) (escape_attach,escape_remove_attachment): New protos. * mail/send.c (send_attach_file): Take encoding and content type as arguments. (send_attach_file_default): New function. (escape_list_attachments) (escape_attach,escape_remove_attachment): New functions. * mail/table.c: New escapes: l, +, ^ * include/mailutils/list.h (mu_list_remove_nth) (mu_list_remove_nth_nd): New protos. * libmailutils/list/Makefile.am (liblist_la_SOURCES): Add removenth.c * libmailutils/list/removenth.c: New file.
Diffstat (limited to 'mail')
-rw-r--r--mail/escape.c35
-rw-r--r--mail/mail.c2
-rw-r--r--mail/mail.h9
-rw-r--r--mail/send.c102
-rw-r--r--mail/table.c3
5 files changed, 134 insertions, 17 deletions
diff --git a/mail/escape.c b/mail/escape.c
index c0c0dcb03..c1ec44812 100644
--- a/mail/escape.c
+++ b/mail/escape.c
@@ -156,16 +156,29 @@ escape_continue (void)
mu_printf (_("(continue)\n"));
}
-static int
-escape_check_args (int argc, char **argv)
+int
+escape_check_args (int argc, char **argv, int minargs, int maxargs)
{
- if (argc == 1)
+ char *escape = "~";
+ if (argc < minargs)
{
- char *escape = "~";
+ minargs--;
mailvar_get (&escape, "escape", mailvar_type_string, 0);
- mu_error (_("%c%s requires an argument"), escape[0], argv[0]);
+ mu_error (ngettext ("%c%s requires at least %d argument",
+ "%c%s requires at least %d arguments",
+ minargs), escape[0], argv[0], minargs);
return 1;
}
+ if (maxargs > 1 && argc > maxargs)
+ {
+ maxargs--;
+ mailvar_get (&escape, "escape", mailvar_type_string, 0);
+ mu_error (ngettext ("%c%s accepts at most %d argument",
+ "%c%s accepts at most %d arguments",
+ maxargs), escape[0], argv[0], maxargs);
+ return 1;
+ }
+
return 0;
}
@@ -184,7 +197,7 @@ escape_command (int argc, char **argv, compose_env_t *env)
const struct mail_command_entry *entry;
int status;
- if (escape_check_args (argc, argv))
+ if (escape_check_args (argc, argv, 2, 2))
return 1;
if (argv[1][0] == '#')
return 0;
@@ -416,6 +429,8 @@ escape_editor (int argc, char **argv, compose_env_t *env)
return escape_run_editor (getenv ("EDITOR"), argc, argv, env);
}
+/* ~l -- escape_list_attachments (send.c) */
+
/* ~v */
int
escape_visual (int argc, char **argv, compose_env_t *env)
@@ -457,7 +472,7 @@ escape_headers (int argc, char **argv, compose_env_t *env)
int
escape_insert (int argc, char **argv, compose_env_t *env)
{
- if (escape_check_args (argc, argv))
+ if (escape_check_args (argc, argv, 2, 2))
return 1;
mailvar_variable_format (env->compstr, mailvar_find_variable (argv[1], 0),
NULL);
@@ -574,7 +589,7 @@ escape_read (int argc, char **argv, compose_env_t *env MU_ARG_UNUSED)
mu_stream_t instr;
int rc;
- if (escape_check_args (argc, argv))
+ if (escape_check_args (argc, argv, 2, 2))
return 1;
filename = util_fullpath (argv[1]);
@@ -597,7 +612,7 @@ int
escape_subj (int argc, char **argv, compose_env_t *env)
{
char *buf;
- if (escape_check_args (argc, argv))
+ if (escape_check_args (argc, argv, 2, 2))
return 1;
mu_argcv_string (argc - 1, argv + 1, &buf);
compose_header_set (env, MU_HEADER_SUBJECT, buf, COMPOSE_REPLACE);
@@ -623,7 +638,7 @@ escape_write (int argc, char **argv, compose_env_t *env)
int rc;
mu_off_t size;
- if (escape_check_args (argc, argv))
+ if (escape_check_args (argc, argv, 2, 2))
return 1;
filename = util_fullpath (argv[1]);
/* FIXME: check for existence first */
diff --git a/mail/mail.c b/mail/mail.c
index e2eb63d6b..400bb0c2d 100644
--- a/mail/mail.c
+++ b/mail/mail.c
@@ -95,7 +95,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'A':
args->hint |= HINT_SEND_MODE;
- if (send_attach_file (arg))
+ if (send_attach_file_default (arg))
exit (1);
break;
diff --git a/mail/mail.h b/mail/mail.h
index c116b1b83..c754dfd3d 100644
--- a/mail/mail.h
+++ b/mail/mail.h
@@ -258,7 +258,9 @@ extern char *mail_expand_name (const char *name);
extern void send_append_header (char *text);
extern void send_append_header2 (char *name, char *value, int mode);
-extern int send_attach_file (const char *name);
+extern int send_attach_file_default (const char *name);
+
+extern int escape_check_args (int argc, char **argv, int minargs, int maxargs);
extern int escape_shell (int argc, char **argv, compose_env_t *env);
extern int escape_command (int argc, char **argv, compose_env_t *env);
@@ -280,6 +282,11 @@ extern int escape_visual (int argc, char **argv, compose_env_t *env);
extern int escape_write (int argc, char **argv, compose_env_t *env);
extern int escape_exit (int argc, char **argv, compose_env_t *env);
extern int escape_pipe (int argc, char **argv, compose_env_t *env);
+extern int escape_list_attachments (int argc, char **argv,
+ compose_env_t *env);
+extern int escape_attach (int argc, char **argv, compose_env_t *env);
+extern int escape_remove_attachment (int argc, char **argv,
+ compose_env_t *env);
/* Cursor */
extern void set_cursor (unsigned value);
diff --git a/mail/send.c b/mail/send.c
index 3b8d446f8..053a28979 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -154,11 +154,13 @@ atchinfo_free (void *p)
}
int
-send_attach_file (const char *name)
+send_attach_file (const char *name,
+ const char *content_type, const char *encoding)
{
int rc;
struct stat st;
struct atchinfo *aptr;
+ mu_list_t list;
if (stat (name, &st))
{
@@ -180,6 +182,16 @@ send_attach_file (const char *name)
return 1;
}
+ if (!encoding)
+ encoding = "base64";
+ mu_filter_get_list (&list);
+ rc = mu_list_locate (list, encoding, NULL);
+ if (rc)
+ {
+ mu_error (_("unsupported encoding: %s"), encoding);
+ return 1;
+ }
+
if (!attlist)
{
rc = mu_list_create (&attlist);
@@ -191,10 +203,10 @@ send_attach_file (const char *name)
mu_list_set_destroy_item (attlist, atchinfo_free);
}
aptr = mu_alloc (sizeof (*aptr));
- aptr->encoding = mu_strdup (default_encoding ?
- default_encoding : "base64");
- aptr->content_type = mu_strdup (default_content_type ?
- default_content_type :
+
+ aptr->encoding = mu_strdup (encoding);
+ aptr->content_type = mu_strdup (content_type ?
+ content_type :
"application/octet-stream");
aptr->filename = mu_strdup (name);
rc = mu_list_append (attlist, aptr);
@@ -206,6 +218,86 @@ send_attach_file (const char *name)
return 0;
}
+int
+send_attach_file_default (const char *name)
+{
+ return send_attach_file (name, default_content_type, default_encoding);
+}
+
+int
+escape_list_attachments (int argc, char **argv, compose_env_t *env)
+{
+ mu_iterator_t itr;
+ int i;
+
+ if (mu_list_is_empty (attlist) ||
+ mu_list_get_iterator (attlist, &itr))
+ {
+ mu_printf ("%s\n", _("No attachments"));
+ return 0;
+ }
+
+ for (mu_iterator_first (itr), i = 1; !mu_iterator_is_done (itr);
+ mu_iterator_next (itr), i++)
+ {
+ struct atchinfo *aptr;
+ if (mu_iterator_current (itr, (void**)&aptr))
+ continue;
+
+ mu_printf ("%3d %-12s %-30s %-s\n",
+ i, aptr->filename, aptr->content_type, aptr->encoding);
+ }
+ mu_iterator_destroy (&itr);
+
+ return 0;
+}
+
+int
+escape_attach (int argc, char **argv, compose_env_t *env)
+{
+ const char *encoding = default_encoding;
+ const char *content_type = default_content_type;
+
+ switch (argc)
+ {
+ case 4:
+ encoding = argv[3];
+ case 3:
+ content_type = argv[2];
+ case 2:
+ return send_attach_file (argv[1], content_type, encoding);
+ default:
+ return escape_check_args (argc, argv, 2, 4);
+ }
+ return 1;
+}
+
+int
+escape_remove_attachment (int argc, char **argv, compose_env_t *env)
+{
+ size_t count;
+ unsigned long n;
+ char *p;
+
+ if (escape_check_args (argc, argv, 2, 2))
+ return 1;
+ n = strtoul (argv[1], &p, 10);
+ if (*p)
+ {
+ mu_error (_("not a valid number: %s"), argv[1]);
+ return 1;
+ }
+
+ mu_list_count (attlist, &count);
+ if (n == 0 || n > count)
+ {
+ mu_error (_("index out of range"));
+ return 1;
+ }
+
+ return mu_list_remove_nth (attlist, n - 1);
+}
+
static int
saveatt (void *item, void *data)
{
diff --git a/mail/table.c b/mail/table.c
index 41eda1dcd..a49661204 100644
--- a/mail/table.c
+++ b/mail/table.c
@@ -226,6 +226,8 @@ static const struct mail_escape_entry mail_escape_table[] = {
{"!", "!", "![shell-command]", escape_shell },
{":", ":", ":[mail-command]", escape_command },
{"-", "-", "-[mail-command]", escape_command },
+ {"+", "+", "+[name [content-type [encoding]]]", escape_attach },
+ {"^", "^", "^[N]", escape_remove_attachment },
{"?", "?", "?", escape_help },
{"A", "A", "A", escape_sign },
{"a", "a", "a", escape_sign },
@@ -237,6 +239,7 @@ static const struct mail_escape_entry mail_escape_table[] = {
{"F", "F", "F[mesg-list]", escape_print },
{"h", "h", "h", escape_headers },
{"i", "i", "i[var-name]", escape_insert },
+ {"l", "l", "l", escape_list_attachments },
{"m", "m", "m[mesg-list]", escape_quote },
{"M", "M", "M[mesg-list]", escape_quote },
{"p", "p", "p", escape_type_input },

Return to:

Send suggestions and report system problems to the System administrator.