Commit d2682d58 d2682d584d54464d291bc74d71a2ad795d990359 by Sergey Poznyakoff

New option -t (compatible with sendmail).

Simplified the help message.
(main): Restructured.
1 parent d0cca271
1 /* GNU Mailutils -- a suite of utilities for electronic mail 1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc. 2 Copyright (C) 1999, 2000, 2001, 2002, 2004 Free Software Foundation, Inc.
3 3
4 GNU Mailutils is free software; you can redistribute it and/or modify 4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by 5 it under the terms of the GNU General Public License as published by
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
38 #include <mailutils/message.h> 38 #include <mailutils/message.h>
39 #include <mailutils/registrar.h> 39 #include <mailutils/registrar.h>
40 #include <mailutils/stream.h> 40 #include <mailutils/stream.h>
41 #include <mailutils/property.h>
41 #include <mailutils/error.h> 42 #include <mailutils/error.h>
42 #include <mailutils/nls.h> 43 #include <mailutils/nls.h>
43 44
...@@ -47,42 +48,38 @@ static char doc[] = ...@@ -47,42 +48,38 @@ static char doc[] =
47 in this message */ 48 in this message */
48 N_("GNU mail.remote -- pseudo-sendmail interface for mail delivery\n\ 49 N_("GNU mail.remote -- pseudo-sendmail interface for mail delivery\n\
49 \v\ 50 \v\
51 This is a simple drop-in replacement for sendmail to forward mail directly\n\
52 to an SMTP gateway.\n\
53 You should always specify your SMTP gateway using --mailer option\n\
54 (the best place to do so is in your configuration file).\n\
50 \n\ 55 \n\
51 An RFC2822 formatted message is read from stdin and delivered using\n\ 56 Examples:\n\
52 the mailer. This utility can be used as a drop-in replacement\n\
53 for /bin/sendmail to forward mail directly to an SMTP gateway.\n\
54 \n\ 57 \n\
55 The default mailer is \"sendmail:\", which is not supported by this\n\ 58 Deliver mail via SMTP gateway at \"mail.example.com\", reading its\n\
56 utility (it is intended to be used when you don't have a working\n\ 59 contents for recipients of the message.\n\
57 sendmail). You should specify your SMTP gateway by specifying\n\
58 a --mailer as something like \"smtp://mail.example.com\". This would\n\
59 normally be added to your user-specific configuration file,\n\
60 ~/.mailutils/mailutils,\n\
61 or the global configuration file,\n\
62 /etc/mailutils.rc,\n\
63 with a line such as:\n\
64 :mailer --mailer=smtp://mail.example.com\n\
65 \n\ 60 \n\
66 If not explicitly specified, the default from address is derived from the\n\ 61 mail.remote --mailer smtp://mail.example.com\n\
67 \"From:\" field in the message, if present, or the default user's email\n\
68 address if not present.\n\
69 \n\ 62 \n\
70 If not explicitly specified, the default to addresses are derived from the\n\ 63 Deliver mail only to \"devnull@foo.bar\"\n\
71 \"To:\", \"Cc:\", and \"Bcc:\" fields in the message.\n\
72 \n\ 64 \n\
73 If --debug is specified, the envelope commands in the SMTP protocol\n\ 65 mail.remote --mailer smtp://mail.example.com devnull@foo.bar\n\
74 transaction will be printed to stdout. If specified more than once,\n\ 66 \n\
75 the data part of the protocol transaction will also be printed to stdout.\n"); 67 Deliver mail to \"devnull@foo.bar\" as well as to the recipients\n\
68 specified in the message itself:\n\
69 \n\
70 mail.remote --mailer smtp://mail.example.com -t devnull@foo.bar\n");
76 71
77 static struct argp_option options[] = { 72 static struct argp_option options[] = {
78 {"from", 'f', N_("ADDR"), 0, N_("Override the default from address")}, 73 {"from", 'f', N_("ADDR"), 0, N_("Override the default from address")},
79 {"debug", 'd', NULL, 0, N_("Enable debugging output")}, 74 {"read-recipients", 't', NULL, 0, N_("Read message for recipients.") },
80 { 0, 'o', "OPT", OPTION_HIDDEN, N_("Ignored for sendmail compatibility")}, 75 {"debug", 'd', NULL, 0, N_("Print envelope commands in the SMTP protocol transaction. If specified more than once, the data part of the protocol transaction will also be printed.")},
81 {0} 76 { NULL, 'o', N_("OPT"), 0, N_("Ignored for sendmail compatibility")},
77 { NULL }
82 }; 78 };
83 79
84 static int optdebug; 80 static int optdebug;
85 static const char* optfrom; 81 static const char *optfrom;
82 static int read_recipients; /* Read recipients from the message */
86 83
87 static error_t 84 static error_t
88 parse_opt (int key, char *arg, struct argp_state *state) 85 parse_opt (int key, char *arg, struct argp_state *state)
...@@ -100,6 +97,10 @@ parse_opt (int key, char *arg, struct argp_state *state) ...@@ -100,6 +97,10 @@ parse_opt (int key, char *arg, struct argp_state *state)
100 case 'o': 97 case 'o':
101 break; 98 break;
102 99
100 case 't':
101 read_recipients = 1;
102 break;
103
103 default: 104 default:
104 return ARGP_ERR_UNKNOWN; 105 return ARGP_ERR_UNKNOWN;
105 } 106 }
...@@ -121,17 +122,29 @@ static const char *capa[] = { ...@@ -121,17 +122,29 @@ static const char *capa[] = {
121 NULL 122 NULL
122 }; 123 };
123 124
125 mailer_t mailer; /* Mailer object */
126 address_t from; /* Sender address */
127 address_t to; /* Recipient addresses */
128 stream_t in; /* Input stream */
129
130 void
131 mr_exit (int status)
132 {
133 address_destroy (&from);
134 address_destroy (&to);
135 stream_destroy (&in, NULL);
136 mailer_destroy (&mailer);
137
138 exit (status ? 1 : 0);
139 }
140
124 int 141 int
125 main (int argc, char **argv) 142 main (int argc, char **argv)
126 { 143 {
127 int status = 0; 144 int status = 0;
128 int optind = 0; 145 int optind = 0;
129 146
130 stream_t in = 0;
131 message_t msg = 0; 147 message_t msg = 0;
132 mailer_t mailer = 0;
133 address_t from = 0;
134 address_t to = 0;
135 148
136 int mailer_flags = 0; 149 int mailer_flags = 0;
137 150
...@@ -154,44 +167,42 @@ main (int argc, char **argv) ...@@ -154,44 +167,42 @@ main (int argc, char **argv)
154 { 167 {
155 mu_error (_("Parsing from addresses failed: %s"), 168 mu_error (_("Parsing from addresses failed: %s"),
156 mu_strerror (status)); 169 mu_strerror (status));
157 goto end; 170 mr_exit (status);
158 } 171 }
159 } 172 }
160 173
161 if (argv[optind]) 174 if (argv[optind])
162 { 175 {
163 char **av = argv + optind; 176 if ((status = address_createv (&to, (const char **) (argv + optind), -1)))
164
165 if ((status = address_createv (&to, (const char **) av, -1)))
166 { 177 {
167 mu_error (_("Parsing to addresses failed: %s"), 178 mu_error (_("Parsing recipient addresses failed: %s"),
168 mu_strerror (status)); 179 mu_strerror (status));
169 goto end; 180 mr_exit (status);
170 } 181 }
171 } 182 }
172 183
173 if ((status = stdio_stream_create (&in, stdin, MU_STREAM_SEEKABLE))) 184 if ((status = stdio_stream_create (&in, stdin, MU_STREAM_SEEKABLE)))
174 { 185 {
175 mu_error (_("Failed: %s"), mu_strerror (status)); 186 mu_error (_("Failed: %s"), mu_strerror (status));
176 goto end; 187 mr_exit (status);
177 } 188 }
178 189
179 if ((status = stream_open (in))) 190 if ((status = stream_open (in)))
180 { 191 {
181 mu_error (_("Opening stdin failed: %s"), mu_strerror (status)); 192 mu_error (_("Opening stdin failed: %s"), mu_strerror (status));
182 goto end; 193 mr_exit (status);
183 } 194 }
184 195
185 if ((status = message_create (&msg, NULL))) 196 if ((status = message_create (&msg, NULL)))
186 { 197 {
187 mu_error (_("Failed: %s"), mu_strerror (status)); 198 mu_error (_("Failed: %s"), mu_strerror (status));
188 goto end; 199 mr_exit (status);
189 } 200 }
190 201
191 if ((status = message_set_stream (msg, in, NULL))) 202 if ((status = message_set_stream (msg, in, NULL)))
192 { 203 {
193 mu_error (_("Failed: %s"), mu_strerror (status)); 204 mu_error (_("Failed: %s"), mu_strerror (status));
194 goto end; 205 mr_exit (status);
195 } 206 }
196 207
197 if ((status = mailer_create (&mailer, NULL))) 208 if ((status = mailer_create (&mailer, NULL)))
...@@ -200,7 +211,7 @@ main (int argc, char **argv) ...@@ -200,7 +211,7 @@ main (int argc, char **argv)
200 mailer_get_url_default (&url); 211 mailer_get_url_default (&url);
201 mu_error (_("Creating mailer '%s' failed: %s"), 212 mu_error (_("Creating mailer '%s' failed: %s"),
202 url, mu_strerror (status)); 213 url, mu_strerror (status));
203 goto end; 214 mr_exit (status);
204 } 215 }
205 216
206 if (optdebug) 217 if (optdebug)
...@@ -213,33 +224,35 @@ main (int argc, char **argv) ...@@ -213,33 +224,35 @@ main (int argc, char **argv)
213 mailer_flags = MAILER_FLAG_DEBUG_DATA; 224 mailer_flags = MAILER_FLAG_DEBUG_DATA;
214 } 225 }
215 226
227 if (read_recipients)
228 {
229 property_t property = NULL;
230
231 mailer_get_property (mailer, &property);
232 property_set_value (property, "READ_RECIPIENTS", "true", 1);
233 }
234
216 if ((status = mailer_open (mailer, mailer_flags))) 235 if ((status = mailer_open (mailer, mailer_flags)))
217 { 236 {
218 const char *url = NULL; 237 const char *url = NULL;
219 mailer_get_url_default (&url); 238 mailer_get_url_default (&url);
220 mu_error (_("Opening mailer '%s' failed: %s"), 239 mu_error (_("Opening mailer '%s' failed: %s"),
221 url, mu_strerror (status)); 240 url, mu_strerror (status));
222 goto end; 241 mr_exit (status);
223 } 242 }
224 243
225 if ((status = mailer_send_message (mailer, msg, from, to))) 244 if ((status = mailer_send_message (mailer, msg, from, to)))
226 { 245 {
227 mu_error (_("Sending message failed: %s"), mu_strerror (status)); 246 mu_error (_("Sending message failed: %s"), mu_strerror (status));
228 goto end; 247 mr_exit (status);
229 } 248 }
230 249
231 if ((status = mailer_close (mailer))) 250 if ((status = mailer_close (mailer)))
232 { 251 {
233 mu_error (_("Closing mailer failed: %s"), mu_strerror (status)); 252 mu_error (_("Closing mailer failed: %s"), mu_strerror (status));
234 goto end; 253 mr_exit (status);
235 } 254 }
236 255
237 end: 256 mr_exit (status);
238
239 address_destroy (&from);
240 address_destroy (&to);
241 stream_destroy (&in, NULL);
242 mailer_destroy (&mailer);
243
244 return status ? 1 : 0;
245 } 257 }
258
......