void kpathsea_init_db (kpathsea kpse) { boolean ok = false; const_string db_path; string *db_files; string *orig_db_files; assert (sizeof(DB_NAME) == sizeof(DB_NAME_LC)); db_path = kpathsea_init_format (kpse, kpse_db_format); db_files = kpathsea_path_search_list_generic (kpse, db_path, db_names, true, true); orig_db_files = db_files; /* Must do this after the path searching (which ends up calling kpse_db_search recursively), so kpse->db.buckets stays NULL. */ kpse->db = hash_create (DB_HASH_SIZE); while (db_files && *db_files) { if (db_build (kpse, &(kpse->db), *db_files)) ok = true; free (*db_files); db_files++; } if (!ok) { /* If db can't be built, leave `size' nonzero (so we don't rebuild it), but clear `buckets' (so we don't look in it). */ free (kpse->db.buckets); kpse->db.buckets = NULL; } free (orig_db_files); /* Add the content of any alias databases. There may exist more than one alias file along DB_NAME files. This duplicates the above code -- should be a function. */ ok = false; db_files = kpathsea_all_path_search (kpse, db_path, ALIAS_NAME); orig_db_files = db_files; kpse->alias_db = hash_create (ALIAS_HASH_SIZE); while (db_files && *db_files) { if (alias_build (kpse, &(kpse->alias_db), *db_files)) ok = true; free (*db_files); db_files++; } if (!ok) { free (kpse->alias_db.buckets); kpse->alias_db.buckets = NULL; } free (orig_db_files); }
/* * Mkcapdb creates a capability hash database for quick retrieval of capability * records. The database contains 2 types of entries: records and references * marked by the first byte in the data. A record entry contains the actual * capability record whereas a reference contains the name (key) under which * the correct record is stored. */ int main(int argc, char *argv[]) { int byteorder, c; capname = NULL; byteorder = 0; while ((c = getopt(argc, argv, "bf:lv")) != -1) { switch(c) { case 'b': case 'l': if (byteorder != 0) usage(); byteorder = c == 'b' ? 4321 : 1234; break; case 'f': capname = optarg; break; case 'v': verbose = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (*argv == NULL) usage(); /* Set byte order. */ openinfo.lorder = byteorder; /* * The database file is the first argument if no name is specified. * Make arrangements to unlink it if exit badly. */ (void)snprintf(buf, sizeof(buf), "%s.db", capname ? capname : *argv); if ((capname = strdup(buf)) == NULL) errx(1, "strdup failed"); if ((capdbp = dbopen(capname, O_CREAT | O_TRUNC | O_RDWR, DEFFILEMODE, DB_HASH, &openinfo)) == NULL) err(1, "%s", buf); if (atexit(dounlink)) err(1, "atexit"); db_build(argv); if (capdbp->close(capdbp) < 0) err(1, "%s", capname); capname = NULL; exit(0); }
void kpathsea_init_db (kpathsea kpse) { const_string db_path; string *db_files; string *orig_db_files; str_list_type unique_list; int dbi; boolean ok = false; assert (sizeof(DB_NAME) == sizeof(DB_NAME_LC)); db_path = kpathsea_init_format (kpse, kpse_db_format); db_files = kpathsea_path_search_list_generic (kpse, db_path, db_names, true, true); orig_db_files = db_files; /* Mac OS X and others can use a case-insensitive, case-preserving filesystem by default, in which case ls-R and ls-r point to the same file. Also, Windows is case-insensitive. In these cases, we want to avoid reading the same file multiple times. */ dbi = 0; unique_list = str_list_init (); while (db_files[dbi] != NULL) { string path1 = db_files[dbi]; string path2 = db_files[dbi + 1]; /* first-pass check in case path1/path2 aren't even potentially equal; mainly in case the order from kpathsea_path_search_list_generic changes. */ if (path2 && strcasecmp (path1, path2) == 0 && same_file_p (path1, path2)) { /* they are the same, skip over path1, we'll add path2 on the next iteration (when it's path1). */ #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { DEBUGF2 ("db:init(): skipping db same_file_p %s, will add %s.\n", path1, path2); } #endif free (path1); } else { /* they are not the same, add path1. */ #ifdef KPSE_DEBUG if (KPATHSEA_DEBUG_P (KPSE_DEBUG_HASH)) { DEBUGF1 ("db:init(): using db file %s.\n", path1); } #endif str_list_add (&unique_list, path1); } /* could be more clever and increment by two, but then would have to avoid jumping off the end of db_files */ dbi++; } /* always add a NULL terminator. */ str_list_add (&unique_list, NULL); free (orig_db_files); db_files = STR_LIST (unique_list); orig_db_files = db_files; /* Must do this after the path searching (which ends up calling kpse_db_search recursively), so kpse->db.buckets stays NULL. */ kpse->db = hash_create (DB_HASH_SIZE); while (db_files && *db_files) { if (db_build (kpse, &(kpse->db), *db_files)) ok = true; free (*db_files); db_files++; } if (!ok) { /* If db can't be built, leave `size' nonzero (so we don't rebuild it), but clear `buckets' (so we don't look in it). */ free (kpse->db.buckets); kpse->db.buckets = NULL; } free (orig_db_files); /* Add the content of any alias databases. There may exist more than one alias file along DB_NAME files. This duplicates the above code -- should be a function. */ ok = false; db_files = kpathsea_all_path_search (kpse, db_path, ALIAS_NAME); orig_db_files = db_files; kpse->alias_db = hash_create (ALIAS_HASH_SIZE); while (db_files && *db_files) { if (alias_build (kpse, &(kpse->alias_db), *db_files)) ok = true; free (*db_files); db_files++; } if (!ok) { free (kpse->alias_db.buckets); kpse->alias_db.buckets = NULL; } free (orig_db_files); }