From 14084ab9bb40b2301a0d31e4260e307cc05a8818 Mon Sep 17 00:00:00 2001 From: Brooks Davis Date: Wed, 5 Mar 2008 17:51:06 +0000 Subject: [PATCH] Add the ability to read a file of commands to ddb(8) modeled after the feature in ipfw(8). --- sbin/ddb/ddb.8 | 14 ++++++++++ sbin/ddb/ddb.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 81 insertions(+), 5 deletions(-) diff --git a/sbin/ddb/ddb.8 b/sbin/ddb/ddb.8 index b23314339fa7..9f355f2c4531 100644 --- a/sbin/ddb/ddb.8 +++ b/sbin/ddb/ddb.8 @@ -43,6 +43,8 @@ .Nm .Cm unscript .Ar scriptname +.Nm +.Ar pathname .Sh DESCRIPTION .Nm configures certain aspects of the @@ -51,6 +53,18 @@ kernel debugger from user space that are not configured at compile-time or easily via .Xr sysctl 8 MIB entries. +.Pp +To ease configuration, commands can be put in a file which is processed using +.Nm +as shown in the last synopsis line. +An absolute +.Ar pathname +must be used. +The file will be read line by line and applied as arguments to the +.Nm +utility. +Whitespace at the beginning of lines will be ignored as will lines where the +first non-whitespace character is #. .Sh SCRIPTING .Nm can be used to configure aspects of diff --git a/sbin/ddb/ddb.c b/sbin/ddb/ddb.c index 9ca0d57e6732..869e34c30bab 100644 --- a/sbin/ddb/ddb.c +++ b/sbin/ddb/ddb.c @@ -27,13 +27,18 @@ #include __FBSDID("$FreeBSD$"); +#include #include #include #include #include +#include #include "ddb.h" +void ddb_readfile(char *file); +void ddb_main(int argc, char *argv[]); + void usage(void) { @@ -46,15 +51,58 @@ usage(void) exit(EX_USAGE); } -int -main(int argc, char *argv[]) +void +ddb_readfile(char *filename) +{ + char buf[BUFSIZ]; + FILE* f; + + if ((f = fopen(filename, "r")) == NULL) + err(EX_UNAVAILABLE, "fopen: %s", filename); + +#define WHITESP " \t" +#define MAXARG 2 + while (fgets(buf, BUFSIZ, f)) { + int argc = 0; + char *argv[MAXARG]; + size_t spn; + + spn = strlen(buf); + if (buf[spn-1] == '\n') + buf[spn-1] = '\0'; + + spn = strspn(buf, WHITESP); + argv[0] = buf + spn; + if (*argv[0] == '#' || *argv[0] == '\0') + continue; + argc++; + + spn = strcspn(argv[0], WHITESP); + argv[1] = argv[0] + spn + strspn(argv[0] + spn, WHITESP);; + argv[0][spn] = '\0'; + if (*argv[1] != '\0') + argc++; + +#ifdef DEBUG + { + int i; + printf("argc = %d\n", argc); + for (i = 0; i < argc; i++) { + printf("arg[%d] = %s\n", i, argv[i]); + } + } +#endif + ddb_main(argc, argv); + } +} + +void +ddb_main(int argc, char *argv[]) { - if (argc < 2) + if (argc < 1) usage(); - argc -= 1; - argv += 1; if (strcmp(argv[0], "script") == 0) ddb_script(argc, argv); else if (strcmp(argv[0], "scripts") == 0) @@ -63,5 +111,19 @@ main(int argc, char *argv[]) ddb_unscript(argc, argv); else usage(); +} + +int +main(int argc, char *argv[]) +{ + + /* + * If we've only got one argument and it's an absolute path to a file, + * interpret as a file to be read in. + */ + if (argc == 2 && argv[1][0] == '/' && access(argv[1], R_OK) == 0) + ddb_readfile(argv[1]); + else + ddb_main(argc-1, argv+1); exit(EX_OK); }