From 9c0ff4fafe4276396125a52c89d36967566fe08c Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Sun, 23 Mar 2014 10:07:26 +0100 Subject: cli: Introduce a logfile command to log errors to a file The evolution would be to introduce libosmocore and start using the logging framework. But even then we can map this option to the file target. Fixes: SYS#263 --- ggsn/cmdline.c | 24 ++++++++++++++++++++++++ ggsn/cmdline.ggo | 2 +- ggsn/cmdline.h | 4 ++++ ggsn/ggsn.c | 12 ++++++++++++ lib/syserr.c | 27 +++++++++++++++++++++++---- lib/syserr.h | 2 ++ 6 files changed, 66 insertions(+), 5 deletions(-) diff --git a/ggsn/cmdline.c b/ggsn/cmdline.c index a84e7e8..3fcfbd5 100644 --- a/ggsn/cmdline.c +++ b/ggsn/cmdline.c @@ -52,6 +52,7 @@ const char *gengetopt_args_info_help[] = { " --timelimit=INT Exit after timelimit seconds (default=`0')", " -a, --apn=STRING Access point name (default=`internet')", " -q, --qos=INT Requested quality of service (default=`0x0b921f')", + " --logfile=STRING Logfile for errors", 0 }; @@ -119,6 +120,7 @@ void clear_given (struct gengetopt_args_info *args_info) args_info->timelimit_given = 0 ; args_info->apn_given = 0 ; args_info->qos_given = 0 ; + args_info->logfile_given = 0 ; } static @@ -155,6 +157,8 @@ void clear_args (struct gengetopt_args_info *args_info) args_info->apn_orig = NULL; args_info->qos_arg = 0x0b921f; args_info->qos_orig = NULL; + args_info->logfile_arg = NULL; + args_info->logfile_orig = NULL; } @@ -181,6 +185,7 @@ void init_args_info(struct gengetopt_args_info *args_info) args_info->timelimit_help = gengetopt_args_info_help[15] ; args_info->apn_help = gengetopt_args_info_help[16] ; args_info->qos_help = gengetopt_args_info_help[17] ; + args_info->logfile_help = gengetopt_args_info_help[18] ; } @@ -290,6 +295,8 @@ cmdline_parser_release (struct gengetopt_args_info *args_info) free_string_field (&(args_info->apn_arg)); free_string_field (&(args_info->apn_orig)); free_string_field (&(args_info->qos_orig)); + free_string_field (&(args_info->logfile_arg)); + free_string_field (&(args_info->logfile_orig)); @@ -356,6 +363,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info) write_into_file(outfile, "apn", args_info->apn_orig, 0); if (args_info->qos_given) write_into_file(outfile, "qos", args_info->qos_orig, 0); + if (args_info->logfile_given) + write_into_file(outfile, "logfile", args_info->logfile_orig, 0); i = EXIT_SUCCESS; @@ -626,6 +635,7 @@ cmdline_parser_internal ( { "timelimit", 1, NULL, 0 }, { "apn", 1, NULL, 'a' }, { "qos", 1, NULL, 'q' }, + { "logfile", 1, NULL, 0 }, { 0, 0, 0, 0 } }; @@ -852,6 +862,20 @@ cmdline_parser_internal ( additional_error)) goto failure; + } + /* Logfile for errors. */ + else if (strcmp (long_options[option_index].name, "logfile") == 0) + { + + + if (update_arg( (void *)&(args_info->logfile_arg), + &(args_info->logfile_orig), &(args_info->logfile_given), + &(local_args_info.logfile_given), optarg, 0, 0, ARG_STRING, + check_ambiguity, override, 0, 0, + "logfile", '-', + additional_error)) + goto failure; + } break; diff --git a/ggsn/cmdline.ggo b/ggsn/cmdline.ggo index e7e0f66..5bb05dc 100644 --- a/ggsn/cmdline.ggo +++ b/ggsn/cmdline.ggo @@ -31,5 +31,5 @@ option "timelimit" - "Exit after timelimit seconds" int default="0" no option "apn" a "Access point name" string default="internet" no option "qos" q "Requested quality of service" int default="0x0b921f" no - +option "logfile" - "Logfile for errors" string no diff --git a/ggsn/cmdline.h b/ggsn/cmdline.h index 1ce222e..f3636e8 100644 --- a/ggsn/cmdline.h +++ b/ggsn/cmdline.h @@ -89,6 +89,9 @@ struct gengetopt_args_info int qos_arg; /**< @brief Requested quality of service (default='0x0b921f'). */ char * qos_orig; /**< @brief Requested quality of service original value given at command line. */ const char *qos_help; /**< @brief Requested quality of service help description. */ + char * logfile_arg; /**< @brief Logfile for errors. */ + char * logfile_orig; /**< @brief Logfile for errors original value given at command line. */ + const char *logfile_help; /**< @brief Logfile for errors help description. */ unsigned int help_given ; /**< @brief Whether help was given. */ unsigned int version_given ; /**< @brief Whether version was given. */ @@ -108,6 +111,7 @@ struct gengetopt_args_info unsigned int timelimit_given ; /**< @brief Whether timelimit was given. */ unsigned int apn_given ; /**< @brief Whether apn was given. */ unsigned int qos_given ; /**< @brief Whether qos was given. */ + unsigned int logfile_given ; /**< @brief Whether logfile was given. */ } ; diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index 1152519..0022b1b 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -283,6 +283,18 @@ int main(int argc, char **argv) if (cmdline_parser_configfile(args_info.conf_arg, &args_info, 0, 0, 0) != 0) exit(1); + + /* Open a log file */ + if (args_info.logfile_arg) { + FILE* log_file = fopen(args_info.logfile_arg, "a"); + if (!log_file) { + printf("Failed to open logfile: '%s'\n", + args_info.logfile_arg); + exit(1); + } + sys_err_setlogfile(log_file); + } + if (args_info.debug_flag) { printf("cmdline_parser_configfile\n"); printf("listen: %s\n", args_info.listen_arg); diff --git a/lib/syserr.c b/lib/syserr.c index 048cd45..66a2067 100644 --- a/lib/syserr.c +++ b/lib/syserr.c @@ -20,6 +20,13 @@ #include "syserr.h" +static FILE* err_log; + +void sys_err_setlogfile(FILE* log) +{ + err_log = log; +} + void sys_err(int pri, char *fn, int ln, int en, char *fmt, ...) { va_list args; @@ -29,11 +36,17 @@ void sys_err(int pri, char *fn, int ln, int en, char *fmt, ...) vsnprintf(buf, SYSERR_MSGSIZE, fmt, args); va_end(args); buf[SYSERR_MSGSIZE - 1] = 0; /* Make sure it is null terminated */ - if (en) + if (en) { + if (err_log) + fprintf(err_log, "%s: %d: %d (%s) %s\n", + fn, ln, en, strerror(en), buf); syslog(pri, "%s: %d: %d (%s) %s", fn, ln, en, strerror(en), buf); - else + } else { + if (err_log) + fprintf(err_log, "%s: %d: %s\n", fn, ln, buf); syslog(pri, "%s: %d: %s", fn, ln, buf); + } } void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer, @@ -65,10 +78,16 @@ void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer, } buf2[pos] = 0; - if (en) + if (en) { + if (err_log) + fprintf(err_log, "%s: %d: %d (%s) %s. %s\n", + fn, ln, en, strerror(en), buf, buf2); syslog(pri, "%s: %d: %d (%s) %s. %s", fn, ln, en, strerror(en), buf, buf2); - else + } else { + if (err_log) + fprintf(err_log, "%s: %d: %s. %s\n", fn, ln, buf, buf2); syslog(pri, "%s: %d: %s. %s", fn, ln, buf, buf2); + } } diff --git a/lib/syserr.h b/lib/syserr.h index e3ebdf0..a65dfc3 100644 --- a/lib/syserr.h +++ b/lib/syserr.h @@ -14,6 +14,8 @@ #define SYSERR_MSGSIZE 256 +void sys_err_setlogfile(FILE*); + void sys_err(int pri, char *filename, int en, int line, char *fmt, ...); void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer, void *pack, unsigned len, char *fmt, ...); -- cgit v1.2.3