Submitted by: Damon Harper
Date: 2006-08-26 Summary: Fix several problems in comsatd This patch fixes several problems in the comsat/action.c function run_user_action. 1. Previously, escape sequences ($u, $H{field}, etc) were expanded BEFORE mu_argcv_get was called. This led to a problem when the substituted values contained double quotes or other characters significant to mu_argcv_get. This is fixed by calling mu_argcv_get first, on the unexpanded strings, then expanding each line as it is processed. 2. mu_argcv_free was not called except in case of an error. This is not terribly significant as the program exits after completing run_user_action, but it could potentially consume a fair amount of memory with a very long .biffrc file, and looks sloppy. This patch makes sure to call mu_argcv_free wherever necessary. 3. Due to an oversight in function act_getline, line counting in .biffrc was incorrect whenever lines were continued with backslashes. Also, a blank line in .biffrc would cause processing to stop since act_getline would return 0 and the while loop in run_user_action would exit. This is fixed by having act_getline return the number of `physical' lines returned, and using that value to increment the line count in run_user_action. 4. act_getline returns -1 if enough memory cannot be allocated, but this return value was ignored in run_user_action. A return of -1 from act_getline will now abort processing in run_user_action. --- mailutils-1.0.orig/comsat/action.c 2005-08-29 03:21:54.000000000 -0700 +++ mailutils-1.0/comsat/action.c 2006-08-26 10:05:55.000000000 -0700 @@ -45,6 +45,7 @@ char buf[256]; int cont = 1; size_t used = 0; + int lines = 0; while (cont && fgets (buf, sizeof buf, fp)) { @@ -56,6 +57,7 @@ { buf[--len] = 0; cont = 1; + lines++; } else cont = 0; @@ -77,7 +79,10 @@ if (*sptr) (*sptr)[used] = 0; - return used; + /* return the number of physical lines used */ + if (used || !feof (fp)) + lines++; + return lines; } static int @@ -341,50 +346,58 @@ fp = open_rc (BIFF_RC, tty); if (fp) { - int line = 0; + int lines; + int line = 1; + int do_abort = 0; - while (act_getline (fp, &stmt, &size)) + while ((lines = act_getline (fp, &stmt, &size)) > 0) { - char *str; int argc; char **argv; + int c; - line++; - str = expand_line (stmt, msg); - if (!str) - continue; - if (mu_argcv_get (str, "", NULL, &argc, &argv) - || argc == 0 - || argv[0][0] == '#') + if (!mu_argcv_get (stmt, "", NULL, &argc, &argv) + && argc > 0 + && argv[0][0] != '#') { - free (str); - mu_argcv_free (argc, argv); - continue; - } - - if (strcmp (argv[0], "beep") == 0) - { - action_beep (tty); - nact++; - } - else if (strcmp (argv[0], "echo") == 0) - { - action_echo (tty, cr, argv[1]); - nact++; - } - else if (strcmp (argv[0], "exec") == 0) - { - action_exec (tty, line, argc-1, argv+1); - nact++; - } - else - { - fprintf (tty, _(".biffrc:%d: unknown keyword"), line); - fprintf (tty, "\r\n"); - syslog (LOG_ERR, _("%s:.biffrc:%d: unknown keyword %s"), - username, line, argv[0]); - break; - } + for(c=1; c