From 3e6a208ae501194fdb39d5f259e327c087dc8c84 Mon Sep 17 00:00:00 2001 From: Jim Warner Date: Sun, 17 Dec 2017 00:00:00 -0600 Subject: [PATCH] top: allow more flexible approach for startup defaults 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 --- NEWS | 2 + top/top.1 | 131 +++++++++----------- top/top.c | 322 ++++++++++++++++++++++++++------------------------ top/top.h | 4 +- top/top_nls.c | 2 +- 5 files changed, 228 insertions(+), 233 deletions(-) diff --git a/NEWS b/NEWS index c968987f..7e2b2e10 100644 --- 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 diff --git a/top/top.1 b/top/top.1 index 59485ecd..4abe16e2 100644 --- 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 @@ -1378,7 +1340,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. @@ -2196,35 +2158,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. @@ -2233,9 +2170,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 @@ -2252,7 +2187,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. @@ -2369,6 +2304,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 .\" ---------------------------------------------------------------------- diff --git a/top/top.c b/top/top.c index f53b211e..d05776c2 100644 --- a/top/top.c +++ b/top/top.c @@ -3546,7 +3546,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 { @@ -3612,34 +3612,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 @@ -3669,143 +3809,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; @@ -3815,11 +3829,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); diff --git a/top/top.h b/top/top.h index 31683cd2..37ba4bf0 100644 --- a/top/top.h +++ b/top/top.h @@ -584,7 +584,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 @@ -759,6 +760,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); diff --git a/top/top_nls.c b/top/top_nls.c index 0bb43a43..35216f4a 100644 --- a/top/top_nls.c +++ b/top/top_nls.c @@ -426,7 +426,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 -- 2.40.0