/*
* 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