Mercurial > dovecot > core-2.2
changeset 9237:30d771700232 HEAD
doveconf -n, -a: Show version number, config file path and system info.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Wed, 06 May 2009 14:33:06 -0400 |
parents | 955e68007ada |
children | c57038025171 |
files | src/config/Makefile.am src/config/doveconf.c src/config/sysinfo-get.c src/config/sysinfo-get.h |
diffstat | 4 files changed, 183 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/src/config/Makefile.am Wed May 06 14:20:14 2009 -0400 +++ b/src/config/Makefile.am Wed May 06 14:33:06 2009 -0400 @@ -29,7 +29,8 @@ all-settings.c \ config-connection.c \ config-parser.c \ - config-request.c + config-request.c \ + sysinfo-get.c config_SOURCES = \ main.c \ @@ -42,7 +43,8 @@ noinst_HEADERS = \ all-settings.h \ config-connection.h \ - config-parser.h + config-parser.h \ + sysinfo-get.h all-settings.c: $(SETTING_FILES) $(top_srcdir)/src/config/settings-get.pl $(top_srcdir)/src/config/settings-get.pl $(SETTING_FILES) > all-settings.c || rm -f all-settings.c
--- a/src/config/doveconf.c Wed May 06 14:20:14 2009 -0400 +++ b/src/config/doveconf.c Wed May 06 14:33:06 2009 -0400 @@ -3,12 +3,16 @@ #include "lib.h" #include "array.h" #include "env-util.h" +#include "ostream.h" +#include "settings-parser.h" #include "master-service.h" -#include "ostream.h" +#include "all-settings.h" +#include "sysinfo-get.h" #include "config-connection.h" #include "config-parser.h" #include "config-request.h" +#include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -173,16 +177,38 @@ } T_END; } +static const char *get_mail_location(void) +{ + struct config_setting_parser_list *l; + const struct setting_define *def; + const char *const *value; + const void *set; + + for (l = config_setting_parsers; l->module_name != NULL; l++) { + if (strcmp(l->module_name, "mail") != 0) + continue; + + set = settings_parser_get(l->parser); + for (def = l->root->defines; def->key != NULL; def++) { + if (strcmp(def->key, "mail_location") == 0) { + value = CONST_PTR_OFFSET(set, def->offset); + return *value; + } + } + } + return ""; +} + int main(int argc, char *argv[]) { enum config_dump_flags flags = CONFIG_DUMP_FLAG_DEFAULTS; - const char *getopt_str, *service_name = ""; + const char *getopt_str, *config_path, *service_name = ""; char **exec_args = NULL; int c; service = master_service_init("config", MASTER_SERVICE_FLAG_STANDALONE, argc, argv); - + i_set_failure_prefix("doveconf: "); getopt_str = t_strconcat("anp:e", master_service_getopt_string(), NULL); while ((c = getopt(argc, argv, getopt_str)) > 0) { if (c == 'e') @@ -201,15 +227,29 @@ exit(FATAL_DEFAULT); } } + config_path = master_service_get_config_path(service); + if (argv[optind] != NULL) exec_args = &argv[optind]; + else { + /* print the config file path before parsing it, so in case + of errors it's still shown */ + printf("# "VERSION": %s\n", config_path); + fflush(stdout); + } master_service_init_finish(service); - config_parse_file(master_service_get_config_path(service)); + config_parse_file(config_path); + + if (exec_args == NULL) { + const char *info; - if (exec_args == NULL) + info = sysinfo_get(get_mail_location()); + if (*info != '\0') + printf("# %s\n", info); + fflush(stdout); config_dump_human(service_name, flags); - else { + } else { env_put("DOVECONF_ENV=1"); config_request_handle(service_name, 0, config_request_putenv, NULL);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/config/sysinfo-get.c Wed May 06 14:33:06 2009 -0400 @@ -0,0 +1,127 @@ +/* Copyright (c) 2008-2009 Dovecot authors, see the included COPYING file */ + +#include "lib.h" +#include "mountpoint.h" +#include "strescape.h" +#include "sysinfo-get.h" + +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#ifdef HAVE_SYS_UTSNAME_H +# include <sys/utsname.h> +#endif + +static bool readfile(const char *path, const char **data_r) +{ + char buf[1024]; + int fd, ret; + + fd = open(path, O_RDONLY); + if (fd == -1) + return FALSE; + ret = read(fd, buf, sizeof(buf)); + (void)close(fd); + if (ret <= 0) + return FALSE; + + *data_r = t_strndup(buf, ret); + return TRUE; +} + +static bool lsb_distro_get(const char *path, const char **name_r) +{ + const char *data, *const *p, *str, *end; + + if (!readfile(path, &data)) + return FALSE; + + for (p = t_strsplit(data, "\n"); *p != '\0'; p++) { + if (strncmp(*p, "DISTRIB_DESCRIPTION=", 20) == 0) + break; + } + if (*p == '\0') + return FALSE; + + str = t_strcut(*p + 20, '\n'); + if (*str != '"') + *name_r = str; + else { + end = strrchr(++str, '"'); + *name_r = str_unescape(p_strdup_until(unsafe_data_stack_pool, + str, end)); + } + return TRUE; +} + +static const char *distro_get(void) +{ + static const char *files[] = { + "", "/etc/redhat-release", + "", "/etc/SuSE-release", + "", "/etc/mandriva-release", + "", "/etc/fedora-release", + "", "/etc/sourcemage-release", + "", "/etc/slackware-version", + "", "/etc/gentoo-release", + "Debian ", "/etc/debian_version", + NULL + }; + const char *name; + unsigned int i; + + if (lsb_distro_get("/etc/lsb-release", &name)) + return name; + for (i = 0; files[i] != NULL; i += 2) { + if (readfile(files[i+1], &name)) { + return t_strconcat(files[i], t_strcut(name, '\n'), + NULL); + } + } + return ""; +} + +static const char *filesystem_get(const char *mail_location) +{ + struct mountpoint mp; + const char *path; + + path = strchr(mail_location, ':'); + if (path == NULL) + path = mail_location; + else + path = t_strcut(path + 1, ':'); + if (*path == '~') { + /* we don't know where users' home dirs are */ + return ""; + } + path = t_strcut(path, '%'); + if (strlen(path) <= 1) + return ""; + + /* all in all it seems we can support only /<path>/%u style location */ + if (mountpoint_get(path, pool_datastack_create(), &mp) < 0) + return ""; + return mp.type == NULL ? "" : mp.type; +} + +const char *sysinfo_get(const char *mail_location) +{ + const char *distro = "", *fs, *uname_info = ""; +#ifdef HAVE_SYS_UTSNAME_H + struct utsname u; + + if (uname(&u) < 0) + i_error("uname() failed: %m"); + else { + uname_info = t_strdup_printf("%s %s %s", + u.sysname, u.release, u.machine); + } + if (strcmp(u.sysname, "Linux") == 0) + distro = distro_get(); +#endif + fs = filesystem_get(mail_location); + if (*uname_info == '\0' && *distro == '\0' && *fs == '\0') + return ""; + return t_strdup_printf("OS: %s %s %s %s %s", u.sysname, u.release, u.machine, distro, fs); +}