/* $Id: imon.c,v 1.6 2002/07/15 11:58:32 paul Exp $ * * iMON , extended version. * original iMON source (c) Michael Knigge * heavily modified and extended by Fritz Elfert * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Log: imon.c,v $ * Revision 1.6 2002/07/15 11:58:32 paul * Explicitly set stdio buffer for /dev/isdninfo to 2048, as it has * happened that stdio used 1024, and /dev/isdninfo doesn't support * partial reads (0 bytes are returned). Usually not a problem, but * with more than one channel connected, a line of > 1024 bytes is * returned. * Also optimized the curses usage a bit, explicitly writing spaces * so that background colours are set correctly everywhere. * Bumped displayed version to 2.2. * * Revision 1.5 2001/08/22 11:12:00 paul * imon wasn't devfs-compliant yet. * * Revision 1.4 2000/06/13 10:51:06 armin * fixed status output if channels are in * a different order. * * Revision 1.3 1997/05/17 12:23:35 fritz * Corrected some Copyright notes to refer to GPL. * * Revision 1.2 1997/03/20 00:19:01 luethje * inserted the line #include in avmb1/avmcapictrl.c and imon/imon.c, * some bugfixes, new structure in isdnlog/isdnrep/isdnrep.c. * * Revision 1.1 1997/02/17 00:09:03 fritz * New CVS tree * */ #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_NCURSES_H # include #endif #ifdef HAVE_CURSES_H # include #endif #ifdef HAVE_CURSES_NCURSES_H # include #endif #ifdef HAVE_NCURSES_CURSES_H # include #endif #include #define KEY_Q 81 #define KEY_q 113 #define CURSOR_INVISIBLE 0 #define CURSOR_NORMAL 1 #define CURSOR_BOLD 2 #define WHITE_ON_BLUE 1 #define YELLOW_ON_BLUE 2 #define RED_ON_BLUE 3 #define GREEN_ON_BLUE 4 #define WHITE_ON_BLACK 5 struct phone_entry { struct phone_entry *next; char phone[30]; char name[30]; }; static int enable_quit = 1; static int show_names = 0; static int stat_x; static int stat_y; static FILE *isdninfo; static int color; static char *phonebook; static struct phone_entry *phones; static char idmap_line[2048]; static char chmap_line[2048]; static char drmap_line[2048]; static char usage_line[2048]; static char flags_line[2048]; static char phone_line[2048]; WINDOW *statwin; WINDOW *stathdr; time_t current_time; static int Star(char *, char *); /* * Wildmat routines */ static int wildmat(char *s, char *p) { register int last; register int matched; register int reverse; for ( ; *p; s++, p++) switch (*p) { case '\\': /* Literal match with following character; fall through. */ p++; default: if (*s != *p) return(0); continue; case '?': /* Match anything. */ if (*s == '\0') return(0); continue; case '*': /* Trailing star matches everything. */ return(*++p ? Star(s, p) : 1); case '[': /* [^....] means inverse character class. */ if ((reverse = (p[1] == '^'))) p++; for (last = 0, matched = 0; *++p && (*p != ']'); last = *p) /* This next line requires a good C compiler. */ if (*p == '-' ? *s <= *++p && *s >= last : *s == *p) matched = 1; if (matched == reverse) return(0); continue; } return(*s == '\0'); } static int Star(char *s, char *p) { while (wildmat(s, p) == 0) if (*++s == '\0') return(0); return(1); } /* * Read phonebook file and create a linked * list of phone entries. */ static void readphonebook() { FILE *f; struct phone_entry *p; struct phone_entry *q; char line[255]; char *s; if (!(f = fopen(phonebook, "r"))) { fprintf(stderr, "Can't open %s\n",phonebook); } p = phones; while (p) { q = p->next; free(p); p = q; } phones = NULL; while (fgets(line,sizeof(line),f)) { if ((s = strchr(line,'\n'))) *s = '\0'; if (line[0]=='#') continue; s = strchr(line,'\t'); *s++ = '\0'; if (strlen(line) && strlen(s)) { q = malloc(sizeof(struct phone_entry)); q->next = phones; strcpy(q->phone,line); strcpy(q->name,s); phones = q; } } fclose(f); if (!phones) show_names = 0; } /* * Find a phone number in list of phone entries. * If found, return corresponding name, else * return number string. */ char *find_name(char *num) { struct phone_entry *p = phones; static char tmp[30]; sprintf(tmp, "%-28.28s", num); if (!show_names) return(tmp); while (p) { if (wildmat(num, p->phone)) { sprintf(tmp, "%-28.28s", p->name); break; } p = p->next; } return tmp; } void cleanup(int dummy) { /* * okay, all done. clear the screen and quit ncurses */ fclose(isdninfo); clear(); if (color == TRUE) { attron(COLOR_PAIR(WHITE_ON_BLACK)); attroff(A_BOLD); } endwin(); exit(0); } void usage(void) { fprintf(stderr,"usage: imon [-q][-p PhoneBookFile]\n"); exit(1); } /* * init ncurses and check if colors can be used. */ int imon_init_ncurses(int *color) { initscr(); noecho(); nonl(); refresh(); cbreak(); nodelay(stdscr,TRUE); keypad(stdscr,TRUE); curs_set(CURSOR_INVISIBLE); statwin = newpad(ISDN_MAX_CHANNELS, 100); stathdr = newpad(3, 100); if ((*color = has_colors()) == TRUE) { start_color(); init_pair(WHITE_ON_BLUE, COLOR_WHITE, COLOR_BLUE); init_pair(YELLOW_ON_BLUE, COLOR_YELLOW, COLOR_BLUE); init_pair(RED_ON_BLUE, COLOR_RED, COLOR_BLUE); init_pair(GREEN_ON_BLUE, COLOR_GREEN, COLOR_BLUE); init_pair(WHITE_ON_BLACK, COLOR_WHITE, COLOR_BLACK); } return(TRUE); } /* * Draw the static part of the screen. */ int imon_draw_mask(int color) { int line; int col; if (color == TRUE) { attron(A_BOLD); wattron(statwin,A_BOLD); wattron(stathdr,A_BOLD); attron(COLOR_PAIR(WHITE_ON_BLUE)); } move(0, 0); addch(ACS_ULCORNER); for(col=2; col= 0) { /* a driver loaded in the meantime, perhaps? */ if (no_channels) { no_channels = 0; if (color) { attron(COLOR_PAIR(YELLOW_ON_BLUE)); } mvaddstr(1, 16, " "); } } /* * now print info for every line */ for(line=0; linetm_year+1900, now->tm_mon+1, now->tm_mday, now->tm_hour,now->tm_min,now->tm_sec); prefresh(stathdr, 0, stat_x, 3, 2, 5, COLS-3); prefresh(statwin, stat_y, stat_x, 5, 2, LINES-5, COLS-3); return(TRUE); } void do_resize(int dummy) { endwin(); imon_init_ncurses(&color); imon_draw_mask(color); imon_draw_status(color, ¤t_time); refresh(); signal(SIGWINCH, do_resize); } int main(int argc, char **argv) { int quit , i; fd_set fdset; struct timeval timeout; static char fbuf[2048]; /* * check parameters */ phonebook = NULL; phones = NULL; for (i=1;i 0) stat_x--; break; case KEY_RIGHT: if (stat_x < (100-COLS-4)) stat_x++; break; case KEY_UP: if (stat_y > 0) stat_y--; break; case KEY_DOWN: if (stat_y < ((ISDN_MAX_CHANNELS + 3) - (LINES-6))) stat_y++; break; } } if (FD_ISSET(fileno(isdninfo),&fdset)) { time(¤t_time); imon_read_status(); } break; case -1: if (errno != EINTR) { perror("select"); sleep(5); return 2; } } imon_draw_status(color, ¤t_time); refresh(); } while (!quit); cleanup(0); return 0; }