📄 tty.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)tty.c 1.1 92/07/30 Copyright Sun Micro";#endif/* * Copyright (c) 1987 by Sun Microsystems, Inc. */#include <curses.h>#include "sundiag.h"#include "struct.h"#include "tty.h"#include <ctype.h>#include <signal.h>#include <fcntl.h>#ifdef sun4#include <mon/idprom.h>#endif/* global's */WINDOW *tty_control[TTY_WINNO];/* control windows,up to TTY_WINNO pages each */WINDOW *tty_status[TTY_WINNO]; /* status windows, up to TTY_WINNO pages each */WINDOW *tty_option=NULL; /* option window(share just one ) */WINDOW *tty_other=NULL; /* other window(share just one) */WINDOW *control_button=NULL; /* the window to display command button */WINDOW *status_button=NULL; /* the window to display test status */WINDOW *console_tty=NULL; /* console/error message window(to draw box) */WINDOW *message_tty=NULL; /* console/error message subwindow */int tty_ppid=0; /* the parent pid of the sundiag */int window_type=CONTROL_TTY;/* type of window currently displayed */int control_index; /* index of current control window displayed */int status_index; /* index of current status window displayed */int control_max; /* the max. index of control windows(#-1) */int status_max; /* the max. index of status windows(#-1) */int status_page; /* current status page */int status_row; /* current status row */char *arg[20]; /* up to 20 command line arguments */int arg_no; /* number of arguments available */char com_line[82]; /* the image of the command line(NULL-terminated) *//* external's */extern char *build_sel_label(); /* in tests.c */extern char get_com(); /* in ttyprocs.c */extern char *strtok();extern char *sprintf();extern Notify_value kill_proc(); /* in sundiag.c */extern Panel init_opt_panel();/* static's */static int command_row; /* the row to put the command promt */static int message_row; /* the row to put the error message */static char kill_char; /* the line kill character */static char del_char; /* the character erase character */static int status_lines; /* number of lines available for test status */static int other_type; /* who is using the "other window"(see below) */#define OTHER_OPTION 1#define OTHER_OPFILE 2#define OTHER_LOGFILE 3#define OTHER_EEPROM 4#define OTHER_SCHEDULE 5#define OTHER_PROCESSORS 6/* forward declarations */extern switch_to_control();static switch_to_status();static struct com_tbl control_tbl1[]={ {"start", 's'}, {"options", 'o'}, {"logfiles", 'l'}, {"status", 'a'}, {"optfiles", 'f'}, {"stop", 't'}, {"quit", 'q'}, {"reset", 'r'}, {"suspend", 'p'}, {"resume", 'u'}, {"eeprom", 'e'}, {"schedule", 'm'}, {"processors", 'c'}, {"intervention", 'i'}, {"help", 'h'}, {"next", 'n'}, {"", '\0'}};static struct com_tbl control_tbl2[]={ {"tests", 'c'}, {"", '\0'}};static struct com_tbl control_tbl3[]={ {"default", 'd'}, {"all", 'a'}, {"none", 'n'}, {"", '\0'}};static struct com_tbl status_tbl[]={ {"done", 'd'}, {"next", 'n'}, {"help", 'h'}, {"", '\0'}};static struct com_tbl popup_tbl[]={ {"default", 'f'}, {"done", 'd'}, {"help", 'h'}, {"", '\0'}};/****************************************************************************** * init_tty_control(), initializes all the control windows needed. * ******************************************************************************/static init_tty_control(){ int lines; /* # of lines available for displaying tests */ int pages; int group; /* current group id(index to groups[] */ int cur_test_i; /* current test index(to tests[]) */ int select_v; int which_line; char temp_buf[82]; lines = LINES-12; for (pages=0, cur_test_i=0, group= -1; pages < TTY_WINNO; ++pages) { tty_control[pages] = newwin(lines, COLS-2, 8, 1); if (cur_test_i == exist_tests) break; /* done */ for (which_line=0; which_line != lines; ++which_line) { if (tests[cur_test_i]->group != group) { group = tests[cur_test_i]->group; groups[group].first = cur_test_i; /* keep the first test in the group */ (void)mvwaddstr(tty_control[pages], which_line++, 16, groups[group].c_label); if (which_line == lines) /* hit the end */ { if (pages+1 == TTY_WINNO) break; /* use up */ tty_control[++pages] = newwin(lines, COLS-2, 8, 1); which_line = 0; } } if (tests[cur_test_i]->which_test == 1) { if (tests[cur_test_i]->test_no > 1) /* multiple tests */ { if (tests[cur_test_i]->type != 2) /* it is not a disabled intervention tests */ select_v = tests[cur_test_i]->dev_enable; else select_v = FALSE; } else select_v = (tests[cur_test_i]->enable && tests[cur_test_i]->type!=2); (void)sprintf(temp_buf, "%s%-30s%s", select_v?"->":" ", build_sel_label(cur_test_i), tests[cur_test_i]->popup?"[OPTION]":""); (void)mvwaddstr(tty_control[pages], which_line, TEST_COL, temp_buf); tests[cur_test_i]->select = (Panel_item)(which_line | (pages << 8)); } else --which_line; /* reuse this line */ if (++cur_test_i == exist_tests) break; /* no more */ } if (cur_test_i == exist_tests) break; /* done */ } control_max = pages; control_button = newwin(5, COLS-2, 3, 1); (void)sprintf(temp_buf, "[%s] [%s] [%s] [%s] [%s] [%s] [%s]", "START", "OPTIONS", "STATUS", "SCHEDULE", "OPTFILES", "STOP", "QUIT"); (void)mvwaddstr(control_button, 0, 4, temp_buf); (void)sprintf(temp_buf, "[%s] [%s] [%s] [%s] [%s] [%s] [%s]", "RESET", "SUSPEND", "RESUME", " EEPROM ", "LOGFILES", "HELP", "NEXT"); (void)mvwaddstr(control_button, 1, 4, temp_buf); (void)sprintf(temp_buf, "[%s]", "PROCESSORS"); (void)mvwaddstr(control_button, 2, 4, temp_buf); (void)sprintf(temp_buf, "[INTERVENTION]: %-18s [TESTS]: %-20s", intervention?"Enable":"Disable", select_value!=0? (select_value>1?"ALL [DEFAULT/NONE]":"NONE [ALL/DEFAULT]"): "DEFAULT [NONE/ALL]"); (void)mvwaddstr(control_button, 3, 6, temp_buf);}/****************************************************************************** * get_next_page(), set/initialize next available status page. * ******************************************************************************/get_next_page(){ if (status_row >= status_lines) { ++status_page; status_row = 0; if (tty_status[status_page] == NULL) /* not created yet */ tty_status[status_page] = newwin(status_lines, COLS-2, 6, 1); (void)wclear(tty_status[status_page]); }} /****************************************************************************** * init_tty_option(), initializes the option window. * ******************************************************************************/static init_tty_option(){ tty_option = newwin(LINES-7, COLS-2, 3, 1); (void)wclear(tty_option);}/****************************************************************************** * init_tty_other(), initializes the other window. * ******************************************************************************/static init_tty_other(){ tty_other = newwin(LINES-7, COLS-2, 3, 1); (void)wclear(tty_other);}/****************************************************************************** * init_tty_status(), initializes status_button and console_tty windows. * ******************************************************************************/static init_tty_status(){ status_button = newwin(2, COLS-2, 3, 1); (void)wclear(status_button); (void)mvwaddstr(status_button, 0, SYS_PASS_COL, "[NEXT] [DONE] [HELP]"); /* command to go back to control window */ time_display(); /* initilaize the "Elapsed time" couter */ console_tty = newwin(6, COLS-2, LINES-10, 1); /* this window is opened just for displaying the "box" */ box(console_tty, '|', '-'); mvwaddch(console_tty, 0, 0, ' '); mvwaddch(console_tty, 0, COLS-3, ' '); mvwaddch(console_tty, 5, 0, ' '); mvwaddch(console_tty, 5, COLS-3, ' '); message_tty = subwin(console_tty, 4, COLS-4, LINES-9, 2); (void)wclear(message_tty); scrollok(message_tty, TRUE); /* allow scrolling */ status_lines = LINES-3-3-6-4; tty_status[0] = newwin(status_lines, COLS-2, 6, 1); /* get the first page */}/****************************************************************************** * init_ttys(), creates/initializes the screens/windows needed. * ******************************************************************************/init_ttys(){ char temp_buf[82]; int i; (void)initscr(); if (COLS < MIN_WIDTH) { (void)fprintf(stderr, "Sundiag: The screen needs to have at least %d columns.\n", MIN_WIDTH); sundiag_exit(1); } if (LINES < MIN_HEIGHT) { (void)fprintf(stderr, "Sundiag: The screen needs to have at least %d rows.\n", MIN_HEIGHT); sundiag_exit(1); } cbreak(); noecho(); nonl(); clear(); kill_char = killchar(); del_char = erasechar(); box(stdscr, '|', '-'); (void)sprintf(temp_buf, "Sundiag %s CPU:%s", version, cpuname); mvaddstr(1,2,temp_buf); move(2,1); for (i=COLS-2; i!=0; --i) addch('-'); command_row = LINES-3; message_row =command_row+1; move(command_row-1, 1); for (i=COLS-2; i!=0; --i) addch('-'); mvaddstr(message_row, 2, "Message: "); mvaddstr(command_row, 2, "Command: "); (void)refresh(); init_tty_control(); /* initialize the control window(s) */ init_tty_status(); /* initialize the status window(s) */ init_tty_option(); /* initialize the option window */ init_tty_other(); /* initialize the "other" window */ if (window_type == STATUS_TTY) switch_to_status(); else switch_to_control();}/****************************************************************************** * tty_message(), print the passed message in the "message:" line * * Input: msg, the message to be printed. * * Note: the message line will be cleared if msg == NULL. * ******************************************************************************/#define BEG_MESSAGE 11 /* starting message(status) line */tty_message(msg)char *msg; /* message to be displayed */{ int keep_x, keep_y; getyx(stdscr, keep_y, keep_x); /* save the current position */ move(message_row, BEG_MESSAGE-1); /* get rid of possible garbage too */ clrtoeol(); /* remove the old message first */ mvaddch(message_row, COLS-1, '|'); move(message_row, BEG_MESSAGE); if (msg != NULL) /* just clear the message if NULL */ /* refresh() needs to be called later */ { if (strlen(msg) > MIN_WIDTH-4) *(msg+MIN_WIDTH-4) = '\0'; /* truncate them off */ addstr(msg); addch(0x07); /* bell */ } move(keep_y, keep_x); (void)refresh(); /* display it */}/****************************************************************************** * console_message(), print the passed message in the "console box" of the * * status window. * * Input: msg, the message to be printed. * ******************************************************************************/console_message(msg)char *msg;{ if (message_tty == NULL) return; /* not initialized yet */ while (*msg != '\0') { if (*msg != '\r') (void)waddch(message_tty, *msg); ++msg; } if (window_type == STATUS_TTY) { (void)wrefresh(message_tty); /* display the message */ (void)refresh(); /* restore the cursor */ }}/****************************************************************************** * tty_test_sel_proc, the tty version of the test selection procedure. * * input: devname, the device name. * ******************************************************************************/tty_test_sel_proc(devname)char *devname;{ int test_id, group_id; int value; for (test_id=0; test_id != exist_tests; ++test_id) /* gone through all existing devices to find the specified device */ if (strcmp(devname, tests[test_id]->devname) == 0) break; if (test_id == exist_tests) /* unknown test */ { tty_message(com_err); return; } if (tests[test_id]->type == 2) { (void)confirm( "Please enable the 'Intervention' mode before select this test.", TRUE); return; /* return if disabled intervention/manufacturing tests */ } if (tests[test_id]->test_no > 1) { value = !tests[test_id]->dev_enable; multi_tests(test_id, value); /* handle multiple tests for a device */ } else { tests[test_id]->enable = !tests[test_id]->enable; value = tests[test_id]->enable; if (tests[test_id]->enable) /* if test is to be enabled */ { print_status(); /* display it on status subwindow */ if (running == GO || running == SUSPEND) /* if tests are running */ start_log(test_id); /* log to information file */ } else /* if test is to be disabled */ { if (tests[test_id]->pid == 0) /* if test is not currently running */ print_status(); /* just remove it */ else (void)kill(tests[test_id]->pid, SIGINT); if (running == GO || running == SUSPEND) /* if tests are running */ stop_log(test_id); /* log to information file */ } } display_enable(test_id, value); /* display it */ group_id = tests[test_id]->group; /* get the group number of the test */ test_id = groups[group_id].first; /* get the first test in the group */ for (; test_id != exist_tests; ++test_id) { if (tests[test_id]->group != group_id) break; /* none was enabled */ if (tests[test_id]->dev_enable && (tests[test_id]->enable || tests[test_id]->test_no > 1) && tests[test_id]->type != 2) { if (!groups[group_id].enable) groups[group_id].enable = TRUE; return; /* done */ } } if (groups[group_id].enable) groups[group_id].enable = FALSE;}/****************************************************************************** * switch_to_control(), switch the screen to dispaly control windows. * ******************************************************************************/switch_to_control(){ window_type = CONTROL_TTY; control_index=0; /* start from 0 */ touchwin(control_button); touchwin(tty_control[control_index]); (void)wrefresh(control_button); (void)wrefresh(tty_control[control_index]); (void)refresh(); /* restore the cursor */}/****************************************************************************** * switch_to_status(), switch the screen to display status windows. * ******************************************************************************/static switch_to_status(){ window_type = STATUS_TTY; status_index=0; /* start from 0 */ touchwin(status_button); touchwin(tty_status[0]); touchwin(console_tty); (void)wrefresh(status_button); (void)wrefresh(tty_status[0]); (void)wrefresh(console_tty); (void)refresh(); /* restore the cursor */}/****************************************************************************** * proc_control_com(), processes control window command. * ******************************************************************************/static char *inactivated_msg="Inactivated while running tests!";#define ID_MACH_SHIFT 24 /* machine id in MSB of gethostid() */#define ID_MACH_MASK 0xffstatic proc_control_com() /* process control window command */{ unsigned long machine_id; if (arg_no == 1) { switch (get_com(control_tbl1, arg[0])) { case 'a': /* go to status window */ switch_to_status(); return; case 'e': /* check EEPROM */#ifdef sun4 /* Check for Sun4c */ if ( cpu_is_sun4c() ) return;#endif sun4#ifdef sun386 tty_message("The EEPROM feature is not available on Sun386i!"); return;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -