/* * $Header: /home/vikas/src/nocol/netconsole/RCS/utils.c,v 1.12 2000/01/19 03:50:56 vikas Exp $ */ /*+ * Utility functions: * * get_reply: prompt and get user's response. * setuserenviron: get terminal type and extract bold strings * outchar: function to print out char (uses macro putc) * */ #ifndef lint static char rcsid[] = "$RCSfile: utils.c,v $ $Revision: 1.12 $ $Date: 2000/01/19 03:50:56 $" ; #endif #include "netconsole.h" /*+ get_reply ** FUNCTION: ** This function prompts a user and gets a response from him. The ** 'prompt' & 'default' are supplied to the function - it returns a ** pointer to a static character string which is the 'reply'. **/ #ifndef C_ANY * * Define types of user responses for get_reply() */ #define C_ANY 0x0 /* Any character (printable or non-) */ #define C_ALPHA 0x1 /* A-z */ #define C_DIGIT 0x2 /* 0-9 */ #define C_SPACE 0x4 /* SPACE, TAB */ #define C_PUNCT 0x8 /* All punctuation characters */ #endif /* C_ANY */ char *get_reply (prompt, deflt, response_type) char *prompt; char *deflt ; int response_type ; /* types defined above */ { static char reply[MAXLINE]; char *r ; /* temp pointer */ int nodefault = 0, invalid = 0; reply[sizeof(reply) - 1] = '\0' ; /* terminate with a NULL */ if (deflt == NULL || *deflt == '\0') nodefault = 1 ; /* No default value */ printf("%s ", prompt); if (nodefault) printf(": "); else printf("[%s]: ", deflt) ; if (strlen(prompt) > 70) /* long string */ putchar('\n'); while (1) { r = (char *)reply ; fgets(reply, MAXLINE, stdin); /* Use fgets() instead of gets() */ reply[strlen(reply) - 1] = '\0'; /* strip terminating newline */ if (*reply == '\0') { if ( nodefault ) { printf("Invalid NULL response!! Enter again: "); continue; /* back to while() loop */ } else /* default has been supplied */ { strncpy(reply, deflt, sizeof(reply) - 1) ; break; } } /* if *reply */ /* * Now check the user's response against the desired response_type */ if (response_type == C_ANY) break; for (invalid = 0; invalid == 0 && *r ; ++r) { register int ch_type = classify(*r) ; if ( (response_type & ch_type) == 0) { fprintf (stderr, "Invalid reply. "); if ( isprint(*(--r)) ) fprintf(stderr, "(character '%c' illegal)\n", *r); fprintf(stderr, " Enter again: "); invalid = 1 ; } } /* end while */ if (! invalid) break; } /* while(1) */ return (reply); } /* end get_reply */ /* * Return class of character 'c' - one of C_ALPHA, C_DIGIT, ... Used * by get_reply() */ classify (c) int c ; { if (isalpha(c)) return (C_ALPHA) ; else if (isdigit(c)) return (C_DIGIT) ; else if (isspace(c)) return (C_SPACE) ; else if (ispunct(c)) return (C_PUNCT); else return (C_ANY); } /* end classify */ /* */ /*+ setuserenviron * FUNCTION * * This function attempts to get the environment variables * relevant to the program (like TERM). It modifies the structure * 'environ' which is a pointer to the strings containing the * variables. If an essential environment variable is not set, then * it sets the variable by prompting or by a default value. * * 'putenv' requires that the storage for the variable be static. * * Lastly gets the value of the termcap variable to enable 'bold' * on the terminals. 'md' = bold, 'mh' = half-intensity, 'me' = end all * */ setuserenviron (term) char *term; { char termtype[MAXLINE], bp[1024] ; /* needed by tgetent */ char *get_reply() ; static char newvar[MAXLINE]; /* has to be static */ bzero(termtype, sizeof (termtype)) ; if (*term == '\0') strcpy (termtype, (char *)getenv("TERM")); /* retrieve TERM type */ else strncpy (termtype, term, sizeof(termtype)); /* cmdline arg */ if (check_terminal(termtype) == -1) /* Extract terminal type */ return(-1) ; sprintf (newvar, "TERM=%s\0",(char *)termtype); if (putenv(newvar) != 0) /* add the new string */ return (-1) ; /* * Extract the bold string from the '/etc/termcap' ("md") */ if ( tgetent(bp, termtype) != 1 ) /* some error */ { bolds[0] = '\0' ; bolde[0] = '\0' ; /* Null strings */ clscr[0] = '\0' ; bellstr[0] = '\0' ; } else /* bp has valid data */ { char *s = (char *)bolds ; tgetstr("md", &s) ; /* extract bold string */ s = (char *)bolde ; tgetstr("me", &s) ; /* end all attr string */ s = (char *)clscr ; tgetstr("cl", &s); s = (char *)bellstr ; if (tgetstr("bl", &s) == NULL) strcpy(bellstr, "\007") ; } } /* end setuserenviron */ /*+ check_terminal ** FUNCTION: ** Check the supplied terminal string against the arrays ** 'good_term' and 'bad_terminals'. Sets the value of the terminal type. ** Return 1 if ok, -1 if error. **/ check_terminal(ptermtype) char *ptermtype ; { register char **p ; char bp[1024]; /* to extract 'tgetent' entry */ int tries = 2 , badterm = 1 ; /* dont prompt if the terminal is in the good_terminals list */ for ( p = good_terminals ; **p != '\0' && *ptermtype; ++p ) if (strcmp (*p, ptermtype) == 0) { printf("Terminal type set to %s\n", ptermtype); return(1) ; } /* Always prompt so user can see the terminal type */ strcpy(ptermtype, get_reply("Terminal type", ptermtype, C_ALPHA|C_DIGIT|C_PUNCT)); for ( p = good_terminals ; **p != '\0' ; ++p ) if (strcmp (*p, ptermtype) == 0) return(1) ; while (tries--) { fprintf (stderr, "Searching for terminal type '%s'...", ptermtype); if ( tgetent(bp, ptermtype) == 1 ) { badterm = 0 ; /* Okay terminal type */ fprintf(stderr, "\n") ; /* * Now check against unacceptable terminals */ for ( p = bad_terminals ; **p != '\0' ; ++p ) if (strcmp (*p, ptermtype) == 0) { badterm = 1 ; break ; } } else /* Couldn't get term entry */ { badterm = 1 ; fprintf(stderr, "not found\n") ; } if (!badterm) return (1) ; if (tries) strncpy(ptermtype, get_reply("Terminal type", "vt100", C_ALPHA|C_DIGIT|C_PUNCT), MAXLINE -1); else break ; } /* end while() */ strcpy(ptermtype, "dumb") ; /* set terminal type to dumb */ fprintf(stderr, "Setting terminal type to '%s'\n", ptermtype) ; sleep (2) ; if ( tgetent(bp, ptermtype) <= 0 ) /* can't even find dumb */ { fprintf(stderr, "(%s) ERROR: tgetent cannot find entry for '%s'\n", prognm, ptermtype); return (-1) ; /* error */ } else return(1); } /*+ ** FUNCTION: ** Just wakeup from the ALARM signal. Do nothing. **/ void wakeup() { signal(SIGALRM, SIG_DFL); /* restore default action */ if (debug) fprintf(stderr, "(debug) wakeup: reset SIGALRM to SIG_DFL") ; } /*+ ** FUNCTION: ** Prints out character to the terminal. Used by tputs, and hence ** cannot be a macro **/ outchar(c) char c ; { putc (c, stdout) ; }