10e3d5408SPeter Wemm /**************************************************************************** 2d8977eafSRong-En Fan * Copyright (c) 1998-2007,2008 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> * 324a1a9510SRong-En Fan * and: Thomas E. Dickey 1996-on * 330e3d5408SPeter Wemm ****************************************************************************/ 340e3d5408SPeter Wemm 350e3d5408SPeter Wemm /* 360e3d5408SPeter Wemm * toe.c --- table of entries report generator 370e3d5408SPeter Wemm */ 380e3d5408SPeter Wemm 390e3d5408SPeter Wemm #include <progs.priv.h> 400e3d5408SPeter Wemm 410e3d5408SPeter Wemm #include <sys/stat.h> 420e3d5408SPeter Wemm 434a1a9510SRong-En Fan #if USE_HASHED_DB 444a1a9510SRong-En Fan #include <hashed_db.h> 454a1a9510SRong-En Fan #endif 464a1a9510SRong-En Fan 47d8977eafSRong-En Fan MODULE_ID("$Id: toe.c,v 1.48 2008/01/05 20:41:26 tom Exp $") 4815589c42SPeter Wemm 4915589c42SPeter Wemm #define isDotname(name) (!strcmp(name, ".") || !strcmp(name, "..")) 500e3d5408SPeter Wemm 510e3d5408SPeter Wemm const char *_nc_progname; 520e3d5408SPeter Wemm 530e3d5408SPeter Wemm #if NO_LEAKS 540e3d5408SPeter Wemm #undef ExitProgram 554a1a9510SRong-En Fan static void ExitProgram(int code) GCC_NORETURN; 5615589c42SPeter Wemm static void 574a1a9510SRong-En Fan ExitProgram(int code) 580e3d5408SPeter Wemm { 590e3d5408SPeter Wemm _nc_free_entries(_nc_head); 605ca44d1cSRong-En Fan _nc_free_tic(code); 610e3d5408SPeter Wemm } 620e3d5408SPeter Wemm #endif 630e3d5408SPeter Wemm 644a1a9510SRong-En Fan #if USE_HASHED_DB 6539f2269fSPeter Wemm static bool 664a1a9510SRong-En Fan make_db_name(char *dst, const char *src, unsigned limit) 6739f2269fSPeter Wemm { 684a1a9510SRong-En Fan static const char suffix[] = DBM_SUFFIX; 694a1a9510SRong-En Fan 704a1a9510SRong-En Fan bool result = FALSE; 714a1a9510SRong-En Fan unsigned lens = sizeof(suffix) - 1; 724a1a9510SRong-En Fan unsigned size = strlen(src); 734a1a9510SRong-En Fan unsigned need = lens + size; 744a1a9510SRong-En Fan 754a1a9510SRong-En Fan if (need <= limit) { 764a1a9510SRong-En Fan if (size >= lens 774a1a9510SRong-En Fan && !strcmp(src + size - lens, suffix)) 784a1a9510SRong-En Fan (void) strcpy(dst, src); 794a1a9510SRong-En Fan else 804a1a9510SRong-En Fan (void) sprintf(dst, "%s%s", src, suffix); 814a1a9510SRong-En Fan result = TRUE; 8239f2269fSPeter Wemm } 834a1a9510SRong-En Fan return result; 844a1a9510SRong-En Fan } 854a1a9510SRong-En Fan #endif 8639f2269fSPeter Wemm 8739f2269fSPeter Wemm static bool 884a1a9510SRong-En Fan is_database(const char *path) 8939f2269fSPeter Wemm { 904a1a9510SRong-En Fan bool result = FALSE; 914a1a9510SRong-En Fan #if USE_DATABASE 924a1a9510SRong-En Fan if (_nc_is_dir_path(path) && access(path, R_OK | X_OK) == 0) { 934a1a9510SRong-En Fan result = TRUE; 944a1a9510SRong-En Fan } 954a1a9510SRong-En Fan #endif 964a1a9510SRong-En Fan #if USE_TERMCAP 974a1a9510SRong-En Fan if (_nc_is_file_path(path) && access(path, R_OK) == 0) { 984a1a9510SRong-En Fan result = TRUE; 994a1a9510SRong-En Fan } 1004a1a9510SRong-En Fan #endif 1014a1a9510SRong-En Fan #if USE_HASHED_DB 1024a1a9510SRong-En Fan if (!result) { 1034a1a9510SRong-En Fan char filename[PATH_MAX]; 1044a1a9510SRong-En Fan if (_nc_is_file_path(path) && access(path, R_OK) == 0) { 1054a1a9510SRong-En Fan result = TRUE; 1064a1a9510SRong-En Fan } else if (make_db_name(filename, path, sizeof(filename))) { 1074a1a9510SRong-En Fan if (_nc_is_file_path(filename) && access(filename, R_OK) == 0) { 1084a1a9510SRong-En Fan result = TRUE; 1094a1a9510SRong-En Fan } 1104a1a9510SRong-En Fan } 1114a1a9510SRong-En Fan } 1124a1a9510SRong-En Fan #endif 1134a1a9510SRong-En Fan return result; 11439f2269fSPeter Wemm } 11539f2269fSPeter Wemm 1164a1a9510SRong-En Fan static void 1174a1a9510SRong-En Fan deschook(const char *cn, TERMTYPE *tp) 1184a1a9510SRong-En Fan /* display a description for the type */ 11915589c42SPeter Wemm { 1204a1a9510SRong-En Fan const char *desc; 1214a1a9510SRong-En Fan 1224a1a9510SRong-En Fan if ((desc = strrchr(tp->term_names, '|')) == 0 || *++desc == '\0') 1234a1a9510SRong-En Fan desc = "(No description)"; 1244a1a9510SRong-En Fan 1254a1a9510SRong-En Fan (void) printf("%-10s\t%s\n", cn, desc); 12615589c42SPeter Wemm } 1274a1a9510SRong-En Fan 1284a1a9510SRong-En Fan #if USE_TERMCAP 1294a1a9510SRong-En Fan static void 1304a1a9510SRong-En Fan show_termcap(char *buffer, 1314a1a9510SRong-En Fan void (*hook) (const char *, TERMTYPE *tp)) 1324a1a9510SRong-En Fan { 1334a1a9510SRong-En Fan TERMTYPE data; 1344a1a9510SRong-En Fan char *next = strchr(buffer, ':'); 1354a1a9510SRong-En Fan char *last; 1364a1a9510SRong-En Fan char *list = buffer; 1374a1a9510SRong-En Fan 1384a1a9510SRong-En Fan if (next) 1394a1a9510SRong-En Fan *next = '\0'; 1404a1a9510SRong-En Fan 1414a1a9510SRong-En Fan last = strrchr(buffer, '|'); 1424a1a9510SRong-En Fan if (last) 1434a1a9510SRong-En Fan ++last; 1444a1a9510SRong-En Fan 1454a1a9510SRong-En Fan data.term_names = strdup(buffer); 1464a1a9510SRong-En Fan while ((next = strtok(list, "|")) != 0) { 1474a1a9510SRong-En Fan if (next != last) 1484a1a9510SRong-En Fan hook(next, &data); 1494a1a9510SRong-En Fan list = 0; 1504a1a9510SRong-En Fan } 1514a1a9510SRong-En Fan free(data.term_names); 1524a1a9510SRong-En Fan } 1534a1a9510SRong-En Fan #endif 1544a1a9510SRong-En Fan 1554a1a9510SRong-En Fan static int 1564a1a9510SRong-En Fan typelist(int eargc, char *eargv[], 1574a1a9510SRong-En Fan bool verbosity, 1584a1a9510SRong-En Fan void (*hook) (const char *, TERMTYPE *tp)) 1594a1a9510SRong-En Fan /* apply a function to each entry in given terminfo directories */ 1604a1a9510SRong-En Fan { 1614a1a9510SRong-En Fan int i; 1624a1a9510SRong-En Fan 1634a1a9510SRong-En Fan for (i = 0; i < eargc; i++) { 1644a1a9510SRong-En Fan #if USE_DATABASE 1654a1a9510SRong-En Fan if (_nc_is_dir_path(eargv[i])) { 1664a1a9510SRong-En Fan DIR *termdir; 1674a1a9510SRong-En Fan DIRENT *subdir; 1684a1a9510SRong-En Fan 1694a1a9510SRong-En Fan if ((termdir = opendir(eargv[i])) == 0) { 1704a1a9510SRong-En Fan (void) fflush(stdout); 1714a1a9510SRong-En Fan (void) fprintf(stderr, 1724a1a9510SRong-En Fan "%s: can't open terminfo directory %s\n", 1734a1a9510SRong-En Fan _nc_progname, eargv[i]); 1744a1a9510SRong-En Fan return (EXIT_FAILURE); 1754a1a9510SRong-En Fan } else if (verbosity) 1764a1a9510SRong-En Fan (void) printf("#\n#%s:\n#\n", eargv[i]); 1774a1a9510SRong-En Fan 1784a1a9510SRong-En Fan while ((subdir = readdir(termdir)) != 0) { 1794a1a9510SRong-En Fan size_t len = NAMLEN(subdir); 1804a1a9510SRong-En Fan char buf[PATH_MAX]; 1814a1a9510SRong-En Fan char name_1[PATH_MAX]; 1824a1a9510SRong-En Fan DIR *entrydir; 1834a1a9510SRong-En Fan DIRENT *entry; 1844a1a9510SRong-En Fan 1854a1a9510SRong-En Fan strncpy(name_1, subdir->d_name, len)[len] = '\0'; 1864a1a9510SRong-En Fan if (isDotname(name_1)) 1874a1a9510SRong-En Fan continue; 1884a1a9510SRong-En Fan 1894a1a9510SRong-En Fan (void) sprintf(buf, "%s/%s/", eargv[i], name_1); 1904a1a9510SRong-En Fan if (chdir(buf) != 0) 1914a1a9510SRong-En Fan continue; 1924a1a9510SRong-En Fan 1934a1a9510SRong-En Fan entrydir = opendir("."); 1944a1a9510SRong-En Fan while ((entry = readdir(entrydir)) != 0) { 1954a1a9510SRong-En Fan char name_2[PATH_MAX]; 1964a1a9510SRong-En Fan TERMTYPE lterm; 1974a1a9510SRong-En Fan char *cn; 1984a1a9510SRong-En Fan int status; 1994a1a9510SRong-En Fan 2004a1a9510SRong-En Fan len = NAMLEN(entry); 2014a1a9510SRong-En Fan strncpy(name_2, entry->d_name, len)[len] = '\0'; 2024a1a9510SRong-En Fan if (isDotname(name_2) || !_nc_is_file_path(name_2)) 2034a1a9510SRong-En Fan continue; 2044a1a9510SRong-En Fan 2054a1a9510SRong-En Fan status = _nc_read_file_entry(name_2, <erm); 2064a1a9510SRong-En Fan if (status <= 0) { 2074a1a9510SRong-En Fan (void) fflush(stdout); 2084a1a9510SRong-En Fan (void) fprintf(stderr, 2094a1a9510SRong-En Fan "%s: couldn't open terminfo file %s.\n", 2104a1a9510SRong-En Fan _nc_progname, name_2); 2114a1a9510SRong-En Fan return (EXIT_FAILURE); 2124a1a9510SRong-En Fan } 2134a1a9510SRong-En Fan 2144a1a9510SRong-En Fan /* only visit things once, by primary name */ 2154a1a9510SRong-En Fan cn = _nc_first_name(lterm.term_names); 2164a1a9510SRong-En Fan if (!strcmp(cn, name_2)) { 2174a1a9510SRong-En Fan /* apply the selected hook function */ 2184a1a9510SRong-En Fan (*hook) (cn, <erm); 2194a1a9510SRong-En Fan } 2204a1a9510SRong-En Fan _nc_free_termtype(<erm); 2214a1a9510SRong-En Fan } 2224a1a9510SRong-En Fan closedir(entrydir); 2234a1a9510SRong-En Fan } 2244a1a9510SRong-En Fan closedir(termdir); 2254a1a9510SRong-En Fan } 2264a1a9510SRong-En Fan #if USE_HASHED_DB 2274a1a9510SRong-En Fan else { 2284a1a9510SRong-En Fan DB *capdbp; 2294a1a9510SRong-En Fan char filename[PATH_MAX]; 2304a1a9510SRong-En Fan 2314a1a9510SRong-En Fan if (make_db_name(filename, eargv[i], sizeof(filename))) { 2324a1a9510SRong-En Fan if ((capdbp = _nc_db_open(filename, FALSE)) != 0) { 2334a1a9510SRong-En Fan DBT key, data; 2344a1a9510SRong-En Fan int code; 2354a1a9510SRong-En Fan 2364a1a9510SRong-En Fan code = _nc_db_first(capdbp, &key, &data); 2374a1a9510SRong-En Fan while (code == 0) { 2384a1a9510SRong-En Fan TERMTYPE lterm; 2394a1a9510SRong-En Fan int used; 2404a1a9510SRong-En Fan char *have; 2414a1a9510SRong-En Fan char *cn; 2424a1a9510SRong-En Fan 2434a1a9510SRong-En Fan if (_nc_db_have_data(&key, &data, &have, &used)) { 2444a1a9510SRong-En Fan if (_nc_read_termtype(<erm, have, used) > 0) { 2454a1a9510SRong-En Fan /* only visit things once, by primary name */ 2464a1a9510SRong-En Fan cn = _nc_first_name(lterm.term_names); 2474a1a9510SRong-En Fan /* apply the selected hook function */ 2484a1a9510SRong-En Fan (*hook) (cn, <erm); 2494a1a9510SRong-En Fan _nc_free_termtype(<erm); 2504a1a9510SRong-En Fan } 2514a1a9510SRong-En Fan } 2524a1a9510SRong-En Fan code = _nc_db_next(capdbp, &key, &data); 2534a1a9510SRong-En Fan } 2544a1a9510SRong-En Fan 2554a1a9510SRong-En Fan _nc_db_close(capdbp); 2564a1a9510SRong-En Fan } 2574a1a9510SRong-En Fan } 2584a1a9510SRong-En Fan } 2594a1a9510SRong-En Fan #endif 2604a1a9510SRong-En Fan #endif 2614a1a9510SRong-En Fan #if USE_TERMCAP 2624a1a9510SRong-En Fan #if HAVE_BSD_CGETENT 2634a1a9510SRong-En Fan char *db_array[2]; 2644a1a9510SRong-En Fan char *buffer = 0; 2654a1a9510SRong-En Fan 2664a1a9510SRong-En Fan if (verbosity) 2674a1a9510SRong-En Fan (void) printf("#\n#%s:\n#\n", eargv[i]); 2684a1a9510SRong-En Fan 2694a1a9510SRong-En Fan db_array[0] = eargv[i]; 2704a1a9510SRong-En Fan db_array[1] = 0; 2714a1a9510SRong-En Fan 2724a1a9510SRong-En Fan if (cgetfirst(&buffer, db_array)) { 2734a1a9510SRong-En Fan show_termcap(buffer, hook); 2744a1a9510SRong-En Fan free(buffer); 2754a1a9510SRong-En Fan while (cgetnext(&buffer, db_array)) { 2764a1a9510SRong-En Fan show_termcap(buffer, hook); 2774a1a9510SRong-En Fan free(buffer); 2784a1a9510SRong-En Fan } 2794a1a9510SRong-En Fan } 2804a1a9510SRong-En Fan cgetclose(); 2814a1a9510SRong-En Fan #else 2824a1a9510SRong-En Fan /* scan termcap text-file only */ 2834a1a9510SRong-En Fan if (_nc_is_file_path(eargv[i])) { 2844a1a9510SRong-En Fan char buffer[2048]; 2854a1a9510SRong-En Fan FILE *fp; 2864a1a9510SRong-En Fan 2874a1a9510SRong-En Fan if ((fp = fopen(eargv[i], "r")) != 0) { 2884a1a9510SRong-En Fan while (fgets(buffer, sizeof(buffer), fp) != 0) { 2894a1a9510SRong-En Fan if (*buffer == '#') 2904a1a9510SRong-En Fan continue; 2914a1a9510SRong-En Fan if (isspace(*buffer)) 2924a1a9510SRong-En Fan continue; 2934a1a9510SRong-En Fan show_termcap(buffer, hook); 2944a1a9510SRong-En Fan } 2954a1a9510SRong-En Fan fclose(fp); 2964a1a9510SRong-En Fan } 2974a1a9510SRong-En Fan } 2984a1a9510SRong-En Fan #endif 2994a1a9510SRong-En Fan #endif 3004a1a9510SRong-En Fan } 3014a1a9510SRong-En Fan 3024a1a9510SRong-En Fan return (EXIT_SUCCESS); 3034a1a9510SRong-En Fan } 3044a1a9510SRong-En Fan 3054a1a9510SRong-En Fan static void 3064a1a9510SRong-En Fan usage(void) 3074a1a9510SRong-En Fan { 3084a1a9510SRong-En Fan (void) fprintf(stderr, "usage: %s [-ahuUV] [-v n] [file...]\n", _nc_progname); 3094a1a9510SRong-En Fan ExitProgram(EXIT_FAILURE); 31015589c42SPeter Wemm } 31115589c42SPeter Wemm 31215589c42SPeter Wemm int 31315589c42SPeter Wemm main(int argc, char *argv[]) 3140e3d5408SPeter Wemm { 3154a1a9510SRong-En Fan bool all_dirs = FALSE; 3160e3d5408SPeter Wemm bool direct_dependencies = FALSE; 3170e3d5408SPeter Wemm bool invert_dependencies = FALSE; 3180e3d5408SPeter Wemm bool header = FALSE; 319d8977eafSRong-En Fan char *report_file = 0; 3204a1a9510SRong-En Fan int i; 3210e3d5408SPeter Wemm int code; 3224a1a9510SRong-En Fan int this_opt, last_opt = '?'; 3234a1a9510SRong-En Fan int v_opt = 0; 3240e3d5408SPeter Wemm 32539f2269fSPeter Wemm _nc_progname = _nc_rootname(argv[0]); 3260e3d5408SPeter Wemm 327d8977eafSRong-En Fan while ((this_opt = getopt(argc, argv, "0123456789ahu:vU:V")) != -1) { 3284a1a9510SRong-En Fan /* handle optional parameter */ 3294a1a9510SRong-En Fan if (isdigit(this_opt)) { 3304a1a9510SRong-En Fan switch (last_opt) { 3314a1a9510SRong-En Fan case 'v': 3324a1a9510SRong-En Fan v_opt = (this_opt - '0'); 3334a1a9510SRong-En Fan break; 3344a1a9510SRong-En Fan default: 3354a1a9510SRong-En Fan if (isdigit(last_opt)) 3364a1a9510SRong-En Fan v_opt *= 10; 3374a1a9510SRong-En Fan else 3384a1a9510SRong-En Fan v_opt = 0; 3394a1a9510SRong-En Fan v_opt += (this_opt - '0'); 3404a1a9510SRong-En Fan last_opt = this_opt; 3414a1a9510SRong-En Fan } 3424a1a9510SRong-En Fan continue; 3434a1a9510SRong-En Fan } 3444a1a9510SRong-En Fan switch (this_opt) { 3454a1a9510SRong-En Fan case 'a': 3464a1a9510SRong-En Fan all_dirs = TRUE; 3474a1a9510SRong-En Fan break; 3480e3d5408SPeter Wemm case 'h': 3490e3d5408SPeter Wemm header = TRUE; 3500e3d5408SPeter Wemm break; 3510e3d5408SPeter Wemm case 'u': 3520e3d5408SPeter Wemm direct_dependencies = TRUE; 353d8977eafSRong-En Fan report_file = optarg; 3540e3d5408SPeter Wemm break; 3550e3d5408SPeter Wemm case 'v': 3564a1a9510SRong-En Fan v_opt = 1; 3570e3d5408SPeter Wemm break; 3580e3d5408SPeter Wemm case 'U': 3590e3d5408SPeter Wemm invert_dependencies = TRUE; 360d8977eafSRong-En Fan report_file = optarg; 3610e3d5408SPeter Wemm break; 3620e3d5408SPeter Wemm case 'V': 36318259542SPeter Wemm puts(curses_version()); 3640e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 3650e3d5408SPeter Wemm default: 3664a1a9510SRong-En Fan usage(); 3670e3d5408SPeter Wemm } 3684a1a9510SRong-En Fan } 3694a1a9510SRong-En Fan set_trace_level(v_opt); 3700e3d5408SPeter Wemm 371d8977eafSRong-En Fan if (report_file != 0) { 372d8977eafSRong-En Fan if (freopen(report_file, "r", stdin) == 0) { 3730e3d5408SPeter Wemm (void) fflush(stdout); 374d8977eafSRong-En Fan fprintf(stderr, "%s: can't open %s\n", _nc_progname, report_file); 3750e3d5408SPeter Wemm ExitProgram(EXIT_FAILURE); 3760e3d5408SPeter Wemm } 3770e3d5408SPeter Wemm 3780e3d5408SPeter Wemm /* parse entries out of the source file */ 379d8977eafSRong-En Fan _nc_set_source(report_file); 38015589c42SPeter Wemm _nc_read_entry_source(stdin, 0, FALSE, FALSE, NULLHOOK); 3810e3d5408SPeter Wemm } 3820e3d5408SPeter Wemm 3830e3d5408SPeter Wemm /* maybe we want a direct-dependency listing? */ 38415589c42SPeter Wemm if (direct_dependencies) { 3850e3d5408SPeter Wemm ENTRY *qp; 3860e3d5408SPeter Wemm 3874a1a9510SRong-En Fan for_entry_list(qp) { 38815589c42SPeter Wemm if (qp->nuses) { 3890e3d5408SPeter Wemm int j; 3900e3d5408SPeter Wemm 3910e3d5408SPeter Wemm (void) printf("%s:", _nc_first_name(qp->tterm.term_names)); 3920e3d5408SPeter Wemm for (j = 0; j < qp->nuses; j++) 39315589c42SPeter Wemm (void) printf(" %s", qp->uses[j].name); 3940e3d5408SPeter Wemm putchar('\n'); 3950e3d5408SPeter Wemm } 3964a1a9510SRong-En Fan } 3970e3d5408SPeter Wemm 3980e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 3990e3d5408SPeter Wemm } 4000e3d5408SPeter Wemm 4010e3d5408SPeter Wemm /* maybe we want a reverse-dependency listing? */ 40215589c42SPeter Wemm if (invert_dependencies) { 4030e3d5408SPeter Wemm ENTRY *qp, *rp; 4040e3d5408SPeter Wemm int matchcount; 4050e3d5408SPeter Wemm 40615589c42SPeter Wemm for_entry_list(qp) { 4070e3d5408SPeter Wemm matchcount = 0; 40815589c42SPeter Wemm for_entry_list(rp) { 4090e3d5408SPeter Wemm if (rp->nuses == 0) 4100e3d5408SPeter Wemm continue; 4110e3d5408SPeter Wemm 4120e3d5408SPeter Wemm for (i = 0; i < rp->nuses; i++) 41315589c42SPeter Wemm if (_nc_name_match(qp->tterm.term_names, 41415589c42SPeter Wemm rp->uses[i].name, "|")) { 4150e3d5408SPeter Wemm if (matchcount++ == 0) 4160e3d5408SPeter Wemm (void) printf("%s:", 4170e3d5408SPeter Wemm _nc_first_name(qp->tterm.term_names)); 4180e3d5408SPeter Wemm (void) printf(" %s", 4190e3d5408SPeter Wemm _nc_first_name(rp->tterm.term_names)); 4200e3d5408SPeter Wemm } 4210e3d5408SPeter Wemm } 4220e3d5408SPeter Wemm if (matchcount) 4230e3d5408SPeter Wemm putchar('\n'); 4240e3d5408SPeter Wemm } 4250e3d5408SPeter Wemm 4260e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 4270e3d5408SPeter Wemm } 4280e3d5408SPeter Wemm 4290e3d5408SPeter Wemm /* 4300e3d5408SPeter Wemm * If we get this far, user wants a simple terminal type listing. 4310e3d5408SPeter Wemm */ 4320e3d5408SPeter Wemm if (optind < argc) { 4330e3d5408SPeter Wemm code = typelist(argc - optind, argv + optind, header, deschook); 4344a1a9510SRong-En Fan } else if (all_dirs) { 4354a1a9510SRong-En Fan DBDIRS state; 4364a1a9510SRong-En Fan int offset; 4374a1a9510SRong-En Fan int pass; 4384a1a9510SRong-En Fan const char *path; 4394a1a9510SRong-En Fan char **eargv = 0; 4400e3d5408SPeter Wemm 4414a1a9510SRong-En Fan code = EXIT_FAILURE; 4424a1a9510SRong-En Fan for (pass = 0; pass < 2; ++pass) { 4434a1a9510SRong-En Fan unsigned count = 0; 4440e3d5408SPeter Wemm 4454a1a9510SRong-En Fan _nc_first_db(&state, &offset); 4464a1a9510SRong-En Fan while ((path = _nc_next_db(&state, &offset)) != 0) { 4474a1a9510SRong-En Fan if (!is_database(path)) { 4484a1a9510SRong-En Fan ; 4494a1a9510SRong-En Fan } else if (eargv != 0) { 4504a1a9510SRong-En Fan unsigned n; 4514a1a9510SRong-En Fan int found = FALSE; 4524a1a9510SRong-En Fan 4534a1a9510SRong-En Fan /* eliminate duplicates */ 4544a1a9510SRong-En Fan for (n = 0; n < count; ++n) { 4554a1a9510SRong-En Fan if (!strcmp(path, eargv[n])) { 4564a1a9510SRong-En Fan found = TRUE; 4574a1a9510SRong-En Fan break; 4580e3d5408SPeter Wemm } 4594a1a9510SRong-En Fan } 4604a1a9510SRong-En Fan if (!found) { 4614a1a9510SRong-En Fan eargv[count] = strdup(path); 4624a1a9510SRong-En Fan ++count; 4634a1a9510SRong-En Fan } 4644a1a9510SRong-En Fan } else { 4654a1a9510SRong-En Fan ++count; 4664a1a9510SRong-En Fan } 4674a1a9510SRong-En Fan } 4684a1a9510SRong-En Fan if (!pass) { 4694a1a9510SRong-En Fan eargv = typeCalloc(char *, count + 1); 4704a1a9510SRong-En Fan } else { 4714a1a9510SRong-En Fan code = typelist((int) count, eargv, header, deschook); 4724a1a9510SRong-En Fan while (count-- > 0) 4734a1a9510SRong-En Fan free(eargv[count]); 4744a1a9510SRong-En Fan free(eargv); 4754a1a9510SRong-En Fan } 4764a1a9510SRong-En Fan } 4774a1a9510SRong-En Fan } else { 4784a1a9510SRong-En Fan DBDIRS state; 4794a1a9510SRong-En Fan int offset; 4804a1a9510SRong-En Fan const char *path; 4814a1a9510SRong-En Fan char *eargv[3]; 4824a1a9510SRong-En Fan int count = 0; 4834a1a9510SRong-En Fan 4844a1a9510SRong-En Fan _nc_first_db(&state, &offset); 4854a1a9510SRong-En Fan while ((path = _nc_next_db(&state, &offset)) != 0) { 4864a1a9510SRong-En Fan if (is_database(path)) { 4874a1a9510SRong-En Fan eargv[count++] = strdup(path); 4884a1a9510SRong-En Fan break; 4894a1a9510SRong-En Fan } 4904a1a9510SRong-En Fan } 4914a1a9510SRong-En Fan eargv[count] = 0; 4924a1a9510SRong-En Fan 4934a1a9510SRong-En Fan code = typelist(count, eargv, header, deschook); 4944a1a9510SRong-En Fan 4954a1a9510SRong-En Fan while (count-- > 0) 4964a1a9510SRong-En Fan free(eargv[count]); 4974a1a9510SRong-En Fan } 4984a1a9510SRong-En Fan _nc_last_db(); 4990e3d5408SPeter Wemm 5000e3d5408SPeter Wemm ExitProgram(code); 5010e3d5408SPeter Wemm } 502