view libutil/dbread.c @ 28:fa81221ac9b6

retrieval of required db fields moved into libutil
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 16 Mar 2021 23:37:36 +0000
parents ca8a6f95826a
children
line wrap: on
line source

/*
 * This module implements functions for reading key=value database files.
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include "dbread.h"

static
parse_read_line(dbs, filename_for_errs, lineno_for_errs)
	struct dbread_state *dbs;
	char *filename_for_errs;
	int lineno_for_errs;
{
	unsigned n;
	char *cp, *np;

	n = 0;
	for (cp = dbs->linebuf; ; ) {
		while (isspace(*cp))
			cp++;
		if (!*cp)
			break;
		if (*cp == '=') {
inv_syntax:		fprintf(stderr, "%s line %d: invalid syntax\n",
				filename_for_errs, lineno_for_errs);
			return(-1);
		}
		for (np = cp; ; cp++) {
			if (*cp == '=')
				break;
			if (!*cp || isspace(*cp))
				goto inv_syntax;
		}
		*cp++ = '\0';
		if (n >= DBREAD_MAX_KV_PAIRS) {
			fprintf(stderr,
				"%s line %d: too many key=value pairs\n",
				filename_for_errs, lineno_for_errs);
			return(-1);
		}
		dbs->kv_pairs[n].key = np;
		dbs->kv_pairs[n].value = cp;
		n++;
		while (*cp && !isspace(*cp))
			cp++;
		if (*cp)
			*cp++ = '\0';
	}
	dbs->num_kv_pairs = n;
	return(0);
}

char *
dbread_find_key(dbs, sought_key)
	struct dbread_state *dbs;
	char *sought_key;
{
	unsigned n;

	for (n = 0; n < dbs->num_kv_pairs; n++)
		if (!strcasecmp(dbs->kv_pairs[n].key, sought_key))
			return dbs->kv_pairs[n].value;
	return 0;
}

char *
dbread_find_key_req(dbs, sought_key)
	struct dbread_state *dbs;
	char *sought_key;
{
	char *val;

	val = dbread_find_key(dbs, sought_key);
	if (val)
		return val;
	fprintf(stderr, "error: card record has no %s field\n", sought_key);
	return 0;
}

dbread_find_record(filename, dbs, sought_key, sought_value)
	char *filename, *sought_key, *sought_value;
	struct dbread_state *dbs;
{
	FILE *inf;
	int lineno;
	char *cp;

	inf = fopen(filename, "r");
	if (!inf) {
		perror(filename);
		return(-1);
	}
	for (lineno = 1; fgets(dbs->linebuf, DBREAD_LINEBUF_SIZE, inf);
	     lineno++) {
		if (!index(dbs->linebuf, '\n')) {
			fprintf(stderr,
				"%s line %d: too long or missing newline\n",
				filename, lineno);
			fclose(inf);
			return(-1);
		}
		if (parse_read_line(dbs, filename, lineno) < 0) {
			/* error msg already printed */
			fclose(inf);
			return(-1);
		}
		cp = dbread_find_key(dbs, sought_key);
		if (!cp)
			continue;
		if (strcmp(cp, sought_value))
			continue;
		/* found our record: struct dbread_state is our return */
		fclose(inf);
		return(0);
	}
	fclose(inf);
	fprintf(stderr, "error: %s=%s not found in %s\n", sought_key,
		sought_value, filename);
	return(-1);
}