Example #1
0
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 );
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
/*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;
}
Example #5
0
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);
}
Example #6
0
/*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;
}
Example #7
0
/*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;
}
Example #8
0
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);
}