comsat: Use mu streams instead of stdio
* comsat/action.c (action_beep, echo_string) (action_echo, action_exec): Take mu_stream_t as first argument. (open_rc): Take mu_stream_t as tty, return mu_stream_t as well. Install the linecon filter. (run_user_action): Take mu_stream_t as first arg. Pass it to all invoked actions. * comsat/comsat.c (get_newline_str): Remove. (need_crlf): New function. (notify_user): Use mu_stream_t instead of FILE. Install a 7bit filter and CRLF filter (if the device requires it). * comsat/comsat.h: Include mailutils/filter.h. (run_user_action): Change signature.
Showing
3 changed files
with
103 additions
and
78 deletions
... | @@ -17,7 +17,7 @@ | ... | @@ -17,7 +17,7 @@ |
17 | 17 | ||
18 | #include "comsat.h" | 18 | #include "comsat.h" |
19 | #include <mailutils/io.h> | 19 | #include <mailutils/io.h> |
20 | #include <mailutils/filter.h> | 20 | #include <mailutils/argcv.h> |
21 | #define obstack_chunk_alloc malloc | 21 | #define obstack_chunk_alloc malloc |
22 | #define obstack_chunk_free free | 22 | #define obstack_chunk_free free |
23 | #include <obstack.h> | 23 | #include <obstack.h> |
... | @@ -188,65 +188,46 @@ const char *default_action = | ... | @@ -188,65 +188,46 @@ const char *default_action = |
188 | "$B(,5)\n" | 188 | "$B(,5)\n" |
189 | "---\n"; | 189 | "---\n"; |
190 | 190 | ||
191 | /* Take care to clear eighth bit, so we won't upset some stupid terminals */ | ||
192 | #define LB(c) ((c)&0x7f) | ||
193 | |||
194 | static void | 191 | static void |
195 | action_beep (FILE *tty) | 192 | action_beep (mu_stream_t tty) |
196 | { | 193 | { |
197 | fprintf (tty, "\a\a"); | 194 | mu_stream_write (tty, "\a\a", 2, NULL); |
195 | mu_stream_flush (tty); | ||
198 | } | 196 | } |
199 | 197 | ||
200 | static void | 198 | static void |
201 | echo_string (FILE *tty, const char *cr, char *str) | 199 | echo_string (mu_stream_t tty, char *str) |
202 | { | 200 | { |
203 | if (!str) | 201 | if (!str) |
204 | return; | 202 | return; |
205 | for (; *str; str++) | 203 | mu_stream_write (tty, str, strlen (str), NULL); |
206 | { | ||
207 | if (*str == '\n') | ||
208 | fprintf (tty, "%s", cr); | ||
209 | else | ||
210 | { | ||
211 | char c = LB (*str); | ||
212 | putc (c, tty); | ||
213 | } | ||
214 | } | ||
215 | fflush (tty); | ||
216 | } | 204 | } |
217 | 205 | ||
218 | static void | 206 | static void |
219 | action_echo (FILE *tty, const char *cr, int omit_newline, | 207 | action_echo (mu_stream_t tty, int omit_newline, int argc, char **argv) |
220 | int argc, char **argv) | ||
221 | { | 208 | { |
222 | int i; | 209 | int i; |
223 | 210 | ||
224 | if (omit_newline) | ||
225 | { | ||
226 | argc--; | ||
227 | argv++; | ||
228 | } | ||
229 | |||
230 | for (i = 0;;) | 211 | for (i = 0;;) |
231 | { | 212 | { |
232 | echo_string (tty, cr, argv[i]); | 213 | echo_string (tty, argv[i]); |
233 | if (++i < argc) | 214 | if (++i < argc) |
234 | echo_string (tty, cr, " "); | 215 | echo_string (tty, " "); |
235 | else | 216 | else |
236 | { | 217 | break; |
237 | if (!omit_newline) | ||
238 | echo_string (tty, cr, "\n"); | ||
239 | break; | ||
240 | } | ||
241 | } | 218 | } |
219 | if (!omit_newline) | ||
220 | echo_string (tty, "\n"); | ||
242 | } | 221 | } |
243 | 222 | ||
244 | static void | 223 | static void |
245 | action_exec (FILE *tty, int argc, char **argv) | 224 | action_exec (mu_stream_t tty, int argc, char **argv) |
246 | { | 225 | { |
247 | pid_t pid; | 226 | mu_stream_t pstream; |
248 | struct stat stb; | 227 | struct stat stb; |
249 | 228 | char *command; | |
229 | int status; | ||
230 | |||
250 | if (argc == 0) | 231 | if (argc == 0) |
251 | { | 232 | { |
252 | mu_diag_output (MU_DIAG_ERROR, _("no arguments for exec")); | 233 | mu_diag_output (MU_DIAG_ERROR, _("no arguments for exec")); |
... | @@ -272,22 +253,30 @@ action_exec (FILE *tty, int argc, char **argv) | ... | @@ -272,22 +253,30 @@ action_exec (FILE *tty, int argc, char **argv) |
272 | return; | 253 | return; |
273 | } | 254 | } |
274 | 255 | ||
275 | pid = fork (); | 256 | /* FIXME: Redirect stderr to out */ |
276 | if (pid == 0) | 257 | /* FIXME: need this: |
258 | status = mu_prog_stream_create_argv (&pstream, argv[0], argv, | ||
259 | MU_STREAM_READ); | ||
260 | */ | ||
261 | status = mu_argcv_join (argc, argv, " ", mu_argcv_escape_no, &command); | ||
262 | if (status) | ||
277 | { | 263 | { |
278 | close (1); | 264 | mu_diag_funcall (MU_DIAG_ERROR, "mu_argcv_join", NULL, status); |
279 | close (2); | 265 | return; |
280 | dup2 (fileno (tty), 1); | 266 | } |
281 | dup2 (fileno (tty), 2); | 267 | status = mu_prog_stream_create (&pstream, command, MU_STREAM_READ); |
282 | fclose (tty); | 268 | if (status) |
283 | execv (argv[0], argv); | 269 | { |
284 | mu_diag_output (MU_DIAG_ERROR, _("cannot execute %s: %s"), argv[0], strerror (errno)); | 270 | mu_diag_funcall (MU_DIAG_ERROR, "mu_prog_stream_create_argv", argv[0], |
285 | exit (0); | 271 | status); |
272 | return; | ||
286 | } | 273 | } |
274 | mu_stream_copy (tty, pstream, 0, NULL); | ||
275 | mu_stream_destroy (&pstream); | ||
287 | } | 276 | } |
288 | 277 | ||
289 | static mu_stream_t | 278 | static mu_stream_t |
290 | open_rc (const char *filename, FILE *tty) | 279 | open_rc (const char *filename, mu_stream_t tty) |
291 | { | 280 | { |
292 | struct stat stb; | 281 | struct stat stb; |
293 | struct passwd *pw = getpwnam (username); | 282 | struct passwd *pw = getpwnam (username); |
... | @@ -307,8 +296,8 @@ open_rc (const char *filename, FILE *tty) | ... | @@ -307,8 +296,8 @@ open_rc (const char *filename, FILE *tty) |
307 | } | 296 | } |
308 | if ((stb.st_mode & 0777) != 0600) | 297 | if ((stb.st_mode & 0777) != 0600) |
309 | { | 298 | { |
310 | fprintf (tty, "%s\r\n", | 299 | mu_stream_printf (tty, "%s\n", |
311 | _("Warning: your .biffrc has wrong permissions")); | 300 | _("Warning: your .biffrc has wrong permissions")); |
312 | mu_diag_output (MU_DIAG_NOTICE, _("%s's %s has wrong permissions"), | 301 | mu_diag_output (MU_DIAG_NOTICE, _("%s's %s has wrong permissions"), |
313 | username, filename); | 302 | username, filename); |
314 | return NULL; | 303 | return NULL; |
... | @@ -319,8 +308,8 @@ open_rc (const char *filename, FILE *tty) | ... | @@ -319,8 +308,8 @@ open_rc (const char *filename, FILE *tty) |
319 | { | 308 | { |
320 | if (rc != ENOENT) | 309 | if (rc != ENOENT) |
321 | { | 310 | { |
322 | fprintf (tty, _("Cannot open .biffrc file: %s\r\n"), | 311 | mu_stream_printf (tty, _("Cannot open .biffrc file: %s\n"), |
323 | mu_strerror (rc)); | 312 | mu_strerror (rc)); |
324 | mu_diag_output (MU_DIAG_NOTICE, _("cannot open %s for %s: %s"), | 313 | mu_diag_output (MU_DIAG_NOTICE, _("cannot open %s for %s: %s"), |
325 | filename, username, mu_strerror (rc)); | 314 | filename, username, mu_strerror (rc)); |
326 | } | 315 | } |
... | @@ -331,8 +320,9 @@ open_rc (const char *filename, FILE *tty) | ... | @@ -331,8 +320,9 @@ open_rc (const char *filename, FILE *tty) |
331 | mu_stream_unref (input); | 320 | mu_stream_unref (input); |
332 | if (rc) | 321 | if (rc) |
333 | { | 322 | { |
334 | fprintf (tty, _("Cannot create filter for your .biffrc file: %s\r\n"), | 323 | mu_stream_printf (tty, |
335 | mu_strerror (rc)); | 324 | _("Cannot create filter for your .biffrc file: %s\n"), |
325 | mu_strerror (rc)); | ||
336 | mu_diag_output (MU_DIAG_NOTICE, | 326 | mu_diag_output (MU_DIAG_NOTICE, |
337 | _("cannot create filter for file %s of %s: %s"), | 327 | _("cannot create filter for file %s of %s: %s"), |
338 | filename, username, mu_strerror (rc)); | 328 | filename, username, mu_strerror (rc)); |
... | @@ -342,7 +332,7 @@ open_rc (const char *filename, FILE *tty) | ... | @@ -342,7 +332,7 @@ open_rc (const char *filename, FILE *tty) |
342 | } | 332 | } |
343 | 333 | ||
344 | void | 334 | void |
345 | run_user_action (FILE *tty, const char *cr, mu_message_t msg) | 335 | run_user_action (mu_stream_t tty, mu_message_t msg) |
346 | { | 336 | { |
347 | mu_stream_t input; | 337 | mu_stream_t input; |
348 | int nact = 0; | 338 | int nact = 0; |
... | @@ -403,8 +393,14 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) | ... | @@ -403,8 +393,14 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) |
403 | 393 | ||
404 | if (strcmp (ws.ws_wordv[0], "echo") == 0) | 394 | if (strcmp (ws.ws_wordv[0], "echo") == 0) |
405 | { | 395 | { |
406 | action_echo (tty, cr, n_option, | 396 | int argc = ws.ws_wordc - 1; |
407 | ws.ws_wordc - 1, ws.ws_wordv + 1); | 397 | char **argv = ws.ws_wordv + 1; |
398 | if (n_option) | ||
399 | { | ||
400 | argc--; | ||
401 | argv++; | ||
402 | } | ||
403 | action_echo (tty, n_option, argc, argv); | ||
408 | nact++; | 404 | nact++; |
409 | } | 405 | } |
410 | else if (strcmp (ws.ws_wordv[0], "exec") == 0) | 406 | else if (strcmp (ws.ws_wordv[0], "exec") == 0) |
... | @@ -414,9 +410,9 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) | ... | @@ -414,9 +410,9 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) |
414 | } | 410 | } |
415 | else | 411 | else |
416 | { | 412 | { |
417 | fprintf (tty, _(".biffrc:%d: unknown keyword"), | 413 | mu_stream_printf (tty, |
418 | locus.mu_line); | 414 | _(".biffrc:%d: unknown keyword\n"), |
419 | fprintf (tty, "\r\n"); | 415 | locus.mu_line); |
420 | mu_diag_output (MU_DIAG_ERROR, _("unknown keyword %s"), | 416 | mu_diag_output (MU_DIAG_ERROR, _("unknown keyword %s"), |
421 | ws.ws_wordv[0]); | 417 | ws.ws_wordv[0]); |
422 | break; | 418 | break; |
... | @@ -424,6 +420,8 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) | ... | @@ -424,6 +420,8 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) |
424 | } | 420 | } |
425 | } | 421 | } |
426 | mu_wordsplit_free (&ws); | 422 | mu_wordsplit_free (&ws); |
423 | /* FIXME: line number is incorrect if .biffrc contains | ||
424 | escaped newlines */ | ||
427 | locus.mu_line++; | 425 | locus.mu_line++; |
428 | } | 426 | } |
429 | mu_stream_destroy (&input); | 427 | mu_stream_destroy (&input); |
... | @@ -433,5 +431,5 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) | ... | @@ -433,5 +431,5 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) |
433 | } | 431 | } |
434 | 432 | ||
435 | if (nact == 0) | 433 | if (nact == 0) |
436 | echo_string (tty, cr, expand_line (default_action, msg)); | 434 | echo_string (tty, expand_line (default_action, msg)); |
437 | } | 435 | } | ... | ... |
... | @@ -358,19 +358,22 @@ comsat_connection (int fd, struct sockaddr *sa, int salen, | ... | @@ -358,19 +358,22 @@ comsat_connection (int fd, struct sockaddr *sa, int salen, |
358 | return 0; | 358 | return 0; |
359 | } | 359 | } |
360 | 360 | ||
361 | static const char * | 361 | static int |
362 | get_newline_str (FILE *fp) | 362 | need_crlf (mu_stream_t str) |
363 | { | 363 | { |
364 | #if defined(OPOST) && defined(ONLCR) | 364 | #if defined(OPOST) && defined(ONLCR) |
365 | mu_transport_t trans[2]; | ||
365 | struct termios tbuf; | 366 | struct termios tbuf; |
366 | 367 | ||
367 | tcgetattr (fileno (fp), &tbuf); | 368 | if (mu_stream_ioctl (str, MU_IOCTL_TRANSPORT, MU_IOCTL_OP_GET, trans)) |
368 | if ((tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)) | 369 | return 1; /* suppose we do need it */ |
369 | return "\n"; | 370 | if (tcgetattr ((int)trans[0], &tbuf) == 0 && |
371 | (tbuf.c_oflag & OPOST) && (tbuf.c_oflag & ONLCR)) | ||
372 | return 0; | ||
370 | else | 373 | else |
371 | return "\r\n"; | 374 | return 1; |
372 | #else | 375 | #else |
373 | return "\r\n"; /* Just in case */ | 376 | return 1; /* Just in case */ |
374 | #endif | 377 | #endif |
375 | } | 378 | } |
376 | 379 | ||
... | @@ -380,21 +383,43 @@ static void | ... | @@ -380,21 +383,43 @@ static void |
380 | notify_user (const char *user, const char *device, const char *path, | 383 | notify_user (const char *user, const char *device, const char *path, |
381 | mu_message_qid_t qid) | 384 | mu_message_qid_t qid) |
382 | { | 385 | { |
383 | FILE *fp; | 386 | mu_stream_t out, dev; |
384 | const char *cr; | ||
385 | mu_mailbox_t mbox = NULL; | 387 | mu_mailbox_t mbox = NULL; |
386 | mu_message_t msg; | 388 | mu_message_t msg; |
387 | int status; | 389 | int status; |
388 | 390 | ||
389 | if (change_user (user)) | 391 | if (change_user (user)) |
390 | return; | 392 | return; |
391 | if ((fp = fopen (device, "w")) == NULL) | 393 | status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE); |
394 | if (status) | ||
392 | { | 395 | { |
393 | mu_error (_("cannot open device %s: %s"), device, mu_strerror (errno)); | 396 | mu_error (_("cannot open device %s: %s"), device, mu_strerror (status)); |
394 | return; | 397 | return; |
395 | } | 398 | } |
396 | 399 | mu_stream_set_buffer (dev, mu_buffer_line, 0); | |
397 | cr = get_newline_str (fp); | 400 | |
401 | status = mu_filter_create (&out, dev, "7bit", MU_FILTER_ENCODE, | ||
402 | MU_STREAM_WRITE); | ||
403 | mu_stream_unref (dev); | ||
404 | if (status) | ||
405 | { | ||
406 | mu_error (_("cannot create 7bit filter: %s"), mu_strerror (status)); | ||
407 | return; | ||
408 | } | ||
409 | |||
410 | if (need_crlf (out)) | ||
411 | { | ||
412 | mu_stream_t str; | ||
413 | status = mu_filter_create (&str, out, "CRLF", MU_FILTER_ENCODE, | ||
414 | MU_STREAM_WRITE); | ||
415 | mu_stream_unref (out); | ||
416 | if (status) | ||
417 | { | ||
418 | mu_error (_("cannot create crlf filter: %s"), mu_strerror (status)); | ||
419 | return; | ||
420 | } | ||
421 | out = str; | ||
422 | } | ||
398 | 423 | ||
399 | if (!path) | 424 | if (!path) |
400 | { | 425 | { |
... | @@ -403,8 +428,9 @@ notify_user (const char *user, const char *device, const char *path, | ... | @@ -403,8 +428,9 @@ notify_user (const char *user, const char *device, const char *path, |
403 | return; | 428 | return; |
404 | } | 429 | } |
405 | 430 | ||
406 | if ((status = mu_mailbox_create (&mbox, path)) != 0 | 431 | if ((status = mu_mailbox_create (&mbox, path)) != 0 || |
407 | || (status = mu_mailbox_open (mbox, MU_STREAM_READ|MU_STREAM_QACCESS)) != 0) | 432 | (status = mu_mailbox_open (mbox, |
433 | MU_STREAM_READ|MU_STREAM_QACCESS)) != 0) | ||
408 | { | 434 | { |
409 | mu_error (_("cannot open mailbox %s: %s"), | 435 | mu_error (_("cannot open mailbox %s: %s"), |
410 | path, mu_strerror (status)); | 436 | path, mu_strerror (status)); |
... | @@ -419,8 +445,8 @@ notify_user (const char *user, const char *device, const char *path, | ... | @@ -419,8 +445,8 @@ notify_user (const char *user, const char *device, const char *path, |
419 | return; /* FIXME: Notify the user, anyway */ | 445 | return; /* FIXME: Notify the user, anyway */ |
420 | } | 446 | } |
421 | 447 | ||
422 | run_user_action (fp, cr, msg); | 448 | run_user_action (out, msg); |
423 | fclose (fp); | 449 | mu_stream_destroy (&out); |
424 | } | 450 | } |
425 | 451 | ||
426 | /* Search utmp for the local user */ | 452 | /* Search utmp for the local user */ | ... | ... |
... | @@ -60,6 +60,7 @@ | ... | @@ -60,6 +60,7 @@ |
60 | #include <mailutils/acl.h> | 60 | #include <mailutils/acl.h> |
61 | #include <mailutils/server.h> | 61 | #include <mailutils/server.h> |
62 | #include <mailutils/cctype.h> | 62 | #include <mailutils/cctype.h> |
63 | #include <mailutils/filter.h> | ||
63 | 64 | ||
64 | #ifndef INADDR_NONE | 65 | #ifndef INADDR_NONE |
65 | # define INADDR_NONE -1 | 66 | # define INADDR_NONE -1 |
... | @@ -77,5 +78,5 @@ extern const char *username; | ... | @@ -77,5 +78,5 @@ extern const char *username; |
77 | extern char *hostname; | 78 | extern char *hostname; |
78 | extern struct daemon_param daemon_param; | 79 | extern struct daemon_param daemon_param; |
79 | 80 | ||
80 | void run_user_action (FILE *tty, const char *cr, mu_message_t msg); | 81 | void run_user_action (mu_stream_t str, mu_message_t msg); |
81 | 82 | ... | ... |
-
Please register or sign in to post a comment