Blame lib/names.c

Packit d3f73b
/*
Packit d3f73b
 * names.c		db names
Packit d3f73b
 *
Packit d3f73b
 *		This program is free software; you can redistribute it and/or
Packit d3f73b
 *		modify it under the terms of the GNU General Public License
Packit d3f73b
 *		as published by the Free Software Foundation; either version
Packit d3f73b
 *		2 of the License, or (at your option) any later version.
Packit d3f73b
 *
Packit d3f73b
 */
Packit d3f73b
Packit d3f73b
#include <stdio.h>
Packit d3f73b
#include <string.h>
Packit d3f73b
#include <stdlib.h>
Packit d3f73b
#include <errno.h>
Packit d3f73b
Packit d3f73b
#include "names.h"
Packit d3f73b
#include "utils.h"
Packit d3f73b
Packit d3f73b
#define MAX_ENTRIES  256
Packit d3f73b
#define NAME_MAX_LEN 512
Packit d3f73b
Packit d3f73b
static int read_id_name(FILE *fp, int *id, char *name)
Packit d3f73b
{
Packit d3f73b
	char buf[NAME_MAX_LEN];
Packit d3f73b
	int min, maj;
Packit d3f73b
Packit d3f73b
	while (fgets(buf, sizeof(buf), fp)) {
Packit d3f73b
		char *p = buf;
Packit d3f73b
Packit d3f73b
		while (*p == ' ' || *p == '\t')
Packit d3f73b
			p++;
Packit d3f73b
Packit d3f73b
		if (*p == '#' || *p == '\n' || *p == 0)
Packit d3f73b
			continue;
Packit d3f73b
Packit d3f73b
		if (sscanf(p, "%x:%x %s\n", &maj, &min, name) == 3) {
Packit d3f73b
			*id = (maj << 16) | min;
Packit d3f73b
		} else if (sscanf(p, "%x:%x %s #", &maj, &min, name) == 3) {
Packit d3f73b
			*id = (maj << 16) | min;
Packit d3f73b
		} else if (sscanf(p, "0x%x %s\n", id, name) != 2 &&
Packit d3f73b
				sscanf(p, "0x%x %s #", id, name) != 2 &&
Packit d3f73b
				sscanf(p, "%d %s\n", id, name) != 2 &&
Packit d3f73b
				sscanf(p, "%d %s #", id, name) != 2) {
Packit d3f73b
			strcpy(name, p);
Packit d3f73b
			return -1;
Packit d3f73b
		}
Packit d3f73b
		return 1;
Packit d3f73b
	}
Packit d3f73b
Packit d3f73b
	return 0;
Packit d3f73b
}
Packit d3f73b
Packit d3f73b
struct db_names *db_names_alloc(void)
Packit d3f73b
{
Packit d3f73b
	struct db_names *db;
Packit d3f73b
Packit d3f73b
	db = calloc(1, sizeof(*db));
Packit d3f73b
	if (!db)
Packit d3f73b
		return NULL;
Packit d3f73b
Packit d3f73b
	db->size = MAX_ENTRIES;
Packit d3f73b
	db->hash = calloc(db->size, sizeof(struct db_entry *));
Packit d3f73b
Packit d3f73b
	return db;
Packit d3f73b
}
Packit d3f73b
Packit d3f73b
int db_names_load(struct db_names *db, const char *path)
Packit d3f73b
{
Packit d3f73b
	struct db_entry *entry;
Packit d3f73b
	FILE *fp;
Packit d3f73b
	int id;
Packit d3f73b
	char namebuf[NAME_MAX_LEN] = {0};
Packit d3f73b
	int ret = -1;
Packit d3f73b
Packit d3f73b
	fp = fopen(path, "r");
Packit d3f73b
	if (!fp)
Packit d3f73b
		return -ENOENT;
Packit d3f73b
Packit d3f73b
	while ((ret = read_id_name(fp, &id, &namebuf[0]))) {
Packit d3f73b
		if (ret == -1) {
Packit d3f73b
			fprintf(stderr, "Database %s is corrupted at %s\n",
Packit d3f73b
					path, namebuf);
Packit d3f73b
			goto Exit;
Packit d3f73b
		}
Packit d3f73b
		ret = -1;
Packit d3f73b
Packit d3f73b
		if (id < 0)
Packit d3f73b
			continue;
Packit d3f73b
Packit d3f73b
		entry = malloc(sizeof(*entry));
Packit d3f73b
		if (!entry)
Packit d3f73b
			goto Exit;
Packit d3f73b
Packit d3f73b
		entry->name = strdup(namebuf);
Packit d3f73b
		if (!entry->name) {
Packit d3f73b
			free(entry);
Packit d3f73b
			goto Exit;
Packit d3f73b
		}
Packit d3f73b
Packit d3f73b
		entry->id   = id;
Packit d3f73b
		entry->next = db->hash[id & (db->size - 1)];
Packit d3f73b
		db->hash[id & (db->size - 1)] = entry;
Packit d3f73b
	}
Packit d3f73b
	ret = 0;
Packit d3f73b
Packit d3f73b
Exit:
Packit d3f73b
	fclose(fp);
Packit d3f73b
	return ret;
Packit d3f73b
}
Packit d3f73b
Packit d3f73b
void db_names_free(struct db_names *db)
Packit d3f73b
{
Packit d3f73b
	int i;
Packit d3f73b
Packit d3f73b
	if (!db)
Packit d3f73b
		return;
Packit d3f73b
Packit d3f73b
	for (i = 0; i < db->size; i++) {
Packit d3f73b
		struct db_entry *entry = db->hash[i];
Packit d3f73b
Packit d3f73b
		while (entry) {
Packit d3f73b
			struct db_entry *next = entry->next;
Packit d3f73b
Packit d3f73b
			free(entry->name);
Packit d3f73b
			free(entry);
Packit d3f73b
			entry = next;
Packit d3f73b
		}
Packit d3f73b
	}
Packit d3f73b
Packit d3f73b
	free(db->hash);
Packit d3f73b
	free(db);
Packit d3f73b
}
Packit d3f73b
Packit d3f73b
char *id_to_name(struct db_names *db, int id, char *name)
Packit d3f73b
{
Packit d3f73b
	struct db_entry *entry;
Packit d3f73b
Packit d3f73b
	if (!db)
Packit d3f73b
		return NULL;
Packit d3f73b
Packit d3f73b
	entry = db->hash[id & (db->size - 1)];
Packit d3f73b
	while (entry && entry->id != id)
Packit d3f73b
		entry = entry->next;
Packit d3f73b
Packit d3f73b
	if (entry) {
Packit d3f73b
		strncpy(name, entry->name, IDNAME_MAX);
Packit d3f73b
		return name;
Packit d3f73b
	}
Packit d3f73b
Packit d3f73b
	snprintf(name, IDNAME_MAX, "%d", id);
Packit d3f73b
	return NULL;
Packit d3f73b
}