Commit 66d125c5 66d125c5f475decd9b13315e0da56c61552039e8 by Sergey Poznyakoff

New file. A framework for the `repl' program.

1 parent 0325fad4
Showing 1 changed file with 203 additions and 0 deletions
1 /* GNU mailutils - a suite of utilities for electronic mail
2 Copyright (C) 2002 Free Software Foundation, Inc.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18 /* MH reply command */
19
20 #include <mh.h>
21
22 const char *argp_program_version = "reply (" PACKAGE_STRING ")";
23 static char doc[] = "GNU MH reply";
24 static char args_doc[] = "[+folder] [msg]";
25
26 #define ARG_NOEDIT 1
27 #define ARG_FCC 2
28 #define ARG_FILTER 3
29 #define ARG_INPLACE 4
30 #define ARG_QUERY 5
31 #define ARG_WHATNOWPROC 6
32 #define ARG_NOWHATNOWPROC 7
33 #define ARG_NODRAFTFOLDER 8
34
35 /* GNU options */
36 static struct argp_option options[] = {
37 {"annotate", 'a', "BOOL", OPTION_ARG_OPTIONAL,
38 "Add Replied: header to the message being replied to"},
39 {"draftfolder", 'd', "FOLDER", 0,
40 "Invoke the draftfolder facility"},
41 {"draftmessage" , 'm', "MSG", 0,
42 "Invoke the draftmessage facility"},
43 {"cc", 'c', "{all|to|cc|me}", 0,
44 "Specify whom to place on the Cc: list of the reply"},
45 {"nocc", 'n', "{all|to|cc|me}", 0,
46 "Specify whom to remove from the Cc: list of the reply"},
47 {"folder", 'f', "FOLDER", 0, "Specify folder to operate upon"},
48 {"editor", 'e', "PROG", 0, "Set the editor program to use"},
49 {"noedit", ARG_NOEDIT, 0, 0, "Suppress the initial edit"},
50 {"fcc", ARG_FCC, "FOLDER", 0, "Set the folder to receive Fcc's."},
51 {"filter", ARG_FILTER, "PROG", 0,
52 "Set the filter program to preprocess the body of the message being replied"},
53 {"form", 'F', "FILE", 0, "Read format from given file"},
54 {"inplace", ARG_INPLACE, "BOOL", 0, "Annotate the message in place"},
55 {"query", ARG_QUERY, "BOOL", 0, "Query for addresses to place in To: and Cc: lists"},
56 {"width", 'w', "NUMBER", 0, "Set output width"},
57 {"whatnowproc", ARG_WHATNOWPROC, "PROG", 0,
58 "Set the relacement for whatnow program"},
59 { "\nUse -help switch to obtain the list of traditional MH options. ", 0, 0, OPTION_DOC, "" },
60 { 0 }
61 };
62
63 /* Traditional MH options */
64 struct mh_option mh_option[] = {
65 {"annotate", 1, 'a', MH_OPT_BOOL },
66 {"cc", 1, 'c', MH_OPT_ARG, "all/to/cc/me"},
67 {"nocc", 3, 'n', MH_OPT_ARG, "all/to/cc/me"},
68 {"form", 4, 'F', MH_OPT_ARG, "formatfile"},
69 {"width", 1, 'w', MH_OPT_ARG, "number"},
70 {"draftfolder", 6, 'd', MH_OPT_ARG, "folder"},
71 {"nodraftfolder", 3, ARG_NODRAFTFOLDER, },
72 {"editor", 1, 'e', MH_OPT_ARG, "program"},
73 {"noedit", 3, ARG_NOEDIT, },
74 {"fcc", 1, ARG_FCC, MH_OPT_ARG, "folder"},
75 {"filter", 2, ARG_FILTER, MH_OPT_ARG, "program"},
76 {"inplace", 1, ARG_INPLACE, MH_OPT_BOOL },
77 {"query", 1, ARG_QUERY, MH_OPT_BOOL },
78 {"whatnowproc", 2, ARG_WHATNOWPROC, MH_OPT_ARG, "program"},
79 {"nowhatnowproc", 3, ARG_NOWHATNOWPROC },
80 { 0 }
81 };
82
83 static char *format_str =
84 "%(lit)%(formataddr %<{reply-to}%?{from}%?{sender}%?{return-path}%>)"
85 "%<(nonnull)%(void(width))%(putaddr To: )\\n%>"
86 "%(lit)%(formataddr{to})%(formataddr{cc})%(formataddr(me))"
87 "%<(nonnull)%(void(width))%(putaddr cc: )\\n%>"
88 "%<{fcc}Fcc: %{fcc}\\n%>"
89 "%<{subject}Subject: Re: %{subject}\\n%>"
90 "%<{date}In-reply-to: Your message of \""
91 "%<(nodate{date})%{date}%|%(pretty{date})%>.\"%<{message-id}\n"
92 " %{message-id}%>\\n%>"
93 "--------\n";
94
95 static mh_format_t format;
96 static int width = 80;
97 static char *draft_file;
98 static mh_msgset_t msgset;
99 static mailbox_t mbox;
100
101 static int
102 opt_handler (int key, char *arg, void *unused)
103 {
104 switch (key)
105 {
106 case '+':
107 case 'f':
108 current_folder = arg;
109 break;
110
111 case 'F':
112 mh_read_formfile (arg, &format_str);
113 break;
114
115 case 'w':
116 width = strtoul (arg, NULL, 0);
117 if (!width)
118 {
119 mh_error ("Invalid width");
120 exit (1);
121 }
122 break;
123
124 case 'a':
125 case 'd':
126 case 'm':
127 case 'c':
128 case 'n':
129 case 'e':
130 case ARG_NOEDIT:
131 case ARG_FCC:
132 case ARG_FILTER:
133 case ARG_INPLACE:
134 case ARG_QUERY:
135 case ARG_WHATNOWPROC:
136 mh_error ("option is not yet implemented");
137 exit (1);
138
139 default:
140 return 1;
141 }
142 return 0;
143 }
144
145 void
146 make_draft ()
147 {
148 int rc;
149 message_t msg;
150 FILE *fp;
151 char buffer[1024];
152 #define bufsize sizeof(buffer)
153
154 /* FIXME: first check if the draft exists */
155 fp = fopen (draft_file, "w+");
156 if (!fp)
157 {
158 mh_error ("cannot open draft file %s: %s",
159 draft_file, strerror (errno));
160 exit (1);
161 }
162
163 rc = mailbox_get_message (mbox, msgset.list[0], &msg);
164 if (rc)
165 {
166 mh_error ("cannot read message %lu: %s",
167 (unsigned long) msgset.list[0],
168 mu_errstring (rc));
169 exit (1);
170 }
171
172 mh_format (&format, msg, msgset.list[0], buffer, bufsize);
173 fprintf (fp, "%s", buffer);
174 fclose (fp);
175 }
176
177 int
178 main (int argc, char **argv)
179 {
180 int index;
181
182 mh_argp_parse (argc, argv, options, mh_option, args_doc, doc,
183 opt_handler, NULL, &index);
184 if (mh_format_parse (format_str, &format))
185 {
186 mh_error ("Bad format string");
187 exit (1);
188 }
189
190 mbox = mh_open_folder (current_folder, 0);
191 mh_msgset_parse (mbox, &msgset, argc - index, argv + index, "cur");
192 if (msgset.count != 1)
193 {
194 mh_error ("only one message at a time!");
195 return 1;
196 }
197
198 draft_file = mh_expand_name ("draft", 0);
199
200 make_draft ();
201
202 return 0;
203 }