top: honor the restrictive, crufty old top rcfile
At one time, new top silently defaulted when an rcfile was found to be incompatible. This is exactly what the old top did. However, after some discussion it was decided top should alert the user and thereby save the system administrator some headaches. Now, some are upset over the fatal error, proving you can't please everybody. But in all fairness, given the difficulty of customizing old top, any reluctance to delete an old saved rcfile is understandable. To ease transition to this new top, old style rcfiles will now be honored and converted to the new format. And if not disabled at ./configure time via CFLAGS, a user will be warned when an old style rcfile is about to be overwritten using the 'W' command. Lastly, the config validation logic was enhanced to help ensure both types of rcfile haven't been edited manually and possibly made unuseable. Reported-By: sergio <mailbox@sergio.spb.ru> Bug-Debian: http://bugs.debian.org/651213 Reported-By: martin f krafft <madduck@debian.org> Bug-Debian: http://bugs.debian.org/651863 Signed-off-by: Jim Warner <james.warner@comcast.net>
This commit is contained in:
parent
488aa10d33
commit
4b98733132
147
top/top.c
147
top/top.c
@ -72,6 +72,9 @@ static char *Myname;
|
||||
/* The 'local' config file support */
|
||||
static char Rc_name [OURPATHSZ];
|
||||
static RCF_t Rc = DEF_RCFILE;
|
||||
#ifndef WARN_CFG_OFF
|
||||
static int Rc_converted;
|
||||
#endif
|
||||
|
||||
/* The run-time acquired page stuff */
|
||||
static unsigned Page_size;
|
||||
@ -658,7 +661,7 @@ static void show_msg (const char *str) {
|
||||
static int show_pmt (const char *str) {
|
||||
int rc;
|
||||
|
||||
PUTT("%s%s%.*s: %s%s%s"
|
||||
PUTT("%s%s%.*s %s%s%s"
|
||||
, tg2(0, Msg_row)
|
||||
, Curwin->capclr_pmt
|
||||
, Screen_cols - 3
|
||||
@ -2153,6 +2156,70 @@ static void before (char *me) {
|
||||
} // end: before
|
||||
|
||||
|
||||
/*
|
||||
* A configs_read *Helper* function responsible for converting a
|
||||
* single window's old rc stuff into a new top compatible rcfile entry */
|
||||
static int config_cvt (WIN_t *q) {
|
||||
#define old_View_NOBOLD 0x000001
|
||||
#define old_VISIBLE_tsk 0x000008
|
||||
#define old_Qsrt_NORMAL 0x000010
|
||||
#define old_Show_HICOLS 0x000200
|
||||
#define old_Show_THREAD 0x010000
|
||||
static struct flags {
|
||||
int old, new;
|
||||
} flags_tab[] = {
|
||||
{ old_View_NOBOLD, View_NOBOLD },
|
||||
{ old_VISIBLE_tsk, Show_TASKON },
|
||||
{ old_Qsrt_NORMAL, Qsrt_NORMAL },
|
||||
{ old_Show_HICOLS, Show_HICOLS },
|
||||
{ old_Show_THREAD, 0 }
|
||||
};
|
||||
static const char field_src[] = OLD_FIELDS;
|
||||
char field_dst[PFLAGSSIZ];
|
||||
int i, x;
|
||||
|
||||
// first we'll touch up this window's winflags...
|
||||
x = q->rc.winflags;
|
||||
q->rc.winflags = 0;
|
||||
for (i = 0; i < MAXTBL(flags_tab); i++) {
|
||||
if (x & flags_tab[i].old) {
|
||||
x &= ~flags_tab[i].old;
|
||||
q->rc.winflags |= flags_tab[i].new;
|
||||
}
|
||||
}
|
||||
q->rc.winflags |= x;
|
||||
|
||||
// now let's convert old top's more limited 26 fields...
|
||||
if (26 != strlen(q->rc.fieldscur))
|
||||
return 0;
|
||||
strcpy(field_dst, field_src);
|
||||
for (i = 0; i < 26; i++) {
|
||||
int c = q->rc.fieldscur[i];
|
||||
x = toupper(c) - 'A';
|
||||
if (x < 0 || x > 25)
|
||||
return 0;
|
||||
field_dst[i] = field_src[x];
|
||||
if (isupper(c))
|
||||
FLDon(field_dst[i]);
|
||||
}
|
||||
strcpy(q->rc.fieldscur, field_dst);
|
||||
|
||||
// lastly, we must adjust the old sort field enum...
|
||||
x = q->rc.sortindx;
|
||||
q->rc.sortindx = field_src[x] - FLD_OFFSET;
|
||||
|
||||
#ifndef WARN_CFG_OFF
|
||||
Rc_converted = 1;
|
||||
#endif
|
||||
return 1;
|
||||
#undef old_View_NOBOLD
|
||||
#undef old_VISIBLE_tsk
|
||||
#undef old_Qsrt_NORMAL
|
||||
#undef old_Show_HICOLS
|
||||
#undef old_Show_THREAD
|
||||
} // 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
|
||||
@ -2168,14 +2235,11 @@ static void before (char *me) {
|
||||
* line b: contains w->winflags, sortindx, maxtasks
|
||||
* line c: contains w->summclr, msgsclr, headclr, taskclr */
|
||||
static void configs_read (void) {
|
||||
#ifdef RCFILE_NOERR
|
||||
RCF_t rcdef = DEF_RCFILE;
|
||||
#endif
|
||||
float tmp_delay = DEF_DELAY;
|
||||
char fbuf[LRGBUFSIZ], *p;
|
||||
char fbuf[LRGBUFSIZ];
|
||||
const char *p;
|
||||
FILE *fp;
|
||||
int i, x;
|
||||
char id;
|
||||
|
||||
p = getenv("HOME");
|
||||
snprintf(Rc_name, sizeof(Rc_name), "%s/.%src", (p && *p) ? p : ".", Myname);
|
||||
@ -2195,61 +2259,66 @@ static void configs_read (void) {
|
||||
if (fp) {
|
||||
fbuf[0] = '\0';
|
||||
fgets(fbuf, sizeof(fbuf), fp); // ignore eyecatcher
|
||||
if (5 != (fscanf(fp, "Id:%c, "
|
||||
"Mode_altscr=%d, Mode_irixps=%d, Delay_time=%f, Curwin=%d\n"
|
||||
, &id, &Rc.mode_altscr, &Rc.mode_irixps, &tmp_delay, &i))
|
||||
|| RCF_VERSION_ID != id)
|
||||
#ifndef RCFILE_NOERR
|
||||
error_exit(fmtmk(N_fmt(RC_bad_files_fmt), Rc_name));
|
||||
#else
|
||||
goto just_default_em;
|
||||
#endif
|
||||
if (5 != fscanf(fp
|
||||
, "Id:%c, Mode_altscr=%d, Mode_irixps=%d, Delay_time=%f, Curwin=%d\n"
|
||||
, &Rc.id, &Rc.mode_altscr, &Rc.mode_irixps, &tmp_delay, &i)) {
|
||||
p = fmtmk(N_fmt(RC_bad_files_fmt), Rc_name);
|
||||
goto default_or_error;
|
||||
}
|
||||
// you saw that, right? (fscanf stickin' it to 'i')
|
||||
Curwin = &Winstk[i];
|
||||
|
||||
for (i = 0 ; i < GROUPSMAX; i++) {
|
||||
p = fmtmk(N_fmt(RC_bad_entry_fmt), i+1, Rc_name);
|
||||
// note: "fieldscur=%__s" on next line should equal PFLAGSSIZ !
|
||||
fscanf(fp, "%3s\tfieldscur=%64s\n"
|
||||
, Winstk[i].rc.winname, Winstk[i].rc.fieldscur);
|
||||
if (2 != fscanf(fp, "%3s\tfieldscur=%64s\n"
|
||||
, Winstk[i].rc.winname, Winstk[i].rc.fieldscur))
|
||||
goto default_or_error;
|
||||
#if PFLAGSSIZ > 64
|
||||
// too bad fscanf is not as flexible with his format string as snprintf
|
||||
# error Hey, fix the above fscanf 'PFLAGSSIZ' dependency !
|
||||
#endif
|
||||
if (3 != fscanf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d\n"
|
||||
, &Winstk[i].rc.winflags, (int*)&Winstk[i].rc.sortindx, &Winstk[i].rc.maxtasks))
|
||||
goto default_or_error;
|
||||
if (4 != fscanf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n"
|
||||
, &Winstk[i].rc.summclr, &Winstk[i].rc.msgsclr
|
||||
, &Winstk[i].rc.headclr, &Winstk[i].rc.taskclr))
|
||||
goto default_or_error;
|
||||
|
||||
if (RCF_VERSION_ID != Rc.id) {
|
||||
if (!config_cvt(&Winstk[i]))
|
||||
goto default_or_error;
|
||||
} else {
|
||||
if (strlen(Winstk[i].rc.fieldscur) != sizeof(DEF_FIELDS) - 1)
|
||||
#ifndef RCFILE_NOERR
|
||||
error_exit(fmtmk(N_fmt(RC_bad_entry_fmt), i+1, Rc_name));
|
||||
#else
|
||||
goto just_default_em;
|
||||
#endif
|
||||
goto default_or_error;
|
||||
for (x = 0; x < P_MAXPFLGS; ++x) {
|
||||
int f = FLDget(&Winstk[i], x);
|
||||
if (P_MAXPFLGS <= f)
|
||||
#ifndef RCFILE_NOERR
|
||||
error_exit(fmtmk(N_fmt(RC_bad_entry_fmt), i+1, Rc_name));
|
||||
#else
|
||||
goto just_default_em;
|
||||
#endif
|
||||
goto default_or_error;
|
||||
}
|
||||
fscanf(fp, "\twinflags=%d, sortindx=%d, maxtasks=%d\n"
|
||||
, &Winstk[i].rc.winflags, (int*)&Winstk[i].rc.sortindx, &Winstk[i].rc.maxtasks);
|
||||
fscanf(fp, "\tsummclr=%d, msgsclr=%d, headclr=%d, taskclr=%d\n"
|
||||
, &Winstk[i].rc.summclr, &Winstk[i].rc.msgsclr
|
||||
, &Winstk[i].rc.headclr, &Winstk[i].rc.taskclr);
|
||||
}
|
||||
} // end: for (GROUPSMAX)
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
} // end: if (fp)
|
||||
|
||||
// lastly, establish the true runtime secure mode and delay time
|
||||
if (!getuid()) Secure_mode = 0;
|
||||
if (!Secure_mode) Rc.delay_time = tmp_delay;
|
||||
return;
|
||||
|
||||
default_or_error:
|
||||
#ifdef RCFILE_NOERR
|
||||
just_default_em:
|
||||
fclose(fp);
|
||||
{ RCF_t rcdef = DEF_RCFILE;
|
||||
|
||||
flcose(fp);
|
||||
Rc = rcdef;
|
||||
for (i = 0 ; i < GROUPSMAX; i++)
|
||||
Winstk[i].rc = Rc.win[i];
|
||||
}
|
||||
#else
|
||||
error_exit(p);
|
||||
#endif
|
||||
} // end: configs_read
|
||||
|
||||
@ -2699,6 +2768,14 @@ static void file_writerc (void) {
|
||||
FILE *fp;
|
||||
int i;
|
||||
|
||||
#ifndef WARN_CFG_OFF
|
||||
if (Rc_converted) {
|
||||
show_pmt(N_fmt(XTRA_warncfg_txt));
|
||||
if ('y' != tolower(keyin(0)))
|
||||
return;
|
||||
Rc_converted = 0;
|
||||
}
|
||||
#endif
|
||||
if (!(fp = fopen(Rc_name, "w"))) {
|
||||
show_msg(fmtmk(N_fmt(FAIL_rc_open_fmt), Rc_name, strerror(errno)));
|
||||
return;
|
||||
|
@ -45,6 +45,7 @@
|
||||
//#define TREE_ONEPASS /* for speed, tolerate dangling children */
|
||||
//#define USE_X_COLHDR /* emphasize header vs. whole col, for 'x' */
|
||||
//#define VALIDATE_NLS /* validate integrity of all 3 nls tables */
|
||||
//#define WARN_CFG_OFF /* warning OFF when overwriting old rcfile */
|
||||
|
||||
|
||||
/*###### Notes, etc. ###################################################*/
|
||||
@ -303,6 +304,7 @@ typedef struct RCW_t { // the 'window' portion of an rcfile
|
||||
|
||||
/* This represents the complete rcfile */
|
||||
typedef struct RCF_t {
|
||||
char id; // rcfile version id
|
||||
int mode_altscr; // 'A' - Alt display mode (multi task windows)
|
||||
int mode_irixps; // 'I' - Irix vs. Solaris mode (SMP-only)
|
||||
float delay_time; // 'd'/'s' - How long to sleep twixt updates
|
||||
@ -360,6 +362,7 @@ typedef struct WIN_t {
|
||||
#define VIZTOGw(q,f) (VIZISw(q)) ? TOGw(q,(f)) : win_warn(Warn_VIZ)
|
||||
|
||||
// Used to test/manipulte fieldscur values
|
||||
#define FLDon(c) ((c) |= 0x80)
|
||||
#define FLDget(q,i) ((FLG_t)((q)->rc.fieldscur[i] & 0x7f) - FLD_OFFSET)
|
||||
#define FLDtog(q,i) ((q)->rc.fieldscur[i] ^= 0x80)
|
||||
#define FLDviz(q,i) ((q)->rc.fieldscur[i] & 0x80)
|
||||
@ -490,10 +493,12 @@ typedef struct WIN_t {
|
||||
#define JOB_FIELDS "¥¦¹·º³´Ä»¼½§Å()*+,-./012568>?@ABCFGHIJKLMNOPQRSTUVWXYZ["
|
||||
#define MEM_FIELDS "¥º»¼½¾¿ÀÁÃij´·Å&'()*+,-./0125689BFGHIJKLMNOPQRSTUVWXYZ["
|
||||
#define USR_FIELDS "¥¦§¨ª°¹·ºÄÅ)+,-./1234568;<=>?@ABCFGHIJKLMNOPQRSTUVWXYZ["
|
||||
/* old top's fields (A-Z) in the first 26 positions */
|
||||
#define OLD_FIELDS "%&*'(-0346789:;<=>?@ACDEFG)+,./125BHIJKLMNOPQRSTUVWXYZ["
|
||||
|
||||
/* The default values for the local config file */
|
||||
#define DEF_RCFILE { \
|
||||
0, 1, DEF_DELAY, 0, { \
|
||||
RCF_VERSION_ID, 0, 1, DEF_DELAY, 0, { \
|
||||
{ P_CPU, DEF_WINFLGS, 0, \
|
||||
COLOR_RED, COLOR_RED, COLOR_YELLOW, COLOR_RED, \
|
||||
"Def", DEF_FIELDS }, \
|
||||
@ -589,6 +594,7 @@ typedef struct WIN_t {
|
||||
//atic void sysinfo_refresh (int forced);
|
||||
/*------ Startup routines ----------------------------------------------*/
|
||||
//atic void before (char *me);
|
||||
//atic int config_cvt (WIN_t *q);
|
||||
//atic void configs_read (void);
|
||||
//atic void parse_args (char **args);
|
||||
//atic void whack_terminal (void);
|
||||
|
@ -260,6 +260,9 @@ static void build_norm_nlstab (void) {
|
||||
Norm_nlstab[FIND_no_next_txt] = _("Locate next inactive, use \"L\"");
|
||||
Norm_nlstab[GET_find_str_txt] = _("Locate string");
|
||||
Norm_nlstab[FIND_no_find_fmt] = _("%s\"%s\" not found");
|
||||
#ifndef WARN_CFG_OFF
|
||||
Norm_nlstab[XTRA_warncfg_txt] = _("Overwrite existing old style rcfile?");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,6 +76,9 @@ enum norm_nls {
|
||||
THREADS_show_fmt, TIME_accumed_fmt, UNKNOWN_cmds_txt, UNKNOWN_opts_fmt,
|
||||
USAGE_abbrev_txt, WORD_allcpus_txt, WORD_another_txt, WORD_eachcpu_fmt,
|
||||
WORD_process_txt, WORD_threads_txt, WRITE_rcfile_fmt, WRONG_switch_fmt,
|
||||
#ifndef WARN_CFG_OFF
|
||||
XTRA_warncfg_txt,
|
||||
#endif
|
||||
norm_MAX
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user