Commit 4f9ae745 4f9ae74585429baa9b9be606e6e2e7512afd65fc by Sergey Poznyakoff

(act_getline): Change return type to

unsigned. Return actual number of input lines processed or 0 on
failure (either I/O, or memory allocation or EOF).
(action_echo): Rewritten to use shell-like syntax
(run_user_action): Rewritten main loop to make it cleaner. In
particular, expand agruments after word splitting. Use new echo
semantics.
1 parent bc6b0c8d
...@@ -39,13 +39,14 @@ ...@@ -39,13 +39,14 @@
39 number of characters and line in the expansion. 39 number of characters and line in the expansion.
40 When omitted, they default to 400, 5. */ 40 When omitted, they default to 400, 5. */
41 41
42 static int 42 static unsigned
43 act_getline (FILE *fp, char **sptr, size_t *size) 43 act_getline (FILE *fp, char **sptr, size_t *size)
44 { 44 {
45 char buf[256]; 45 char buf[256];
46 int cont = 1; 46 int cont = 1;
47 size_t used = 0; 47 size_t used = 0;
48 48 unsigned lines = 0;
49
49 while (cont && fgets (buf, sizeof buf, fp)) 50 while (cont && fgets (buf, sizeof buf, fp))
50 { 51 {
51 int len = strlen (buf); 52 int len = strlen (buf);
...@@ -56,6 +57,7 @@ act_getline (FILE *fp, char **sptr, size_t *size) ...@@ -56,6 +57,7 @@ act_getline (FILE *fp, char **sptr, size_t *size)
56 { 57 {
57 buf[--len] = 0; 58 buf[--len] = 0;
58 cont = 1; 59 cont = 1;
60 lines++;
59 } 61 }
60 else 62 else
61 cont = 0; 63 cont = 0;
...@@ -67,7 +69,7 @@ act_getline (FILE *fp, char **sptr, size_t *size) ...@@ -67,7 +69,7 @@ act_getline (FILE *fp, char **sptr, size_t *size)
67 { 69 {
68 *sptr = realloc (*sptr, len + used + 1); 70 *sptr = realloc (*sptr, len + used + 1);
69 if (!*sptr) 71 if (!*sptr)
70 return -1; 72 return 0;
71 *size = len + used + 1; 73 *size = len + used + 1;
72 } 74 }
73 memcpy (*sptr + used, buf, len); 75 memcpy (*sptr + used, buf, len);
...@@ -77,7 +79,9 @@ act_getline (FILE *fp, char **sptr, size_t *size) ...@@ -77,7 +79,9 @@ act_getline (FILE *fp, char **sptr, size_t *size)
77 if (*sptr) 79 if (*sptr)
78 (*sptr)[used] = 0; 80 (*sptr)[used] = 0;
79 81
80 return used; 82 if (used && !feof (fp))
83 lines++;
84 return lines;
81 } 85 }
82 86
83 static int 87 static int
...@@ -237,7 +241,7 @@ action_beep (FILE *tty) ...@@ -237,7 +241,7 @@ action_beep (FILE *tty)
237 } 241 }
238 242
239 static void 243 static void
240 action_echo (FILE *tty, const char *cr, char *str) 244 echo_string (FILE *tty, const char *cr, char *str)
241 { 245 {
242 if (!str) 246 if (!str)
243 return; 247 return;
...@@ -255,6 +259,32 @@ action_echo (FILE *tty, const char *cr, char *str) ...@@ -255,6 +259,32 @@ action_echo (FILE *tty, const char *cr, char *str)
255 } 259 }
256 260
257 static void 261 static void
262 action_echo (FILE *tty, const char *cr, int omit_newline,
263 int argc, char **argv)
264 {
265 int i;
266
267 if (omit_newline)
268 {
269 argc--;
270 argv++;
271 }
272
273 for (i = 0;;)
274 {
275 echo_string (tty, cr, argv[i]);
276 if (++i < argc)
277 echo_string (tty, cr, " ");
278 else
279 {
280 if (!omit_newline)
281 echo_string (tty, cr, "\n");
282 break;
283 }
284 }
285 }
286
287 static void
258 action_exec (FILE *tty, int line, int argc, char **argv) 288 action_exec (FILE *tty, int line, int argc, char **argv)
259 { 289 {
260 pid_t pid; 290 pid_t pid;
...@@ -337,58 +367,68 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg) ...@@ -337,58 +367,68 @@ run_user_action (FILE *tty, const char *cr, mu_message_t msg)
337 int nact = 0; 367 int nact = 0;
338 char *stmt = NULL; 368 char *stmt = NULL;
339 size_t size = 0; 369 size_t size = 0;
340 370
341 fp = open_rc (BIFF_RC, tty); 371 fp = open_rc (BIFF_RC, tty);
342 if (fp) 372 if (fp)
343 { 373 {
344 int line = 0; 374 unsigned line = 1, n;
345 375
346 while (act_getline (fp, &stmt, &size)) 376 while ((n = act_getline (fp, &stmt, &size)))
347 { 377 {
348 char *str;
349 int argc; 378 int argc;
350 char **argv; 379 char **argv;
351 380
352 line++; 381 if (mu_argcv_get (stmt, "", NULL, &argc, &argv) == 0
353 str = expand_line (stmt, msg); 382 && argc
354 if (!str) 383 && argv[0][0] != '#')
355 continue;
356 if (mu_argcv_get (str, "", NULL, &argc, &argv)
357 || argc == 0
358 || argv[0][0] == '#')
359 {
360 free (str);
361 mu_argcv_free (argc, argv);
362 continue;
363 }
364
365 if (strcmp (argv[0], "beep") == 0)
366 {
367 action_beep (tty);
368 nact++;
369 }
370 else if (strcmp (argv[0], "echo") == 0)
371 {
372 action_echo (tty, cr, argv[1]);
373 nact++;
374 }
375 else if (strcmp (argv[0], "exec") == 0)
376 {
377 action_exec (tty, line, argc-1, argv+1);
378 nact++;
379 }
380 else
381 { 384 {
382 fprintf (tty, _(".biffrc:%d: unknown keyword"), line); 385 if (strcmp (argv[0], "beep") == 0)
383 fprintf (tty, "\r\n"); 386 {
384 syslog (LOG_ERR, _("%s:.biffrc:%d: unknown keyword %s"), 387 /* FIXME: excess arguments are ignored */
385 username, line, argv[0]); 388 action_beep (tty);
386 break; 389 nact++;
390 }
391 else
392 {
393 /* Rest of actions require keyword expansion */
394 int i;
395 int n_option = argc > 1 && strcmp (argv[1], "-n") == 0;
396
397 for (i = 1; i < argc; i++)
398 {
399 char *oldarg = argv[i];
400 argv[i] = expand_line (argv[i], msg);
401 free (oldarg);
402 if (!argv[i])
403 break;
404 }
405
406 if (strcmp (argv[0], "echo") == 0)
407 {
408 action_echo (tty, cr, n_option, argc - 1, argv + 1);
409 nact++;
410 }
411 else if (strcmp (argv[0], "exec") == 0)
412 {
413 action_exec (tty, line, argc - 1, argv + 1);
414 nact++;
415 }
416 else
417 {
418 fprintf (tty, _(".biffrc:%d: unknown keyword"), line);
419 fprintf (tty, "\r\n");
420 syslog (LOG_ERR, _("%s:.biffrc:%d: unknown keyword %s"),
421 username, line, argv[0]);
422 break;
423 }
424 }
387 } 425 }
426 mu_argcv_free (argc, argv);
427 line += n;
388 } 428 }
389 fclose (fp); 429 fclose (fp);
390 } 430 }
391 431
392 if (nact == 0) 432 if (nact == 0)
393 action_echo (tty, cr, expand_line (default_action, msg)); 433 echo_string (tty, cr, expand_line (default_action, msg));
394 } 434 }
......