File procps-3.2.8-add-system-switch.diff of Package procps

From f09de20e534804464d89d76c607ac877573ad9fe Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Fri, 26 Aug 2011 11:11:50 +0200
Subject: [PATCH 1/3] add --system switch

instead of requiring distributions to construct a loop around sysctl
in boot scripts just scan a set of default directories if the --system
switch is used.
Config files are applied in alphabetic order of their base name.
Each base name is only applied once according to the directory
preference. /etc/sysctl.conf is always applied last.
---
 sysctl.8 |    5 ++++
 sysctl.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/sysctl.8 b/sysctl.8
index e26c4fb..d2b0ceb 100644
--- a/sysctl.8
+++ b/sysctl.8
@@ -64,6 +64,11 @@ Display all values currently available.
 .TP
 .B "-A"
 Display all values currently available in table form.
+.TP
+.B "--system"
+Load settings from system configuration files (/lib/sysctl.d/*.conf,
+/usr/lib/sysctl.d/*.conf, /usr/local/lib/sysctl.d/*.conf,
+/etc/sysctl.d/*.conf, /run/sysctl.d/*.conf, /etc/sysctl.conf)
 .SH EXAMPLES
 .TP
 /sbin/sysctl -a
diff --git a/sysctl.c b/sysctl.c
index 9be79ce..bf4e529 100644
--- a/sysctl.c
+++ b/sysctl.c
@@ -453,6 +453,76 @@ static int Preload(const char *restrict const filename) {
    return rc;
 }
 
+struct pair {
+   char* name;
+   char* value;
+};
+
+static int sortpairs(const void* A, const void* B)
+{
+   const struct pair* a = *(struct pair* const*)A;
+   const struct pair* b = *(struct pair* const*)B;
+   return strcmp(a->name, b->name);
+}
+
+static int PreloadSystem(void) {
+   unsigned di, i;
+   const char* dirs[] = {
+      "/run/sysctl.d",
+      "/etc/sysctl.d",
+      "/usr/local/lib/sysctl.d",
+      "/usr/lib/sysctl.d",
+      "/lib/sysctl.d",
+   };
+   struct pair** cfgs = NULL;
+   unsigned ncfgs = 0;
+   enum { nprealloc = 16 };
+
+   for (di=0; di < sizeof(dirs)/sizeof(dirs[0]); ++di) {
+      struct dirent* de;
+      DIR* dp = opendir(dirs[di]);
+      if (!dp)
+	 continue;
+      while (( de = readdir(dp) )) {
+	 if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) {
+	    continue;
+	 }
+	 if (strlen(de->d_name) < 6 || !strcmp(de->d_name+strlen(de->d_name)-6, ".conf"))
+	    continue;
+	 /* check if config already known */
+	 for (i = 0; i < ncfgs; ++i) {
+	    if (!strcmp(cfgs[i]->name, de->d_name))
+	       break;
+	 }
+	 if (i < ncfgs) // already in
+	    continue;
+
+	 if (ncfgs % nprealloc == 0) {
+	    cfgs = realloc(cfgs, sizeof(struct pair*)*(ncfgs+nprealloc));
+	 }
+	 cfgs[ncfgs] = malloc(sizeof(struct pair) + strlen(de->d_name)*2+2 + strlen(dirs[di])+1);
+	 cfgs[ncfgs]->name = (char*)cfgs[ncfgs]+sizeof(struct pair);
+	 strcpy(cfgs[ncfgs]->name, de->d_name);
+	 cfgs[ncfgs]->value = (char*)cfgs[ncfgs]+sizeof(struct pair) + strlen(cfgs[ncfgs]->name)+1;
+	 sprintf(cfgs[ncfgs]->value, "%s/%s", dirs[di], de->d_name);
+	 ncfgs++;
+
+      }
+      closedir(dp);
+   }
+
+   qsort(cfgs, ncfgs, sizeof(struct cfg*), sortpairs);
+
+   for (i = 0; i < ncfgs; ++i) {
+      if (!Quiet)
+	 printf("* Applying %s ...\n", cfgs[i]->value);
+      Preload(cfgs[i]->value);
+   }
+
+   if (!Quiet)
+      printf("* Applying %s ...\n", DEFAULT_PRELOAD);
+   return Preload(DEFAULT_PRELOAD);
+}
 
 
 /*
@@ -488,6 +558,10 @@ int main(int argc, char *argv[]) {
                  fprintf(stdout, "sysctl (%s)\n",procps_version);
                  exit(0);
               }
+              if (!strcmp("--system",*argv)) {
+                 IgnoreError = true;
+                 return PreloadSystem();
+              }
               fprintf(stderr, ERR_UNKNOWN_PARAMETER, *argv);
               return Usage(me);
          }
-- 
1.7.3.4

openSUSE Build Service is sponsored by