_nc_set_writedir(char *dir) /* set the write directory for compiled entries */ { const char *destination; char actual[PATH_MAX]; if (dir == 0 && use_terminfo_vars()) dir = getenv("TERMINFO"); if (dir != 0) (void) _nc_tic_dir(dir); destination = _nc_tic_dir(0); if (make_directory(destination) < 0) { char *home = _nc_home_terminfo(); if (home != 0) { destination = home; if (make_directory(destination) < 0) _nc_err_abort("%s: permission denied (errno %d)", destination, errno); } } /* * Note: because of this code, this logic should be exercised * *once only* per run. */ if (chdir(_nc_tic_dir(destination)) < 0 || getcwd(actual, sizeof(actual)) == 0) _nc_err_abort("%s: not a directory", destination); _nc_keep_tic_dir(strdup(actual)); }
_nc_leaks_tinfo(void) { #if NO_LEAKS char *s; #endif T((T_CALLED("_nc_free_tinfo()"))); #if NO_LEAKS _nc_free_tparm(); _nc_tgetent_leaks(); _nc_free_entries(_nc_head); _nc_get_type(0); _nc_first_name(0); _nc_keyname_leaks(); #if BROKEN_LINKER || USE_REENTRANT _nc_names_leaks(); _nc_codes_leaks(); FreeIfNeeded(_nc_prescreen.real_acs_map); #endif if ((s = _nc_home_terminfo()) != 0) free(s); #endif /* NO_LEAKS */ returnVoid; }
_nc_leaks_tinfo(void) { #if NO_LEAKS char *s; #endif T((T_CALLED("_nc_free_tinfo()"))); #if NO_LEAKS _nc_globals.leak_checking = TRUE; _nc_free_tparm(); _nc_tgetent_leaks(); if (TerminalOf(CURRENT_SCREEN) != 0) { del_curterm(TerminalOf(CURRENT_SCREEN)); } _nc_forget_prescr(); _nc_comp_captab_leaks(); _nc_free_entries(_nc_head); _nc_get_type(0); _nc_first_name(0); _nc_db_iterator_leaks(); _nc_keyname_leaks(); #if BROKEN_LINKER || USE_REENTRANT _nc_names_leaks(); _nc_codes_leaks(); FreeIfNeeded(_nc_prescreen.real_acs_map); #endif _nc_comp_error_leaks(); if ((s = _nc_home_terminfo()) != 0) free(s); #ifdef TRACE T((T_RETURN(""))); trace(0); _nc_trace_buf(-1, (size_t) 0); #endif #endif /* NO_LEAKS */ returnVoid; }
_nc_set_writedir(char *dir) { const char *destination; char actual[PATH_MAX]; if (dir == 0 #ifndef USE_ROOT_ENVIRON && use_terminfo_vars() #endif ) dir = getenv("TERMINFO"); if (dir != 0) (void) _nc_tic_dir(dir); destination = _nc_tic_dir(0); if (make_db_root(destination) < 0) { char *home = _nc_home_terminfo(); if (home != 0) { destination = home; if (make_db_root(destination) < 0) _nc_err_abort("%s: permission denied (errno %d)", destination, errno); } } /* * Note: because of this code, this logic should be exercised * *once only* per run. */ #if USE_HASHED_DB make_db_path(actual, destination, sizeof(actual)); #else if (chdir(_nc_tic_dir(destination)) < 0 || getcwd(actual, sizeof(actual)) == 0) _nc_err_abort("%s: not a directory", destination); #endif _nc_keep_tic_dir(strdup(actual)); }
_nc_freeall(void) { WINDOWLIST *p, *q; char *s; T((T_CALLED("_nc_freeall()"))); #if NO_LEAKS _nc_free_tparm(); if (_nc_oldnums != 0) { FreeAndNull(_nc_oldnums); } #endif if (SP != 0) { while (_nc_windows != 0) { /* Delete only windows that're not a parent */ for (p = _nc_windows; p != 0; p = p->next) { bool found = FALSE; for (q = _nc_windows; q != 0; q = q->next) { if ((p != q) && (q->win._flags & _SUBWIN) && (&(p->win) == q->win._parent)) { found = TRUE; break; } } if (!found) { delwin(&(p->win)); break; } } } delscreen(SP); } del_curterm(cur_term); _nc_free_entries(_nc_head); _nc_get_type(0); _nc_first_name(0); #if USE_WIDEC_SUPPORT FreeIfNeeded(_nc_wacs); #endif #if NO_LEAKS _nc_alloc_entry_leaks(); _nc_captoinfo_leaks(); _nc_comp_scan_leaks(); #endif if ((s = _nc_home_terminfo()) != 0) free(s); (void) _nc_printf_string(0, 0); #ifdef TRACE (void) _nc_trace_buf(-1, 0); #endif #if HAVE_LIBDBMALLOC malloc_dump(malloc_errfd); #elif HAVE_LIBDMALLOC #elif HAVE_LIBMPATROL __mp_summary(); #elif HAVE_PURIFY purify_all_inuse(); #endif returnVoid; }
_nc_first_db(DBDIRS * state, int *offset) { bool cache_has_expired = FALSE; *state = dbdTIC; *offset = 0; T(("_nc_first_db")); /* build a blob containing all of the strings we will use for a lookup * table. */ if (my_blob == 0 || (cache_has_expired = cache_expired())) { size_t blobsize = 0; const char *values[dbdLAST]; struct stat *my_stat; int j, k; if (cache_has_expired) free_cache(); for (j = 0; j < dbdLAST; ++j) values[j] = 0; /* * This is the first item in the list, and is used only when tic is * writing to the database, as a performance improvement. */ values[dbdTIC] = TicDirectory; #if NCURSES_USE_DATABASE #ifdef TERMINFO_DIRS values[dbdCfgList] = TERMINFO_DIRS; #endif #ifdef TERMINFO values[dbdCfgOnce] = TERMINFO; #endif #endif #if NCURSES_USE_TERMCAP values[dbdCfgList2] = TERMPATH; #endif if (use_terminfo_vars()) { #if NCURSES_USE_DATABASE values[dbdEnvOnce] = cache_getenv("TERMINFO", dbdEnvOnce); values[dbdHome] = _nc_home_terminfo(); (void) cache_getenv("HOME", dbdHome); values[dbdEnvList] = cache_getenv("TERMINFO_DIRS", dbdEnvList); #endif #if NCURSES_USE_TERMCAP values[dbdEnvOnce2] = cache_getenv("TERMCAP", dbdEnvOnce2); /* only use $TERMCAP if it is an absolute path */ if (values[dbdEnvOnce2] != 0 && *values[dbdEnvOnce2] != '/') { values[dbdEnvOnce2] = 0; } values[dbdEnvList2] = cache_getenv("TERMPATH", dbdEnvList2); #endif /* NCURSES_USE_TERMCAP */ } for (j = 0; j < dbdLAST; ++j) { if (values[j] == 0) values[j] = ""; blobsize += 2 + strlen(values[j]); } my_blob = malloc(blobsize); if (my_blob != 0) { *my_blob = '\0'; for (j = 0; j < dbdLAST; ++j) { add_to_blob(values[j], blobsize); } /* Now, build an array which will be pointers to the distinct * strings in the blob. */ blobsize = 2; for (j = 0; my_blob[j] != '\0'; ++j) { if (my_blob[j] == NCURSES_PATHSEP) ++blobsize; } my_list = typeCalloc(char *, blobsize); my_stat = typeCalloc(struct stat, blobsize); if (my_list != 0 && my_stat != 0) { k = 0; my_list[k++] = my_blob; for (j = 0; my_blob[j] != '\0'; ++j) { if (my_blob[j] == NCURSES_PATHSEP) { my_blob[j] = '\0'; my_list[k++] = &my_blob[j + 1]; } } /* * Eliminate duplicates from the list. */ for (j = 0; my_list[j] != 0; ++j) { #ifdef TERMINFO if (*my_list[j] == '\0') my_list[j] = strdup(TERMINFO); #endif for (k = 0; k < j; ++k) { if (!strcmp(my_list[j], my_list[k])) { k = j - 1; while ((my_list[j] = my_list[j + 1]) != 0) { ++j; } j = k; break; } } } /* * Eliminate non-existent databases, and those that happen to * be symlinked to another location. */ for (j = 0; my_list[j] != 0; ++j) { bool found = check_existence(my_list[j], &my_stat[j]); #if HAVE_LINK if (found) { for (k = 0; k < j; ++k) { if (my_stat[j].st_dev == my_stat[k].st_dev && my_stat[j].st_ino == my_stat[k].st_ino) { found = FALSE; break; } } } #endif if (!found) { k = j; while ((my_list[k] = my_list[k + 1]) != 0) { ++k; } --j; } } my_size = j; my_time = time((time_t *) 0); } else { FreeAndNull(my_blob); } free(my_stat); }
_nc_next_db(DBDIRS * state, int *offset) { const char *result; char *envp; while (*state < dbdLAST) { DBDIRS next = (DBDIRS) ((int) (*state) + 1); result = 0; switch (*state) { case dbdTIC: if (HaveTicDirectory) result = _nc_tic_dir(0); break; #if USE_DATABASE case dbdEnvOnce: if (use_terminfo_vars()) { if ((envp = getenv("TERMINFO")) != 0) result = _nc_tic_dir(envp); } break; case dbdHome: if (use_terminfo_vars()) { result = _nc_home_terminfo(); } break; case dbdEnvList: if (use_terminfo_vars()) { if ((result = NEXT_DBD(getenv("TERMINFO_DIRS"), offset)) != 0) next = *state; } break; case dbdCfgList: #ifdef TERMINFO_DIRS if ((result = NEXT_DBD(TERMINFO_DIRS, offset)) != 0) next = *state; #endif break; case dbdCfgOnce: #ifndef TERMINFO_DIRS result = TERMINFO; #endif break; #endif /* USE_DATABASE */ #if USE_TERMCAP case dbdEnvOnce2: if (use_terminfo_vars()) { if ((envp = getenv("TERMCAP")) != 0) result = _nc_tic_dir(envp); } break; case dbdEnvList2: if (use_terminfo_vars()) { if ((result = NEXT_DBD(getenv("TERMPATH"), offset)) != 0) next = *state; } break; case dbdCfgList2: if ((result = NEXT_DBD(TERMPATH, offset)) != 0) next = *state; break; #endif /* USE_TERMCAP */ case dbdLAST: break; } if (*state != next) { *state = next; *offset = 0; _nc_last_db(); } if (result != 0) { return result; } } return 0; }