/*
**  Copyright 2000-2004 University of Illinois Board of Trustees
**  Copyright 2000-2004 Mark D. Roth
**  All rights reserved.
**
**  siteinfo.c - libphclient code to parse siteinfo data
**
**  Mark D. Roth <roth@feep.net>
*/

#include <internal.h>

#include <errno.h>

#ifdef STDC_HEADERS
# include <string.h>
# include <stdlib.h>
#endif

#include <strings.h>


int
ph_is_siteinfo_cached(PH *ph)
{
	return (ph->ph_siteinfo != NULL ? 1 : 0);
}


/* ph_free_siteinfo_list() - free a siteinfo list. */
static void
ph_free_siteinfo_list(struct ph_siteinfo *si)
{
	int i;

	for (i = 0; si[i].ps_info != NULL; i++)
	{
#ifdef DEBUG
		printf("freeing siteinfo[%d]:  \"%s\" = \"%s\"\n", i,
		       (si[i].ps_info ? si[i].ps_info : ""),
		       (si[i].ps_data ? si[i].ps_data : ""));
#endif
		free(si[i].ps_info);
		free(si[i].ps_data);
	}

	free(si);
}


/*
** ph_retrieve_siteinfo() - read siteinfo from server.
** returns:
**	0				success
**	-1				error (sets errno)
*/
int
ph_retrieve_siteinfo(PH *ph)
{
	char *info, *setting;
	char buf[PH_BUF_SIZE];
	int code = -1, infonum = 0, i, save_errno;
	ph_memblock_t *blockp;
	struct ph_siteinfo *phsi;

	/* don't load if already cached */
	if (ph_is_siteinfo_cached(ph))
		return 0;

	if (ph_mmgr_malloc(ph->ph_mmgr, ph_MMGR_ARRAY,
			   0, sizeof(struct ph_siteinfo),
			   (ph_free_func_t)ph_free_siteinfo_list,
			   &blockp) == -1)
		return -1;
	phsi = (struct ph_siteinfo *)ph_mmgr_ptr(blockp);

	/* send command */
	if (ph_send_command(ph, "siteinfo") == -1)
		return -1;

	/* read responses */
	while (ph_get_response(ph, &code, buf, sizeof(buf)) == 0)
	{
		if (code < LR_OK && code > 0)
			continue;
		if (code == LR_OK)
		{
			ph->ph_siteinfo = phsi;
			ph_mmgr_free(blockp, 0);
			return 0;
		}

		if (ph_parse_response(buf, &i, &info, &setting) == -1)
		{
			save_errno = errno;
			ph_mmgr_free(blockp, 1);
			errno = save_errno;
			return -1;
		}

#ifdef DEBUG
		printf("code=%d, i=%d, info=\"%s\", setting=\"%s\", "
		       "infonum=%d\n", code, i, info, setting, infonum);
#endif

		if (ph_mmgr_array_add(blockp, infonum + 2) == -1)
		{
			save_errno = errno;
			ph_mmgr_free(blockp, 1);
			errno = save_errno;
			return -1;
		}
		phsi = (struct ph_siteinfo *)ph_mmgr_ptr(blockp);

		phsi[infonum].ps_info = strdup(info);
		phsi[infonum].ps_data = strdup(setting);
		if (phsi[infonum].ps_info == NULL
		    || phsi[infonum].ps_data == NULL)
		{
			save_errno = errno;
			ph_mmgr_free(blockp, 1);
			errno = save_errno;
			return -1;
		}

		infonum++;
	}

	save_errno = errno;
	ph_mmgr_free(blockp, 1);
	errno = save_errno;
	return -1;
}


/*
** ph_get_siteinfo() - return the value of a specific info field.
** returns:
**	0				success
**	-1				error (sets errno)
**	PH_ERR_DATAERR			unknown siteinfo field
*/
int
ph_get_siteinfo(PH *ph, char *info, char **data)
{
	int i;

	if (!ph_is_siteinfo_cached(ph) && ph_retrieve_siteinfo(ph) == -1)
		return -1;

	for (i = 0; ph->ph_siteinfo[i].ps_info != NULL; i++)
		if (strcasecmp(ph->ph_siteinfo[i].ps_info, info) == 0)
		{
			*data = ph->ph_siteinfo[i].ps_data;
			return 0;
		}

	return PH_ERR_DATAERR;
}


/*
** ph_siteinfo_iterate() - iterate through siteinfo list.
** returns:
**	1				data returned
**	0				no more data
**	-1				error (sets errno)
*/
int
ph_siteinfo_iterate(PH *ph, struct ph_siteinfo **siteinfo)
{
	if (!ph_is_siteinfo_cached(ph) && ph_retrieve_siteinfo(ph) == -1)
		return -1;

	/* first entry */
	if (*siteinfo == NULL)
	{
		*siteinfo = &(ph->ph_siteinfo[0]);
		return 1;
	}

	/* next entry */
	(*siteinfo)++;
	if ((*siteinfo)->ps_info != NULL)
		return 1;

	/* last entry */
	*siteinfo = NULL;
	return 0;
}


/*
** ph_free_siteinfo() - free the siteinfo list associated with ph.
*/
void
ph_free_siteinfo(PH *ph)
{
	if (ph->ph_siteinfo != NULL)
		ph_free_siteinfo_list(ph->ph_siteinfo);
	ph->ph_siteinfo = NULL;
}




syntax highlighted by Code2HTML, v. 0.9.1