Commit ac08a857 ac08a8575ae8ea3b85180bd05464a48768f398ee by Sergey Poznyakoff

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.
1 parent c2b48051
...@@ -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
......