]> granicus.if.org Git - vnstat/commitdiff
add extra vnstat subdirectory to default pid and logfile paths, create dirs during...
authorTeemu Toivola <git@humdi.net>
Mon, 18 Aug 2014 21:30:30 +0000 (00:30 +0300)
committerTeemu Toivola <git@humdi.net>
Mon, 18 Aug 2014 21:30:30 +0000 (00:30 +0300)
CHANGES
cfg/vnstat.conf
man/vnstat.conf.5
src/cfg.c
src/common.h
src/daemon.c
src/daemon.h
src/vnstatd.c
tests/daemon_tests.c

diff --git a/CHANGES b/CHANGES
index 978c4c0189636023f57b5f31a9e67a76a943837a..b4ac04bd58305e951e1c3670c382148d4ecafd57 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -22,8 +22,9 @@
  - Improve daemon startup prints
  - Add parameters for changing daemon process user and group
  - Add example upstart job configuration file (thanks to Cameron Norman)
- - Create database directory during daemon startup if necessary
- - Update ownership of database files if needed during daemon startup
+ - Create database, pid and log dirs during daemon startup if necessary
+ - Update ownership of database, log and pid files if needed during daemon
+   startup if started as root and configured to change process user and group
  - Remove cron update related example files and documentation, the cron
    update method should be considered as deprecated
 
index ccadd202700628878810f7d4e73f3da211a710f8..7767247237c88f7d0d65bc1ad203b5e4dd0c6550 100644 (file)
@@ -95,17 +95,17 @@ SaveOnStatusChange 1
 # enable / disable logging (0 = disabled, 1 = logfile, 2 = syslog)
 UseLogging 2
 
-# create db directory if missing (1 = enabled, 0 = disabled)
-CreateDBDir 1
+# create dirs if needed (1 = enabled, 0 = disabled)
+CreateDirs 1
 
-# update ownership of files when needed (1 = enabled, 0 = disabled)
+# update ownership of files if needed (1 = enabled, 0 = disabled)
 UpdateFileOwner 1
 
 # file used for logging if UseLogging is set to 1
-LogFile "/var/log/vnstat.log"
+LogFile "/var/log/vnstat/vnstat.log"
 
 # file used as daemon pid / lock file
-PidFile "/var/run/vnstat.pid"
+PidFile "/var/run/vnstat/vnstat.pid"
 
 
 # vnstati
index 82fe456a2df684378e11ab89092246e709425114..ff2b5a806c81cef049aab95614013714fc7c3900 100644 (file)
@@ -130,9 +130,19 @@ to write to the file at the same time.
 .SH DAEMON RELATED KEYWORDS
 
 .TP
-.BI CreateDBDir
-Enable or disable the creation of the database directory when the directory
-doesn't exist. The daemon process will try to create the directory using
+.BI CreateDirs
+Enable or disable the creation of directories when a configured path doesn't
+exist. This includes
+.BI DatabaseDir
+,
+.BI LogFile
+and
+.BI PidFile
+directories. The
+.BI LogFile
+directory will be created only when
+.BI UseLogging
+has been set to 1. The daemon process will try to create the directory using
 permissions of the user used to start the process.
 
 .TP
@@ -179,8 +189,8 @@ offline or comes online. 1 = enabled, 0 = disabled.
 .TP
 .BI UpdateFileOwner
 Enable or disable the update of file ownership during daemon process startup.
-Only database files will be modified if the user or group change feature
-is enabled and the files don't match the requested user or group.
+Only database, log and pid files will be modified if the user or group change
+feature is enabled and the files don't match the requested user or group.
 This option can only be used when the process is started as root.
 
 .TP
index 8b46dba4b6eee07864e0cec10837f7fdc49c877f..b0679c3d21d5a3241df85cbf24ff20219fe51856 100644 (file)
--- a/src/cfg.c
+++ b/src/cfg.c
@@ -108,10 +108,10 @@ void printcfgfile(void)
        printf("# enable / disable logging (0 = disabled, 1 = logfile, 2 = syslog)\n");
        printf("UseLogging %d\n\n", cfg.uselogging);
 
-       printf("# create db directory if missing (1 = enabled, 0 = disabled)\n");
-       printf("CreateDBDir %d\n\n", cfg.createdbdir);
+       printf("# create dirs if needed (1 = enabled, 0 = disabled)\n");
+       printf("CreateDirs %d\n\n", cfg.createdirs);
 
-       printf("# update ownership of files when needed (1 = enabled, 0 = disabled)\n");
+       printf("# update ownership of files if needed (1 = enabled, 0 = disabled)\n");
        printf("UpdateFileOwner %d\n\n", cfg.updatefileowner);
 
        printf("# file used for logging if UseLogging is set to 1\n");
@@ -194,7 +194,7 @@ int loadcfg(const char *cfgfile)
                { "OfflineSaveInterval", 0, &cfg.offsaveinterval, 0, 0 },
                { "SaveOnStatusChange", 0, &cfg.savestatus, 0, 0 },
                { "UseLogging", 0, &cfg.uselogging, 0, 0 },
-               { "CreateDBDir", 0, &cfg.createdbdir, 0, 0 },
+               { "CreateDirs", 0, &cfg.createdirs, 0, 0 },
                { "UpdateFileOwner", 0, &cfg.updatefileowner, 0, 0 },
                { "LogFile", cfg.logfile, 0, 512, 0 },
                { "PidFile", cfg.pidfile, 0, 512, 0 },
@@ -471,9 +471,9 @@ void validatecfg(void)
                printe(PT_Config);
        }
 
-       if (cfg.createdbdir<0 || cfg.createdbdir>2) {
-               cfg.createdbdir = CREATEDBDIR;
-               snprintf(errorstring, 512, "Invalid value for CreateDBDir, resetting to \"%d\".", cfg.createdbdir);
+       if (cfg.createdirs<0 || cfg.createdirs>2) {
+               cfg.createdirs = CREATEDIRS;
+               snprintf(errorstring, 512, "Invalid value for CreateDirs, resetting to \"%d\".", cfg.createdirs);
                printe(PT_Config);
        }
 
@@ -564,7 +564,7 @@ void defaultcfg(void)
        cfg.offsaveinterval = OFFSAVEINTERVAL;
        cfg.savestatus = SAVESTATUS;
        cfg.uselogging = USELOGGING;
-       cfg.createdbdir = CREATEDBDIR;
+       cfg.createdirs = CREATEDIRS;
        cfg.updatefileowner = UPDATEFILEOWNER;
        strncpy_nt(cfg.logfile, LOGFILE, 512);
        strncpy_nt(cfg.pidfile, PIDFILE, 512);
index c4e817bf73dfb63f97b604908583438b44ac2467..b5afc391c3bec8100d19030f9ef95fc912fa8843 100644 (file)
@@ -21,6 +21,7 @@
 #include <sys/statvfs.h>
 #include <pwd.h>
 #include <grp.h>
+#include <libgen.h>
 
 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) || defined(__FreeBSD_kernel__)
 #include <sys/param.h>
@@ -176,10 +177,10 @@ and most can be changed later from the config file.
 #define OFFSAVEINTERVAL 30
 #define SAVESTATUS 1
 #define USELOGGING 2
-#define CREATEDBDIR 1
+#define CREATEDIRS 1
 #define UPDATEFILEOWNER 1
-#define LOGFILE "/var/log/vnstat.log"
-#define PIDFILE "/var/run/vnstat.pid"
+#define LOGFILE "/var/log/vnstat/vnstat.log"
+#define PIDFILE "/var/run/vnstat/vnstat.pid"
 
 /* no transparency by default */
 #define TRANSBG 0
@@ -212,7 +213,7 @@ typedef struct {
        char logfile[512], pidfile[512];
        char daemonuser[33], daemongroup[33];
        short updateinterval, pollinterval, saveinterval, offsaveinterval, savestatus, uselogging;
-       short createdbdir, updatefileowner;
+       short createdirs, updatefileowner;
 } CFG;
 
 /* internal interface information structure */
index f1a4515c2da9076196ed6c8cfa73bac75c09898a..a600cefa0101ad0077b8a82a6410a48252e7da16 100644 (file)
@@ -329,10 +329,12 @@ int mkpath(const char *dir, const mode_t mode)
        }
 
        if (direxists(dir)) {
+               if (debug)
+                       printf("already exists: %s\n", dir);
                return 1;
        }
 
-       if (!cfg.createdbdir) {
+       if (!cfg.createdirs) {
                return 0;
        }
 
@@ -353,8 +355,6 @@ int mkpath(const char *dir, const mode_t mode)
        for (; i<len; i++) {
                if (tmp[i] == '/') {
                        tmp[i] = '\0';
-                       if (debug)
-                               printf("for: %s\n", tmp);
                        if (!direxists(tmp)) {
                                if (mkdir(tmp, mode)!=0) {
                                        if (debug)
@@ -362,8 +362,6 @@ int mkpath(const char *dir, const mode_t mode)
                                        ret = 0;
                                        break;
                                }
-                       } else if (debug) {
-                               printf("skip\n");
                        }
                        tmp[i] = '/';
                }
@@ -373,6 +371,8 @@ int mkpath(const char *dir, const mode_t mode)
                        if (debug)
                                printf("Error: mkdir() \"%s\": %s\n", tmp, strerror(errno));
                        ret = 0;
+               } else if (debug) {
+                       printf("created: %s\n", tmp);
                }
        }
 
@@ -728,14 +728,80 @@ void handleintsignals(DSTATE *s)
        intsignal = 0;
 }
 
-void preparedbdir(DSTATE *s)
+void preparedirs(DSTATE *s)
 {
+       /* database directory */
        if (mkpath(s->dirname, 0775)) {
-               updatedbowner(s->dirname, s->user, s->group);
+               updatedirowner(s->dirname, s->user, s->group);
+       }
+
+       if (!cfg.createdirs) {
+               return;
+       }
+
+       /* possible pid/lock and log directory */
+       preparevnstatdir(cfg.pidfile, s->user, s->group);
+       if (cfg.uselogging == 1) {
+               preparevnstatdir(cfg.logfile, s->user, s->group);
+       }
+}
+
+void preparevnstatdir(const char *file, const char *user, const char *group)
+{
+       int len, i, lastslash=0;
+       char *path, *base;
+
+       if (file == NULL) {
+               return;
+       }
+
+       len = strlen(file);
+       if (len<2) {
+               return;
+       }
+
+       if (file[len-1] == '/') {
+               return;
+       }
+
+       path = strdup(file);
+       if (path == NULL) {
+               return;
+       }
+
+       /* verify that path ends with vnstat or vnstatd */
+       base = basename(dirname(path));
+       if (strcmp(base, "vnstat")!=0 && strcmp(base, "vnstatd")!=0) {
+               free(path);
+               return;
+       }
+       free(path);
+
+       path = strdup(file);
+       if (path == NULL) {
+               return;
+       }
+
+       /* extract path */
+       for (i=0; i<len; i++) {
+               if (path[i] == '/') {
+                       lastslash = i;
+               }
+       }
+       if (lastslash == 0) {
+               free(path);
+               return;
+       }
+       path[lastslash] = '\0';
+
+       /* create & chmod if needed */
+       if (mkpath(path, 0775)) {
+               updatedirowner(path, user, group);
        }
+       free(path);
 }
 
-void updatedbowner(const char *dir, const char *user, const char *group)
+void updatedirowner(const char *dir, const char *user, const char *group)
 {
        DIR *d;
        struct dirent *di;
@@ -764,7 +830,7 @@ void updatedbowner(const char *dir, const char *user, const char *group)
        if (statbuf.st_uid != uid || statbuf.st_gid != gid) {
                if (chown(dir, uid, gid) != 0) {
                        if (debug)
-                               printf("Error: updatedbowner() chown() \"%s\": %s\n", dir, strerror(errno));
+                               printf("Error: updatedirowner() chown() \"%s\": %s\n", dir, strerror(errno));
                        return;
                } else {
                        if (debug)
@@ -774,7 +840,7 @@ void updatedbowner(const char *dir, const char *user, const char *group)
 
        if ((d=opendir(dir))==NULL) {
                if (debug)
-                       printf("Error: updatedbowner() diropen() \"%s\": %s\n", dir, strerror(errno));
+                       printf("Error: updatedirowner() diropen() \"%s\": %s\n", dir, strerror(errno));
                return;
        }
 
index 7d4f88c28f0b30bd61b81700aecd8062e8df69c1..27705c20e3b41a99eb7e08fc5f61403bbb815d44 100644 (file)
@@ -33,7 +33,8 @@ void datalist_getifinfo(DSTATE *s);
 int datalist_timevalidation(DSTATE *s);
 int datalist_writedb(DSTATE *s);
 void handleintsignals(DSTATE *s);
-void preparedbdir(DSTATE *s);
-void updatedbowner(const char *dir, const char *user, const char *group);
+void preparedirs(DSTATE *s);
+void preparevnstatdir(const char *dir, const char *user, const char *group);
+void updatedirowner(const char *dir, const char *user, const char *group);
 
 #endif
index a5364aa4e6a49f0f020d3e270fc367848104bf30..140e95d4fd65b4db011074547c8b2359ec31a89e 100644 (file)
@@ -130,7 +130,7 @@ int main(int argc, char *argv[])
                return 0;
        }
 
-       preparedbdir(&s);
+       preparedirs(&s);
 
        /* set user and/or group if requested */
        setgroup(s.group);
index 27c147354afa02b6067fc54b6ed0db56b84fe721..98d54e49b5f129e152dd6e4db560ecc43b50950a 100644 (file)
@@ -731,33 +731,55 @@ START_TEST(mkpath_with_dir)
 }
 END_TEST
 
-START_TEST(preparedbdir_with_no_dir)
+START_TEST(preparedirs_with_no_dir)
 {
+       char logdir[512], piddir[512];
+
        DSTATE s;
        initdstate(&s);
        defaultcfg();
+       cfg.uselogging = 1;
        strncpy_nt(s.dirname, TESTDBDIR, 512);
+       snprintf(logdir, 512, "%s/log/vnstat", TESTDIR);
+       snprintf(piddir, 512, "%s/pid/vnstat", TESTDIR);
+       snprintf(cfg.logfile, 512, "%s/vnstat.log", logdir);
+       snprintf(cfg.pidfile, 512, "%s/vnstat.pid", piddir);
 
        ck_assert_int_eq(remove_directory(TESTDIR), 1);
        ck_assert_int_eq(direxists(TESTDBDIR), 0);
-       preparedbdir(&s);
+       ck_assert_int_eq(direxists(logdir), 0);
+       ck_assert_int_eq(direxists(piddir), 0);
+       preparedirs(&s);
        ck_assert_int_eq(direxists(TESTDBDIR), 1);
+       ck_assert_int_eq(direxists(logdir), 1);
+       ck_assert_int_eq(direxists(piddir), 1);
 }
 END_TEST
 
-START_TEST(preparedbdir_with_dir)
+START_TEST(preparedirs_with_dir)
 {
+       char logdir[512], piddir[512];
+
        DSTATE s;
        initdstate(&s);
        defaultcfg();
+       cfg.uselogging = 1;
        strncpy_nt(s.dirname, TESTDBDIR, 512);
+       snprintf(logdir, 512, "%s/log/vnstat", TESTDIR);
+       snprintf(piddir, 512, "%s/pid/vnstat", TESTDIR);
+       snprintf(cfg.logfile, 512, "%s/vnstat.log", logdir);
+       snprintf(cfg.pidfile, 512, "%s/vnstat.pid", piddir);
 
        ck_assert_int_eq(remove_directory(TESTDIR), 1);
        ck_assert_int_eq(direxists(TESTDBDIR), 0);
        ck_assert_int_eq(mkpath(TESTDBDIR, 0775), 1);
        ck_assert_int_eq(direxists(TESTDBDIR), 1);
-       preparedbdir(&s);
+       ck_assert_int_eq(direxists(logdir), 0);
+       ck_assert_int_eq(direxists(piddir), 0);
+       preparedirs(&s);
        ck_assert_int_eq(direxists(TESTDBDIR), 1);
+       ck_assert_int_eq(direxists(logdir), 1);
+       ck_assert_int_eq(direxists(piddir), 1);
 }
 END_TEST
 
@@ -808,8 +830,8 @@ void add_daemon_tests(Suite *s)
        tcase_add_test(tc_daemon, direxists_with_dir);
        tcase_add_test(tc_daemon, mkpath_with_no_dir);
        tcase_add_test(tc_daemon, mkpath_with_dir);
-       tcase_add_test(tc_daemon, preparedbdir_with_no_dir);
-       tcase_add_test(tc_daemon, preparedbdir_with_dir);
+       tcase_add_test(tc_daemon, preparedirs_with_no_dir);
+       tcase_add_test(tc_daemon, preparedirs_with_dir);
        suite_add_tcase(s, tc_daemon);
 }