static int find_dst(struct parse_arg *pasrc, const char *dst) { int ret; struct parse_arg padst; struct _lookup *cl; struct _region data; ret = _lookup_seq_open(&cl, CS_PIVOT, _LOOKUP_CASE_IGNORE); if (ret) return ret; ret = _lookup_seq_lookup(cl, pasrc->dst, &data); while (ret == 0) { ret = parse_line(&padst, &data); if (ret) break; if (strcmp(dst, padst.dst) == 0) { pasrc->norm += padst.norm; break; } ret = _lookup_seq_next(cl, NULL, &data); } _lookup_seq_close(cl); return ret; }
static int find_best_pivot_lookup(const char *src, const char *dst, char *pivot, size_t pvlen, unsigned long *rnorm) { int ret; struct _lookup *cl; struct _region data; struct parse_arg pa; unsigned long norm_min; char pivot_min[PATH_MAX]; ret = _lookup_seq_open(&cl, CS_PIVOT, _LOOKUP_CASE_IGNORE); if (ret) return ret; norm_min = ULONG_MAX; /* find pivot code */ ret = _lookup_seq_lookup(cl, src, &data); while (ret == 0) { ret = parse_line(&pa, &data); if (ret) break; ret = find_dst(&pa, dst); if (ret) break; if (pa.norm < norm_min) { norm_min = pa.norm; strlcpy(pivot_min, pa.dst, sizeof(pivot_min)); } ret = _lookup_seq_next(cl, NULL, &data); } _lookup_seq_close(cl); if (ret != ENOENT) return ret; if (norm_min == ULONG_MAX) return ENOENT; strlcpy(pivot, pivot_min, pvlen); if (rnorm) *rnorm = norm_min; return 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); }