10e3d5408SPeter Wemm /**************************************************************************** 2*73f0a83dSXin LI * Copyright (c) 1998-2012,2013 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 47*73f0a83dSXin LI MODULE_ID("$Id: toe.c,v 1.74 2013/12/15 01:08:28 tom Exp $") 4815589c42SPeter Wemm 4915589c42SPeter Wemm #define isDotname(name) (!strcmp(name, ".") || !strcmp(name, "..")) 500e3d5408SPeter Wemm 51*73f0a83dSXin LI typedef struct { 52*73f0a83dSXin LI int db_index; 53*73f0a83dSXin LI unsigned long checksum; 54*73f0a83dSXin LI char *term_name; 55*73f0a83dSXin LI char *description; 56*73f0a83dSXin LI } TERMDATA; 57*73f0a83dSXin LI 580e3d5408SPeter Wemm const char *_nc_progname; 590e3d5408SPeter Wemm 60*73f0a83dSXin LI static TERMDATA *ptr_termdata; /* array of terminal data */ 61*73f0a83dSXin LI static size_t use_termdata; /* actual usage in ptr_termdata[] */ 62*73f0a83dSXin LI static size_t len_termdata; /* allocated size of ptr_termdata[] */ 63*73f0a83dSXin LI 640e3d5408SPeter Wemm #if NO_LEAKS 650e3d5408SPeter Wemm #undef ExitProgram 664a1a9510SRong-En Fan static void ExitProgram(int code) GCC_NORETURN; 6715589c42SPeter Wemm static void 684a1a9510SRong-En Fan ExitProgram(int code) 690e3d5408SPeter Wemm { 700e3d5408SPeter Wemm _nc_free_entries(_nc_head); 715ca44d1cSRong-En Fan _nc_free_tic(code); 720e3d5408SPeter Wemm } 730e3d5408SPeter Wemm #endif 740e3d5408SPeter Wemm 75*73f0a83dSXin LI static void failed(const char *) GCC_NORETURN; 76*73f0a83dSXin LI 7706bfebdeSXin LI static void 7806bfebdeSXin LI failed(const char *msg) 7906bfebdeSXin LI { 8006bfebdeSXin LI perror(msg); 8106bfebdeSXin LI ExitProgram(EXIT_FAILURE); 8206bfebdeSXin LI } 8306bfebdeSXin LI 84*73f0a83dSXin LI static char * 85*73f0a83dSXin LI strmalloc(const char *value) 86*73f0a83dSXin LI { 87*73f0a83dSXin LI char *result = strdup(value); 88*73f0a83dSXin LI if (result == 0) { 89*73f0a83dSXin LI failed("strmalloc"); 90*73f0a83dSXin LI } 91*73f0a83dSXin LI return result; 92*73f0a83dSXin LI } 93*73f0a83dSXin LI 94*73f0a83dSXin LI static TERMDATA * 95*73f0a83dSXin LI new_termdata(void) 96*73f0a83dSXin LI { 97*73f0a83dSXin LI size_t want = use_termdata + 1; 98*73f0a83dSXin LI 99*73f0a83dSXin LI if (want >= len_termdata) { 100*73f0a83dSXin LI len_termdata = (2 * want) + 10; 101*73f0a83dSXin LI ptr_termdata = typeRealloc(TERMDATA, len_termdata, ptr_termdata); 102*73f0a83dSXin LI if (ptr_termdata == 0) 103*73f0a83dSXin LI failed("ptr_termdata"); 104*73f0a83dSXin LI } 105*73f0a83dSXin LI 106*73f0a83dSXin LI return ptr_termdata + use_termdata++; 107*73f0a83dSXin LI } 108*73f0a83dSXin LI 109*73f0a83dSXin LI static int 110*73f0a83dSXin LI compare_termdata(const void *a, const void *b) 111*73f0a83dSXin LI { 112*73f0a83dSXin LI const TERMDATA *p = (const TERMDATA *) a; 113*73f0a83dSXin LI const TERMDATA *q = (const TERMDATA *) b; 114*73f0a83dSXin LI int result = strcmp(p->term_name, q->term_name); 115*73f0a83dSXin LI 116*73f0a83dSXin LI if (result == 0) { 117*73f0a83dSXin LI result = (p->db_index - q->db_index); 118*73f0a83dSXin LI } 119*73f0a83dSXin LI return result; 120*73f0a83dSXin LI } 121*73f0a83dSXin LI 122*73f0a83dSXin LI /* 123*73f0a83dSXin LI * Sort the array of TERMDATA and print it. If more than one database is being 124*73f0a83dSXin LI * reported, add a column to show which database has a given entry. 125*73f0a83dSXin LI */ 126*73f0a83dSXin LI static void 127*73f0a83dSXin LI show_termdata(int eargc, char **eargv) 128*73f0a83dSXin LI { 129*73f0a83dSXin LI int j, k; 130*73f0a83dSXin LI size_t n; 131*73f0a83dSXin LI 132*73f0a83dSXin LI if (use_termdata) { 133*73f0a83dSXin LI if (eargc > 1) { 134*73f0a83dSXin LI for (j = 0; j < eargc; ++j) { 135*73f0a83dSXin LI for (k = 0; k <= j; ++k) { 136*73f0a83dSXin LI printf("--"); 137*73f0a83dSXin LI } 138*73f0a83dSXin LI printf("> "); 139*73f0a83dSXin LI printf("%s\n", eargv[j]); 140*73f0a83dSXin LI } 141*73f0a83dSXin LI } 142*73f0a83dSXin LI if (use_termdata > 1) 143*73f0a83dSXin LI qsort(ptr_termdata, use_termdata, sizeof(TERMDATA), compare_termdata); 144*73f0a83dSXin LI for (n = 0; n < use_termdata; ++n) { 145*73f0a83dSXin LI 146*73f0a83dSXin LI /* 147*73f0a83dSXin LI * If there is more than one database, show how they differ. 148*73f0a83dSXin LI */ 149*73f0a83dSXin LI if (eargc > 1) { 150*73f0a83dSXin LI unsigned long check = 0; 151*73f0a83dSXin LI k = 0; 152*73f0a83dSXin LI for (;;) { 153*73f0a83dSXin LI for (; k < ptr_termdata[n].db_index; ++k) { 154*73f0a83dSXin LI printf("--"); 155*73f0a83dSXin LI } 156*73f0a83dSXin LI 157*73f0a83dSXin LI /* 158*73f0a83dSXin LI * If this is the first entry, or its checksum differs 159*73f0a83dSXin LI * from the first entry's checksum, print "*". Otherwise 160*73f0a83dSXin LI * it looks enough like a duplicate to print "+". 161*73f0a83dSXin LI */ 162*73f0a83dSXin LI printf("%c-", ((check == 0 163*73f0a83dSXin LI || (check != ptr_termdata[n].checksum)) 164*73f0a83dSXin LI ? '*' 165*73f0a83dSXin LI : '+')); 166*73f0a83dSXin LI check = ptr_termdata[n].checksum; 167*73f0a83dSXin LI 168*73f0a83dSXin LI ++k; 169*73f0a83dSXin LI if ((n + 1) >= use_termdata 170*73f0a83dSXin LI || strcmp(ptr_termdata[n].term_name, 171*73f0a83dSXin LI ptr_termdata[n + 1].term_name)) { 172*73f0a83dSXin LI break; 173*73f0a83dSXin LI } 174*73f0a83dSXin LI ++n; 175*73f0a83dSXin LI } 176*73f0a83dSXin LI for (; k < eargc; ++k) { 177*73f0a83dSXin LI printf("--"); 178*73f0a83dSXin LI } 179*73f0a83dSXin LI printf(":\t"); 180*73f0a83dSXin LI } 181*73f0a83dSXin LI 182*73f0a83dSXin LI (void) printf("%-10s\t%s\n", 183*73f0a83dSXin LI ptr_termdata[n].term_name, 184*73f0a83dSXin LI ptr_termdata[n].description); 185*73f0a83dSXin LI } 186*73f0a83dSXin LI } 187*73f0a83dSXin LI } 188*73f0a83dSXin LI 189*73f0a83dSXin LI static void 190*73f0a83dSXin LI free_termdata(void) 191*73f0a83dSXin LI { 192*73f0a83dSXin LI if (ptr_termdata != 0) { 193*73f0a83dSXin LI while (use_termdata != 0) { 194*73f0a83dSXin LI --use_termdata; 195*73f0a83dSXin LI free(ptr_termdata[use_termdata].term_name); 196*73f0a83dSXin LI free(ptr_termdata[use_termdata].description); 197*73f0a83dSXin LI } 198*73f0a83dSXin LI free(ptr_termdata); 199*73f0a83dSXin LI ptr_termdata = 0; 200*73f0a83dSXin LI } 201*73f0a83dSXin LI use_termdata = 0; 202*73f0a83dSXin LI len_termdata = 0; 203*73f0a83dSXin LI } 204*73f0a83dSXin LI 205*73f0a83dSXin LI static char ** 206*73f0a83dSXin LI allocArgv(size_t count) 207*73f0a83dSXin LI { 208*73f0a83dSXin LI char **result = typeCalloc(char *, count + 1); 209*73f0a83dSXin LI if (result == 0) 210*73f0a83dSXin LI failed("realloc eargv"); 211*73f0a83dSXin LI 212*73f0a83dSXin LI assert(result != 0); 213*73f0a83dSXin LI return result; 214*73f0a83dSXin LI } 215*73f0a83dSXin LI 216*73f0a83dSXin LI static void 217*73f0a83dSXin LI freeArgv(char **argv) 218*73f0a83dSXin LI { 219*73f0a83dSXin LI if (argv) { 220*73f0a83dSXin LI int count = 0; 221*73f0a83dSXin LI while (argv[count]) { 222*73f0a83dSXin LI free(argv[count++]); 223*73f0a83dSXin LI } 224*73f0a83dSXin LI free(argv); 225*73f0a83dSXin LI } 226*73f0a83dSXin LI } 227*73f0a83dSXin LI 2284a1a9510SRong-En Fan #if USE_HASHED_DB 22939f2269fSPeter Wemm static bool 2304a1a9510SRong-En Fan make_db_name(char *dst, const char *src, unsigned limit) 23139f2269fSPeter Wemm { 2324a1a9510SRong-En Fan static const char suffix[] = DBM_SUFFIX; 2334a1a9510SRong-En Fan 2344a1a9510SRong-En Fan bool result = FALSE; 235*73f0a83dSXin LI size_t lens = sizeof(suffix) - 1; 236*73f0a83dSXin LI size_t size = strlen(src); 237*73f0a83dSXin LI size_t need = lens + size; 2384a1a9510SRong-En Fan 2394a1a9510SRong-En Fan if (need <= limit) { 2404a1a9510SRong-En Fan if (size >= lens 241*73f0a83dSXin LI && !strcmp(src + size - lens, suffix)) { 242*73f0a83dSXin LI _nc_STRCPY(dst, src, PATH_MAX); 243*73f0a83dSXin LI } else { 244*73f0a83dSXin LI _nc_SPRINTF(dst, _nc_SLIMIT(PATH_MAX) "%s%s", src, suffix); 245*73f0a83dSXin LI } 2464a1a9510SRong-En Fan result = TRUE; 24739f2269fSPeter Wemm } 2484a1a9510SRong-En Fan return result; 2494a1a9510SRong-En Fan } 2504a1a9510SRong-En Fan #endif 25139f2269fSPeter Wemm 252*73f0a83dSXin LI typedef void (DescHook) (int /* db_index */ , 253*73f0a83dSXin LI int /* db_limit */ , 254*73f0a83dSXin LI const char * /* term_name */ , 255*73f0a83dSXin LI TERMTYPE * /* term */ ); 25639f2269fSPeter Wemm 257*73f0a83dSXin LI static const char * 258*73f0a83dSXin LI term_description(TERMTYPE *tp) 25915589c42SPeter Wemm { 2604a1a9510SRong-En Fan const char *desc; 2614a1a9510SRong-En Fan 262*73f0a83dSXin LI if (tp->term_names == 0 263*73f0a83dSXin LI || (desc = strrchr(tp->term_names, '|')) == 0 264*73f0a83dSXin LI || (*++desc == '\0')) { 2654a1a9510SRong-En Fan desc = "(No description)"; 26615589c42SPeter Wemm } 2674a1a9510SRong-En Fan 268*73f0a83dSXin LI return desc; 269*73f0a83dSXin LI } 270*73f0a83dSXin LI 271*73f0a83dSXin LI /* display a description for the type */ 2724a1a9510SRong-En Fan static void 273*73f0a83dSXin LI deschook(int db_index, int db_limit, const char *term_name, TERMTYPE *tp) 274*73f0a83dSXin LI { 275*73f0a83dSXin LI (void) db_index; 276*73f0a83dSXin LI (void) db_limit; 277*73f0a83dSXin LI (void) printf("%-10s\t%s\n", term_name, term_description(tp)); 278*73f0a83dSXin LI } 279*73f0a83dSXin LI 280*73f0a83dSXin LI static unsigned long 281*73f0a83dSXin LI string_sum(const char *value) 282*73f0a83dSXin LI { 283*73f0a83dSXin LI unsigned long result = 0; 284*73f0a83dSXin LI 285*73f0a83dSXin LI if ((intptr_t) value == (intptr_t) (-1)) { 286*73f0a83dSXin LI result = ~result; 287*73f0a83dSXin LI } else if (value) { 288*73f0a83dSXin LI while (*value) { 289*73f0a83dSXin LI result += UChar(*value); 290*73f0a83dSXin LI ++value; 291*73f0a83dSXin LI } 292*73f0a83dSXin LI } 293*73f0a83dSXin LI return result; 294*73f0a83dSXin LI } 295*73f0a83dSXin LI 296*73f0a83dSXin LI static unsigned long 297*73f0a83dSXin LI checksum_of(TERMTYPE *tp) 298*73f0a83dSXin LI { 299*73f0a83dSXin LI unsigned long result = string_sum(tp->term_names); 300*73f0a83dSXin LI unsigned i; 301*73f0a83dSXin LI 302*73f0a83dSXin LI for (i = 0; i < NUM_BOOLEANS(tp); i++) { 303*73f0a83dSXin LI result += (unsigned long) (tp->Booleans[i]); 304*73f0a83dSXin LI } 305*73f0a83dSXin LI for (i = 0; i < NUM_NUMBERS(tp); i++) { 306*73f0a83dSXin LI result += (unsigned long) (tp->Numbers[i]); 307*73f0a83dSXin LI } 308*73f0a83dSXin LI for (i = 0; i < NUM_STRINGS(tp); i++) { 309*73f0a83dSXin LI result += string_sum(tp->Strings[i]); 310*73f0a83dSXin LI } 311*73f0a83dSXin LI return result; 312*73f0a83dSXin LI } 313*73f0a83dSXin LI 314*73f0a83dSXin LI /* collect data, to sort before display */ 315*73f0a83dSXin LI static void 316*73f0a83dSXin LI sorthook(int db_index, int db_limit, const char *term_name, TERMTYPE *tp) 317*73f0a83dSXin LI { 318*73f0a83dSXin LI TERMDATA *data = new_termdata(); 319*73f0a83dSXin LI 320*73f0a83dSXin LI data->db_index = db_index; 321*73f0a83dSXin LI data->checksum = ((db_limit > 1) ? checksum_of(tp) : 0); 322*73f0a83dSXin LI data->term_name = strmalloc(term_name); 323*73f0a83dSXin LI data->description = strmalloc(term_description(tp)); 324*73f0a83dSXin LI } 325*73f0a83dSXin LI 326*73f0a83dSXin LI #if NCURSES_USE_TERMCAP 327*73f0a83dSXin LI static void 328*73f0a83dSXin LI show_termcap(int db_index, int db_limit, char *buffer, DescHook hook) 3294a1a9510SRong-En Fan { 3304a1a9510SRong-En Fan TERMTYPE data; 3314a1a9510SRong-En Fan char *next = strchr(buffer, ':'); 3324a1a9510SRong-En Fan char *last; 3334a1a9510SRong-En Fan char *list = buffer; 3344a1a9510SRong-En Fan 3354a1a9510SRong-En Fan if (next) 3364a1a9510SRong-En Fan *next = '\0'; 3374a1a9510SRong-En Fan 3384a1a9510SRong-En Fan last = strrchr(buffer, '|'); 3394a1a9510SRong-En Fan if (last) 3404a1a9510SRong-En Fan ++last; 3414a1a9510SRong-En Fan 342*73f0a83dSXin LI memset(&data, 0, sizeof(data)); 343*73f0a83dSXin LI data.term_names = strmalloc(buffer); 3444a1a9510SRong-En Fan while ((next = strtok(list, "|")) != 0) { 3454a1a9510SRong-En Fan if (next != last) 346*73f0a83dSXin LI hook(db_index, db_limit, next, &data); 3474a1a9510SRong-En Fan list = 0; 3484a1a9510SRong-En Fan } 3494a1a9510SRong-En Fan free(data.term_names); 3504a1a9510SRong-En Fan } 3514a1a9510SRong-En Fan #endif 3524a1a9510SRong-En Fan 353*73f0a83dSXin LI #if NCURSES_USE_DATABASE 354*73f0a83dSXin LI static char * 355*73f0a83dSXin LI copy_entryname(DIRENT * src) 356*73f0a83dSXin LI { 357*73f0a83dSXin LI size_t len = NAMLEN(src); 358*73f0a83dSXin LI char *result = malloc(len + 1); 359*73f0a83dSXin LI if (result == 0) 360*73f0a83dSXin LI failed("copy entryname"); 361*73f0a83dSXin LI memcpy(result, src->d_name, len); 362*73f0a83dSXin LI result[len] = '\0'; 363*73f0a83dSXin LI 364*73f0a83dSXin LI return result; 365*73f0a83dSXin LI } 366*73f0a83dSXin LI #endif 367*73f0a83dSXin LI 3684a1a9510SRong-En Fan static int 3694a1a9510SRong-En Fan typelist(int eargc, char *eargv[], 370*73f0a83dSXin LI int verbosity, 371*73f0a83dSXin LI DescHook hook) 3724a1a9510SRong-En Fan /* apply a function to each entry in given terminfo directories */ 3734a1a9510SRong-En Fan { 3744a1a9510SRong-En Fan int i; 3754a1a9510SRong-En Fan 3764a1a9510SRong-En Fan for (i = 0; i < eargc; i++) { 377*73f0a83dSXin LI #if NCURSES_USE_DATABASE 3784a1a9510SRong-En Fan if (_nc_is_dir_path(eargv[i])) { 3795d08fb1fSRong-En Fan char *cwd_buf = 0; 3804a1a9510SRong-En Fan DIR *termdir; 3814a1a9510SRong-En Fan DIRENT *subdir; 3824a1a9510SRong-En Fan 3834a1a9510SRong-En Fan if ((termdir = opendir(eargv[i])) == 0) { 3844a1a9510SRong-En Fan (void) fflush(stdout); 3854a1a9510SRong-En Fan (void) fprintf(stderr, 3864a1a9510SRong-En Fan "%s: can't open terminfo directory %s\n", 3874a1a9510SRong-En Fan _nc_progname, eargv[i]); 388*73f0a83dSXin LI continue; 389*73f0a83dSXin LI } 390*73f0a83dSXin LI 391*73f0a83dSXin LI if (verbosity) 3924a1a9510SRong-En Fan (void) printf("#\n#%s:\n#\n", eargv[i]); 3934a1a9510SRong-En Fan 3944a1a9510SRong-En Fan while ((subdir = readdir(termdir)) != 0) { 395*73f0a83dSXin LI size_t cwd_len; 396*73f0a83dSXin LI char *name_1; 3974a1a9510SRong-En Fan DIR *entrydir; 3984a1a9510SRong-En Fan DIRENT *entry; 3994a1a9510SRong-En Fan 400*73f0a83dSXin LI name_1 = copy_entryname(subdir); 401*73f0a83dSXin LI if (isDotname(name_1)) { 402*73f0a83dSXin LI free(name_1); 403*73f0a83dSXin LI continue; 404*73f0a83dSXin LI } 405*73f0a83dSXin LI 406*73f0a83dSXin LI cwd_len = NAMLEN(subdir) + strlen(eargv[i]) + 3; 4075d08fb1fSRong-En Fan cwd_buf = typeRealloc(char, cwd_len, cwd_buf); 40806bfebdeSXin LI if (cwd_buf == 0) 40906bfebdeSXin LI failed("realloc cwd_buf"); 41006bfebdeSXin LI 41106bfebdeSXin LI assert(cwd_buf != 0); 4125d08fb1fSRong-En Fan 413*73f0a83dSXin LI _nc_SPRINTF(cwd_buf, _nc_SLIMIT(cwd_len) 414*73f0a83dSXin LI "%s/%s/", eargv[i], name_1); 415*73f0a83dSXin LI free(name_1); 4164a1a9510SRong-En Fan 4175d08fb1fSRong-En Fan if (chdir(cwd_buf) != 0) 4184a1a9510SRong-En Fan continue; 4194a1a9510SRong-En Fan 4204a1a9510SRong-En Fan entrydir = opendir("."); 4215d08fb1fSRong-En Fan if (entrydir == 0) { 4225d08fb1fSRong-En Fan perror(cwd_buf); 4235d08fb1fSRong-En Fan continue; 4245d08fb1fSRong-En Fan } 4254a1a9510SRong-En Fan while ((entry = readdir(entrydir)) != 0) { 426*73f0a83dSXin LI char *name_2; 4274a1a9510SRong-En Fan TERMTYPE lterm; 4284a1a9510SRong-En Fan char *cn; 4294a1a9510SRong-En Fan int status; 4304a1a9510SRong-En Fan 431*73f0a83dSXin LI name_2 = copy_entryname(entry); 432*73f0a83dSXin LI if (isDotname(name_2) || !_nc_is_file_path(name_2)) { 433*73f0a83dSXin LI free(name_2); 4344a1a9510SRong-En Fan continue; 435*73f0a83dSXin LI } 4364a1a9510SRong-En Fan 4374a1a9510SRong-En Fan status = _nc_read_file_entry(name_2, <erm); 4384a1a9510SRong-En Fan if (status <= 0) { 4394a1a9510SRong-En Fan (void) fflush(stdout); 4404a1a9510SRong-En Fan (void) fprintf(stderr, 4414a1a9510SRong-En Fan "%s: couldn't open terminfo file %s.\n", 4424a1a9510SRong-En Fan _nc_progname, name_2); 443*73f0a83dSXin LI free(cwd_buf); 444*73f0a83dSXin LI free(name_2); 445*73f0a83dSXin LI closedir(entrydir); 446*73f0a83dSXin LI closedir(termdir); 4474a1a9510SRong-En Fan return (EXIT_FAILURE); 4484a1a9510SRong-En Fan } 4494a1a9510SRong-En Fan 4504a1a9510SRong-En Fan /* only visit things once, by primary name */ 4514a1a9510SRong-En Fan cn = _nc_first_name(lterm.term_names); 4524a1a9510SRong-En Fan if (!strcmp(cn, name_2)) { 4534a1a9510SRong-En Fan /* apply the selected hook function */ 454*73f0a83dSXin LI hook(i, eargc, cn, <erm); 4554a1a9510SRong-En Fan } 4564a1a9510SRong-En Fan _nc_free_termtype(<erm); 457*73f0a83dSXin LI free(name_2); 4584a1a9510SRong-En Fan } 4594a1a9510SRong-En Fan closedir(entrydir); 4604a1a9510SRong-En Fan } 4614a1a9510SRong-En Fan closedir(termdir); 4625d08fb1fSRong-En Fan if (cwd_buf != 0) 4635d08fb1fSRong-En Fan free(cwd_buf); 464*73f0a83dSXin LI continue; 4654a1a9510SRong-En Fan } 4664a1a9510SRong-En Fan #if USE_HASHED_DB 4674a1a9510SRong-En Fan else { 4684a1a9510SRong-En Fan DB *capdbp; 4694a1a9510SRong-En Fan char filename[PATH_MAX]; 4704a1a9510SRong-En Fan 471*73f0a83dSXin LI if (verbosity) 472*73f0a83dSXin LI (void) printf("#\n#%s:\n#\n", eargv[i]); 473*73f0a83dSXin LI 4744a1a9510SRong-En Fan if (make_db_name(filename, eargv[i], sizeof(filename))) { 4754a1a9510SRong-En Fan if ((capdbp = _nc_db_open(filename, FALSE)) != 0) { 4764a1a9510SRong-En Fan DBT key, data; 4774a1a9510SRong-En Fan int code; 4784a1a9510SRong-En Fan 4794a1a9510SRong-En Fan code = _nc_db_first(capdbp, &key, &data); 4804a1a9510SRong-En Fan while (code == 0) { 4814a1a9510SRong-En Fan TERMTYPE lterm; 4824a1a9510SRong-En Fan int used; 4834a1a9510SRong-En Fan char *have; 4844a1a9510SRong-En Fan char *cn; 4854a1a9510SRong-En Fan 4864a1a9510SRong-En Fan if (_nc_db_have_data(&key, &data, &have, &used)) { 4874a1a9510SRong-En Fan if (_nc_read_termtype(<erm, have, used) > 0) { 4884a1a9510SRong-En Fan /* only visit things once, by primary name */ 4894a1a9510SRong-En Fan cn = _nc_first_name(lterm.term_names); 4904a1a9510SRong-En Fan /* apply the selected hook function */ 491*73f0a83dSXin LI hook(i, eargc, cn, <erm); 4924a1a9510SRong-En Fan _nc_free_termtype(<erm); 4934a1a9510SRong-En Fan } 4944a1a9510SRong-En Fan } 4954a1a9510SRong-En Fan code = _nc_db_next(capdbp, &key, &data); 4964a1a9510SRong-En Fan } 4974a1a9510SRong-En Fan 4984a1a9510SRong-En Fan _nc_db_close(capdbp); 499*73f0a83dSXin LI continue; 5004a1a9510SRong-En Fan } 5014a1a9510SRong-En Fan } 5024a1a9510SRong-En Fan } 5034a1a9510SRong-En Fan #endif 5044a1a9510SRong-En Fan #endif 505*73f0a83dSXin LI #if NCURSES_USE_TERMCAP 5064a1a9510SRong-En Fan #if HAVE_BSD_CGETENT 507*73f0a83dSXin LI { 508*73f0a83dSXin LI CGETENT_CONST char *db_array[2]; 5094a1a9510SRong-En Fan char *buffer = 0; 5104a1a9510SRong-En Fan 5114a1a9510SRong-En Fan if (verbosity) 5124a1a9510SRong-En Fan (void) printf("#\n#%s:\n#\n", eargv[i]); 5134a1a9510SRong-En Fan 5144a1a9510SRong-En Fan db_array[0] = eargv[i]; 5154a1a9510SRong-En Fan db_array[1] = 0; 5164a1a9510SRong-En Fan 517*73f0a83dSXin LI if (cgetfirst(&buffer, db_array) > 0) { 518*73f0a83dSXin LI show_termcap(i, eargc, buffer, hook); 5194a1a9510SRong-En Fan free(buffer); 520*73f0a83dSXin LI while (cgetnext(&buffer, db_array) > 0) { 521*73f0a83dSXin LI show_termcap(i, eargc, buffer, hook); 5224a1a9510SRong-En Fan free(buffer); 5234a1a9510SRong-En Fan } 5244a1a9510SRong-En Fan cgetclose(); 525*73f0a83dSXin LI continue; 526*73f0a83dSXin LI } 527*73f0a83dSXin LI } 5284a1a9510SRong-En Fan #else 5294a1a9510SRong-En Fan /* scan termcap text-file only */ 5304a1a9510SRong-En Fan if (_nc_is_file_path(eargv[i])) { 5314a1a9510SRong-En Fan char buffer[2048]; 5324a1a9510SRong-En Fan FILE *fp; 5334a1a9510SRong-En Fan 534*73f0a83dSXin LI if (verbosity) 535*73f0a83dSXin LI (void) printf("#\n#%s:\n#\n", eargv[i]); 536*73f0a83dSXin LI 5374a1a9510SRong-En Fan if ((fp = fopen(eargv[i], "r")) != 0) { 5384a1a9510SRong-En Fan while (fgets(buffer, sizeof(buffer), fp) != 0) { 5394a1a9510SRong-En Fan if (*buffer == '#') 5404a1a9510SRong-En Fan continue; 5414a1a9510SRong-En Fan if (isspace(*buffer)) 5424a1a9510SRong-En Fan continue; 543*73f0a83dSXin LI show_termcap(i, eargc, buffer, hook); 5444a1a9510SRong-En Fan } 5454a1a9510SRong-En Fan fclose(fp); 5464a1a9510SRong-En Fan } 5474a1a9510SRong-En Fan } 5484a1a9510SRong-En Fan #endif 5494a1a9510SRong-En Fan #endif 5504a1a9510SRong-En Fan } 5514a1a9510SRong-En Fan 552*73f0a83dSXin LI if (hook == sorthook) { 553*73f0a83dSXin LI show_termdata(eargc, eargv); 554*73f0a83dSXin LI free_termdata(); 555*73f0a83dSXin LI } 556*73f0a83dSXin LI 5574a1a9510SRong-En Fan return (EXIT_SUCCESS); 5584a1a9510SRong-En Fan } 5594a1a9510SRong-En Fan 5604a1a9510SRong-En Fan static void 5614a1a9510SRong-En Fan usage(void) 5624a1a9510SRong-En Fan { 563*73f0a83dSXin LI (void) fprintf(stderr, "usage: %s [-ahsuUV] [-v n] [file...]\n", _nc_progname); 5644a1a9510SRong-En Fan ExitProgram(EXIT_FAILURE); 56515589c42SPeter Wemm } 56615589c42SPeter Wemm 56715589c42SPeter Wemm int 56815589c42SPeter Wemm main(int argc, char *argv[]) 5690e3d5408SPeter Wemm { 5704a1a9510SRong-En Fan bool all_dirs = FALSE; 5710e3d5408SPeter Wemm bool direct_dependencies = FALSE; 5720e3d5408SPeter Wemm bool invert_dependencies = FALSE; 5730e3d5408SPeter Wemm bool header = FALSE; 574d8977eafSRong-En Fan char *report_file = 0; 5755d08fb1fSRong-En Fan unsigned i; 5760e3d5408SPeter Wemm int code; 5774a1a9510SRong-En Fan int this_opt, last_opt = '?'; 578*73f0a83dSXin LI unsigned v_opt = 0; 579*73f0a83dSXin LI DescHook *hook = deschook; 5800e3d5408SPeter Wemm 58139f2269fSPeter Wemm _nc_progname = _nc_rootname(argv[0]); 5820e3d5408SPeter Wemm 583*73f0a83dSXin LI while ((this_opt = getopt(argc, argv, "0123456789ahsu:vU:V")) != -1) { 5844a1a9510SRong-En Fan /* handle optional parameter */ 5854a1a9510SRong-En Fan if (isdigit(this_opt)) { 5864a1a9510SRong-En Fan switch (last_opt) { 5874a1a9510SRong-En Fan case 'v': 588*73f0a83dSXin LI v_opt = (unsigned) (this_opt - '0'); 5894a1a9510SRong-En Fan break; 5904a1a9510SRong-En Fan default: 5914a1a9510SRong-En Fan if (isdigit(last_opt)) 5924a1a9510SRong-En Fan v_opt *= 10; 5934a1a9510SRong-En Fan else 5944a1a9510SRong-En Fan v_opt = 0; 595*73f0a83dSXin LI v_opt += (unsigned) (this_opt - '0'); 5964a1a9510SRong-En Fan last_opt = this_opt; 5974a1a9510SRong-En Fan } 5984a1a9510SRong-En Fan continue; 5994a1a9510SRong-En Fan } 6004a1a9510SRong-En Fan switch (this_opt) { 6014a1a9510SRong-En Fan case 'a': 6024a1a9510SRong-En Fan all_dirs = TRUE; 6034a1a9510SRong-En Fan break; 6040e3d5408SPeter Wemm case 'h': 6050e3d5408SPeter Wemm header = TRUE; 6060e3d5408SPeter Wemm break; 607*73f0a83dSXin LI case 's': 608*73f0a83dSXin LI hook = sorthook; 609*73f0a83dSXin LI break; 6100e3d5408SPeter Wemm case 'u': 6110e3d5408SPeter Wemm direct_dependencies = TRUE; 612d8977eafSRong-En Fan report_file = optarg; 6130e3d5408SPeter Wemm break; 6140e3d5408SPeter Wemm case 'v': 6154a1a9510SRong-En Fan v_opt = 1; 6160e3d5408SPeter Wemm break; 6170e3d5408SPeter Wemm case 'U': 6180e3d5408SPeter Wemm invert_dependencies = TRUE; 619d8977eafSRong-En Fan report_file = optarg; 6200e3d5408SPeter Wemm break; 6210e3d5408SPeter Wemm case 'V': 62218259542SPeter Wemm puts(curses_version()); 6230e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 6240e3d5408SPeter Wemm default: 6254a1a9510SRong-En Fan usage(); 6260e3d5408SPeter Wemm } 6274a1a9510SRong-En Fan } 6284a1a9510SRong-En Fan set_trace_level(v_opt); 6290e3d5408SPeter Wemm 630d8977eafSRong-En Fan if (report_file != 0) { 631d8977eafSRong-En Fan if (freopen(report_file, "r", stdin) == 0) { 6320e3d5408SPeter Wemm (void) fflush(stdout); 633d8977eafSRong-En Fan fprintf(stderr, "%s: can't open %s\n", _nc_progname, report_file); 6340e3d5408SPeter Wemm ExitProgram(EXIT_FAILURE); 6350e3d5408SPeter Wemm } 6360e3d5408SPeter Wemm 6370e3d5408SPeter Wemm /* parse entries out of the source file */ 638d8977eafSRong-En Fan _nc_set_source(report_file); 63915589c42SPeter Wemm _nc_read_entry_source(stdin, 0, FALSE, FALSE, NULLHOOK); 6400e3d5408SPeter Wemm } 6410e3d5408SPeter Wemm 6420e3d5408SPeter Wemm /* maybe we want a direct-dependency listing? */ 64315589c42SPeter Wemm if (direct_dependencies) { 6440e3d5408SPeter Wemm ENTRY *qp; 6450e3d5408SPeter Wemm 6464a1a9510SRong-En Fan for_entry_list(qp) { 64715589c42SPeter Wemm if (qp->nuses) { 6485d08fb1fSRong-En Fan unsigned j; 6490e3d5408SPeter Wemm 6500e3d5408SPeter Wemm (void) printf("%s:", _nc_first_name(qp->tterm.term_names)); 6510e3d5408SPeter Wemm for (j = 0; j < qp->nuses; j++) 65215589c42SPeter Wemm (void) printf(" %s", qp->uses[j].name); 6530e3d5408SPeter Wemm putchar('\n'); 6540e3d5408SPeter Wemm } 6554a1a9510SRong-En Fan } 6560e3d5408SPeter Wemm 6570e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 6580e3d5408SPeter Wemm } 6590e3d5408SPeter Wemm 6600e3d5408SPeter Wemm /* maybe we want a reverse-dependency listing? */ 66115589c42SPeter Wemm if (invert_dependencies) { 6620e3d5408SPeter Wemm ENTRY *qp, *rp; 6630e3d5408SPeter Wemm int matchcount; 6640e3d5408SPeter Wemm 66515589c42SPeter Wemm for_entry_list(qp) { 6660e3d5408SPeter Wemm matchcount = 0; 66715589c42SPeter Wemm for_entry_list(rp) { 6680e3d5408SPeter Wemm if (rp->nuses == 0) 6690e3d5408SPeter Wemm continue; 6700e3d5408SPeter Wemm 6710e3d5408SPeter Wemm for (i = 0; i < rp->nuses; i++) 67215589c42SPeter Wemm if (_nc_name_match(qp->tterm.term_names, 67315589c42SPeter Wemm rp->uses[i].name, "|")) { 6740e3d5408SPeter Wemm if (matchcount++ == 0) 6750e3d5408SPeter Wemm (void) printf("%s:", 6760e3d5408SPeter Wemm _nc_first_name(qp->tterm.term_names)); 6770e3d5408SPeter Wemm (void) printf(" %s", 6780e3d5408SPeter Wemm _nc_first_name(rp->tterm.term_names)); 6790e3d5408SPeter Wemm } 6800e3d5408SPeter Wemm } 6810e3d5408SPeter Wemm if (matchcount) 6820e3d5408SPeter Wemm putchar('\n'); 6830e3d5408SPeter Wemm } 6840e3d5408SPeter Wemm 6850e3d5408SPeter Wemm ExitProgram(EXIT_SUCCESS); 6860e3d5408SPeter Wemm } 6870e3d5408SPeter Wemm 6880e3d5408SPeter Wemm /* 6890e3d5408SPeter Wemm * If we get this far, user wants a simple terminal type listing. 6900e3d5408SPeter Wemm */ 6910e3d5408SPeter Wemm if (optind < argc) { 692*73f0a83dSXin LI code = typelist(argc - optind, argv + optind, header, hook); 6934a1a9510SRong-En Fan } else if (all_dirs) { 6944a1a9510SRong-En Fan DBDIRS state; 6954a1a9510SRong-En Fan int offset; 6964a1a9510SRong-En Fan int pass; 6974a1a9510SRong-En Fan const char *path; 6984a1a9510SRong-En Fan char **eargv = 0; 6990e3d5408SPeter Wemm 7004a1a9510SRong-En Fan code = EXIT_FAILURE; 7014a1a9510SRong-En Fan for (pass = 0; pass < 2; ++pass) { 702*73f0a83dSXin LI size_t count = 0; 7030e3d5408SPeter Wemm 7044a1a9510SRong-En Fan _nc_first_db(&state, &offset); 7054a1a9510SRong-En Fan while ((path = _nc_next_db(&state, &offset)) != 0) { 706*73f0a83dSXin LI if (pass) { 707*73f0a83dSXin LI eargv[count] = strmalloc(path); 7080e3d5408SPeter Wemm } 7094a1a9510SRong-En Fan ++count; 7104a1a9510SRong-En Fan } 7114a1a9510SRong-En Fan if (!pass) { 712*73f0a83dSXin LI eargv = allocArgv(count); 71306bfebdeSXin LI if (eargv == 0) 714*73f0a83dSXin LI failed("eargv"); 7154a1a9510SRong-En Fan } else { 716*73f0a83dSXin LI code = typelist((int) count, eargv, header, hook); 717*73f0a83dSXin LI freeArgv(eargv); 7184a1a9510SRong-En Fan } 7194a1a9510SRong-En Fan } 7204a1a9510SRong-En Fan } else { 7214a1a9510SRong-En Fan DBDIRS state; 7224a1a9510SRong-En Fan int offset; 7234a1a9510SRong-En Fan const char *path; 724*73f0a83dSXin LI char **eargv = allocArgv((size_t) 2); 725*73f0a83dSXin LI size_t count = 0; 7264a1a9510SRong-En Fan 727*73f0a83dSXin LI if (eargv == 0) 728*73f0a83dSXin LI failed("eargv"); 7294a1a9510SRong-En Fan _nc_first_db(&state, &offset); 730*73f0a83dSXin LI if ((path = _nc_next_db(&state, &offset)) != 0) { 731*73f0a83dSXin LI eargv[count++] = strmalloc(path); 7324a1a9510SRong-En Fan } 7334a1a9510SRong-En Fan 734*73f0a83dSXin LI code = typelist((int) count, eargv, header, hook); 7354a1a9510SRong-En Fan 736*73f0a83dSXin LI freeArgv(eargv); 7374a1a9510SRong-En Fan } 7384a1a9510SRong-En Fan _nc_last_db(); 7390e3d5408SPeter Wemm 7400e3d5408SPeter Wemm ExitProgram(code); 7410e3d5408SPeter Wemm } 742