/* GNU mailutils - a suite of utilities for electronic mail Copyright (C) 2002 Free Software Foundation, Inc. This program 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* MH reply command */ #include const char *argp_program_version = "reply (" PACKAGE_STRING ")"; static char doc[] = "GNU MH reply"; static char args_doc[] = "[+folder] [msg]"; #define ARG_NOEDIT 1 #define ARG_FCC 2 #define ARG_FILTER 3 #define ARG_INPLACE 4 #define ARG_QUERY 5 #define ARG_WHATNOWPROC 6 #define ARG_NOWHATNOWPROC 7 #define ARG_NODRAFTFOLDER 8 /* GNU options */ static struct argp_option options[] = { {"annotate", 'a', "BOOL", OPTION_ARG_OPTIONAL, "Add Replied: header to the message being replied to"}, {"draftfolder", 'd', "FOLDER", 0, "Invoke the draftfolder facility"}, {"draftmessage" , 'm', "MSG", 0, "Invoke the draftmessage facility"}, {"cc", 'c', "{all|to|cc|me}", 0, "Specify whom to place on the Cc: list of the reply"}, {"nocc", 'n', "{all|to|cc|me}", 0, "Specify whom to remove from the Cc: list of the reply"}, {"folder", 'f', "FOLDER", 0, "Specify folder to operate upon"}, {"editor", 'e', "PROG", 0, "Set the editor program to use"}, {"noedit", ARG_NOEDIT, 0, 0, "Suppress the initial edit"}, {"fcc", ARG_FCC, "FOLDER", 0, "Set the folder to receive Fcc's."}, {"filter", ARG_FILTER, "PROG", 0, "Set the filter program to preprocess the body of the message being replied"}, {"form", 'F', "FILE", 0, "Read format from given file"}, {"inplace", ARG_INPLACE, "BOOL", 0, "Annotate the message in place"}, {"query", ARG_QUERY, "BOOL", 0, "Query for addresses to place in To: and Cc: lists"}, {"width", 'w', "NUMBER", 0, "Set output width"}, {"whatnowproc", ARG_WHATNOWPROC, "PROG", 0, "Set the relacement for whatnow program"}, { "\nUse -help switch to obtain the list of traditional MH options. ", 0, 0, OPTION_DOC, "" }, { 0 } }; /* Traditional MH options */ struct mh_option mh_option[] = { {"annotate", 1, 'a', MH_OPT_BOOL }, {"cc", 1, 'c', MH_OPT_ARG, "all/to/cc/me"}, {"nocc", 3, 'n', MH_OPT_ARG, "all/to/cc/me"}, {"form", 4, 'F', MH_OPT_ARG, "formatfile"}, {"width", 1, 'w', MH_OPT_ARG, "number"}, {"draftfolder", 6, 'd', MH_OPT_ARG, "folder"}, {"nodraftfolder", 3, ARG_NODRAFTFOLDER, }, {"editor", 1, 'e', MH_OPT_ARG, "program"}, {"noedit", 3, ARG_NOEDIT, }, {"fcc", 1, ARG_FCC, MH_OPT_ARG, "folder"}, {"filter", 2, ARG_FILTER, MH_OPT_ARG, "program"}, {"inplace", 1, ARG_INPLACE, MH_OPT_BOOL }, {"query", 1, ARG_QUERY, MH_OPT_BOOL }, {"whatnowproc", 2, ARG_WHATNOWPROC, MH_OPT_ARG, "program"}, {"nowhatnowproc", 3, ARG_NOWHATNOWPROC }, { 0 } }; static char *format_str = "%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)" "%<(nonnull)%(void(width))%(putaddr To: )\\n%>" "%(lit)%(formataddr{to})%(formataddr{cc})%(formataddr(me))" "%<(nonnull)%(void(width))%(putaddr cc: )\\n%>" "%<{fcc}Fcc: %{fcc}\\n%>" "%<{subject}Subject: Re: %{subject}\\n%>" "%<{date}In-reply-to: Your message of \"" "%<(nodate{date})%{date}%|%(pretty{date})%>.\"%<{message-id}\n" " %{message-id}%>\\n%>" "--------\n"; static mh_format_t format; static int width = 80; static char *draft_file; static mh_msgset_t msgset; static mailbox_t mbox; static int opt_handler (int key, char *arg, void *unused) { switch (key) { case '+': case 'f': current_folder = arg; break; case 'F': mh_read_formfile (arg, &format_str); break; case 'w': width = strtoul (arg, NULL, 0); if (!width) { mh_error ("Invalid width"); exit (1); } break; case 'a': case 'd': case 'm': case 'c': case 'n': case 'e': case ARG_NOEDIT: case ARG_FCC: case ARG_FILTER: case ARG_INPLACE: case ARG_QUERY: case ARG_WHATNOWPROC: mh_error ("option is not yet implemented"); exit (1); default: return 1; } return 0; } void make_draft () { int rc; message_t msg; FILE *fp; char buffer[1024]; #define bufsize sizeof(buffer) /* FIXME: first check if the draft exists */ fp = fopen (draft_file, "w+"); if (!fp) { mh_error ("cannot open draft file %s: %s", draft_file, strerror (errno)); exit (1); } rc = mailbox_get_message (mbox, msgset.list[0], &msg); if (rc) { mh_error ("cannot read message %lu: %s", (unsigned long) msgset.list[0], mu_errstring (rc)); exit (1); } mh_format (&format, msg, msgset.list[0], buffer, bufsize); fprintf (fp, "%s", buffer); fclose (fp); } int main (int argc, char **argv) { int index; mh_argp_parse (argc, argv, options, mh_option, args_doc, doc, opt_handler, NULL, &index); if (mh_format_parse (format_str, &format)) { mh_error ("Bad format string"); exit (1); } mbox = mh_open_folder (current_folder, 0); mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur"); if (msgset.count != 1) { mh_error ("only one message at a time!"); return 1; } draft_file = mh_expand_name ("draft", 0); make_draft (); return 0; }