Пример #1
0
int
_citrus_lookup_factory_convert(FILE *out, FILE *in)
{
	struct _citrus_db_factory *df;
	struct _region r;
	char *line;
	size_t size;
	int ret;

	ret = _db_factory_create(&df, &_db_hash_std, NULL);
	if (ret)
		return (ret);

	while ((line = fgetln(in, &size)) != NULL)
		if ((ret = convert_line(df, line, size))) {
			_db_factory_free(df);
			return (ret);
		}

	ret = dump_db(df, &r);
	_db_factory_free(df);
	if (ret)
		return (ret);

	if (fwrite(_region_head(&r), _region_size(&r), 1, out) != 1)
		return (errno);

	return (0);
}
Пример #2
0
static int
parse_line(struct parse_arg *pa, struct _region *r)
{
	char buf[20];
	struct zone z1, z2;
	size_t len;

	len = _region_size(r);
	z1.begin = _bcs_skip_ws_len(_region_head(r), &len);
	if (len == 0)
		return EFTYPE;
	z1.end = _bcs_skip_nonws_len(z1.begin, &len);
	if (len == 0)
		return EFTYPE;
	z2.begin = _bcs_skip_ws_len(z1.end, &len);
	if (len == 0)
		return EFTYPE;
	z2.end = _bcs_skip_nonws_len(z2.begin, &len);

	/* z1 : dst name, z2 : norm */
	snprintf(pa->dst, sizeof(pa->dst),
		 "%.*s", (int)(z1.end-z1.begin), z1.begin);
	snprintf(buf, sizeof(buf),
		 "%.*s", (int)(z2.end-z2.begin), z2.begin);
	pa->norm = _bcs_strtoul(buf, NULL, 0);

	return 0;
}
Пример #3
0
char *
_citrus_lookup_simple(const char *name, const char *key,
		      char *linebuf, size_t linebufsize, int ignore_case)
{
	int ret;
	struct _citrus_lookup *cl;
	struct _region data;

	ret = _citrus_lookup_seq_open(&cl, name, ignore_case);
	if (ret)
		return NULL;

	ret = _citrus_lookup_seq_lookup(cl, key, &data);
	if (ret) {
		_citrus_lookup_seq_close(cl);
		return NULL;
	}

	snprintf(linebuf, linebufsize, "%.*s",
		 (int)_region_size(&data), (const char *)_region_head(&data));

	_citrus_lookup_seq_close(cl);

	return linebuf;
}
Пример #4
0
static int
get32(struct _region *r, uint32_t *rval)
{
	if (_region_size(r) != 4)
		return EFTYPE;

	memcpy(rval, _region_head(r), (size_t)4);
	*rval = be32toh(*rval);

	return 0;
}
Пример #5
0
int
_citrus_db_lookup_string_by_string(struct _citrus_db *db, const char *key,
                                   const char **rdata, struct _citrus_db_locator *dl)
{
    struct _region r;
    int ret;

    ret = _citrus_db_lookup_by_string(db, key, &r, dl);
    if (ret)
        return (ret);

    /* check whether the string is null terminated */
    if (_region_size(&r) == 0)
        return (EFTYPE);
    if (*((const char*)_region_head(&r)+_region_size(&r)-1) != '\0')
        return (EFTYPE);

    if (rdata)
        *rdata = _region_head(&r);

    return (0);
}
Пример #6
0
int
_citrus_db_lookup8_by_string(struct _citrus_db *db, const char *key,
                             uint8_t *rval, struct _citrus_db_locator *dl)
{
    struct _region r;
    int ret;

    ret = _citrus_db_lookup_by_string(db, key, &r, dl);
    if (ret)
        return (ret);

    if (_region_size(&r) != 1)
        return (EFTYPE);

    if (rval)
        memcpy(rval, _region_head(&r), 1);

    return (0);
}
Пример #7
0
uint32_t
_citrus_db_hash_std(struct _region *r)
{
	const uint8_t *p;
	uint32_t hash, tmp;
	size_t i;

	hash = 0;
	p = _region_head(r);

	for (i = _region_size(r); i > 0; i--) {
		hash <<= 4;
		hash += _bcs_tolower(*p);
		tmp = hash & 0xF0000000;
		if (tmp != 0) {
			hash ^= tmp;
			hash ^= tmp >> 24;
		}
		p++;
	}
static int
parse_var(struct _citrus_mapper_646 *m6, struct _memstream *ms,
    const char *dir)
{
	struct _region r;
	char path[PATH_MAX];

	m6->m6_forward = 1;
	_memstream_skip_ws(ms);
	/* whether backward */
	if (_memstream_peek(ms) == '!') {
		_memstream_getc(ms);
		m6->m6_forward = 0;
	}
	/* get description file path */
	_memstream_getregion(ms, &r, _memstream_remainder(ms));
	snprintf(path, sizeof(path), "%s/%.*s",
		 dir, (int)_region_size(&r), (char *)_region_head(&r));
	/* remove trailing white spaces */
	path[_bcs_skip_nonws(path)-path] = '\0';
	return (parse_file(m6, path));
}
Пример #9
0
int
_citrus_db_lookup32_by_string(struct _citrus_db *db, const char *key,
                              uint32_t *rval, struct _citrus_db_locator *dl)
{
    struct _region r;
    uint32_t val;
    int ret;

    ret = _citrus_db_lookup_by_string(db, key, &r, dl);
    if (ret)
        return (ret);

    if (_region_size(&r) != 4)
        return (EFTYPE);

    if (rval) {
        memcpy(&val, _region_head(&r), 4);
        *rval = be32toh(val);
    }

    return (0);
}
Пример #10
0
int
_citrus_db_lookup16_by_string(struct _citrus_db *db, const char *key,
			      uint16_t *rval, struct _citrus_db_locator *dl)
{
	int ret;
	struct _region r;
	uint16_t val;

	ret = _citrus_db_lookup_by_string(db, key, &r, dl);
	if (ret)
		return ret;

	if (_region_size(&r) != 2)
		return EFTYPE;

	if (rval) {
		memcpy(&val, _region_head(&r), 2);
		*rval = be16toh(val);
	}

	return 0;
}
Пример #11
0
/*
 * _citrus_esdb_get_list:
 *	get esdb entries.
 */
int
_citrus_esdb_get_list(char ***rlist, size_t *rnum, bool sorted)
{
	struct _citrus_lookup *cla, *cld;
	struct _region key, data;
	char **list, **q;
	char buf[PATH_MAX];
	size_t num;
	int ret;

	num = 0;

	ret = _lookup_seq_open(&cla, _PATH_ESDB "/" ESDB_ALIAS,
	    _LOOKUP_CASE_IGNORE);
	if (ret)
		goto quit0;

	ret = _lookup_seq_open(&cld, _PATH_ESDB "/" ESDB_DIR,
	    _LOOKUP_CASE_IGNORE);
	if (ret)
		goto quit1;

	/* count number of entries */
	num = _lookup_get_num_entries(cla) + _lookup_get_num_entries(cld);

	_lookup_seq_rewind(cla);
	_lookup_seq_rewind(cld);

	/* allocate list pointer space */
	list = malloc(num * sizeof(char *));
	num = 0;
	if (list == NULL) {
		ret = errno;
		goto quit3;
	}

	/* get alias entries */
	while ((ret = _lookup_seq_next(cla, &key, &data)) == 0) {
		if (sorted)
			snprintf(buf, sizeof(buf), "%.*s/%.*s",
			    (int)_region_size(&data),
			    (const char *)_region_head(&data),
			    (int)_region_size(&key),
			    (const char *)_region_head(&key));
		else
			snprintf(buf, sizeof(buf), "%.*s/%.*s",
			    (int)_region_size(&data),
			    (const char *)_region_head(&data),
			    (int)_region_size(&key),
			    (const char *)_region_head(&key));
		_bcs_convert_to_upper(buf);
		list[num] = strdup(buf);
		if (list[num] == NULL) {
			ret = errno;
			goto quit3;
		}
		num++;
	}
	if (ret != ENOENT)
		goto quit3;
	/* get dir entries */
	while ((ret = _lookup_seq_next(cld, &key, &data)) == 0) {
		if (!sorted)
			snprintf(buf, sizeof(buf), "%.*s",
			    (int)_region_size(&key),
			    (const char *)_region_head(&key));
		else {
			/* check duplicated entry */
			char *p;
			char buf1[PATH_MAX];

			snprintf(buf1, sizeof(buf1), "%.*s",
			    (int)_region_size(&data),
			    (const char *)_region_head(&data));
			if ((p = strchr(buf1, '/')) != NULL)
				memcpy(buf1, p + 1, strlen(p) - 1);
			if ((p = strstr(buf1, ".esdb")) != NULL)
				*p = '\0';
			snprintf(buf, sizeof(buf), "%s/%.*s", buf1,
			    (int)_region_size(&key),
			    (const char *)_region_head(&key));
		}
		_bcs_convert_to_upper(buf);
		ret = _lookup_seq_lookup(cla, buf, NULL);
		if (ret) {
			if (ret != ENOENT)
				goto quit3;
			/* not duplicated */
			list[num] = strdup(buf);
			if (list[num] == NULL) {
				ret = errno;
				goto quit3;
			}
			num++;
		}
	}
	if (ret != ENOENT)
		goto quit3;

	ret = 0;
	/* XXX: why reallocing the list space posteriorly?
	    shouldn't be done earlier? */
	q = realloc(list, num * sizeof(char *));
	if (!q) {
		ret = ENOMEM;
		goto quit3;
	}
	list = q;
	*rlist = list;
	*rnum = num;
quit3:
	if (ret)
		_citrus_esdb_free_list(list, num);
	_lookup_seq_close(cld);
quit1:
	_lookup_seq_close(cla);
quit0:
	return (ret);
}
Пример #12
0
static int
find_best_pivot_pvdb(const char *src, const char *dst, char *pivot,
		     size_t pvlen, unsigned long *rnorm)
{
	int ret, num, i;
	struct _region fr, r1, r2;
	struct _citrus_db *db1, *db2, *db3;
	char buf[LINE_MAX];
	unsigned long norm;
	uint32_t val32;

	ret = _map_file(&fr, CS_PIVOT ".pvdb");
	if (ret) {
		if (ret == ENOENT)
			ret = NO_SUCH_FILE;
		return ret;
	}
	ret = _db_open(&db1, &fr, _CITRUS_PIVOT_MAGIC, _db_hash_std, NULL);
	if (ret)
		goto quit1;
	ret = open_subdb(&db2, db1, src);
	if (ret)
		goto quit2;

	num = _db_get_num_entries(db2);
	*rnorm = ULONG_MAX;
	for (i = 0; i < num; i++) {
		/* iterate each pivot */
		ret = _db_get_entry(db2, i, &r1, &r2);
		if (ret)
			goto quit3;
		/* r1:pivot name, r2:norm among src and pivot */
		ret = get32(&r2, &val32);
		if (ret)
			goto quit3;
		norm = val32;
		snprintf(buf, sizeof(buf), "%.*s",
			 (int)_region_size(&r1), (char *)_region_head(&r1));
		/* buf: pivot name */
		ret = open_subdb(&db3, db1, buf);
		if (ret)
			goto quit3;
		if (_db_lookup_by_s(db3, dst, &r2, NULL) != 0)
			/* don't break the loop, test all src/dst pairs. */
			goto quit4;
		/* r2: norm among pivot and dst */
		ret = get32(&r2, &val32);
		if (ret)
			goto quit4;
		norm += val32;
		/* judge minimum norm */
		if (norm < *rnorm) {
			*rnorm = norm;
			strlcpy(pivot, buf, pvlen);
		}
quit4:
		_db_close(db3);
		if (ret)
			goto quit3;
	}
quit3:
	_db_close(db2);
quit2:
	_db_close(db1);
quit1:
	_unmap_file(&fr);
	if (ret)
		return ret;

	if (*rnorm == ULONG_MAX)
		return ENOENT;

	return 0;
}
Пример #13
0
int
_citrus_db_lookup(struct _citrus_db *db, struct _citrus_region *key,
                  struct _citrus_region *data, struct _citrus_db_locator *dl)
{
    struct _citrus_db_entry_x *dex;
    struct _citrus_db_header_x *dhx;
    struct _citrus_region r;
    struct _memstream ms;
    uint32_t hashval, num_entries;
    size_t offset;

    _memstream_bind(&ms, &db->db_region);

    dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx));
    num_entries = be32toh(dhx->dhx_num_entries);
    if (num_entries == 0)
        return (ENOENT);

    if (dl != NULL && dl->dl_offset>0) {
        hashval = dl->dl_hashval;
        offset = dl->dl_offset;
        if (offset >= _region_size(&db->db_region))
            return (ENOENT);
    } else {
        hashval = db->db_hashfunc(key)%num_entries;
        offset = be32toh(dhx->dhx_entry_offset) +
                 hashval * _CITRUS_DB_ENTRY_SIZE;
        if (dl)
            dl->dl_hashval = hashval;
    }
    do {
        /* seek to the next entry */
        if (_citrus_memory_stream_seek(&ms, offset, SEEK_SET))
            return (EFTYPE);
        /* get the entry record */
        dex = _memstream_getregion(&ms, NULL, _CITRUS_DB_ENTRY_SIZE);
        if (dex == NULL)
            return (EFTYPE);

        /* jump to next entry having the same hash value. */
        offset = be32toh(dex->dex_next_offset);

        /* save the current position */
        if (dl) {
            dl->dl_offset = offset;
            if (offset == 0)
                dl->dl_offset = _region_size(&db->db_region);
        }

        /* compare hash value. */
        if (be32toh(dex->dex_hash_value) != hashval)
            /* not found */
            break;
        /* compare key length */
        if (be32toh(dex->dex_key_size) == _region_size(key)) {
            /* seek to the head of the key. */
            if (_memstream_seek(&ms, be32toh(dex->dex_key_offset),
                                SEEK_SET))
                return (EFTYPE);
            /* get the region of the key */
            if (_memstream_getregion(&ms, &r,
                                     _region_size(key)) == NULL)
                return (EFTYPE);
            /* compare key byte stream */
            if (memcmp(_region_head(&r), _region_head(key),
                       _region_size(key)) == 0) {
                /* match */
                if (_memstream_seek(
                            &ms, be32toh(dex->dex_data_offset),
                            SEEK_SET))
                    return (EFTYPE);
                if (_memstream_getregion(
                            &ms, data,
                            be32toh(dex->dex_data_size)) == NULL)
                    return (EFTYPE);
                return (0);
            }
        }
    } while (offset != 0);

    return (ENOENT);
}