Blame lib/names.c

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