/*
 *  Project   : NNTP (RFC 977) extension
 *  Module    : xindex.c
 *  Author    : I.Lea
 *  Created   : 07-03-92
 *  Updated   : 18-11-92
 *  Notes     : Add a command to retieve tin style index files 
 *              from the NNTP server so as to save space on the
 *              client.
 *              Ideas borrowed from XTHREAD nntp extension code
 *              posted by Tim Iverson to alt.sources in mid'91.
 *  Copyright : (c) Copyright 1992 by Iain Lea
 *              You may  freely  copy or  redistribute  this software,
 *              so  long as there is no profit made from its use, sale
 *              trade or  reproduction.  You may not change this copy-
 *              right notice, and it must be included in any copy made
 */

#include "common.h"
#ifndef lint
static char sccsid[] = "$Id: xindex.c,v 1.3 1994/11/01 07:24:58 sob Exp sob $";
#endif
#ifdef XINDEX

#undef	DEBUG_XINDEX		/* set to define to turn on more debug info */
#define HASH_VALUE 1409		/* mod value for hashing group name */

#ifndef MAXPATHLEN
#	define MAXPATHLEN 256
#endif

#ifdef __STDC__
void xindex (int argc, char *argv[]);
static void find_index_file (char *group, char *index_file);
static long hash_groupname (char *group);
#else
void xindex ();
static void find_index_file ();
static long hash_groupname ();
#endif

/*
 *  Usage: XINDEX groupname
 *
 *  Retrieve an index file for the specified newsgroup (ie. alt.sources)
 *
 *  This command is NOT documented in RFC977.
 */

void xindex (argc, argv)
	int	argc;
	char	*argv[];
{
	char	line[NNTP_STRLEN];
	char	group[MAXPATHLEN];
	char	index_file[MAXPATHLEN];
	char	*cp;
	FILE	*fp;
	
	/*
	 * "parse" the argument list
	 */
	if (argc == 1) {
		printf("%d Usage: XINDEX group\r\n", ERR_CMDSYN);
		(void) fflush(stdout);
		return;
	} else {
		strncpy (group, argv[1], sizeof (group)-1);
#if defined(SYSLOG) && defined(DEBUG_XINDEX)
		syslog(LOG_INFO, "%s xindex %s", hostname, group);
#endif

		find_index_file(group, index_file);
		
		if ((fp = fopen(index_file, "r")) == NULL) {
#ifdef SYSLOG
			syslog(LOG_INFO, "%s xindex cannot open %s (%s)",
				hostname, group, index_file);
#endif
			printf("%d XINDEX Cannot open %s\r\n",
				ERR_XINDEX, group);
			(void) fflush(stdout);
			return;
		}

		printf("%d XINDEX %s index file follows\r\n", 
			OK_XINDEX, group);
		(void) fflush(stdout);
		
		while (fgets(line, sizeof(line), fp) != NULL) {
			if ((cp = index(line, '\n')) != NULL)
				*cp = '\0';
			putline(line);
		}
		(void) fclose(fp);
	
		putline(".");
		(void) fflush(stdout);
	}
}

/*
 *  Look in XINDEX_DIR dir (defined in conf.h) for the index file 
 *  for the given group. Hashing the group name gets a number. 
 *  See if that #.1 file exists; if so, read first line. Is it the
 *  Group we want? If not try #.2. Repeat until no such file or we 
 *  find the right file.
 */

static void find_index_file (group, index_file)
	char *group;
	char *index_file;
{
	char buf[MAXPATHLEN], *p;
	FILE *fp;
	int i = 1;
	unsigned long hash;
	struct stat sb;
	
	hash = hash_groupname (group);

	while (1) {
		sprintf (index_file, "%s/%lu.%d", XINDEX_DIR, hash, i);
		
		if ((fp = fopen (index_file, "r")) == NULL) {
			return;
		}

		if (fgets (buf, sizeof (buf), fp) == NULL) {
			fclose (fp);
			return;
		}
		fclose (fp);

		for (p = buf; *p && *p != '\n'; p++) {
			continue;
		}	
		*p = '\0';

		if (strcmp (buf, group) == 0) {
			return;
		}	
		i++;
	}	
}

/*
 * hash group name for filename of group
 */

static long hash_groupname (group)
	char *group;
{
	unsigned long hash_value;
	unsigned char *ptr = (unsigned char *) group;

	hash_value = *ptr++;

	while (*ptr)
		hash_value = ((hash_value << 1) ^ *ptr++) % HASH_VALUE;

	return (hash_value);
}

#endif /* XINDEX */



syntax highlighted by Code2HTML, v. 0.9.1