diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2001-11-12 13:10:38 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2001-11-12 13:10:38 +0000 |
commit | 814b830cdb12753fb7983a2a2a470c33fbb6bd2c (patch) | |
tree | 411b185502e4d8af7492490f965444df1be2a5fc /comsat | |
parent | b1b6fda270d7bff800d497ce5948cafda99edad2 (diff) | |
download | mailutils-814b830cdb12753fb7983a2a2a470c33fbb6bd2c.tar.gz mailutils-814b830cdb12753fb7983a2a2a470c33fbb6bd2c.tar.bz2 |
Implemented exec. Fixed trivial bug in expand_escape().
Diffstat (limited to 'comsat')
-rw-r--r-- | comsat/action.c | 75 |
1 files changed, 66 insertions, 9 deletions
diff --git a/comsat/action.c b/comsat/action.c index 1be35ca6e..0e65601ef 100644 --- a/comsat/action.c +++ b/comsat/action.c @@ -26,7 +26,8 @@ beep -- Produce audible signal echo STRING -- Output STRING to the user's tty - exec PROG ARGS... -- Execute given program (not yet implemented) + exec PROG ARGS... -- Execute given program (absolute pathname + required) Following metacharacters are accepted in strings: @@ -95,7 +96,7 @@ backslash(int c) } int -expand_escape (char **pp, message_t msg, struct obstack *stk) +expand_escape (char **pp, message_t msg, char *cr, struct obstack *stk) { char *p = *pp; char *start, *sval, *namep; @@ -153,7 +154,6 @@ expand_escape (char **pp, message_t msg, struct obstack *stk) lncount = strtoul (p + 1, &p, 0); if (*p != ')') break; - p++; } if (size == 0) size = 400; @@ -177,12 +177,13 @@ expand_escape (char **pp, message_t msg, struct obstack *stk) while (lncount--) { char *s = strchr (q, '\n'); - if (!q) + if (!s) break; - size += s - q + 1; + size = s - q; + obstack_grow (stk, q, size); + obstack_grow (stk, cr, strlen (cr)); q = s + 1; } - obstack_grow (stk, buf, size); } free (buf); } @@ -228,7 +229,7 @@ expand_line (char *str, char *cr, message_t msg) } break; case '$': - if (expand_escape (&p, msg, &stk) == 0) + if (expand_escape (&p, msg, cr, &stk) == 0) break; /*FALLTHRU*/ default: @@ -242,7 +243,8 @@ expand_line (char *str, char *cr, message_t msg) } char *default_action = -"Mail to \a$u@$h\a ---\n" +"Mail to \a$u@$h\a\n" +"---\n" "From: $H{from}\n" "Subject: $H{Subject}\n" "---\n" @@ -270,12 +272,61 @@ action_echo (FILE *tty, char *str) fprintf (tty, "%s", str); } +void +action_exec (FILE *tty, int line, int argc, char **argv) +{ + pid_t pid; + struct stat stb; + + if (argc == 0) + { + syslog (LOG_ERR, "%s:.biffrc:%d: No arguments for exec", username, line); + return; + } + + if (argv[0][0] != '/') + { + syslog (LOG_ERR, "%s:.biffrc:%d: Not an absolute pathname", + username, line); + return; + } + + if (stat (argv[0], &stb)) + { + syslog (LOG_ERR, "%s:.biffrc:%d: can't stat %s: %s", + username, line, argv[0], strerror (errno)); + return; + } + + if (stb.st_mode & (S_ISUID|S_ISGID)) + { + syslog (LOG_ERR, "%s:.biffrc:%d: won't execute set[ug]id programs", + username, line); + return; + } + + pid = fork (); + if (pid == 0) + { + close (1); + close (2); + dup2 (fileno (tty), 1); + dup2 (fileno (tty), 2); + fclose (tty); + execv (argv[0], argv); + syslog (LOG_ERR, "can't execute %s: %s", argv[0], strerror (errno)); + } +} + FILE * open_rc (char *filename, FILE *tty) { struct stat stb; struct passwd *pw = getpwnam (username); - + + /* To be on the safe side, we do not allow root to have his .biffrc */ + if (!allow_biffrc || pw->pw_uid == 0) + return NULL; if (stat (filename, &stb) == 0) { if (stb.st_uid != pw->pw_uid) @@ -337,8 +388,14 @@ run_user_action (FILE *tty, char *cr, message_t msg) action_echo (tty, 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\r\n"); syslog (LOG_ERR, "%s:.biffrc:%d: unknown keyword %s", username, line, argv[0]); break; |