From 3cfb1d880ebf22546486316cb74cce21f007eb07 Mon Sep 17 00:00:00 2001 From: Andre Noll Date: Sun, 18 Jan 2009 02:25:42 +0100 Subject: [PATCH] Use symbolic names for loglevels and clean up the ggo mess. We now use m4 to generate the ggo files, which allows to get rid of a lot of duplicated command line options and improves the readability of the man pages. --- INSTALL | 10 +-- Makefile.in | 32 ++++---- NEWS | 5 +- README.afs | 2 +- REQUIREMENTS | 1 + afh.c | 5 +- audioc.c | 4 +- audiod.c | 2 +- bash_completion | 2 +- client.c | 4 +- client_common.c | 2 +- command.c | 2 +- daemon.c | 31 ++------ daemon.h | 4 +- filter.c | 4 +- fsck.c | 8 +- ggo/{afh.ggo => afh.m4} | 12 +-- ggo/{audioc.ggo => audioc.m4} | 10 +-- ggo/{audiod.ggo => audiod.m4} | 74 ++++--------------- ggo/{client.ggo => client.m4} | 14 +++- ggo/color.m4 | 34 +++++++++ ggo/config_file.m4 | 14 ++++ ggo/daemon.m4 | 11 +++ ggo/{filter.ggo => filter.m4} | 11 +-- ggo/{fsck.ggo => fsck.m4} | 12 +-- ggo/group.m4 | 12 +++ ggo/{gui.ggo => gui.m4} | 30 +++----- ggo/header.m4 | 1 + ggo/logfile.m4 | 11 +++ ggo/loglevel.m4 | 22 ++++++ ggo/{Makefile.ggo => makefile} | 17 +++++ ggo/{recv.ggo => recv.m4} | 11 +-- ggo/{server.ggo => server.m4} | 130 +++++---------------------------- ggo/user.m4 | 21 ++++++ ggo/{write.ggo => write.m4} | 8 +- gui.c | 20 ++--- recv.c | 7 +- server.c | 6 +- string.c | 19 +++++ string.h | 1 + write.c | 4 +- 41 files changed, 315 insertions(+), 315 deletions(-) rename ggo/{afh.ggo => afh.m4} (96%) rename ggo/{audioc.ggo => audioc.m4} (70%) rename ggo/{audiod.ggo => audiod.m4} (82%) rename ggo/{client.ggo => client.m4} (69%) create mode 100644 ggo/color.m4 create mode 100644 ggo/config_file.m4 create mode 100644 ggo/daemon.m4 rename ggo/{filter.ggo => filter.m4} (80%) rename ggo/{fsck.ggo => fsck.m4} (85%) create mode 100644 ggo/group.m4 rename ggo/{gui.ggo => gui.m4} (65%) create mode 100644 ggo/header.m4 create mode 100644 ggo/logfile.m4 create mode 100644 ggo/loglevel.m4 rename ggo/{Makefile.ggo => makefile} (74%) rename ggo/{recv.ggo => recv.m4} (67%) rename ggo/{server.ggo => server.m4} (68%) create mode 100644 ggo/user.m4 rename ggo/{write.ggo => write.m4} (84%) diff --git a/INSTALL b/INSTALL index 4d89153f..b0bbbadb 100644 --- a/INSTALL +++ b/INSTALL @@ -99,10 +99,10 @@ the directory /var/paraslash. Alternatively, use the --afs_socket Option to specify a different location for the afs command socket. -For this first try, we'll use a debug level of two to make the -output of para_server more verbose. +For this first try, we'll use the info loglevel to make the output +of para_server more verbose. - para_server -l 2 + para_server -l info Now you can use para_client to connect to the server and issue commands. Open a new shell (as "bar" on "client_host" in the above @@ -164,7 +164,7 @@ Paraslash comes with its own receiving and playing software, which will be described next. Try the following on client_host (assuming Linux/ALSA and an mp3 stream): - para_recv -l 2 -r 'http -i server_host' > file.mp3 + para_recv -l info -r 'http -i server_host' > file.mp3 # (interrupt with CTRL+C after a few seconds) ls -l file.mp3 # should not be empty para_filter -f mp3dec -f wav < file.mp3 > file.wav @@ -196,7 +196,7 @@ supposed to play the audio stream. Try for help. Usually you have to specify only server_host as the receiver specifier for each supported audio format, like this: - para_audiod -l 2 -r 'mp3:http -i server_host' + para_audiod -l info -r 'mp3:http -i server_host' The preferred way to use para_audiod is to run it once at system start as an unprivileged user. para_audiod needs to create a "well-known" diff --git a/Makefile.in b/Makefile.in index fc0ffa48..670be971 100644 --- a/Makefile.in +++ b/Makefile.in @@ -60,15 +60,21 @@ BINARIES = para_server para_client para_audioc para_recv \ man_binaries := $(BINARIES) man_pages := $(patsubst %, man/man1/%.1, $(man_binaries)) man_pages_in := $(patsubst %, web/%.man.in.html, $(man_binaries)) + ggo_dir := ggo -gengetopts := $(wildcard $(ggo_dir)/*.ggo) -gengetopts_c := $(patsubst %/,, $(gengetopts:.ggo=.cmdline.c)) -gengetopts_h := $(patsubst %/,, $(gengetopts:.ggo=.cmdline.h)) + +m4_ggos := afh audioc audiod client filter fsck gui recv server write +all_ggos := $(m4_ggos) dccp_recv oggdec_filter alsa_write fade http_recv \ + osx_write udp_recv amp_filter compress_filter file_write \ + grab_client mp3dec_filter +ggo_generated := $(addsuffix .cmdline.c, $(all_ggos)) $(addsuffix .cmdline.h, $(all_ggos)) \ + $(addsuffix .ggo, $(addprefix $(ggo_dir)/,$(m4_ggos))) + autocrap := config.h.in configure tarball_pfx := @PACKAGE_TARNAME@-$(PACKAGE_VERSION) tarball_delete = web versions pics .changelog_before_cvs .changelog_cvs .gitignore tarball_delete := $(patsubst %,$(tarball_pfx)/%,$(tarball_delete)) -tarball_add := $(gengetopts_c) $(gengetopts_h) $(autocrap) +tarball_add := $(ggo_generated) $(autocrap) tarball := @PACKAGE_TARNAME@-$(PACKAGE_VERSION).tar.bz2 .PHONY: clean distclean maintainer-clean install man tarball @@ -79,7 +85,7 @@ tarball: $(tarball) *.o: para.h config.h gcc-compat.h include Makefile.deps -include $(ggo_dir)/Makefile.ggo +include $(ggo_dir)/makefile %_command_list.c %_command_list.h: %.cmd ./command_util.sh c < $< >$@ @@ -98,21 +104,9 @@ man/man1/para_audiod.1: para_audiod audiod_command_list.man mkdir -p man/man1 help2man -h --detailed-help -N -i audiod_command_list.man ./para_audiod > $@ -man/man1/para_filter.1: para_filter - mkdir -p man/man1 - help2man -h --detailed-help -N ./$< > $@ - -man/man1/para_write.1: para_write - mkdir -p man/man1 - help2man -h --detailed-help -N ./$< > $@ - -man/man1/para_recv.1: para_recv - mkdir -p man/man1 - help2man -h --detailed-help -N ./$< > $@ - man/man1/%.1: % mkdir -p man/man1 - help2man -N ./$< > $@ + help2man -h --detailed-help -N ./$< > $@ man/html/%.html: man/man1/%.1 mkdir -p man/html @@ -187,7 +181,7 @@ distclean: clean rm -f GPATH GRTAGS GSYMS GTAGS maintainer-clean: distclean - rm -f $(gengetopts_c) $(gengetopts_h) *.tar.bz2 \ + rm -f $(ggo_generated) *.tar.bz2 \ config.h configure \ config.h.in skencil/*.pdf skencil/*.ps rm -f *_command_list.* *.man man/man1/* diff --git a/NEWS b/NEWS index fdc4c071..5464bd7a 100644 --- a/NEWS +++ b/NEWS @@ -5,7 +5,7 @@ NEWS 0.3.4 (to be announced) "elliptic inheritance" ---------------------------------------------- -The new udp sender and various other improvements. +The new udp sender, colored logs and various other improvements. - The udp sender replaces the ortp sender. The new code is both smaller and cleaner than the old ortp sender/receiver @@ -13,9 +13,12 @@ The new udp sender and various other improvements. libraries, it is built unconditionally. The default port for udp streaming now defaults to 8000, like for the http and the dccp senders/receivers. + - Loglevels are now specified as symbolic names, e.g. + "--loglevel info". - para_server/para_audiod: Color support for log messages. - new options for mp3dec: --ignore-crc, --bufsize - new audiod option: --config-file. + - gengetopt cleanups. - Improved help/man pages: The documentation of para_audiod, para_recv, para_filter and para_write now also contains all options of the available receivers/filters/writers. The diff --git a/README.afs b/README.afs index 01d4b52e..ca01df6a 100644 --- a/README.afs +++ b/README.afs @@ -225,7 +225,7 @@ songs is Troubles? --------- -Use the debug loglevel (option -l 0 for most commands) to show +Use the debug loglevel (option -l debug for most commands) to show debugging info. Almost all paraslash executables have a brief online help which is displayed by using the -h switch. The --detailed-help option prints the full help text. diff --git a/REQUIREMENTS b/REQUIREMENTS index 889ad5f9..c1743fd2 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS @@ -53,3 +53,4 @@ Hacking the source: - grutatxt http://www.triptico.com/software/grutatxt.html - doxygen http://www.stack.nl/~dimitri/doxygen/ - global ftp://ftp.gnu.org/pub/gnu/global + - m4: ftp://ftp.gnu.org/pub/gnu/m4/ diff --git a/afh.c b/afh.c index 2d92d04d..fad93c49 100644 --- a/afh.c +++ b/afh.c @@ -21,7 +21,9 @@ static struct afh_args_info conf; const char *status_item_list[] = {STATUS_ITEM_ARRAY}; INIT_AFH_ERRLISTS; -INIT_STDERR_LOGGING(conf.loglevel_arg) + +static int loglevel; +INIT_STDERR_LOGGING(loglevel) static void print_info(int audio_format_num, struct afh_info *afhi) { @@ -139,6 +141,7 @@ int main(int argc, char **argv) afh_cmdline_parser(argc, argv, &conf); HANDLE_VERSION_FLAG("afh", conf); + loglevel = get_loglevel_by_name(conf.loglevel_arg); ret = -E_AFH_SYNTAX; if (conf.inputs_num == 0) goto out; diff --git a/audioc.c b/audioc.c index 0c2049ad..666990db 100644 --- a/audioc.c +++ b/audioc.c @@ -21,7 +21,8 @@ INIT_AUDIOC_ERRLISTS; /** the gengetopt structure containing command line args */ struct audioc_args_info conf; -INIT_STDERR_LOGGING(conf.loglevel_arg); +static int loglevel; +INIT_STDERR_LOGGING(loglevel); static char *concat_args(unsigned argc, char * const *argv) { @@ -87,6 +88,7 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } } + loglevel = get_loglevel_by_name(conf.loglevel_arg); args = conf.inputs_num? concat_args(conf.inputs_num, conf.inputs) : para_strdup("stat"); diff --git a/audiod.c b/audiod.c index b781527c..a92c4e3b 100644 --- a/audiod.c +++ b/audiod.c @@ -1143,7 +1143,7 @@ int main(int argc, char *argv[]) PARA_EMERG_LOG("init stream io error: %s\n", para_strerror(-i)); exit(EXIT_FAILURE); } - log_welcome("para_audiod", conf.loglevel_arg); + log_welcome("para_audiod"); server_uptime(UPTIME_SET); set_initial_status(); FOR_EACH_SLOT(i) diff --git a/bash_completion b/bash_completion index aeee64c1..cd647e20 100644 --- a/bash_completion +++ b/bash_completion @@ -2,7 +2,7 @@ # # Licensed under the GPL v2. For licencing details see COPYING. -PC="para_client -l 5 -- " +PC="para_client -l error -- " __para_commandlist= __para_sender_list= diff --git a/client.c b/client.c index 10cb8050..fdd07b24 100644 --- a/client.c +++ b/client.c @@ -54,7 +54,8 @@ static struct task svt = { .status = "supervisor task" }; -INIT_STDERR_LOGGING(ct->conf.loglevel_arg); +static int client_loglevel; /* loglevel */ +INIT_STDERR_LOGGING(client_loglevel); /** @@ -82,6 +83,7 @@ int main(int argc, char *argv[]) ret = client_open(argc, argv, &ct); if (ret < 0) /* can not use PARA_LOG here because ct is NULL */ exit(EXIT_FAILURE); + client_loglevel = get_loglevel_by_name(ct->conf.loglevel_arg); register_task(&svt); ret = schedule(&s); if (ret < 0) diff --git a/client_common.c b/client_common.c index e5be430d..e757a3a7 100644 --- a/client_common.c +++ b/client_common.c @@ -364,7 +364,7 @@ int client_open(int argc, char *argv[], struct client_task **ct_ptr) goto out; } ret = 1; - PARA_INFO_LOG("loglevel: %d\n", ct->conf.loglevel_arg); + PARA_INFO_LOG("loglevel: %s\n", ct->conf.loglevel_arg); PARA_INFO_LOG("config_file: %s\n", ct->config_file); PARA_INFO_LOG("key_file: %s\n", ct->key_file); PARA_NOTICE_LOG("connecting %s:%d\n", ct->conf.hostname_arg, diff --git a/command.c b/command.c index 19a9aa7e..9abe04a3 100644 --- a/command.c +++ b/command.c @@ -283,7 +283,7 @@ int com_si(int fd, int argc, __a_unused char * const * argv) "server_pid: %d\n" "afs_pid: %d\n" "connections (active/accepted/total): %u/%u/%u\n" - "current loglevel: %i\n" + "current loglevel: %s\n" "supported audio formats: %s\n" "supported senders: %s\n" "%s", diff --git a/daemon.c b/daemon.c index 2f706b01..cae63ea7 100644 --- a/daemon.c +++ b/daemon.c @@ -58,25 +58,6 @@ void daemon_set_default_log_colors(void) } } -static int get_loglevel_by_name(const char *txt, size_t n) -{ - if (!strncasecmp(txt, "debug", n)) - return LL_DEBUG; - if (!strncasecmp(txt, "info", n)) - return LL_INFO; - if (!strncasecmp(txt, "notice", n)) - return LL_NOTICE; - if (!strncasecmp(txt, "warning", n)) - return LL_WARNING; - if (!strncasecmp(txt, "error", n)) - return LL_ERROR; - if (!strncasecmp(txt, "crit", n)) - return LL_CRIT; - if (!strncasecmp(txt, "emerg", n)) - return LL_EMERG; - return -1; -} - /** * Set the color for one loglevel. * @@ -93,7 +74,7 @@ int daemon_set_log_color(char const *arg) if (!p) goto err; - ret = get_loglevel_by_name(arg, p - arg); + ret = get_loglevel_by_name(arg); if (ret < 0) goto err; ll = ret; @@ -126,9 +107,12 @@ void daemon_set_logfile(char *logfile_name) * * \param loglevel The smallest level that should be logged. */ -void daemon_set_loglevel(int loglevel) +void daemon_set_loglevel(char *loglevel) { - me->loglevel = loglevel; + int ret = get_loglevel_by_name(loglevel); + + assert(ret >= 0); + me->loglevel = ret; } /** @@ -234,11 +218,10 @@ void daemon_open_log_or_die(void) /** * Log the startup message containing the paraslash version. */ -void log_welcome(const char *whoami, int loglevel) +void log_welcome(const char *whoami) { PARA_INFO_LOG("welcome to %s " PACKAGE_VERSION " ("BUILD_DATE")\n", whoami); - PARA_DEBUG_LOG("using loglevel %d\n", loglevel); } /** diff --git a/daemon.h b/daemon.h index c0a9f20c..c8dd997f 100644 --- a/daemon.h +++ b/daemon.h @@ -4,7 +4,7 @@ void daemonize(void); void daemon_open_log_or_die(void); void daemon_close_log(void); -void log_welcome(const char *whoami, int loglevel); +void log_welcome(const char *whoami); void drop_privileges_or_die(const char *username, const char *groupname); /** used for server_uptime() */ enum uptime {UPTIME_SET, UPTIME_GET}; @@ -13,7 +13,7 @@ __malloc char *uptime_str(void); void daemon_set_logfile(char *logfile_name); void daemon_set_flag(unsigned flag); void daemon_clear_flag(unsigned flag); -void daemon_set_loglevel(int loglevel); +void daemon_set_loglevel(char *loglevel); void daemon_set_default_log_colors(void); int daemon_set_log_color(char const *arg); diff --git a/filter.c b/filter.c index 50b17ad7..96880b7d 100644 --- a/filter.c +++ b/filter.c @@ -44,7 +44,8 @@ static struct stdout_task *sot = &stdout_task_struct; /** Gengetopt struct that holds the command line args. */ static struct filter_args_info conf; -INIT_STDERR_LOGGING(conf.loglevel_arg); +static int loglevel; +INIT_STDERR_LOGGING(loglevel); static void open_filters(void) { @@ -162,6 +163,7 @@ int main(int argc, char *argv[]) ret = parse_config(argc, argv); if (ret < 0) goto out; + loglevel = get_loglevel_by_name(conf.loglevel_arg); ret = init_filter_chain(); if (ret < 0) goto out; diff --git a/fsck.c b/fsck.c index 04db5de3..3b605c2d 100644 --- a/fsck.c +++ b/fsck.c @@ -19,7 +19,9 @@ static struct fsck_args_info conf; INIT_FSCK_ERRLISTS; -INIT_STDERR_LOGGING(conf.loglevel_arg); + +static int loglevel; +INIT_STDERR_LOGGING(loglevel); /* taken from git */ signed char hexval_table[256] = { @@ -955,6 +957,7 @@ int main(int argc, char **argv) goto out; } HANDLE_VERSION_FLAG("fsck", conf); + loglevel = get_loglevel_by_name(conf.loglevel_arg); if (conf.base_dir_given) base_dir = para_strdup(conf.base_dir_arg); else { @@ -978,9 +981,6 @@ out: base_dir? base_dir : "", para_strerror(-ret) ); - if (conf.loglevel_arg > 1) - PARA_EMERG_LOG("re-run with \"--loglevel %d\" to increase verbosity\n", - conf.loglevel_arg - 1); } else PARA_NOTICE_LOG("success\n"); if (base_dir) diff --git a/ggo/afh.ggo b/ggo/afh.m4 similarity index 96% rename from ggo/afh.ggo rename to ggo/afh.m4 index 056a34da..97b8f288 100644 --- a/ggo/afh.ggo +++ b/ggo/afh.m4 @@ -1,3 +1,5 @@ +include(header.m4) + text " para_afh, the audio format handler tool, is a stand-alone program contained in the paraslash package for analyzing and streaming audio @@ -17,14 +19,11 @@ files. It can be used to to sdout. This may be useful for third-party software that is capable of reading from stdin. " + -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ -"set loglevel (0-6)" -int typestr="level" -default="4" -optional +include(loglevel.m4) + defgroup "mode" #-------------- groupdesc=" @@ -120,3 +119,4 @@ details=" send. This option changes the default behaviour, i.e. no header is written. " + diff --git a/ggo/audioc.ggo b/ggo/audioc.m4 similarity index 70% rename from ggo/audioc.ggo rename to ggo/audioc.m4 index 87ef71e3..ad112e27 100644 --- a/ggo/audioc.ggo +++ b/ggo/audioc.m4 @@ -1,11 +1,5 @@ -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ -"set loglevel (0-6)" - int typestr="level" - default="4" - optional - - +include(header.m4) +include(loglevel.m4) option "socket" s #~~~~~~~~~~~~~~~~ "well-known socket (default=/var/paraslash/audiod.socket.$HOSTNAME)" diff --git a/ggo/audiod.ggo b/ggo/audiod.m4 similarity index 82% rename from ggo/audiod.ggo rename to ggo/audiod.m4 index 6048b874..5390d1b0 100644 --- a/ggo/audiod.ggo +++ b/ggo/audiod.m4 @@ -1,67 +1,22 @@ +include(header.m4) +define(CURRENT_PROGRAM,para_audiod) +define(DEFAULT_CONFIG_FILE,~/.paraslash/audiod.conf) + + ######################### section "General options" ######################### + -text " - These options are identical to their counterparts in para_server - and are discussed in detail there. -" - -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ -"set loglevel (0-6)" -int typestr="level" -default="3" -optional - -option "color" C -#~~~~~~~~~~~~~~~ -"activate color output" -enum typestr="when" -values = "yes","no","auto" -default = "auto" -optional - -option "log_color" - -#~~~~~~~~~~~~~~~~~~~ -"select a color for one type of log message" -string typestr="color_spec" -multiple -optional -details=" - Example: --log_color \"INFO:yellow black bold\" -" - -option "config_file" c -#~~~~~~~~~~~~~~~~~~~~~ -"(default='~/.paraslash/audiod.conf'" -string typestr="filename" -optional - -option "logfile" L -#~~~~~~~~~~~~~~~~~ -"where to write log output" -string typestr="filename" -optional - -option "daemon" d -#~~~~~~~~~~~~~~~~ -"run as background daemon" -flag off -dependon="logfile" - -option "user" u -#~~~~~~~~~~~~~~ -"run as the given user" -string typestr="name" -optional - -option "group" g -#~~~~~~~~~~~~~~~ -"set group id" -string typestr="group" -optional +include(loglevel.m4) +include(color.m4) +include(config_file.m4) +include(logfile.m4) +include(daemon.m4) +include(user.m4) +include(group.m4) + ######################## section "Audiod options" ######################## @@ -237,3 +192,4 @@ details=" This is useful mainly for syncronizing the audio output of different clients. " + diff --git a/ggo/client.ggo b/ggo/client.m4 similarity index 69% rename from ggo/client.ggo rename to ggo/client.m4 index 1d6b410d..1ae5a38a 100644 --- a/ggo/client.ggo +++ b/ggo/client.m4 @@ -1,9 +1,17 @@ -# file client.conf +include(header.m4) +define(CURRENT_PROGRAM,para_client) +define(DEFAULT_CONFIG_FILE,~/.paraslash/client.conf) + args "--no-handle-error" option "hostname" i "ip or host to connect" string typestr="host" default="localhost" optional option "user" u "paraslash username" string typestr="username" default="" optional option "server_port" p "port to connect" int typestr="port" default="2990" optional option "key_file" k "(default='~/.paraslash/key.')" string typestr="filename" optional -option "loglevel" l "set loglevel (0-6)" int typestr="number" default="5" optional -option "config_file" c "(default='~/.paraslash/client.conf')" string typestr="filename" optional + + +include(loglevel.m4) +include(config_file.m4) + + option "plain" - "request an uncrypted session" flag off + diff --git a/ggo/color.m4 b/ggo/color.m4 new file mode 100644 index 00000000..63e996f3 --- /dev/null +++ b/ggo/color.m4 @@ -0,0 +1,34 @@ + + +option "color" C +#~~~~~~~~~~~~~~~ +"activate color output" +enum typestr="when" +values = "yes","no","auto" +default = "auto" +optional + +option "log_color" - +#~~~~~~~~~~~~~~~~~~~ +"select a color for one type of log message" +string typestr="color_spec" +multiple +optional +details=" + The format of \"color_spec\" is [fg [bg]] [attr]. + + Valid colors for \"fg\" and \"bg\" are \"normal\", \"black\", + \"red\", \"green\", \"yellow\", \"blue\", \"magenta\", + \"cyan\", and \"white\". + + The \"attr\" value must be one of \"bold\", \"dim\", \"ul\", + \"blink\", \"reverse\". + + Examples: + + --log_color \"debug:green\" + --log_color \"info:yellow bold\" + --log_color \"notice:white red bold\" +" + + diff --git a/ggo/config_file.m4 b/ggo/config_file.m4 new file mode 100644 index 00000000..9e2ca407 --- /dev/null +++ b/ggo/config_file.m4 @@ -0,0 +1,14 @@ + +option "config_file" c +#~~~~~~~~~~~~~~~~~~~~~ +"(default='DEFAULT_CONFIG_FILE'" +string typestr="filename" +optional +details=" + CURRENT_PROGRAM reads its config file right after parsing + the options that were given at the command line. If an + option is given both at the command line and in the + config file, the value that was specified at the command line + takes precedence. +" + diff --git a/ggo/daemon.m4 b/ggo/daemon.m4 new file mode 100644 index 00000000..b4e842ac --- /dev/null +++ b/ggo/daemon.m4 @@ -0,0 +1,11 @@ + +option "daemon" d +#~~~~~~~~~~~~~~~~ +"run as background daemon" +flag off +dependon="logfile" +details=" + Note that CURRENT_PROGRAM refuses to start in daemon mode if no + logfile was specified. +" + diff --git a/ggo/filter.ggo b/ggo/filter.m4 similarity index 80% rename from ggo/filter.ggo rename to ggo/filter.m4 index e3ac59a2..4e991764 100644 --- a/ggo/filter.ggo +++ b/ggo/filter.m4 @@ -1,10 +1,6 @@ -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ - "set loglevel (0-6)" -int typestr="level" -default="3" -optional - +include(header.m4) +include(loglevel.m4) + option "filter" f #~~~~~~~~~~~~~~~~ "Specify filter." @@ -22,3 +18,4 @@ details=" -f 'compress --inertia 5 --damp 2' " + diff --git a/ggo/fsck.ggo b/ggo/fsck.m4 similarity index 85% rename from ggo/fsck.ggo rename to ggo/fsck.m4 index eb7c6275..d593058e 100644 --- a/ggo/fsck.ggo +++ b/ggo/fsck.m4 @@ -1,12 +1,7 @@ -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ - -"set loglevel (0-6)" - - int typestr="level" - default="2" - optional +include(header.m4) +include(loglevel.m4) + option "base_dir" b #~~~~~~~~~~~~~~~~~~ "Full path to the database directory @@ -45,3 +40,4 @@ option "dry_run" - flag off + diff --git a/ggo/group.m4 b/ggo/group.m4 new file mode 100644 index 00000000..2a59ad9a --- /dev/null +++ b/ggo/group.m4 @@ -0,0 +1,12 @@ +option "group" g +#~~~~~~~~~~~~~~~ +"set group id" +string typestr="group" +optional +details=" + This option sets the group id according to 'group'. This option + is silently ignored if EUID != 0. Otherwise, real/effective + GID and the saved set-group ID are all set to the GID given by + 'group'. Must not be given in the config file. +" + diff --git a/ggo/gui.ggo b/ggo/gui.m4 similarity index 65% rename from ggo/gui.ggo rename to ggo/gui.m4 index a90d1b4f..dd1e2496 100644 --- a/ggo/gui.ggo +++ b/ggo/gui.m4 @@ -1,25 +1,16 @@ -#------------------------ -section "general options" -#------------------------ - -option "config_file" c -#~~~~~~~~~~~~~~~~~~~~~~ -"(default='~/.paraslash/gui.conf')" +include(header.m4) +define(CURRENT_PROGRAM,para_gui) - string typestr="filename" - optional + +######################### +section "general options" +######################### + -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ - "set loglevel (0-6)" -int typestr="level" -default="3" -optional -details=" - See \"para_server --detailed-help\" for the discussion of - loglevels. -" +include(config_file.m4) +include(loglevel.m4) + option "timeout" t #~~~~~~~~~~~~~~~~~ "set timeout" @@ -53,3 +44,4 @@ for each key mapping." string typestr="k:m:c" optional multiple + diff --git a/ggo/header.m4 b/ggo/header.m4 new file mode 100644 index 00000000..c4231879 --- /dev/null +++ b/ggo/header.m4 @@ -0,0 +1 @@ +changequote(,) diff --git a/ggo/logfile.m4 b/ggo/logfile.m4 new file mode 100644 index 00000000..bb102939 --- /dev/null +++ b/ggo/logfile.m4 @@ -0,0 +1,11 @@ + +option "logfile" L +#~~~~~~~~~~~~~~~~~ +"where to write log output" +string typestr="filename" +optional +details=" + If this option is not given, CURRENT_PROGRAM writes the log + messages to to stderr +" + diff --git a/ggo/loglevel.m4 b/ggo/loglevel.m4 new file mode 100644 index 00000000..0badbf4c --- /dev/null +++ b/ggo/loglevel.m4 @@ -0,0 +1,22 @@ + +option "loglevel" l +#~~~~~~~~~~~~~~~~~~ +"set loglevel" +string typestr="level" +values = "debug","info","notice","warning","error","crit","emerg" +default="warning" +optional +details=" + Log only messages with severity greater or equal the given + value. + + debug: Produces really noisy output. + info: Still noisy, but won't fill up the disk quicky. + notice: Indicates normal, but significant event. + warning: Unexpected events that can be handled. + error: Unhandled error condition. + crit: System might be unreliable. + emerg: Last message before exit. +" + + diff --git a/ggo/Makefile.ggo b/ggo/makefile similarity index 74% rename from ggo/Makefile.ggo rename to ggo/makefile index e1b232ec..4988d6fe 100644 --- a/ggo/Makefile.ggo +++ b/ggo/makefile @@ -50,3 +50,20 @@ grab_client.cmdline.h grab_client.cmdline.c: $(ggo_dir)/grab_client.ggo --set-package="para_$(subst .cmdline,,$(*F))" \ --set-version="$(PACKAGE_VERSION)" < $< +$(ggo_dir)/server.ggo $(ggo_dir)/audiod.ggo: \ + $(ggo_dir)/loglevel.m4 $(ggo_dir)/color.m4 \ + $(ggo_dir)/config_file.m4 $(ggo_dir)/logfile.m4 \ + $(ggo_dir)/daemon.m4 $(ggo_dir)/user.m4 \ + $(ggo_dir)/group.m4 + +$(ggo_dir)/afh.ggo: $(ggo_dir)/loglevel.m4 +$(ggo_dir)/audioc.ggo: $(ggo_dir)/loglevel.m4 +$(ggo_dir)/filter.ggo: $(ggo_dir)/loglevel.m4 +$(ggo_dir)/fsck.ggo: $(ggo_dir)/loglevel.m4 +$(ggo_dir)/gui.ggo: $(ggo_dir)/loglevel.m4 +$(ggo_dir)/recv.ggo: $(ggo_dir)/loglevel.m4 +$(ggo_dir)/write.ggo: $(ggo_dir)/loglevel.m4 +$(ggo_dir)/client.ggo: $(ggo_dir)/loglevel.m4 $(ggo_dir)/config_file.m4 + +$(ggo_dir)/%.ggo: $(ggo_dir)/%.m4 $(ggo_dir)/header.m4 + (cd $(ggo_dir) && m4 $( $@ diff --git a/ggo/recv.ggo b/ggo/recv.m4 similarity index 67% rename from ggo/recv.ggo rename to ggo/recv.m4 index 2f647613..9702e12b 100644 --- a/ggo/recv.ggo +++ b/ggo/recv.m4 @@ -1,10 +1,7 @@ -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ -"set loglevel (0-6)" -int typestr="level" -default="3" -optional +include(header.m4) +include(loglevel.m4) + option "receiver" r "Select receiver" string typestr="receiver_spec" @@ -16,4 +13,4 @@ details=" -r 'http -i www.paraslash.org -p 8009' " - + diff --git a/ggo/server.ggo b/ggo/server.m4 similarity index 68% rename from ggo/server.ggo rename to ggo/server.m4 index 055dbc10..30c3b41a 100644 --- a/ggo/server.ggo +++ b/ggo/server.m4 @@ -1,56 +1,20 @@ +include(header.m4) +define(CURRENT_PROGRAM,para_server) +define(DEFAULT_CONFIG_FILE,~/.paraslash/server.conf) + + ######################### section "General options" ######################### + -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ -"set loglevel (0-6)" -int typestr="level" -default="3" -optional -details=" - Larger values mean less verbose output. Loglevel 0 (debug) gets - really noisy; a value of 1 (info) produces still noisy output, - but this won't fill up the disk quicky. Messaged logged with - loglevel 2 (notice) indicate normal but significant events - while level 3 (warning) logs unexpected events that can be - handled. Unhandled error conditions are logged with loglevel - 4 (error) and crititcal errors are logged using loglevel 5 - (crit). Finally, loglevel 6 (emerg) is reserved for messages - that cause para_server to terminate immediately. -" - -option "color" C -#~~~~~~~~~~~~~~~ -"activate color output" -enum typestr="when" -values = "yes","no","auto" -default = "auto" -optional - -option "log_color" - -#~~~~~~~~~~~~~~~~~~~ -"select a color for one type of log message" -string typestr="color_spec" -multiple -optional -details=" - The format of \"color_spec\" is [fg [bg]] [attr]. - - Valid colors for \"fg\" and \"bg\" are \"normal\", \"black\", - \"red\", \"green\", \"yellow\", \"blue\", \"magenta\", - \"cyan\", and \"white\". - - The \"attr\" value must be one of \"bold\", \"dim\", \"ul\", - \"blink\", \"reverse\". - - Examples: - - --log_color \"debug:green\" - --log_color \"info:yellow bold\" - --log_color \"notice:white red bold\" -" +include(loglevel.m4) +include(color.m4) +include(daemon.m4) +include(user.m4) +include(group.m4) + option "port" p #~~~~~~~~~~~~~~ "listening port" @@ -64,76 +28,15 @@ details=" to connect to para_server. " -option "daemon" d -#~~~~~~~~~~~~~~~~ -"run as background daemon" -flag off -dependon="logfile" -details=" - Note that para_server refuses to start in daemon mode if no - logfile was specified. -" - -option "user" u -#~~~~~~~~~~~~~~ -"run as the given user" -string typestr="name" -optional -details=" - para_server does not need any special privileges. If started - as root (EUID == 0) this option must be given at the command - line (not in the configuration file) so that para_server - can drop the root privileges right after parsing the command - line options, but before parsing the configuration file. In - this case, real/effective/saved UID are all set to the UID - of 'name'. As the configuration file is read afterwards, - those options that have a default value depending on the UID - (e.g. the directory for the configuration file) are computed - by using the uid of 'name'. This option has no effect if - para_server is started as a non-root user (i.e. EUID != 0) -" - - -option "group" g -#~~~~~~~~~~~~~~~ -"set group id" -string typestr="group" -optional -details=" - This option sets the group id according to 'group'. This option - is silently ignored if EUID != 0. Otherwise, real/effective - GID and the saved set-group ID are all set to the GID given by - 'group'. Must not be given in the config file. -" - ############################# section "Configuration files" ############################# + +include(logfile.m4) +include(config_file.m4) -option "logfile" L -#~~~~~~~~~~~~~~~~~ -"where to write log output" -string typestr="filename" -optional -details=" - If this option is not given, para_server writes the log - messages to to stderr -" - -option "config_file" c -#~~~~~~~~~~~~~~~~~~~~~ -"(default='~/.paraslash/server.conf'" -string typestr="filename" -optional -details=" - para_server reads its config file right after parsing - the options that were given at the command line. If an - option is given both at the command line and in the - config file, the value that was specified at the command line - takes precedence. -" - + option "user_list" - #~~~~~~~~~~~~~~~~~~~ "(default='~/.paraslash/server.users')" @@ -396,3 +299,4 @@ details=" \"num\" for the sending udp socket. Only useful for multicast udp streaming. " + diff --git a/ggo/user.m4 b/ggo/user.m4 new file mode 100644 index 00000000..1bd5c59a --- /dev/null +++ b/ggo/user.m4 @@ -0,0 +1,21 @@ + +option "user" u +#~~~~~~~~~~~~~~ +"run as the given user" +string typestr="name" +optional +details=" + CURRENT_PROGRAM does not need any special privileges. + + If started as root (EUID == 0) this option must + be given at the command line (not in the configuration + file) so that CURRENT_PROGRAM can drop the root + privileges right after parsing the command line options, + but before parsing the configuration file. In this case, + real/effective/saved UID are all set to the UID of 'name'. As + the configuration file is read afterwards, those options that + have a default value depending on the UID (e.g. the directory + for the configuration file) are computed by using the uid of + 'name'. This option has no effect if CURRENT_PROGRAM + is started as a non-root user (i.e. EUID != 0). +" diff --git a/ggo/write.ggo b/ggo/write.m4 similarity index 84% rename from ggo/write.ggo rename to ggo/write.m4 index 8f557bb9..41e44dd7 100644 --- a/ggo/write.ggo +++ b/ggo/write.m4 @@ -1,9 +1,5 @@ -option "loglevel" l -#~~~~~~~~~~~~~~~~~~ -"set loglevel (0-6)" -int typestr="level" -default="4" -optional +include(header.m4) +include(loglevel.m4) option "bufsize" b #~~~~~~~~~~~~~~~~~ diff --git a/gui.c b/gui.c index f08976d2..499845d9 100644 --- a/gui.c +++ b/gui.c @@ -489,12 +489,14 @@ static int add_output_line(char *line, __a_unused void *data) return 1; } +static int loglevel; + __printf_2_3 void para_log(int ll, const char *fmt,...) { int color; char *msg; - if (ll < conf.loglevel_arg || !curses_active) + if (ll < loglevel || !curses_active) return; switch (ll) { case LL_DEBUG: @@ -562,8 +564,7 @@ __noreturn __printf_2_3 static void msg_n_exit(int ret, const char* fmt, ...) static void print_welcome(void) { - int ll = conf.loglevel_arg; - if (ll > LL_NOTICE) + if (loglevel > LL_NOTICE) return; outputf(COLOR_WELCOME, "Welcome to para_gui " PACKAGE_VERSION " \"" CODENAME "\". Theme: %s", theme.name); @@ -1168,24 +1169,24 @@ err_out: static void com_ll_decr(void) { - if (conf.loglevel_arg <= LL_DEBUG) { + if (loglevel <= LL_DEBUG) { print_in_bar(COLOR_ERRMSG, "loglevel already at maximal verbosity\n"); return; } - conf.loglevel_arg--; - print_in_bar(COLOR_MSG, "loglevel set to %d\n", conf.loglevel_arg); + loglevel--; + print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel); } static void com_ll_incr(void) { - if (conf.loglevel_arg >= LL_EMERG) { + if (loglevel >= LL_EMERG) { print_in_bar(COLOR_ERRMSG, "loglevel already at miminal verbosity\n"); return; } - conf.loglevel_arg++; - print_in_bar(COLOR_MSG, "loglevel set to %d\n", conf.loglevel_arg); + loglevel++; + print_in_bar(COLOR_MSG, "loglevel set to %d\n", loglevel); } /* @@ -1391,6 +1392,7 @@ int main(int argc, char *argv[]) }; gui_cmdline_parser_config_file(cf, &conf, ¶ms); } + loglevel = get_loglevel_by_name(conf.loglevel_arg); if (check_key_map_args() < 0) { fprintf(stderr, "invalid key map in config file\n"); exit(EXIT_FAILURE); diff --git a/recv.c b/recv.c index 2386c1ef..df8b9ce9 100644 --- a/recv.c +++ b/recv.c @@ -16,14 +16,16 @@ #include "recv.h" #include "recv.cmdline.h" #include "fd.h" +#include "string.h" #include "error.h" #include "stdout.h" /** the gengetopt args info struct */ struct recv_args_info conf; -/** always log to stderr */ -INIT_STDERR_LOGGING(conf.loglevel_arg); +static int loglevel; +/** Always log to stderr. */ +INIT_STDERR_LOGGING(loglevel); /** init array of error codes used by para_recv */ INIT_RECV_ERRLISTS; @@ -85,6 +87,7 @@ int main(int argc, char *argv[]) PARA_EMERG_LOG("parse failed\n"); goto out; } + loglevel = get_loglevel_by_name(conf.loglevel_arg); r = &receivers[receiver_num]; rn.receiver = r; ret = r->open(&rn); diff --git a/server.c b/server.c index c11fb58a..4822ebb5 100644 --- a/server.c +++ b/server.c @@ -202,7 +202,7 @@ err_out: void parse_config_or_die(int override) { char *home = para_homedir(); - int ret, ll = conf.loglevel_arg; + int ret; char *cf; daemon_close_log(); @@ -237,7 +237,7 @@ void parse_config_or_die(int override) daemon_set_logfile(conf.logfile_arg); daemon_open_log_or_die(); } - daemon_set_loglevel(ll); + daemon_set_loglevel(conf.loglevel_arg); init_colors_or_die(); daemon_set_flag(DF_LOG_PID); daemon_set_flag(DF_LOG_LL); @@ -491,7 +491,7 @@ static void server_init(int argc, char **argv) drop_privileges_or_die(conf.user_arg, conf.group_arg); /* parse config file, open log and set defaults */ parse_config_or_die(0); - log_welcome("para_server", conf.loglevel_arg); + log_welcome("para_server"); init_ipc_or_die(); /* init mmd struct and mmd->lock */ /* make sure, the global now pointer is uptodate */ gettimeofday(now, NULL); diff --git a/string.c b/string.c index ba32e8bf..3c80d27c 100644 --- a/string.c +++ b/string.c @@ -586,3 +586,22 @@ int para_atoi32(const char *str, int32_t *value) *value = tmp; return 1; } + +int get_loglevel_by_name(const char *txt) +{ + if (!strcasecmp(txt, "debug")) + return LL_DEBUG; + if (!strcasecmp(txt, "info")) + return LL_INFO; + if (!strcasecmp(txt, "notice")) + return LL_NOTICE; + if (!strcasecmp(txt, "warning")) + return LL_WARNING; + if (!strcasecmp(txt, "error")) + return LL_ERROR; + if (!strcasecmp(txt, "crit")) + return LL_CRIT; + if (!strcasecmp(txt, "emerg")) + return LL_EMERG; + return -1; +} diff --git a/string.h b/string.h index 6a003330..77e62e90 100644 --- a/string.h +++ b/string.h @@ -49,3 +49,4 @@ int for_each_line_ro(char *buf, size_t size, line_handler_t *line_handler, void *private_data); int para_atoi64(const char *str, int64_t *result); int para_atoi32(const char *str, int32_t *value); +int get_loglevel_by_name(const char *txt); diff --git a/write.c b/write.c index e28e1c01..238f2ab9 100644 --- a/write.c +++ b/write.c @@ -122,7 +122,8 @@ register_check_wav: s->timeout.tv_usec = 1; } -INIT_STDERR_LOGGING(conf.loglevel_arg) +static int loglevel; +INIT_STDERR_LOGGING(loglevel) static struct writer_node_group *check_args(void) { @@ -130,6 +131,7 @@ static struct writer_node_group *check_args(void) struct writer_node_group *g = NULL; struct initial_delay_task *idt = &the_initial_delay_task; + loglevel = get_loglevel_by_name(conf.loglevel_arg); if (conf.start_time_given) { long unsigned sec, usec; if (sscanf(conf.start_time_arg, "%lu:%lu", -- 2.39.2