10e3d5408SPeter Wemm /**************************************************************************** 20e3d5408SPeter Wemm * Copyright (c) 1998 Free Software Foundation, Inc. * 30e3d5408SPeter Wemm * * 40e3d5408SPeter Wemm * Permission is hereby granted, free of charge, to any person obtaining a * 50e3d5408SPeter Wemm * copy of this software and associated documentation files (the * 60e3d5408SPeter Wemm * "Software"), to deal in the Software without restriction, including * 70e3d5408SPeter Wemm * without limitation the rights to use, copy, modify, merge, publish, * 80e3d5408SPeter Wemm * distribute, distribute with modifications, sublicense, and/or sell * 90e3d5408SPeter Wemm * copies of the Software, and to permit persons to whom the Software is * 100e3d5408SPeter Wemm * furnished to do so, subject to the following conditions: * 110e3d5408SPeter Wemm * * 120e3d5408SPeter Wemm * The above copyright notice and this permission notice shall be included * 130e3d5408SPeter Wemm * in all copies or substantial portions of the Software. * 140e3d5408SPeter Wemm * * 150e3d5408SPeter Wemm * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * 160e3d5408SPeter Wemm * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * 170e3d5408SPeter Wemm * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * 180e3d5408SPeter Wemm * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, * 190e3d5408SPeter Wemm * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR * 200e3d5408SPeter Wemm * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR * 210e3d5408SPeter Wemm * THE USE OR OTHER DEALINGS IN THE SOFTWARE. * 220e3d5408SPeter Wemm * * 230e3d5408SPeter Wemm * Except as contained in this notice, the name(s) of the above copyright * 240e3d5408SPeter Wemm * holders shall not be used in advertising or otherwise to promote the * 250e3d5408SPeter Wemm * sale, use or other dealings in this Software without prior written * 260e3d5408SPeter Wemm * authorization. * 270e3d5408SPeter Wemm ****************************************************************************/ 280e3d5408SPeter Wemm 290e3d5408SPeter Wemm /**************************************************************************** 300e3d5408SPeter Wemm * Author: Zeyd M. Ben-Halim <zmbenhal@netcom.com> 1992,1995 * 310e3d5408SPeter Wemm * and: Eric S. Raymond <esr@snark.thyrsus.com> * 320e3d5408SPeter Wemm ****************************************************************************/ 330e3d5408SPeter Wemm 340e3d5408SPeter Wemm /* 350e3d5408SPeter Wemm * toe.c --- table of entries report generator 360e3d5408SPeter Wemm * 370e3d5408SPeter Wemm */ 380e3d5408SPeter Wemm 390e3d5408SPeter Wemm #include <progs.priv.h> 400e3d5408SPeter Wemm 410e3d5408SPeter Wemm #include <sys/stat.h> 420e3d5408SPeter Wemm 430e3d5408SPeter Wemm #include <dump_entry.h> 440e3d5408SPeter Wemm #include <term_entry.h> 450e3d5408SPeter Wemm 460e3d5408SPeter Wemm MODULE_ID("$Id: toe.c,v 0.19 1998/03/08 01:02:46 tom Exp $") 470e3d5408SPeter Wemm 480e3d5408SPeter Wemm const char *_nc_progname; 490e3d5408SPeter Wemm 500e3d5408SPeter Wemm static int typelist(int eargc, char *eargv[], bool, 510e3d5408SPeter Wemm void (*)(const char *, TERMTYPE *)); 520e3d5408SPeter Wemm static void deschook(const char *, TERMTYPE *); 530e3d5408SPeter Wemm 540e3d5408SPeter Wemm #if NO_LEAKS 550e3d5408SPeter Wemm #undef ExitProgram 560e3d5408SPeter Wemm static void ExitProgram(int code) GCC_NORETURN; 570e3d5408SPeter Wemm static void ExitProgram(int code) 580e3d5408SPeter Wemm { 590e3d5408SPeter Wemm _nc_free_entries(_nc_head); 600e3d5408SPeter Wemm _nc_leaks_dump_entry(); 610e3d5408SPeter Wemm _nc_free_and_exit(code); 620e3d5408SPeter Wemm } 630e3d5408SPeter Wemm #endif 640e3d5408SPeter Wemm 650e3d5408SPeter Wemm int main (int argc, char *argv[]) 660e3d5408SPeter Wemm { 670e3d5408SPeter Wemm bool direct_dependencies = FALSE; 680e3d5408SPeter Wemm bool invert_dependencies = FALSE; 690e3d5408SPeter Wemm bool header = FALSE; 700e3d5408SPeter Wemm int i, c, debug_level = 0; 710e3d5408SPeter Wemm int code; 720e3d5408SPeter Wemm 730e3d5408SPeter Wemm if ((_nc_progname = strrchr(argv[0], '/')) == NULL) 740e3d5408SPeter Wemm _nc_progname = argv[0]; 750e3d5408SPeter Wemm else 760e3d5408SPeter Wemm _nc_progname++; 770e3d5408SPeter Wemm 780e3d5408SPeter Wemm while ((c = getopt(argc, argv, "huv:UV")) != EOF) 790e3d5408SPeter Wemm switch (c) 800e3d5408SPeter Wemm { 810e3d5408SPeter Wemm case 'h': 820e3d5408SPeter Wemm header = TRUE; 830e3d5408SPeter Wemm break; 840e3d5408SPeter Wemm case 'u': 850e3d5408SPeter Wemm direct_dependencies = TRUE; 860e3d5408SPeter Wemm break; 870e3d5408SPeter Wemm case 'v': 880e3d5408SPeter Wemm debug_level = atoi(optarg); 890e3d5408SPeter Wemm _nc_tracing = (1 << debug_level) - 1; 900e3d5408SPeter Wemm break; 910e3d5408SPeter Wemm case 'U': 920e3d5408SPeter Wemm invert_dependencies = TRUE; 930e3d5408SPeter Wemm break; 940e3d5408SPeter Wemm case 'V': 950e3d5408SPeter Wemm (void) fputs(NCURSES_VERSION, stdout); 960e3d5408SPeter Wemm putchar('\n'); 970e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 980e3d5408SPeter Wemm default: 990e3d5408SPeter Wemm (void) fprintf (stderr, "usage: toe [-huUV] [-v n] [file...]\n"); 1000e3d5408SPeter Wemm ExitProgram(EXIT_FAILURE); 1010e3d5408SPeter Wemm } 1020e3d5408SPeter Wemm 1030e3d5408SPeter Wemm if (direct_dependencies || invert_dependencies) 1040e3d5408SPeter Wemm { 1050e3d5408SPeter Wemm if (freopen(argv[optind], "r", stdin) == NULL) 1060e3d5408SPeter Wemm { 1070e3d5408SPeter Wemm (void) fflush(stdout); 1080e3d5408SPeter Wemm fprintf(stderr, "%s: can't open %s\n", _nc_progname, argv[optind]); 1090e3d5408SPeter Wemm ExitProgram(EXIT_FAILURE); 1100e3d5408SPeter Wemm } 1110e3d5408SPeter Wemm 1120e3d5408SPeter Wemm /* parse entries out of the source file */ 1130e3d5408SPeter Wemm _nc_set_source(argv[optind]); 1140e3d5408SPeter Wemm _nc_read_entry_source(stdin, (char *)NULL, 1150e3d5408SPeter Wemm FALSE, FALSE, 1160e3d5408SPeter Wemm NULLHOOK); 1170e3d5408SPeter Wemm } 1180e3d5408SPeter Wemm 1190e3d5408SPeter Wemm /* maybe we want a direct-dependency listing? */ 1200e3d5408SPeter Wemm if (direct_dependencies) 1210e3d5408SPeter Wemm { 1220e3d5408SPeter Wemm ENTRY *qp; 1230e3d5408SPeter Wemm 1240e3d5408SPeter Wemm for_entry_list(qp) 1250e3d5408SPeter Wemm if (qp->nuses) 1260e3d5408SPeter Wemm { 1270e3d5408SPeter Wemm int j; 1280e3d5408SPeter Wemm 1290e3d5408SPeter Wemm (void) printf("%s:", _nc_first_name(qp->tterm.term_names)); 1300e3d5408SPeter Wemm for (j = 0; j < qp->nuses; j++) 1310e3d5408SPeter Wemm (void) printf(" %s", (char *)(qp->uses[j].parent)); 1320e3d5408SPeter Wemm putchar('\n'); 1330e3d5408SPeter Wemm } 1340e3d5408SPeter Wemm 1350e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 1360e3d5408SPeter Wemm } 1370e3d5408SPeter Wemm 1380e3d5408SPeter Wemm /* maybe we want a reverse-dependency listing? */ 1390e3d5408SPeter Wemm if (invert_dependencies) 1400e3d5408SPeter Wemm { 1410e3d5408SPeter Wemm ENTRY *qp, *rp; 1420e3d5408SPeter Wemm int matchcount; 1430e3d5408SPeter Wemm 1440e3d5408SPeter Wemm for_entry_list(qp) 1450e3d5408SPeter Wemm { 1460e3d5408SPeter Wemm matchcount = 0; 1470e3d5408SPeter Wemm for_entry_list(rp) 1480e3d5408SPeter Wemm { 1490e3d5408SPeter Wemm if (rp->nuses == 0) 1500e3d5408SPeter Wemm continue; 1510e3d5408SPeter Wemm 1520e3d5408SPeter Wemm for (i = 0; i < rp->nuses; i++) 1530e3d5408SPeter Wemm if (_nc_name_match(qp->tterm.term_names,(char*)rp->uses[i].parent, "|")) 1540e3d5408SPeter Wemm { 1550e3d5408SPeter Wemm if (matchcount++ == 0) 1560e3d5408SPeter Wemm (void) printf("%s:", 1570e3d5408SPeter Wemm _nc_first_name(qp->tterm.term_names)); 1580e3d5408SPeter Wemm (void) printf(" %s", 1590e3d5408SPeter Wemm _nc_first_name(rp->tterm.term_names)); 1600e3d5408SPeter Wemm } 1610e3d5408SPeter Wemm } 1620e3d5408SPeter Wemm if (matchcount) 1630e3d5408SPeter Wemm putchar('\n'); 1640e3d5408SPeter Wemm } 1650e3d5408SPeter Wemm 1660e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 1670e3d5408SPeter Wemm } 1680e3d5408SPeter Wemm 1690e3d5408SPeter Wemm /* 1700e3d5408SPeter Wemm * If we get this far, user wants a simple terminal type listing. 1710e3d5408SPeter Wemm */ 1720e3d5408SPeter Wemm if (optind < argc) { 1730e3d5408SPeter Wemm code = typelist(argc-optind, argv+optind, header, deschook); 1740e3d5408SPeter Wemm } else { 1750e3d5408SPeter Wemm char *by_env, *home, *eargv[3]; 1760e3d5408SPeter Wemm int j; 1770e3d5408SPeter Wemm 1780e3d5408SPeter Wemm j = 0; 1790e3d5408SPeter Wemm if ((by_env = getenv("TERMINFO")) != (char *)NULL) 1800e3d5408SPeter Wemm eargv[j++] = by_env; 1810e3d5408SPeter Wemm else 1820e3d5408SPeter Wemm { 1830e3d5408SPeter Wemm if ((home = getenv("HOME")) != (char *)NULL) 1840e3d5408SPeter Wemm { 1850e3d5408SPeter Wemm char personal[PATH_MAX]; 1860e3d5408SPeter Wemm struct stat sb; 1870e3d5408SPeter Wemm 1880e3d5408SPeter Wemm (void) sprintf(personal, PRIVATE_INFO, home); 1890e3d5408SPeter Wemm if (stat(personal, &sb) == 0 1900e3d5408SPeter Wemm && (sb.st_mode & S_IFMT) == S_IFDIR) 1910e3d5408SPeter Wemm eargv[j++] = personal; 1920e3d5408SPeter Wemm } 1930e3d5408SPeter Wemm eargv[j++] = TERMINFO; 1940e3d5408SPeter Wemm } 1950e3d5408SPeter Wemm eargv[j] = (char *)NULL; 1960e3d5408SPeter Wemm 1970e3d5408SPeter Wemm code = typelist(j, eargv, header, deschook); 1980e3d5408SPeter Wemm } 1990e3d5408SPeter Wemm 2000e3d5408SPeter Wemm ExitProgram(code); 2010e3d5408SPeter Wemm } 2020e3d5408SPeter Wemm 2030e3d5408SPeter Wemm static void deschook(const char *cn, TERMTYPE *tp) 2040e3d5408SPeter Wemm /* display a description for the type */ 2050e3d5408SPeter Wemm { 2060e3d5408SPeter Wemm const char *desc; 2070e3d5408SPeter Wemm 2080e3d5408SPeter Wemm if ((desc = strrchr(tp->term_names, '|')) == (char *)NULL) 2090e3d5408SPeter Wemm desc = "(No description)"; 2100e3d5408SPeter Wemm else 2110e3d5408SPeter Wemm ++desc; 2120e3d5408SPeter Wemm 2130e3d5408SPeter Wemm (void) printf("%-10s\t%s\n", cn, desc); 2140e3d5408SPeter Wemm } 2150e3d5408SPeter Wemm 2160e3d5408SPeter Wemm static int typelist(int eargc, char *eargv[], 2170e3d5408SPeter Wemm bool verbosity, 2180e3d5408SPeter Wemm void (*hook)(const char *, TERMTYPE *tp)) 2190e3d5408SPeter Wemm /* apply a function to each entry in given terminfo directories */ 2200e3d5408SPeter Wemm { 2210e3d5408SPeter Wemm int i; 2220e3d5408SPeter Wemm 2230e3d5408SPeter Wemm for (i = 0; i < eargc; i++) 2240e3d5408SPeter Wemm { 2250e3d5408SPeter Wemm DIR *termdir; 2260e3d5408SPeter Wemm struct dirent *subdir; 2270e3d5408SPeter Wemm 2280e3d5408SPeter Wemm if ((termdir = opendir(eargv[i])) == (DIR *)NULL) 2290e3d5408SPeter Wemm { 2300e3d5408SPeter Wemm (void) fflush(stdout); 2310e3d5408SPeter Wemm (void) fprintf(stderr, 2320e3d5408SPeter Wemm "%s: can't open terminfo directory %s\n", 2330e3d5408SPeter Wemm _nc_progname, eargv[i]); 2340e3d5408SPeter Wemm return(EXIT_FAILURE); 2350e3d5408SPeter Wemm } 2360e3d5408SPeter Wemm else if (verbosity) 2370e3d5408SPeter Wemm (void) printf("#\n#%s:\n#\n", eargv[i]); 2380e3d5408SPeter Wemm 2390e3d5408SPeter Wemm while ((subdir = readdir(termdir)) != NULL) 2400e3d5408SPeter Wemm { 2410e3d5408SPeter Wemm size_t len = NAMLEN(subdir); 2420e3d5408SPeter Wemm char buf[PATH_MAX]; 2430e3d5408SPeter Wemm char name_1[PATH_MAX]; 2440e3d5408SPeter Wemm DIR *entrydir; 2450e3d5408SPeter Wemm struct dirent *entry; 2460e3d5408SPeter Wemm 2470e3d5408SPeter Wemm strncpy(name_1, subdir->d_name, len)[len] = '\0'; 2480e3d5408SPeter Wemm if (!strcmp(name_1, ".") 2490e3d5408SPeter Wemm || !strcmp(name_1, "..")) 2500e3d5408SPeter Wemm continue; 2510e3d5408SPeter Wemm 2520e3d5408SPeter Wemm (void) strcpy(buf, eargv[i]); 2530e3d5408SPeter Wemm (void) strcat(buf, "/"); 2540e3d5408SPeter Wemm (void) strcat(buf, name_1); 2550e3d5408SPeter Wemm (void) strcat(buf, "/"); 2560e3d5408SPeter Wemm chdir(buf); 2570e3d5408SPeter Wemm entrydir = opendir("."); 2580e3d5408SPeter Wemm while ((entry = readdir(entrydir)) != NULL) 2590e3d5408SPeter Wemm { 2600e3d5408SPeter Wemm char name_2[PATH_MAX]; 2610e3d5408SPeter Wemm TERMTYPE lterm; 2620e3d5408SPeter Wemm char *cn; 2630e3d5408SPeter Wemm int status; 2640e3d5408SPeter Wemm 2650e3d5408SPeter Wemm len = NAMLEN(entry); 2660e3d5408SPeter Wemm strncpy(name_2, entry->d_name, len)[len] = '\0'; 2670e3d5408SPeter Wemm if (!strcmp(name_2, ".") 2680e3d5408SPeter Wemm || !strcmp(name_2, "..")) 2690e3d5408SPeter Wemm continue; 2700e3d5408SPeter Wemm 2710e3d5408SPeter Wemm status = _nc_read_file_entry(name_2, <erm); 2720e3d5408SPeter Wemm if (status <= 0) 2730e3d5408SPeter Wemm { 2740e3d5408SPeter Wemm (void) fflush(stdout); 2750e3d5408SPeter Wemm (void) fprintf(stderr, 2760e3d5408SPeter Wemm "toe: couldn't open terminfo file %s.\n", 2770e3d5408SPeter Wemm name_2); 2780e3d5408SPeter Wemm return(EXIT_FAILURE); 2790e3d5408SPeter Wemm } 2800e3d5408SPeter Wemm 2810e3d5408SPeter Wemm /* only visit things once, by primary name */ 2820e3d5408SPeter Wemm cn = _nc_first_name(lterm.term_names); 2830e3d5408SPeter Wemm if (!strcmp(cn, name_2)) 2840e3d5408SPeter Wemm { 2850e3d5408SPeter Wemm /* apply the selected hook function */ 2860e3d5408SPeter Wemm (*hook)(cn, <erm); 2870e3d5408SPeter Wemm } 2880e3d5408SPeter Wemm if (lterm.term_names) { 2890e3d5408SPeter Wemm free(lterm.term_names); 2900e3d5408SPeter Wemm lterm.term_names = NULL; 2910e3d5408SPeter Wemm } 2920e3d5408SPeter Wemm if (lterm.str_table) { 2930e3d5408SPeter Wemm free(lterm.str_table); 2940e3d5408SPeter Wemm lterm.str_table = NULL; 2950e3d5408SPeter Wemm } 2960e3d5408SPeter Wemm } 2970e3d5408SPeter Wemm closedir(entrydir); 2980e3d5408SPeter Wemm } 2990e3d5408SPeter Wemm closedir(termdir); 3000e3d5408SPeter Wemm } 3010e3d5408SPeter Wemm 3020e3d5408SPeter Wemm return(EXIT_SUCCESS); 3030e3d5408SPeter Wemm } 304