home *** CD-ROM | disk | FTP | other *** search
- /* 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"
-
- #ifdef XTHREAD
-
- # ifdef __GNUC__
- # define alloca __builtin_alloca
- # endif
-
-
- /* 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"))
- {
- char *cp, *thread_name();
-
- file = thread_name("*******");
- what = "db.init";
- for (cp = file; *cp != '*'; cp++)
- ;
- strcpy(cp, 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];
- #ifndef 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 */
-