static void ps_map_rehash( struct ps_map * map ) { struct ps_map old = *map; size_t i; map->table = BJAM_MALLOC( map->table_size * 2 * sizeof( struct ps_map_entry * ) ); map->table_size *= 2; for ( i = 0; i < map->table_size; ++i ) { map->table[ i ] = NULL; } for ( i = 0; i < old.table_size; ++i ) { struct ps_map_entry * pos; for ( pos = old.table[ i ]; pos; ) { struct ps_map_entry * tmp = pos->next; unsigned hash_val = list_hash( pos->key ); unsigned bucket = hash_val % map->table_size; pos->next = map->table[ bucket ]; map->table[ bucket ] = pos; pos = tmp; } } BJAM_FREE( old.table ); }
void *thread_func(void *arg) { long long thread_num = (long long)arg; // insert elements int start_elem = thread_num * num_iterations; int end_elem = start_elem + num_iterations - 1; int i, hash; for (i = start_elem; i <= end_elem; i++) { hash = list_hash(list_elements[i]->key); insert_func(sorted_lists[hash], list_elements[i]); } //printf("printing list:\n"); //SortedList_print(sorted_list); // count lengths int total_length = 0; for (i = 0; i < num_lists; i++) { int list_size = length_func(sorted_lists[i]); if (list_size == -1) { fprintf(stderr, "length() detected corrupted list!\n"); exit(1); } total_length += list_size; } // lookup, deletes SortedListElement_t *found; for (i = start_elem; i <= end_elem; i++) { const char *key = list_elements[i]->key; hash = list_hash(key); found = lookup_func(sorted_lists[hash], key); if (found == NULL) { fprintf(stderr, "lookup() did not find key!\n"); exit(1); } if (delete_func(found)) { fprintf(stderr, "delete() detected corrupted list!\n"); exit(1); } } return (void*)arg; }
static struct ps_map_entry * ps_map_insert(struct ps_map * map, LIST * key) { unsigned hash_val = list_hash( key ); unsigned bucket = hash_val % map->table_size; struct ps_map_entry * pos; for ( pos = map->table[bucket]; pos ; pos = pos->next ) { if ( list_equal( pos->key, key ) ) return pos; } if ( map->num_elems >= map->table_size ) { ps_map_rehash( map ); bucket = hash_val % map->table_size; } pos = BJAM_MALLOC( sizeof( struct ps_map_entry ) ); pos->next = map->table[bucket]; pos->key = key; pos->value = 0; map->table[bucket] = pos; ++map->num_elems; return pos; }
/*load rules from DB*/ int dp_load_db(void) { int i, nr_rows; db1_res_t * res = 0; db_val_t * values; db_row_t * rows; db_key_t query_cols[DP_TABLE_COL_NO] = { &dpid_column, &pr_column, &match_op_column, &match_exp_column, &match_len_column, &subst_exp_column, &repl_exp_column, &attrs_column }; db_key_t order = &pr_column; dpl_node_t *rule; LM_DBG("init\n"); if( (*crt_idx) != (*next_idx)){ LM_WARN("a load command already generated, aborting reload...\n"); return 0; } if (dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0){ LM_ERR("error in use_table %.*s\n", dp_table_name.len, dp_table_name.s); return -1; } if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) { if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, DP_TABLE_COL_NO, order, 0) < 0){ LM_ERR("failed to query database!\n"); return -1; } if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) { LM_ERR("failed to fetch\n"); if (res) dp_dbf.free_result(dp_db_handle, res); return -1; } } else { /*select the whole table and all the columns*/ if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, DP_TABLE_COL_NO, order, &res) < 0){ LM_ERR("failed to query database\n"); return -1; } } nr_rows = RES_ROW_N(res); *next_idx = ((*crt_idx) == 0)? 1:0; destroy_hash(*next_idx); if(nr_rows == 0){ LM_WARN("no data in the db\n"); goto end; } do { for(i=0; i<RES_ROW_N(res); i++){ rows = RES_ROWS(res); values = ROW_VALUES(rows+i); if((rule = build_rule(values)) ==0 ) goto err2; if(add_rule2hash(rule , *next_idx) != 0) goto err2; } if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) { if(dp_dbf.fetch_result(dp_db_handle, &res, dp_fetch_rows)<0) { LM_ERR("failure while fetching!\n"); if (res) dp_dbf.free_result(dp_db_handle, res); return -1; } } else { break; } } while(RES_ROW_N(res)>0); end: /*update data*/ *crt_idx = *next_idx; list_hash(*crt_idx); dp_dbf.free_result(dp_db_handle, res); return 0; err2: if(rule) destroy_rule(rule); destroy_hash(*next_idx); dp_dbf.free_result(dp_db_handle, res); *next_idx = *crt_idx; return -1; }
size_t list_dump_filedescriptor(const list_t *l, int fd) { struct list_entry_s *x; void *ser_buf; uint32_t bufsize; struct timeval timeofday; struct list_dump_header_s header; if (l->attrs.meter == NULL && l->attrs.serializer == NULL) return 0; /**** DUMP FORMAT **** [ ver timestamp | totlen numels elemlen hash | DATA ] where DATA can be: @ for constant-size list (element size is constant; elemlen > 0) [ elem elem ... elem ] @ for other lists (element size dictated by element_meter each time; elemlen <= 0) [ size elem size elem ... size elem ] all integers are encoded in NETWORK BYTE FORMAT *****/ /* prepare HEADER */ /* version */ header.ver = htons( SIMCLIST_DUMPFORMAT_VERSION ); /* timestamp */ gettimeofday(&timeofday, NULL); header.timestamp = (int64_t)timeofday.tv_sec * 1000000 + (int64_t)timeofday.tv_usec; header.timestamp = hton64(header.timestamp); header.rndterm = htonl((int32_t)random()); /* total list size is postprocessed afterwards */ /* number of elements */ header.numels = htonl(l->numels); /* include an hash, if possible */ if (l->attrs.hasher != NULL) { header.listhash = htonl(list_hash(l)); } else { header.listhash = htonl(0); } header.totlistlen = header.elemlen = 0; /* leave room for the header at the beginning of the file */ lseek(fd, SIMCLIST_DUMPFORMAT_HEADERLEN, SEEK_SET); /* write CONTENT */ if (l->numels > 0) { /* SPECULATE that the list has constant element size */ if (l->attrs.serializer != NULL) { /* user user-specified serializer */ ser_buf = l->attrs.serializer(l->head_sentinel->next->data, & header.elemlen); free(ser_buf); /* request custom serialization of each element */ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { ser_buf = l->attrs.serializer(x->data, &bufsize); header.totlistlen += bufsize; if (header.elemlen != 0) { /* continue on speculation */ if (header.elemlen != bufsize) { free(ser_buf); /* constant element length speculation broken! */ header.elemlen = 0; header.totlistlen = 0; x = l->head_sentinel; /* restart from the beginning */ continue; } /* speculation confirmed */ write(fd, ser_buf, bufsize); } else { /* speculation found broken */ write(fd, &bufsize, sizeof(size_t)); write(fd, ser_buf, bufsize); } free(ser_buf); } } else if (l->attrs.meter != NULL) { header.elemlen = (uint32_t)l->attrs.meter(l->head_sentinel->next->data); /* serialize the element straight from its data */ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { bufsize = l->attrs.meter(x->data); header.totlistlen += bufsize; if (header.elemlen != 0) { if (header.elemlen != bufsize) { /* constant element length speculation broken! */ header.elemlen = 0; header.totlistlen = 0; x = l->head_sentinel; /* restart from the beginning */ continue; } write(fd, x->data, bufsize); } else { write(fd, &bufsize, sizeof(size_t)); write(fd, x->data, bufsize); } } } /* adjust endianness */ header.elemlen = htonl(header.elemlen); header.totlistlen = htonl(header.totlistlen); } /* write random terminator */ write(fd, & header.rndterm, sizeof(header.rndterm)); /* list terminator */ /* write header */ lseek(fd, 0, SEEK_SET); write(fd, & header.ver, sizeof(header.ver)); /* version */ write(fd, & header.timestamp, sizeof(header.timestamp)); /* timestamp */ write(fd, & header.rndterm, sizeof(header.rndterm)); /* random terminator */ write(fd, & header.totlistlen, sizeof(header.totlistlen)); /* total length of elements */ write(fd, & header.numels, sizeof(header.numels)); /* number of elements */ write(fd, & header.elemlen, sizeof(header.elemlen)); /* size of each element, or 0 for independent */ write(fd, & header.listhash, sizeof(header.listhash)); /* list hash, or 0 for "ignore" */ return ntohl(header.totlistlen); }
/*load rules from DB*/ int dp_load_db(dp_connection_list_p dp_conn) { int i, nr_rows; db_res_t * res = 0; db_val_t * values; db_row_t * rows; db_key_t query_cols[DP_TABLE_COL_NO] = { &dpid_column, &pr_column, &match_op_column, &match_exp_column, &match_flags_column, &subst_exp_column, &repl_exp_column, &attrs_column, &timerec_column }; db_key_t order = &pr_column; /* disabled condition */ db_key_t cond_cols[1] = { &disabled_column }; db_val_t cond_val[1]; dpl_node_t *rule; int no_rows = 10; lock_start_write( dp_conn->ref_lock ); if( dp_conn->crt_index != dp_conn->next_index){ LM_WARN("a load command already generated, aborting reload...\n"); lock_stop_write( dp_conn->ref_lock ); return 0; } dp_conn->next_index = dp_conn->crt_index == 0 ? 1 : 0; lock_stop_write( dp_conn->ref_lock ); if (dp_conn->dp_dbf.use_table(*dp_conn->dp_db_handle, &dp_conn->table_name) < 0){ LM_ERR("error in use_table\n"); goto err1; } VAL_TYPE(cond_val) = DB_INT; VAL_NULL(cond_val) = 0; VAL_INT(cond_val) = 0; if (DB_CAPABILITY(dp_conn->dp_dbf, DB_CAP_FETCH)) { if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle,cond_cols, 0,cond_val,query_cols,1, DP_TABLE_COL_NO, order, 0) < 0){ LM_ERR("failed to query database!\n"); goto err1; } no_rows = estimate_available_rows( 4+4+4+64+4+64+64+128, DP_TABLE_COL_NO); if (no_rows==0) no_rows = 10; if(dp_conn->dp_dbf.fetch_result(*dp_conn->dp_db_handle, &res, no_rows)<0) { LM_ERR("failed to fetch\n"); if (res) dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res); goto err1; } } else { /*select the whole table and all the columns*/ if(dp_conn->dp_dbf.query(*dp_conn->dp_db_handle, cond_cols,0,cond_val,query_cols,1, DP_TABLE_COL_NO, order, &res) < 0){ LM_ERR("failed to query database\n"); goto err1; } } nr_rows = RES_ROW_N(res); if(nr_rows == 0){ LM_WARN("no data in the db\n"); goto end; } do { for(i=0; i<RES_ROW_N(res); i++){ rows = RES_ROWS(res); values = ROW_VALUES(rows+i); if ((rule = build_rule(values)) == NULL) { LM_WARN(" failed to build rule -> skipping\n"); continue; } rule->table_id = i; if(add_rule2hash(rule , dp_conn, dp_conn->next_index) != 0) { LM_ERR("add_rule2hash failed\n"); goto err2; } } if (DB_CAPABILITY(dp_conn->dp_dbf, DB_CAP_FETCH)) { if(dp_conn->dp_dbf.fetch_result(*dp_conn->dp_db_handle, &res, no_rows)<0) { LM_ERR("failure while fetching!\n"); if (res) dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res); goto err1; } } else { break; } } while(RES_ROW_N(res)>0); end: /*update data*/ lock_start_write( dp_conn->ref_lock ); destroy_hash(&dp_conn->hash[dp_conn->crt_index]); dp_conn->crt_index = dp_conn->next_index; lock_stop_write( dp_conn->ref_lock ); list_hash(dp_conn->hash[dp_conn->crt_index], dp_conn->ref_lock); dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res); return 0; err1: lock_start_write( dp_conn->ref_lock ); dp_conn->next_index = dp_conn->crt_index; lock_stop_write( dp_conn->ref_lock ); return -1; err2: if(rule) destroy_rule(rule); destroy_hash(&dp_conn->hash[dp_conn->next_index]); dp_conn->dp_dbf.free_result(*dp_conn->dp_db_handle, res); lock_start_write( dp_conn->ref_lock ); dp_conn->next_index = dp_conn->crt_index; /* if lock defined - release the exclusive writing access */ lock_stop_write( dp_conn->ref_lock ); return -1; }
/*load rules from DB*/ int dp_load_db(void) { int i, nr_rows; db_res_t * res = 0; db_val_t * values; db_row_t * rows; db_key_t query_cols[DP_TABLE_COL_NO] = { &dpid_column, &pr_column, &match_op_column, &match_exp_column, &match_len_column, &subst_exp_column, &repl_exp_column, &attrs_column }; db_key_t order = &pr_column; dpl_node_t *rule; int no_rows = 10; if( (*crt_idx) != (*next_idx)){ LM_WARN("a load command already generated, aborting reload...\n"); return 0; } if (dp_dbf.use_table(dp_db_handle, &dp_table_name) < 0){ LM_ERR("error in use_table\n"); return -1; } if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) { if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, DP_TABLE_COL_NO, order, 0) < 0){ LM_ERR("failed to query database!\n"); return -1; } no_rows = estimate_available_rows( 4+4+4+64+4+64+64+128, DP_TABLE_COL_NO); if (no_rows==0) no_rows = 10; if(dp_dbf.fetch_result(dp_db_handle, &res, no_rows)<0) { LM_ERR("failed to fetch\n"); if (res) dp_dbf.free_result(dp_db_handle, res); return -1; } } else { /*select the whole table and all the columns*/ if(dp_dbf.query(dp_db_handle,0,0,0,query_cols, 0, DP_TABLE_COL_NO, order, &res) < 0){ LM_ERR("failed to query database\n"); return -1; } } nr_rows = RES_ROW_N(res); lock_start_write( ref_lock ); *next_idx = ((*crt_idx) == 0)? 1:0; if(nr_rows == 0){ LM_WARN("no data in the db\n"); goto end; } do { for(i=0; i<RES_ROW_N(res); i++){ rows = RES_ROWS(res); values = ROW_VALUES(rows+i); if ((rule = build_rule(values)) == NULL ) { LM_WARN(" failed to build rule -> skipping\n"); continue; } if(add_rule2hash(rule , *next_idx) != 0) { LM_ERR("add_rule2hash failed\n"); goto err2; } } if (DB_CAPABILITY(dp_dbf, DB_CAP_FETCH)) { if(dp_dbf.fetch_result(dp_db_handle, &res, no_rows)<0) { LM_ERR("failure while fetching!\n"); if (res) dp_dbf.free_result(dp_db_handle, res); lock_stop_write( ref_lock ); return -1; } } else { break; } } while(RES_ROW_N(res)>0); end: destroy_hash(*crt_idx); /*update data*/ *crt_idx = *next_idx; /* release the exclusive writing access */ lock_stop_write( ref_lock ); list_hash(*crt_idx); dp_dbf.free_result(dp_db_handle, res); return 0; err2: if(rule) destroy_rule(rule); destroy_hash(*next_idx); dp_dbf.free_result(dp_db_handle, res); *next_idx = *crt_idx; /* if lock defined - release the exclusive writing access */ if(ref_lock) /* release the readers */ lock_stop_write( ref_lock ); return -1; }
int main(int argc, char **argv) { u_char print_version = 0; char hostname[DCC_MAXDOMAINLEN]; int file_num; DCC_CK_TYPES type; char tbuf[80]; const char *cp, *cp0; struct timeval tv1, tv2; int us; struct tm tm; char *p; u_long l; int i; dcc_syslog_init(0, argv[0], 0); while ((i = getopt(argc, argv, "vVHDG:h:s:C:I:A:L:P:T:")) != -1) { switch (i) { case 'v': ++verbose; break; case 'V': dcc_version_print(); print_version = 1; break; case 'G': if (!strcasecmp(optarg, "on")) { grey_on = 1; } else if (!strcasecmp(optarg, "off")) { grey_on = 0; } else { usage(); } break; case 'h': homedir = optarg; break; case 's': l = strtoul(optarg, &p, 10); if ((*p != '\0' && *p != ',') || !DCC_ID_SRVR_NORMAL(l)) dcc_logbad(EX_USAGE, "invalid DCC ID \"-s %s\"", optarg); srvr.clnt_id = l; if (*p != '\0') { ++p; p += strspn(p, DCC_WHITESPACE); } hostname[0] = '\0'; srvr.port = 0; if (*p == '\0') break; cp = dcc_parse_nm_port(dcc_emsg, p, srvr.port, hostname, sizeof(hostname), &srvr.port, 0, 0, 0, 0); if (!cp) dcc_logbad(EX_USAGE, "%s", dcc_emsg); cp += strspn(cp, DCC_WHITESPACE); if (*cp != '\0') dcc_logbad(EX_USAGE, "unrecognized port number in" "\"-s %s\"", optarg); if (hostname[0] != '\0') BUFCPY(srvr.hostname, hostname); break; case 'H': no_hash = 1; break; case 'D': no_data = 1; break; case 'C': if (num_search_cksums >= DIM(search_cksums)) { dcc_error_msg("too many -C checksums"); break; } matching = 1; cp0 = optarg; /* separate checksum type and checksum in cp and tbuf */ cp = dcc_parse_word(0, tbuf, sizeof(tbuf), optarg, "checksum type", 0, 0); if (!cp) exit(1); if (!strcasecmp(tbuf, "hex")) { /* ignore "hex" */ cp0 = cp; cp = dcc_parse_word(0, tbuf, sizeof(tbuf), cp, "checksum type", 0, 0); if (!cp) dcc_logbad(EX_USAGE, "unrecognized checksum" " \"-C %s\"", optarg); } if (*cp == '\0') { /* allow bare checksum type */ type = dcc_str2type_del(tbuf, -1); if (type == DCC_CK_INVALID) dcc_logbad(EX_USAGE, "unrecognized checksum type" " \"-C %s\"", optarg); search_cksums[num_search_cksums].type = type; memset(&search_cksums[num_search_cksums].sum, 0, sizeof(DCC_SUM)); search_cksums[num_search_cksums].type_only = 1; ++num_search_cksums; break; } /* allow missing checksum type */ l = strtoul(tbuf, &p, 16); if (*p == '\0') { if (0 >= dcc_parse_hex_ck(dcc_emsg, 0, "-", DCC_CK_FLOD_PATH, cp0, 0, save_cksum)) dcc_logbad(EX_USAGE, "%s", dcc_emsg); break; } type = dcc_str2type_del(tbuf, -1); if (type == DCC_CK_FLOD_PATH) dcc_logbad(EX_USAGE, "unrecognized checksum type" " \"-C %s\"", optarg); if (1 <= dcc_parse_hex_ck(dcc_emsg, 0, tbuf, type, cp, 0, save_cksum)) break; /* allow strings for server-IDs */ if (type == DCC_CK_SRVR_ID && (i = strlen(cp)) <= ISZ(DCC_SUM)) { DCC_SUM name; memset(&name, 0, sizeof(name)); memcpy(&name, cp, i); save_cksum(0, 0, type, &name, 0); break; } dcc_logbad(EX_USAGE, "%s", dcc_emsg); break; case 'I': if (num_search_ids >= DIM(search_ids)) { dcc_error_msg("too many -I IDs"); break; } search_ids[num_search_ids] = strtoul(optarg, &p, 10); if (search_ids[num_search_ids] > DCC_SRVR_ID_MAX || *p != '\0') dcc_logbad(EX_USAGE, "invalid server-ID \"-I %s\"", optarg); ++num_search_ids; matching = 1; break; case 'A': dbaddr = strtoul(optarg, &p, 16); if (*p != '\0') dcc_logbad(EX_USAGE, "invalid database address \"%s\"", optarg); matching = 1; break; case 'L': max_pathlen = strtoul(optarg, &p, 10); if (*p != '\0') dcc_logbad(EX_USAGE, "invalid path length \"%s\"", optarg); matching = 1; break; case 'P': page_offset = strtoul(optarg, &p, 10); if (*p != '\0') dcc_logbad(EX_USAGE, "invalid number of pages \"%s\"", optarg); matching = 1; break; case 'T': if (num_search_ts >= DIM(search_ts)) { dcc_error_msg("too many -T timestamps"); break; } memset(&tm, 0, sizeof(tm)); i = sscanf(optarg, "%d/%d/%d %d:%d:%d.%d%c", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &us, tbuf); if (i < 6 || i > 7 || tm.tm_mon <= 0) dcc_logbad(EX_USAGE,"bad timestamp \"%s\"", optarg); --tm.tm_mon; tm.tm_year += 100; tv1.tv_sec = DCC_TIMEGM(&tm); if (tv1.tv_sec < 0) dcc_logbad(EX_USAGE, "invalid timestamp \"%s\"", optarg); tv2.tv_sec = tv1.tv_sec; if (i == 7) { if (us >= DCC_US) dcc_logbad(EX_USAGE, "invalid microseconds" " in \"%s\"", optarg); tv1.tv_usec = us; tv2.tv_usec = us; } else { tv1.tv_usec = 0; tv2.tv_usec = DCC_US-1; } timeval2ts(&search_ts[num_search_ts].lo, &tv1, 0); timeval2ts(&search_ts[num_search_ts].hi, &tv2, 0); ++num_search_ts; matching = 1; break; default: usage(); } } argc -= optind; argv += optind; def_argv[0] = grey_on ? grey_db_nm : dcc_db_nm; if (argc == 0) { if (print_version) exit(EX_OK); argv = def_argv; argc = 1; } dcc_clnt_unthread_init(); if (!dcc_cdhome(dcc_emsg, homedir, 1)) dcc_logbad(emsg_ex_code(dcc_emsg), "%s", dcc_emsg); flod_mmap_path_set(); if (matching) { if (no_data && no_hash) dcc_logbad(EX_USAGE, "patterns need data or hash table"); if (!no_data && !no_hash) no_hash = 1; } if (dbaddr != 0 && page_offset != 0) dcc_logbad(EX_USAGE, "-P and -A are incompatible"); if (srvr.clnt_id != 0) { if (argc != 1) dcc_logbad(EX_USAGE, "lock only one file"); i = load_ids(dcc_emsg, srvr.clnt_id, &srvr_clnt_tbl, 1, verbose > 4); if (!srvr_clnt_tbl) dcc_logbad(emsg_ex_code(dcc_emsg), "%s", dcc_emsg); if (i <= 0) dcc_error_msg("%s", dcc_emsg); memcpy(srvr.passwd, srvr_clnt_tbl->cur_passwd, sizeof(srvr.passwd)); if (srvr.hostname[0] == '\0') BUFCPY(srvr.hostname, "127.0.0.1"); if (srvr.port == 0) srvr.port = DCC_GREY2PORT(grey_on); i = DCC_CLNT_FG_SLOW; if (grey_on) i |= DCC_CLNT_FG_GREY; ctxt = dcc_tmp_clnt_init(dcc_emsg, 0, &srvr, 0, 0, i, 0); if (!ctxt) dcc_logbad(emsg_ex_code(dcc_emsg), "%s", dcc_emsg); if (!lock_dbclean(dcc_emsg, *argv)) dcc_logbad(emsg_ex_code(dcc_emsg), "%s: dbclean running?", dcc_emsg); atexit(rel_db); signal(SIGALRM, sigterm); signal(SIGHUP, sigterm); signal(SIGTERM, sigterm); signal(SIGINT, sigterm); if (!dcc_aop_persist(dcc_emsg, ctxt, grey_on ? DCC_CLNT_FG_GREY : 0, verbose != 0, DCC_AOP_DB_UNLOAD, 0, 60*5, &aop_resp)) dcc_logbad(emsg_ex_code(dcc_emsg), "%s", dcc_emsg); } for (file_num = 1; *argv != 0; ++argv, ++file_num) { if (fd_db >= 0) close(fd_db); if (fd_hash >= 0) close(fd_hash); BUFCPY(db_nm, *argv); snprintf(hash_nm, sizeof(hash_nm), "%s"DB_HASH_SUFFIX, db_nm); if (file_num != 1) fputc('\n', stdout); if (verbose || argc > 1) printf(" %s\n", db_nm); /* try to open the hash table and the database * fail only if we cannot open the database */ open_hash(); if (!open_db()) continue; /* print the header of the database followed by its contents */ list_db(); list_hash(); } exit(EX_OK); }