/* This file (and only this file - not the entire nntp distribution) is
* hereby placed in the public domain. Use it as you see fit, but if you
* manage to find some wonderful use for this code elsewhere, it would be
* nice to receive mention for it.
*
* - Tim Iverson
* iverson@xstor.com -/- uunet!xstor!iverson
* 3/28/91
* modified by Wayne Davison (davison@borland.com) to work with trn 2.0
* 10/6/91
*/
#include "common.h"
#ifndef lint
static char sccsid[] = "$Id: xthread.c,v 1.2 1994/11/01 06:08:21 sob Exp sob $";
#endif
#ifdef XTHREAD
# ifdef __GNUC__
# define alloca __builtin_alloca
# endif
char *thread_name();
/* Usage: XTHREAD [DBINIT|THREAD]
*
* DBINIT dump the contents of the db.init file to stdout
* THREAD dump the contents of the thread file for the current
* newsgroup to stdout (default if no argument).
*
* N.B. These two files are not ascii and no attempt is made at converting
* native byte size to any type of standard whatsoever. This'll have
* to be fixed if this command is to be integrated into the protocol.
*
* This command is not documented in rfc977.
*/
void
xthread(argc, argv)
int argc;
char *argv[];
{
register FILE *fp;
struct stat s;
char *buf, *file, *what;
/* can't transfer threads, only read 'em */
if (!canread)
{
printf("%d You only have permission to transfer, sorry.\r\n",
ERR_ACCESS);
(void) fflush(stdout);
return;
}
/* "parse" the argument */
if (argc == 2 && !strcasecmp(argv[1], "dbinit"))
{
file = thread_name("*******");
what = "db.init";
strcpy(index(file, '*'), what);
}
else if (argc == 1 || argc == 2 && !strcasecmp(argv[1], "thread"))
{
if (!threadfile)
{
printf("%d You are not currently in a newsgroup.\r\n",
ERR_NCING);
(void) fflush(stdout);
return;
}
file = threadfile;
what = "thread";
}
else
{
printf("%d Usage: XTHREAD [DBINIT|THREAD]\r\n", ERR_CMDSYN);
(void) fflush(stdout);
return;
}
/* try to open the file to be transfered */
if (!(fp = fopen(file, "r")))
{
printf("%d %s file is not available.\r\n", ERR_FAULT, what);
(void) fflush(stdout);
#ifdef SYSLOG
if (!strcmp(what, "db.init"))
syslog(LOG_ERR, "xthread: fopen %s: %m", file);
#endif
return;
}
/* tell 'em how much binary data is coming down the pike */
fstat(fileno(fp), &s);
printf("%d %u bytes of %s file follows verbatim (binary!)\r\n",
OK_BIN, s.st_size, what);
/* copy the file verbatim to stdout */
#ifdef __GNUC__
if (buf = alloca(s.st_size))
{
/* ah-so! got lotsa memoree */
read(fileno(fp), buf, s.st_size);
fwrite(buf, s.st_size, 1, stdout);
}
else
#endif
{
int bytes;
char buf[BUFSIZ];
while (bytes = fread(buf, 1, sizeof buf, fp))
fwrite(buf, bytes, 1, stdout);
}
fputs("\r\n.\r\n", stdout);
fflush(stdout);
fclose(fp);
}
/* Change a newsgroup name into the name of the thread data file. We
** subsitute any '.'s in the group name into '/'s (unless LONG_THREAD_NAMES
** is defined), prepend the path, and append the '/.thread' (or '.th') on to
** the end.
*/
char *
thread_name(group)
char *group;
{
static char name_buff[MAXPATHLEN];
#ifdef LONG_THREAD_NAMES
char group_buff[512];
register char *ptr;
strcpy(group_buff, group);
ptr = group = group_buff;
while ((ptr = index(ptr, '/'))) {
*ptr = '.';
}
#endif
#ifdef SUFFIX
sprintf(name_buff, "%s/%s%s", threaddir, group, SUFFIX);
#else
sprintf(name_buff, "%s/%s", threaddir, group);
#endif
return name_buff;
}
#endif /* not XTHREAD */
syntax highlighted by Code2HTML, v. 0.9.1