]> granicus.if.org Git - procps-ng/commitdiff
top: allow more flexible approach for startup defaults
authorJim Warner <james.warner@comcast.net>
Sun, 17 Dec 2017 06:00:00 +0000 (00:00 -0600)
committerCraig Small <csmall@enc.com.au>
Sat, 23 Dec 2017 06:44:34 +0000 (17:44 +1100)
Those references below offer more detail regarding the
default startup changes beginning with version 3.3.10.

It is important to remember that all such changes were
supposed to impact only new users or users who had not
saved the personal config file (via that 'W' command).
However, I introduced a bug wherein the rcfile was not
fully honored. This gave the changes a bad reputation.

That bug was corrected in release 3.3.11 but the issue
of default startup options keeps resurfacing. And it's
clear there's no consensus on what should be included.

Our --disable-modern-top configure option is of little
help since it remains an all-or-nothing approach. What
we need is an answer offering unlimited customization.
So, this commit will provide distribution packagers or
system administrators with a much more flexible way to
set their own preferred startup default configuration.

A new rcfile is being introduced: '/etc/topdefaultrc',
whose format/content is the same as a personal rcfile.
Thus once a 'proper' enterprise configuration has been
established and saved via 'W', it can be copied to the
/etc/ directory. Thereafter, startup in the absence of
a saved rcfile will use that configuration as default.

Now if a distribution packager or system administrator
wishes to expose their users to some of top's advanced
capabilities they can do so gradually. Perhaps setting
up graph mode for summary area task and memory display
while retaining the %CPU sort could be tried. Or maybe
showing colors, but better customized for a particular
terminal emulator. Such possibilities are now endless.

[ in exploiting this new capability, i hope that the ]
[ other windows (alt display mode) aren't overlooked ]

Reference(s):
. Sep, 2014 - Not fully honoring rcfile bug discussed
https://www.freelists.org/post/procps/top-saved-rcfile-bug
. Oct, 2014 - Attempt to defend new startup defaults
https://bugzilla.redhat.com/show_bug.cgi?id=1153049
. Jul, 2015 - Forest vs. %CPU views discussion
https://gitlab.com/procps-ng/procps/issues/6
. Oct, 2017 - Question the use of --disable-modern-top
https://bugzilla.redhat.com/show_bug.cgi?id=1499410
. Oct, 2017 - Forest vs. %CPU views discussion again
https://www.freelists.org/post/procps/Forest-mode-by-default-in-top-seems-a-bit-strange
. Dec, 2017 - Rehash of 3.3.10 startup defaults change
https://gitlab.com/procps-ng/procps/issues/78

Signed-off-by: Jim Warner <james.warner@comcast.net>
NEWS
top/top.1
top/top.c
top/top.h
top/top_nls.c

diff --git a/NEWS b/NEWS
index c968987fc0a9cb6ad3469d003a8a5891dda069e3..7e2b2e10a038626c8feb10876a2a8b700cddc6d9 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,8 @@ procps-ng-NEXT
   * top: address a wishlist man page NLS suggestion        Debian #865689
   * top: fix potential distortion in 'Mem' graph display   issue #64
   * top: provide proper multi-byte string handling         issue #68
+  * top: startup defaults are fully customizable           Redhat #1153049, #1499410, issues #6, #78
+  *      see man page 6c. SYSTEM Configuration File
   * watch: define HOST_NAME_MAX where not defined          Debian #830734
   * vmstat: Fix alignment for disk partition format        issue #69
   * watch: Support ANSI 39,49 reset sequences              issue #73
index 44e6c1d15b61fe2fa89701fd8b97627d2568df77..28a713e86ceeb5f151d051eddd46bd6b1c4ce746 100644 (file)
--- a/top/top.1
+++ b/top/top.1
@@ -69,7 +69,7 @@
 .
 .\" Document /////////////////////////////////////////////////////////////
 .\" ----------------------------------------------------------------------
-.TH TOP 1 "August 2017" "procps-ng" "User Commands"
+.TH TOP 1 "December 2017" "procps-ng" "User Commands"
 .\" ----------------------------------------------------------------------
 
 .\" ----------------------------------------------------------------------
@@ -113,7 +113,6 @@ The remaining Table of Contents
 .nf
     OVERVIEW
        Operation
-       Startup Defaults
        Linux Memory Types
     1. COMMAND\-LINE Options
     2. SUMMARY Display
@@ -139,9 +138,10 @@ The remaining Table of Contents
        d. SEARCHING in a Window
        e. FILTERING in a Window
     6. FILES
-       a. SYSTEM Configuration File
-       b. PERSONAL Configuration File
-       c. ADDING INSPECT Entries
+       a. PERSONAL Configuration File
+       b. ADDING INSPECT Entries
+       c. SYSTEM Configuration File
+       d. SYSTEM Restrictions File
     7. STUPID TRICKS Sampler
        a. Kernel Magic
        b. Bouncing Windows
@@ -231,44 +231,6 @@ And there are four additional keys available with line oriented input.
        End      jump to \fBend\fR of input line
 .fi
 
-.\" ......................................................................
-.SS Startup Defaults
-.\" ----------------------------------------------------------------------
-The following startup defaults assume no \*(CF, thus no user customizations.
-Even so, items shown with an \*(AK could be overridden through the
-command-line.
-All are explained in detail in the sections that follow.
-
-.nf
-    \fIGlobal-defaults\fR
-       A \- Alt display      Off (full-screen)
-     * d \- Delay time       1.5 seconds
-     * H \- Threads mode     Off (summarize as tasks)
-       I \- Irix mode        On  (no, `solaris' smp)
-     * p \- PID monitoring   Off (show all processes)
-     * s \- Secure mode      Off (unsecured)
-       B \- Bold enable      On  (yes, bold globally)
-    \fISummary-Area-defaults\fR
-       l \- Load Avg/Uptime  On  (thus program name)
-       t \- Task/Cpu states  On  (1+1 lines, see `1')
-       m \- Mem/Swap usage   On  (2 lines worth)
-     * 1 \- Single Cpu       Off (thus multiple cpus)
-    \fITask-Area-defaults\fR
-       b \- Bold hilite      Off (use `reverse')
-     * c \- Command line     Off (name, not cmdline)
-     * i \- Idle tasks       On  (show all tasks)
-       J \- Num align right  On  (not left justify)
-       j \- Str align right  Off (not right justify)
-       R \- Reverse sort     On  (pids high-to-low)
-     * S \- Cumulative time  Off (no, dead children)
-     * u \- User filter      Off (show euid only)
-     * U \- User filter      Off (show any uid)
-       V \- Forest view      On  (show as branches)
-       x \- Column hilite    Off (no, sort field)
-       y \- Row hilite       On  (yes, running tasks)
-       z \- color/mono       On  (show colors)
-.fi
-
 .\" ......................................................................
 .SS Linux Memory Types
 .\" ----------------------------------------------------------------------
@@ -376,7 +338,7 @@ Later this can be changed with the `d' or `s' \*(CIs.
 Fractional seconds are honored, but a negative number is not allowed.
 In all cases, however, such changes are prohibited if \*(We is running
 in Secure mode, except for root (unless the `s' \*(CO was used).
-For additional information on Secure mode \*(Xt 6a. SYSTEM Configuration File.
+For additional information on Secure mode \*(Xt 6d. SYSTEM Restrictions File.
 
 .TP 5
 \-\fBE\fR\ \ :\fIExtend-Memory-Scaling\fR as:\ \ \fB-E  k\fR | \fBm\fR | \fBg\fR | \fBt\fR | \fBp\fR | \fBe\fR
@@ -448,7 +410,7 @@ The `p', `u' and `U' \*(COs are mutually exclusive.
 .TP 5
 \-\fBs\fR\ \ :\fISecure-mode\fR operation \fR
 Starts \*(We with secure mode forced, even for root.
-This mode is far better controlled through the system \*(CF
+This mode is far better controlled through a system \*(CF
 (\*(Xt 6. FILES).
 
 .TP 5
@@ -1377,7 +1339,7 @@ while the normal \*(We iterative display is paused.
 
 \*(NT This \*(CI is only fully realized when supporting entries have been
 manually added to the end of the \*(We \*(CF.
-For details on creating those entries, \*(Xt 6c. ADDING INSPECT Entries.
+For details on creating those entries, \*(Xt 6b. ADDING INSPECT Entries.
 
 Most of the keys used to navigate the Inspect feature are reflected in
 its header prologue.
@@ -2190,35 +2152,10 @@ to filtering.
 .\" ----------------------------------------------------------------------
 .SH 6. FILES
 .\" ----------------------------------------------------------------------
-.\" ......................................................................
-.SS 6a. SYSTEM Configuration File
+.SS 6a. PERSONAL Configuration File
 .\" ----------------------------------------------------------------------
-The presence of this file will influence which version of the help screen
-is shown to an ordinary user.
-More importantly, it will limit what ordinary users are allowed
-to do when \*(We is running.
-They will not be able to issue the following commands.
-.nf
-    k        Kill a task
-    r        Renice a task
-    d or s   Change delay/sleep interval
-.fi
-
-The system \*(CF is\fB not\fR created by \*(We.
-Rather, you create this file manually and place it in the \fI/etc \fR
-directory.
-Its name must be `toprc' and must have no leading `.' (period).
-It must have only two lines.
+This file is created or updated via the 'W' \*(CI.
 
-Here is an example of the contents of\fI /etc/toprc\fR:
-.nf
-    s        # line 1: secure mode switch
-    5.0      # line 2: delay interval in seconds
-.fi
-
-.\" ......................................................................
-.SS 6b. PERSONAL Configuration File
-.\" ----------------------------------------------------------------------
 The legacy version is written as `$HOME/.your\-name\-4\-\*(We' + `rc'
 with a leading period.
 
@@ -2227,9 +2164,7 @@ without a leading period.
 The procps directory will be subordinate to either $XDG_CONFIG_HOME when
 set as an absolute path or the $HOME/.config directory.
 
-Use the `W' \*(CI to create it or update it.
-
-Here is the general layout:
+While not intended to be edited manually, here is the general layout:
 .nf
     global   # line  1: the program name/alias notation
       "      # line  2: id,altscr,irixps,delay,curwin
@@ -2246,7 +2181,7 @@ If the $HOME and $XDG_CONFIG_HOME variables are not present, \*(We will try
 to write the personal \*(CF in the current directory, subject to permissions.
 
 .\" ......................................................................
-.SS 6c. ADDING INSPECT Entries
+.SS 6b. ADDING INSPECT Entries
 .\" ----------------------------------------------------------------------
 To exploit the `Y' \*(CI, you must add entries at the\fB end\fR of the
 \*(We personal \*(CF.
@@ -2363,6 +2298,48 @@ those numbered selections actually mean.
 In that way, many more choices can be made visible.
 .PP
 
+.\" ......................................................................
+.SS 6c. SYSTEM Configuration File
+.\" ----------------------------------------------------------------------
+This \*(CF represents defaults for users who have not saved their own \*(CF.
+The format mirrors exactly the personal \*(CF and can also include `inspect'
+entries as explained above.
+
+Creating it is a simple process.
+
+1. Configure \*(We appropriately for your installation and preserve that
+configuration with the `W' \*(CI.
+
+2. Add and test any desired `inspect' entries.
+
+3. Copy that \*(CF to the \fI/etc/\fR directory as `\fBtopdefaultrc\fR'.
+
+.\" ......................................................................
+.SS 6d. SYSTEM Restrictions File
+.\" ----------------------------------------------------------------------
+The presence of this file will influence which version of the help screen
+is shown to an ordinary user.
+
+More importantly, it will limit what ordinary users are allowed
+to do when \*(We is running.
+They will not be able to issue the following commands.
+.nf
+    k        Kill a task
+    r        Renice a task
+    d or s   Change delay/sleep interval
+.fi
+
+This \*(CF is not created by \*(We.
+Rather, it is created manually and placed it in the \fI/etc/\fR
+directory as `\fBtoprc\fR'.
+
+It should have exactly two lines, as shown in this example:
+.nf
+    s        # line 1: secure mode switch
+    5.0      # line 2: delay interval in seconds
+.fi
+
+.\" ......................................................................
 .\" ----------------------------------------------------------------------
 .SH 7. STUPID TRICKS Sampler
 .\" ----------------------------------------------------------------------
index 5b76f24aab2e5e80619ab29e2ebff38529081cf5..c89b18b9605af24aec8e16d831266970a32509de 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -3084,7 +3084,7 @@ static void before (char *me) {
 
 
         /*
-         * A configs_read *Helper* function responsible for converting
+         * A config_file *Helper* function responsible for converting
          * a single window's old rc stuff into a new style rcfile entry */
 static int config_cvt (WIN_t *q) {
    static struct {
@@ -3150,34 +3150,174 @@ static int config_cvt (WIN_t *q) {
    x = q->rc.sortindx;
    q->rc.sortindx = fields_src[x] - FLD_OFFSET;
 
-   Rc_questions = 1;
    return 0;
 } // end: config_cvt
 
 
         /*
-         * Build the local RC file name then try to read both of 'em.
-         * 'SYS_RCFILESPEC' contains two lines consisting of the secure
-         *   mode switch and an update interval.  It's presence limits what
-         *   ordinary users are allowed to do.
-         * 'Rc_name' contains multiple lines - 3 global + 3 per window.
-         *   line 1  : an eyecatcher and creating program/alias name
-         *   line 2  : an id, Mode_altcsr, Mode_irixps, Delay_time, Curwin.
-         *   For each of the 4 windows:
-         *     line a: contains w->winname, fieldscur
-         *     line b: contains w->winflags, sortindx, maxtasks, graph modes
-         *     line c: contains w->summclr, msgsclr, headclr, taskclr
-         *   line 15 : miscellaneous additional global settings
-         *   Any remaining lines are devoted to the 'Inspect Other' feature */
+         * A configs_read *Helper* function responsible for processing
+         * a configuration file (personal or system-wide default) */
+static const char *config_file (FILE *fp, const char *name, float *delay) {
+   char fbuf[LRGBUFSIZ];
+   int i, tmp_whole, tmp_fract;
+   const char *p = NULL;
+
+   p = fmtmk(N_fmt(RC_bad_files_fmt), name);
+   if (fgets(fbuf, sizeof(fbuf), fp))       // ignore eyecatcher
+      ;                                     // avoid -Wunused-result
+   if (6 != fscanf(fp
+      , "Id:%c, Mode_altscr=%d, Mode_irixps=%d, Delay_time=%d.%d, Curwin=%d\n"
+      , &Rc.id, &Rc.mode_altscr, &Rc.mode_irixps, &tmp_whole, &tmp_fract, &i)) {
+         return p;
+   }
+   if (Rc.id < 'a' || Rc.id > RCF_VERSION_ID)
+      return p;
+   // you saw that, right?  (fscanf stickin' it to 'i')
+   Curwin = &Winstk[i];
+   // this may be ugly, but it keeps us locale independent...
+   *delay = (float)tmp_whole + (float)tmp_fract / 1000;
+
+   for (i = 0 ; i < GROUPSMAX; i++) {
+      int x;
+      WIN_t *w = &Winstk[i];
+      p = fmtmk(N_fmt(RC_bad_entry_fmt), i+1, name);
+
+      // note: "fieldscur=%__s" on next line should equal (PFLAGSSIZ -1) !
+      if (2 != fscanf(fp, "%3s\tfieldscur=%99s\n"
+         , w->rc.winname, w->rc.fieldscur))
+            return p;
+#if PFLAGSSIZ != 100
+ too bad fscanf is not as flexible with his format string as snprintf
+error Hey, fix the above fscanf 'PFLAGSSIZ' dependency !
+#endif
+      // be tolerant of missing release 3.3.10 graph modes additions
+      if (3 > fscanf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d, graph_cpus=%d, graph_mems=%d\n"
+         , &w->rc.winflags, &w->rc.sortindx, &w->rc.maxtasks, &w->rc.graph_cpus, &w->rc.graph_mems))
+            return p;
+      if (4 != fscanf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n"
+         , &w->rc.summclr, &w->rc.msgsclr
+         , &w->rc.headclr, &w->rc.taskclr))
+            return p;
+
+      switch (Rc.id) {
+         case 'a':                          // 3.2.8 (former procps)
+            if (config_cvt(w))
+               return p;
+         case 'f':                          // 3.3.0 thru 3.3.3 (ng)
+            SETw(w, Show_JRNUMS);
+         case 'g':                          // from 3.3.4 thru 3.3.8
+            scat(w->rc.fieldscur, RCF_PLUS_H);
+         case 'h':                          // this is release 3.3.9
+            w->rc.graph_cpus = w->rc.graph_mems = 0;
+            // these next 2 are really global, but best documented here
+            Rc.summ_mscale = Rc.task_mscale = SK_Kb;
+         case 'i':                          // actual RCF_VERSION_ID
+            scat(w->rc.fieldscur, RCF_PLUS_J);
+         case 'j':                          // and the next version
+         default:
+            if (strlen(w->rc.fieldscur) != sizeof(DEF_FIELDS) - 1)
+               return p;
+            for (x = 0; x < EU_MAXPFLGS; ++x)
+               if (EU_MAXPFLGS <= FLDget(w, x))
+                  return p;
+            break;
+      }
+#ifndef USE_X_COLHDR
+      OFFw(w, NOHIFND_xxx | NOHISEL_xxx);
+#endif
+   } // end: for (GROUPSMAX)
+
+   // any new addition(s) last, for older rcfiles compatibility...
+   if (fscanf(fp, "Fixed_widest=%d, Summ_mscale=%d, Task_mscale=%d, Zero_suppress=%d\n"
+      , &Rc.fixed_widest, &Rc.summ_mscale, &Rc.task_mscale, &Rc.zero_suppress))
+         ;                                  // avoid -Wunused-result
+
+   // we'll start off Inspect stuff with 1 'potential' blank line
+   // ( only realized if we end up with Inspect.total > 0 )
+   for (i = 0, Inspect.raw = alloc_s("\n");;) {
+    #define iT(element) Inspect.tab[i].element
+      size_t lraw = strlen(Inspect.raw) +1;
+      char *s;
+
+      if (!fgets(fbuf, sizeof(fbuf), fp)) break;
+      lraw += strlen(fbuf) +1;
+      Inspect.raw = alloc_r(Inspect.raw, lraw);
+      strcat(Inspect.raw, fbuf);
+
+      if (fbuf[0] == '#' || fbuf[0] == '\n') continue;
+      Inspect.tab = alloc_r(Inspect.tab, sizeof(struct I_ent) * (i + 1));
+
+      if (!(s = strtok(fbuf, "\t\n"))) { Rc_questions = 1; continue; }
+      iT(type) = alloc_s(s);
+      if (!(s = strtok(NULL, "\t\n"))) { Rc_questions = 1; continue; }
+      iT(name) = alloc_s(s);
+      if (!(s = strtok(NULL, "\t\n"))) { Rc_questions = 1; continue; }
+      iT(fmts) = alloc_s(s);
+
+      switch (toupper(fbuf[0])) {
+         case 'F':
+            iT(func) = insp_do_file;
+            break;
+         case 'P':
+            iT(func) = insp_do_pipe;
+            break;
+         default:
+            Rc_questions = 1;
+            continue;
+      }
+      iT(farg) = (strstr(iT(fmts), "%d")) ? 1 : 0;
+      iT(fstr) = alloc_c(FNDBUFSIZ);
+      iT(flen) = 0;
+
+      ++i;
+    #undef iT
+   } // end: for ('inspect' entries)
+
+   Inspect.total = i;
+#ifndef INSP_OFFDEMO
+   if (!Inspect.total) {
+    #define mkS(n) N_txt(YINSP_demo ## n ## _txt)
+      const char *sels[] = { mkS(01), mkS(02), mkS(03) };
+      Inspect.total = Inspect.demo = MAXTBL(sels);
+      Inspect.tab = alloc_c(sizeof(struct I_ent) * Inspect.total);
+      for (i = 0; i < Inspect.total; i++) {
+         Inspect.tab[i].type = alloc_s(N_txt(YINSP_deqtyp_txt));
+         Inspect.tab[i].name = alloc_s(sels[i]);
+         Inspect.tab[i].func = insp_do_demo;
+         Inspect.tab[i].fmts = alloc_s(N_txt(YINSP_deqfmt_txt));
+         Inspect.tab[i].fstr = alloc_c(FNDBUFSIZ);
+      }
+    #undef mkS
+   }
+#endif
+   return NULL;
+} // end: config_file
+
+
+        /*
+         * Try reading up to 3 rcfiles
+         * 1. 'SYS_RCRESTRICT' contains two lines consisting of the secure
+         *     mode switch and an update interval.  Its presence limits what
+         *     ordinary users are allowed to do.
+         * 2. 'Rc_name' contains multiple lines - 3 global + 3 per window.
+         *     line 1  : an eyecatcher and creating program/alias name
+         *     line 2  : an id, Mode_altcsr, Mode_irixps, Delay_time, Curwin.
+         *     For each of the 4 windows:
+         *       line a: contains w->winname, fieldscur
+         *       line b: contains w->winflags, sortindx, maxtasks, graph modes
+         *       line c: contains w->summclr, msgsclr, headclr, taskclr
+         *     line 15 : miscellaneous additional global settings
+         *     Any remaining lines are devoted to the 'Inspect Other' feature
+         * 3. 'SYS_RCDEFAULTS' system-wide defaults if 'Rc_name' absent
+         *    format is identical to #2 above */
 static void configs_read (void) {
    float tmp_delay = DEF_DELAY;
-   char fbuf[LRGBUFSIZ];
    const char *p, *p_home;
    FILE *fp;
-   int i;
 
-   fp = fopen(SYS_RCFILESPEC, "r");
+   fp = fopen(SYS_RCRESTRICT, "r");
    if (fp) {
+      char fbuf[SMLBUFSIZ];
       if (fgets(fbuf, sizeof(fbuf), fp)) {     // sys rc file, line 1
          Secure_mode = 1;
          if (fgets(fbuf, sizeof(fbuf), fp))    // sys rc file, line 2
@@ -3207,143 +3347,17 @@ static void configs_read (void) {
    }
 
    if (fp) {
-      int tmp_whole, tmp_fract;
-      if (fgets(fbuf, sizeof(fbuf), fp))       // ignore eyecatcher
-         ;                                     // avoid -Wunused-result
-      if (6 != fscanf(fp
-         , "Id:%c, Mode_altscr=%d, Mode_irixps=%d, Delay_time=%d.%d, Curwin=%d\n"
-         , &Rc.id, &Rc.mode_altscr, &Rc.mode_irixps, &tmp_whole, &tmp_fract, &i)) {
-            p = fmtmk(N_fmt(RC_bad_files_fmt), Rc_name);
-            Rc_questions = -1;
-            goto try_inspect_entries;          // maybe a faulty 'inspect' echo
-      }
-      // you saw that, right?  (fscanf stickin' it to 'i')
-      Curwin = &Winstk[i];
-      // this may be ugly, but it keeps us locale independent...
-      tmp_delay = (float)tmp_whole + (float)tmp_fract / 1000;
-
-      for (i = 0 ; i < GROUPSMAX; i++) {
-         int x;
-         WIN_t *w = &Winstk[i];
-         p = fmtmk(N_fmt(RC_bad_entry_fmt), i+1, Rc_name);
-
-         // note: "fieldscur=%__s" on next line should equal (PFLAGSSIZ -1) !
-         if (2 != fscanf(fp, "%3s\tfieldscur=%99s\n"
-            , w->rc.winname, w->rc.fieldscur))
-               goto default_or_error;
-#if PFLAGSSIZ != 100
- // too bad fscanf is not as flexible with his format string as snprintf
- # error Hey, fix the above fscanf 'PFLAGSSIZ' dependency !
-#endif
-         // be tolerant of missing release 3.3.10 graph modes additions
-         if (3 > fscanf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d, graph_cpus=%d, graph_mems=%d\n"
-            , &w->rc.winflags, &w->rc.sortindx, &w->rc.maxtasks, &w->rc.graph_cpus, &w->rc.graph_mems))
-               goto default_or_error;
-         if (4 != fscanf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n"
-            , &w->rc.summclr, &w->rc.msgsclr
-            , &w->rc.headclr, &w->rc.taskclr))
-               goto default_or_error;
-
-         switch (Rc.id) {
-            case 'a':                          // 3.2.8 (former procps)
-               if (config_cvt(w))
-                  goto default_or_error;
-            case 'f':                          // 3.3.0 thru 3.3.3 (ng)
-               SETw(w, Show_JRNUMS);
-            case 'g':                          // from 3.3.4 thru 3.3.8
-               scat(w->rc.fieldscur, RCF_PLUS_H);
-            case 'h':                          // this is release 3.3.9
-               w->rc.graph_cpus = w->rc.graph_mems = 0;
-               // these next 2 are really global, but best documented here
-               Rc.summ_mscale = Rc.task_mscale = SK_Kb;
-            case 'i':                          // actual RCF_VERSION_ID
-               scat(w->rc.fieldscur, RCF_PLUS_J);
-            case 'j':                          // and the next version
-            default:
-               if (strlen(w->rc.fieldscur) != sizeof(DEF_FIELDS) - 1)
-                  goto default_or_error;
-               for (x = 0; x < EU_MAXPFLGS; ++x)
-                  if (EU_MAXPFLGS <= FLDget(w, x))
-                     goto default_or_error;
-               break;
-         }
-#ifndef USE_X_COLHDR
-         OFFw(w, NOHIFND_xxx | NOHISEL_xxx);
-#endif
-      } // end: for (GROUPSMAX)
-
-      // any new addition(s) last, for older rcfiles compatibility...
-      if (fscanf(fp, "Fixed_widest=%d, Summ_mscale=%d, Task_mscale=%d, Zero_suppress=%d\n"
-         , &Rc.fixed_widest, &Rc.summ_mscale, &Rc.task_mscale, &Rc.zero_suppress))
-            ;                                  // avoid -Wunused-result
-
-try_inspect_entries:
-      // we'll start off Inspect stuff with 1 'potential' blank line
-      // ( only realized if we end up with Inspect.total > 0 )
-      for (i = 0, Inspect.raw = alloc_s("\n");;) {
-       #define iT(element) Inspect.tab[i].element
-         size_t lraw = strlen(Inspect.raw) +1;
-         char *s;
-
-         if (!fgets(fbuf, sizeof(fbuf), fp)) break;
-         lraw += strlen(fbuf) +1;
-         Inspect.raw = alloc_r(Inspect.raw, lraw);
-         strcat(Inspect.raw, fbuf);
-
-         if (fbuf[0] == '#' || fbuf[0] == '\n') continue;
-         Inspect.tab = alloc_r(Inspect.tab, sizeof(struct I_ent) * (i + 1));
-
-         if (!(s = strtok(fbuf, "\t\n"))) { Rc_questions = 1; continue; }
-         iT(type) = alloc_s(s);
-         if (!(s = strtok(NULL, "\t\n"))) { Rc_questions = 1; continue; }
-         iT(name) = alloc_s(s);
-         if (!(s = strtok(NULL, "\t\n"))) { Rc_questions = 1; continue; }
-         iT(fmts) = alloc_s(s);
-
-         switch (toupper(fbuf[0])) {
-            case 'F':
-               iT(func) = insp_do_file;
-               break;
-            case 'P':
-               iT(func) = insp_do_pipe;
-               break;
-            default:
-               Rc_questions = 1;
-               continue;
-         }
-
-         iT(farg) = (strstr(iT(fmts), "%d")) ? 1 : 0;
-         iT(fstr) = alloc_c(FNDBUFSIZ);
-         iT(flen) = 0;
-
-         if (Rc_questions < 0) Rc_questions = 1;
-         ++i;
-       #undef iT
-      } // end: for ('inspect' entries)
-
-      Inspect.total = i;
-#ifndef INSP_OFFDEMO
-      if (!Inspect.total) {
-       #define mkS(n) N_txt(YINSP_demo ## n ## _txt)
-         const char *sels[] = { mkS(01), mkS(02), mkS(03) };
-         Inspect.total = Inspect.demo = MAXTBL(sels);
-         Inspect.tab = alloc_c(sizeof(struct I_ent) * Inspect.total);
-         for (i = 0; i < Inspect.total; i++) {
-            Inspect.tab[i].type = alloc_s(N_txt(YINSP_deqtyp_txt));
-            Inspect.tab[i].name = alloc_s(sels[i]);
-            Inspect.tab[i].func = insp_do_demo;
-            Inspect.tab[i].fmts = alloc_s(N_txt(YINSP_deqfmt_txt));
-            Inspect.tab[i].fstr = alloc_c(FNDBUFSIZ);
-         }
-       #undef mkS
-      }
-#endif
-      if (Rc_questions < 0) {
-         p = fmtmk(N_fmt(RC_bad_files_fmt), Rc_name);
+      if ((p = config_file(fp, Rc_name, &tmp_delay)))
          goto default_or_error;
-      }
       fclose(fp);
-   } // end: if (fp)
+   } else {
+      fp = fopen(SYS_RCDEFAULTS, "r");
+      if (fp) {
+         if ((p = config_file(fp, SYS_RCDEFAULTS, &tmp_delay)))
+            goto default_or_error;
+         fclose(fp);
+      }
+   }
 
    // lastly, establish the true runtime secure mode and delay time
    if (!getuid()) Secure_mode = 0;
@@ -3353,11 +3367,11 @@ try_inspect_entries:
 default_or_error:
 #ifdef RCFILE_NOERR
 {  RCF_t rcdef = DEF_RCFILE;
+   int i;
    fclose(fp);
    Rc = rcdef;
    for (i = 0 ; i < GROUPSMAX; i++)
       Winstk[i].rc  = Rc.win[i];
-   Rc_questions = 1;
 }
 #else
    error_exit(p);
index b021079ad1b32529c212be5cc9a07a39f9544f70..214f60768b48a72b02667b8a96887f24d25f9668 100644 (file)
--- a/top/top.h
+++ b/top/top.h
@@ -459,7 +459,8 @@ typedef struct WIN_t {
 /*      ( see module top_nls.c for the nls translatable data ) */
 
         /* Configuration files support */
-#define SYS_RCFILESPEC  "/etc/toprc"
+#define SYS_RCRESTRICT  "/etc/toprc"
+#define SYS_RCDEFAULTS  "/etc/topdefaultrc"
 #define RCF_EYECATCHER  "Config File (Linux processes with windows)\n"
 #define RCF_PLUS_H      "\\]^_`abcdefghij"
 #ifdef VER_J_RCFILE
@@ -619,6 +620,7 @@ typedef struct WIN_t {
 /*------  Startup routines  ----------------------------------------------*/
 //atic void          before (char *me);
 //atic int           config_cvt (WIN_t *q);
+//atic const char   *config_file (FILE *fp, const char *name, float *delay);
 //atic void          configs_read (void);
 //atic void          parse_args (char **args);
 //atic void          whack_terminal (void);
index 54c7defa22fda7ee3e16fe8383ebdf620cc7960c..908f2028987bce461ae6d63ed40d64dd83fc3e17 100644 (file)
@@ -423,7 +423,7 @@ static void build_norm_nlstab (void) {
    Norm_nlstab[GET_find_str_txt] = _("Locate string");
    Norm_nlstab[FIND_no_find_fmt] = _("%s\"%s\" not found");
    Norm_nlstab[XTRA_fixwide_fmt] = _("width incr is %d, change to (0 default, -1 auto)");
-   Norm_nlstab[XTRA_warncfg_txt] = _("Overwrite existing obsolete/corrupted rcfile?");
+   Norm_nlstab[XTRA_warncfg_txt] = _("rcfile has 'inspect' entry error(s), write anyway?");
    Norm_nlstab[XTRA_badflds_fmt] = _("unrecognized field name '%s'");
    Norm_nlstab[XTRA_winsize_txt] = _("even using field names only, window is now too small");
 #ifndef INSP_OFFDEMO