comsat: add a way to specify alternative biffrc file name; new biffrc statement: tty
* comsat/comsat.c (options): New option --file. (biffrc): New variable. (comsatd_parse_opt): Handle the --file option. (open_tty): New function. (notify_user): Open the tty using open_tty function and a default set of filters. (main): Hanlde --file option. * comsat/action.c (run_user_action): Implement the `tty' statement. * comsat/comsat.h (biffrc): New extern. (open_tty): New function. mu: accept a chain of filters. * mu/filter.c (filter_doc, filter_docstring): Update. (mutool_filter): Accept a filter chain.
Showing
4 changed files
with
175 additions
and
39 deletions
... | @@ -331,7 +331,7 @@ run_user_action (mu_stream_t tty, mu_message_t msg) | ... | @@ -331,7 +331,7 @@ run_user_action (mu_stream_t tty, mu_message_t msg) |
331 | mu_stream_t input; | 331 | mu_stream_t input; |
332 | int nact = 0; | 332 | int nact = 0; |
333 | 333 | ||
334 | input = open_rc (BIFF_RC, tty); | 334 | input = open_rc (biffrc, tty); |
335 | if (input) | 335 | if (input) |
336 | { | 336 | { |
337 | char *stmt = NULL; | 337 | char *stmt = NULL; |
... | @@ -385,7 +385,22 @@ run_user_action (mu_stream_t tty, mu_message_t msg) | ... | @@ -385,7 +385,22 @@ run_user_action (mu_stream_t tty, mu_message_t msg) |
385 | break; | 385 | break; |
386 | } | 386 | } |
387 | 387 | ||
388 | if (strcmp (ws.ws_wordv[0], "echo") == 0) | 388 | if (strcmp (ws.ws_wordv[0], "tty") == 0) |
389 | { | ||
390 | mu_stream_t ntty = open_tty (ws.ws_wordv[1], | ||
391 | ws.ws_wordc - 2, | ||
392 | ws.ws_wordv + 2); | ||
393 | if (!ntty) | ||
394 | { | ||
395 | mu_stream_printf (tty, | ||
396 | _(".biffrc:%d: cannot open tty\n"), | ||
397 | locus.mu_line); | ||
398 | break; | ||
399 | } | ||
400 | mu_stream_destroy (&tty); | ||
401 | tty = ntty; | ||
402 | } | ||
403 | else if (strcmp (ws.ws_wordv[0], "echo") == 0) | ||
389 | { | 404 | { |
390 | int argc = ws.ws_wordc - 1; | 405 | int argc = ws.ws_wordc - 1; |
391 | char **argv = ws.ws_wordv + 1; | 406 | char **argv = ws.ws_wordv + 1; | ... | ... |
... | @@ -66,6 +66,8 @@ static struct argp_option options[] = | ... | @@ -66,6 +66,8 @@ static struct argp_option options[] = |
66 | { "inetd", 'i', 0, 0, N_("run in inetd mode"), 0 }, | 66 | { "inetd", 'i', 0, 0, N_("run in inetd mode"), 0 }, |
67 | { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL, | 67 | { "daemon", 'd', N_("NUMBER"), OPTION_ARG_OPTIONAL, |
68 | N_("runs in daemon mode with a maximum of NUMBER children"), 0 }, | 68 | N_("runs in daemon mode with a maximum of NUMBER children"), 0 }, |
69 | { "file", 'f', N_("FILE"), 0, | ||
70 | N_("read FILE instead of .biffrc"), 0 }, | ||
69 | { NULL, 0, NULL, 0, NULL, 0 } | 71 | { NULL, 0, NULL, 0, NULL, 0 } |
70 | }; | 72 | }; |
71 | 73 | ||
... | @@ -110,6 +112,7 @@ static int change_user (const char *user); | ... | @@ -110,6 +112,7 @@ static int change_user (const char *user); |
110 | 112 | ||
111 | static int reload = 0; | 113 | static int reload = 0; |
112 | int test_mode; | 114 | int test_mode; |
115 | char *biffrc = BIFF_RC; | ||
113 | 116 | ||
114 | struct mu_cfg_param comsat_cfg_param[] = { | 117 | struct mu_cfg_param comsat_cfg_param[] = { |
115 | { "allow-biffrc", mu_cfg_bool, &allow_biffrc, 0, NULL, | 118 | { "allow-biffrc", mu_cfg_bool, &allow_biffrc, 0, NULL, |
... | @@ -147,6 +150,10 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) | ... | @@ -147,6 +150,10 @@ comsatd_parse_opt (int key, char *arg, struct argp_state *state) |
147 | mu_argp_node_list_new (lst, "max-children", arg); | 150 | mu_argp_node_list_new (lst, "max-children", arg); |
148 | break; | 151 | break; |
149 | 152 | ||
153 | case 'f': | ||
154 | biffrc = arg; | ||
155 | break; | ||
156 | |||
150 | case 'i': | 157 | case 'i': |
151 | mu_argp_node_list_new (lst, "mode", "inetd"); | 158 | mu_argp_node_list_new (lst, "mode", "inetd"); |
152 | break; | 159 | break; |
... | @@ -236,7 +243,7 @@ comsat_process (char *buffer, size_t rdlen) | ... | @@ -236,7 +243,7 @@ comsat_process (char *buffer, size_t rdlen) |
236 | { | 243 | { |
237 | if (require_tty) | 244 | if (require_tty) |
238 | return; | 245 | return; |
239 | strcpy (tty, "/dev/null"); | 246 | tty[0] = 0; |
240 | } | 247 | } |
241 | 248 | ||
242 | /* Child: do actual I/O */ | 249 | /* Child: do actual I/O */ |
... | @@ -377,50 +384,112 @@ need_crlf (mu_stream_t str) | ... | @@ -377,50 +384,112 @@ need_crlf (mu_stream_t str) |
377 | #endif | 384 | #endif |
378 | } | 385 | } |
379 | 386 | ||
380 | /* NOTE: Do not bother to free allocated memory, as the program exits | 387 | static mu_stream_t |
381 | immediately after executing this */ | 388 | _open_tty (const char *device, int argc, char **argv) |
382 | static void | ||
383 | notify_user (const char *user, const char *device, const char *path, | ||
384 | mu_message_qid_t qid) | ||
385 | { | 389 | { |
386 | mu_stream_t out, dev; | 390 | mu_stream_t dev, base_dev, prev_stream; |
387 | mu_mailbox_t mbox = NULL; | ||
388 | mu_message_t msg; | ||
389 | int status; | 391 | int status; |
390 | 392 | ||
391 | if (change_user (user)) | ||
392 | return; | ||
393 | status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE); | 393 | status = mu_file_stream_create (&dev, device, MU_STREAM_WRITE); |
394 | if (status) | 394 | if (status) |
395 | { | 395 | { |
396 | mu_error (_("cannot open device %s: %s"), device, mu_strerror (status)); | 396 | mu_error (_("cannot open device %s: %s"), |
397 | return; | 397 | device, mu_strerror (status)); |
398 | return NULL; | ||
398 | } | 399 | } |
399 | mu_stream_set_buffer (dev, mu_buffer_line, 0); | 400 | mu_stream_set_buffer (dev, mu_buffer_line, 0); |
400 | 401 | ||
401 | status = mu_filter_create (&out, dev, "7bit", MU_FILTER_ENCODE, | 402 | prev_stream = base_dev = dev; |
402 | MU_STREAM_WRITE); | 403 | while (argc) |
403 | mu_stream_unref (dev); | ||
404 | if (status) | ||
405 | { | 404 | { |
406 | mu_error (_("cannot create 7bit filter: %s"), mu_strerror (status)); | 405 | int i; |
407 | return; | 406 | int mode; |
407 | int qmark; | ||
408 | char *fltname; | ||
409 | |||
410 | fltname = argv[0]; | ||
411 | if (fltname[0] == '?') | ||
412 | { | ||
413 | qmark = 1; | ||
414 | fltname++; | ||
408 | } | 415 | } |
416 | else | ||
417 | qmark = 0; | ||
409 | 418 | ||
410 | if (need_crlf (out)) | 419 | if (fltname[0] == '~') |
420 | { | ||
421 | mode = MU_FILTER_DECODE; | ||
422 | fltname++; | ||
423 | } | ||
424 | else | ||
411 | { | 425 | { |
412 | mu_stream_t str; | 426 | mode = MU_FILTER_ENCODE; |
413 | status = mu_filter_create (&str, out, "CRLF", MU_FILTER_ENCODE, | 427 | } |
414 | MU_STREAM_WRITE); | 428 | |
415 | mu_stream_unref (out); | 429 | for (i = 1; i < argc; i++) |
430 | if (strcmp (argv[i], "+") == 0) | ||
431 | break; | ||
432 | |||
433 | if (qmark == 0 || need_crlf (base_dev)) | ||
434 | { | ||
435 | status = mu_filter_create_args (&dev, prev_stream, fltname, | ||
436 | i, (const char **)argv, | ||
437 | mode, MU_STREAM_WRITE); | ||
438 | mu_stream_unref (prev_stream); | ||
416 | if (status) | 439 | if (status) |
417 | { | 440 | { |
418 | mu_error (_("cannot create crlf filter: %s"), mu_strerror (status)); | 441 | mu_error (_("cannot open filter stream: %s"), |
419 | return; | 442 | mu_strerror (status)); |
443 | return NULL; | ||
444 | } | ||
445 | prev_stream = dev; | ||
446 | } | ||
447 | argc -= i; | ||
448 | argv += i; | ||
449 | if (argc) | ||
450 | { | ||
451 | argc--; | ||
452 | argv++; | ||
453 | } | ||
420 | } | 454 | } |
421 | out = str; | 455 | return dev; |
456 | } | ||
457 | |||
458 | mu_stream_t | ||
459 | open_tty (const char *device, int argc, char **argv) | ||
460 | { | ||
461 | mu_stream_t dev; | ||
462 | |||
463 | if (!device || !*device || strcmp (device, "null") == 0) | ||
464 | { | ||
465 | int rc = mu_nullstream_create (&dev, MU_STREAM_WRITE); | ||
466 | if (rc) | ||
467 | mu_error (_("cannot open null stream: %s"), mu_strerror (rc)); | ||
422 | } | 468 | } |
469 | else | ||
470 | dev = _open_tty (device, argc, argv); | ||
471 | return dev; | ||
472 | } | ||
473 | |||
474 | /* NOTE: Do not bother to free allocated memory, as the program exits | ||
475 | immediately after executing this */ | ||
476 | static void | ||
477 | notify_user (const char *user, const char *device, const char *path, | ||
478 | mu_message_qid_t qid) | ||
479 | { | ||
480 | mu_stream_t dev; | ||
481 | mu_mailbox_t mbox = NULL; | ||
482 | mu_message_t msg; | ||
483 | static char *default_filters[] = { "7bit", "+", "?CRLF", NULL }; | ||
484 | int status; | ||
485 | |||
486 | if (change_user (user)) | ||
487 | return; | ||
423 | 488 | ||
489 | dev = open_tty (device, MU_ARRAY_SIZE (default_filters) - 1, | ||
490 | default_filters); | ||
491 | if (!dev) | ||
492 | return; | ||
424 | if (!path) | 493 | if (!path) |
425 | { | 494 | { |
426 | path = mailbox_path (user); | 495 | path = mailbox_path (user); |
... | @@ -445,8 +514,8 @@ notify_user (const char *user, const char *device, const char *path, | ... | @@ -445,8 +514,8 @@ notify_user (const char *user, const char *device, const char *path, |
445 | return; /* FIXME: Notify the user, anyway */ | 514 | return; /* FIXME: Notify the user, anyway */ |
446 | } | 515 | } |
447 | 516 | ||
448 | run_user_action (out, msg); | 517 | run_user_action (dev, msg); |
449 | mu_stream_destroy (&out); | 518 | mu_stream_destroy (&dev); |
450 | } | 519 | } |
451 | 520 | ||
452 | /* Search utmp for the local user */ | 521 | /* Search utmp for the local user */ |
... | @@ -614,6 +683,19 @@ main (int argc, char **argv) | ... | @@ -614,6 +683,19 @@ main (int argc, char **argv) |
614 | } | 683 | } |
615 | } | 684 | } |
616 | 685 | ||
686 | if (biffrc[0] == '.') | ||
687 | { | ||
688 | char *cwd = mu_getcwd (); | ||
689 | biffrc = mu_make_file_name (cwd, biffrc); | ||
690 | if (!biffrc) | ||
691 | { | ||
692 | mu_error ("%s", mu_strerror (ENOMEM)); | ||
693 | exit (1); | ||
694 | } | ||
695 | mu_normalize_path (biffrc); | ||
696 | free (cwd); | ||
697 | } | ||
698 | |||
617 | notify_user (user, "/dev/tty", argv[0], argv[1]); | 699 | notify_user (user, "/dev/tty", argv[0], argv[1]); |
618 | exit (0); | 700 | exit (0); |
619 | } | 701 | } |
... | @@ -655,4 +737,3 @@ main (int argc, char **argv) | ... | @@ -655,4 +737,3 @@ main (int argc, char **argv) |
655 | 737 | ||
656 | return c != 0; | 738 | return c != 0; |
657 | } | 739 | } |
658 | ... | ... |
... | @@ -77,6 +77,8 @@ extern int maxlines; | ... | @@ -77,6 +77,8 @@ extern int maxlines; |
77 | extern const char *username; | 77 | extern const char *username; |
78 | extern char *hostname; | 78 | extern char *hostname; |
79 | extern struct daemon_param daemon_param; | 79 | extern struct daemon_param daemon_param; |
80 | extern char *biffrc; | ||
80 | 81 | ||
81 | void run_user_action (mu_stream_t str, mu_message_t msg); | 82 | void run_user_action (mu_stream_t str, mu_message_t msg); |
83 | mu_stream_t open_tty (const char *device, int argc, char **argv); | ||
82 | 84 | ... | ... |
... | @@ -23,9 +23,9 @@ | ... | @@ -23,9 +23,9 @@ |
23 | #include "argp.h" | 23 | #include "argp.h" |
24 | #include "mu.h" | 24 | #include "mu.h" |
25 | 25 | ||
26 | static char filter_doc[] = N_("mu filter - apply a filter to the input"); | 26 | static char filter_doc[] = N_("mu filter - apply a chain of filters to the input"); |
27 | char filter_docstring[] = N_("apply a filter to the input"); | 27 | char filter_docstring[] = N_("apply a chain of filters to the input"); |
28 | static char filter_args_doc[] = N_("NAME [ARGS]"); | 28 | static char filter_args_doc[] = N_("[~]NAME [ARGS] [+ [~]NAME [ARGS]...]"); |
29 | 29 | ||
30 | static struct argp_option filter_options[] = { | 30 | static struct argp_option filter_options[] = { |
31 | { "encode", 'e', NULL, 0, N_("encode the input (default)") }, | 31 | { "encode", 'e', NULL, 0, N_("encode the input (default)") }, |
... | @@ -126,12 +126,23 @@ list_filters () | ... | @@ -126,12 +126,23 @@ list_filters () |
126 | return mu_list_do (list, filter_printer, NULL); | 126 | return mu_list_do (list, filter_printer, NULL); |
127 | } | 127 | } |
128 | 128 | ||
129 | static int | ||
130 | negate_filter_mode (int mode) | ||
131 | { | ||
132 | if (mode == MU_FILTER_DECODE) | ||
133 | return MU_FILTER_ENCODE; | ||
134 | else if (mode == MU_FILTER_ENCODE) | ||
135 | return MU_FILTER_DECODE; | ||
136 | abort (); | ||
137 | } | ||
138 | |||
129 | int | 139 | int |
130 | mutool_filter (int argc, char **argv) | 140 | mutool_filter (int argc, char **argv) |
131 | { | 141 | { |
132 | int rc, index; | 142 | int rc, index; |
133 | mu_stream_t flt; | 143 | mu_stream_t flt, prev_stream; |
134 | const char *fltname; | 144 | const char *fltname; |
145 | int mode; | ||
135 | 146 | ||
136 | if (argp_parse (&filter_argp, argc, argv, ARGP_IN_ORDER, &index, NULL)) | 147 | if (argp_parse (&filter_argp, argc, argv, ARGP_IN_ORDER, &index, NULL)) |
137 | return 1; | 148 | return 1; |
... | @@ -155,19 +166,46 @@ mutool_filter (int argc, char **argv) | ... | @@ -155,19 +166,46 @@ mutool_filter (int argc, char **argv) |
155 | return 1; | 166 | return 1; |
156 | } | 167 | } |
157 | 168 | ||
169 | prev_stream = mu_strin; | ||
170 | do | ||
171 | { | ||
172 | int i; | ||
173 | |||
158 | fltname = argv[0]; | 174 | fltname = argv[0]; |
175 | if (fltname[0] == '~') | ||
176 | { | ||
177 | mode = negate_filter_mode (filter_mode); | ||
178 | fltname++; | ||
179 | } | ||
180 | else | ||
181 | mode = filter_mode; | ||
182 | |||
183 | for (i = 1; i < argc; i++) | ||
184 | if (strcmp (argv[i], "+") == 0) | ||
185 | break; | ||
159 | 186 | ||
160 | if (line_length_option) | 187 | if (line_length_option) |
161 | reset_line_length (fltname, line_length); | 188 | reset_line_length (fltname, line_length); |
162 | 189 | ||
163 | rc = mu_filter_create_args (&flt, mu_strin, fltname, | 190 | rc = mu_filter_create_args (&flt, prev_stream, fltname, |
164 | argc, (const char **)argv, | 191 | i, (const char **)argv, |
165 | filter_mode, MU_STREAM_READ); | 192 | mode, MU_STREAM_READ); |
193 | mu_stream_unref (prev_stream); | ||
166 | if (rc) | 194 | if (rc) |
167 | { | 195 | { |
168 | mu_error (_("cannot open filter stream: %s"), mu_strerror (rc)); | 196 | mu_error (_("cannot open filter stream: %s"), mu_strerror (rc)); |
169 | return 1; | 197 | return 1; |
170 | } | 198 | } |
199 | prev_stream = flt; | ||
200 | argc -= i; | ||
201 | argv += i; | ||
202 | if (argc) | ||
203 | { | ||
204 | argc--; | ||
205 | argv++; | ||
206 | } | ||
207 | } | ||
208 | while (argc); | ||
171 | 209 | ||
172 | rc = mu_stream_copy (mu_strout, flt, 0, NULL); | 210 | rc = mu_stream_copy (mu_strout, flt, 0, NULL); |
173 | 211 | ... | ... |
-
Please register or sign in to post a comment