home *** CD-ROM | disk | FTP | other *** search
- /*#define PROCDEBUG*/
- /*
- ** BATCHNEWS.C
- **
- ** BATCHNEWS [-h hostname] [-t temp-directory]
- **
- ** (C)Copyright 1990, Mark R. Rinfret, All Rights Reserved
- **
- ** Author: Mark R. Rinfret, September 1990
- ** library compress routines melded in Apr 1991, Matt Dillon
- ** Modified May 1991 by Henning Schmiedehausen
- ** Changes Copyright 1993 by Michael B. Smith. All Rights Reserved.
- **
- ** The batchnews program allows you to forward news to other sites.
- ** It expects to find a text file named UUSpool:batch/<system>
- ** where <system> is the name of the system to receive the news.
- **
- ** The file UULib:sys is the configuration file which determines the
- ** newsgroups that are to be forwarded to <system>.
- **
- ** Options
- **
- ** -h Normally, BatchNews batches news for all hosts. The -h
- ** argument allows a single host to be specified.
- **
- ** -t The -t argument allows the user to specify where temporary
- ** spool-files are to be built. Normally, these are in UUNews.
- ** Specifying T: can speed up processing significantly, at a
- ** cost in higher memory usage.
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <ctype.h>
- #include <log.h>
- #include <exec/types.h>
- #include <dos/dos.h>
- #include <clib/dos_protos.h>
- #include <owndevunit.h>
-
- #include "version.h"
- #include "config.h"
-
- IDENT (".10");
-
- static char
- TmpBuf [2048],
- TmpBuf2 [256];
- char
- *TmpDir = NULL,
- *SingleHost = NULL,
- *NewsDir = NULL,
- *WKName = NULL;
- struct Library
- *OwnDevUnitBase = NULL;
- int
- _bufsiz = 8192,
- SpoolSize;
- short
- Bits = 12;
-
- #define PROG_NAME "BatchNews"
-
- #ifdef PROCDEBUG
- #define PROC(x) const char *_proc = x; printf ("%s: enter\n", _proc)
- #define D(x) printf ("%s: ", _proc); printf x
- #else
- #define PROC(x)
- #define D(x)
- #endif
-
- void myexit (void);
- void BatchNews (const char *dirName, const char *systemName);
- void SpoolBatch (const char *systemName);
-
- void
- usage (const char *name)
- {
- fprintf (stderr, "usage: %s [-t temp-directory] [-h hostname]\n", name);
-
- exit (30);
- }
-
- int
- main (int ac, char **av)
- {
- int
- j;
- char
- *ptr,
- *batchDirName;
- struct FileInfoBlock
- *fib = malloc (sizeof (struct FileInfoBlock));
- BPTR
- lock;
- PROC ("main");
-
- LogProgram = PROG_NAME;
- atexit (myexit);
- if ((OwnDevUnitBase = OpenLibrary (ODU_NAME, 0)) == NULL) {
- fprintf (stderr, "Couldn't open library '%s'\n", ODU_NAME);
- exit (20);
- }
-
- if (!fib) {
- ulog (-1, "No mem!");
- exit (30);
- }
-
- for (j = 1; j < ac; j++) {
- ptr = av [j];
- if (*ptr != '-')
- usage (av [0]);
- ptr++;
- switch (*ptr) {
- case 'h':
- ptr++;
- if (*ptr)
- SingleHost = ptr;
- else
- SingleHost = av [++j];
- D (("SingleHost is '%s'\n", SingleHost));
- break;
-
- case 't':
- ptr++;
- if (*ptr)
- TmpDir = ptr;
- else
- TmpDir = av [++j];
- D (("TmpDir is '%s'\n", TmpDir));
- break;
-
- default:
- usage (av [0]);
- }
- }
-
- LockFile ("BATCHNEWS");
-
- NewsDir = GetConfigDir (UUNEWS);
- Bits = (short) atoi (GetConfig (BATCHBITS, "12"));
- SpoolSize = atoi (GetConfig (SPOOLSIZE, "65000"));
-
- if (Bits < 12 || Bits > 16)
- Bits = 12;
-
- if (SpoolSize <= 100)
- SpoolSize = 16000;
-
- if (safe_chdir (NewsDir)) {
- ulog (-1, "BatchNews: NewsDir '%s' doesn't exist; quitting", NewsDir);
- exit (20);
- }
-
- ptr = TmpFileName ("news-work");
- if (TmpDir) {
- int
- i = strlen (TmpDir);
- char
- *p = TmpDir + (i - 1);
-
- WKName = malloc (strlen (ptr) + i + 3);
- if (!WKName) {
- ulog (-1, "No mem!");
- exit (30);
- }
-
- sprintf (WKName, "%s%s%s",
- TmpDir,
- (*p == ':' || *p == '/') ? "" : "/",
- ptr);
- }
- else {
- WKName = strdup (ptr);
- if (!WKName) {
- ulog (-1, "No mem!");
- exit (30);
- }
- }
-
- batchDirName = strdup (MakeConfigPath (UUSPOOL, "batch"));
- if (!batchDirName) {
- ulog (-1, "No mem!");
- exit (30);
- }
- lock = Lock (batchDirName, SHARED_LOCK);
- if (!lock) {
- ulog (-1,"Where is batch directory '%s'?", batchDirName);
- exit (20);
- }
-
- if (SingleHost) {
- if (is_in_L_sys_file (SingleHost))
- BatchNews (batchDirName, SingleHost);
- else
- ulog (-1, "Invalid host name '%s'", SingleHost);
- }
- else {
- if (Examine (lock, fib)) {
- while (ExNext (lock, fib)) {
- if (fib->fib_DirEntryType > 0)
- continue;
- D (("scan: '%s'\n", fib->fib_FileName));
-
- if (is_in_L_sys_file (fib->fib_FileName)) {
- BatchNews (batchDirName, fib->fib_FileName);
- }
- }
- }
- }
- UnLock (lock);
-
- D (("exit\n"));
- exit (0);
- }
-
- void
- myexit (void)
- {
- PROC ("myexit");
-
- UnLockFiles ();
-
- if (OwnDevUnitBase) {
- CloseLibrary (OwnDevUnitBase);
- OwnDevUnitBase = NULL;
- }
-
- D (("exit\n"));
- return;
- }
-
- void
- BatchNews (const char *dirName, const char *systemName)
- {
- static char
- batchFileName [128];
- struct FileInfoBlock
- *fib = malloc (sizeof (struct FileInfoBlock));
- char
- *newsFileName = NULL,
- *nodename = FindConfig (NODENAME),
- *domainname = FindConfig (DOMAINNAME),
- *domainpath = GetConfig (DOMAINPATH, "N");
- FILE
- *newsFile = NULL,
- *workFile = NULL,
- *batchFile = NULL;
- BPTR
- lock = 0;
- int
- fileSize,
- length,
- ret = 0,
- totalSize,
- workPos;
-
- PROC ("BatchNews");
- D (("system '%s'\n", systemName));
-
- if (!fib) {
- ulog (-1, "No mem!");
- return;
- }
-
- if (domainpath [0] == '1' ||
- domainpath [0] == 'y' ||
- domainpath [0] == 'Y') {
- domainpath = domainname;
- }
- else {
- domainpath = "";
- }
-
- strcpy (batchFileName, dirName);
- strcat (batchFileName, "/");
- strcat (batchFileName, systemName);
- batchFile = fopen (batchFileName, "r");
- if (!batchFile) {
- if (SingleHost)
- ulog (-1, "No news to batch for '%s'", SingleHost);
- D (("leaving, can't open '%s'\n", batchFileName));
- goto done; /* Try later? */
- }
-
- workFile = fopen (WKName, "w");
- if (!workFile) {
- no_workfile:
- ret = errno;
- ulog (-1, "Failed to open work file '%s'\n", WKName);
- D (("leaving, Can't open '%s'\n", WKName));
- goto done;
- }
-
- totalSize = 0;
-
- while (fgets (TmpBuf, sizeof (TmpBuf), batchFile)) {
- D (("file %s", TmpBuf));
-
- if (*TmpBuf == '\0' || *TmpBuf == '\n')
- continue;
-
- length = strlen (TmpBuf);
-
- if (TmpBuf [length - 1] == '\n')
- TmpBuf [--length] = '\0'; /* Drop trailing newline. */
-
- if (newsFileName = HandleHeirarchy (NewsDir, TmpBuf, 1)) {
- strcpy (TmpBuf, newsFileName);
- D (("%s\n", TmpBuf));
- free (newsFileName);
-
- fileSize = -1;
- if (lock = Lock (TmpBuf, SHARED_LOCK)) {
- if (Examine (lock, fib))
- fileSize = fib->fib_Size;
- UnLock (lock);
- }
-
- if (fileSize < 0) {
- ulog (-1, "Article '%s' is missing (IoErr %ld)", TmpBuf, IoErr ());
- D (("Bad art name? '%s'\n", TmpBuf));
- continue;
- }
-
- if (fileSize + totalSize + 64 > SpoolSize) {
- fclose (workFile);
- SpoolBatch (systemName);
- totalSize = 0;
- workFile = fopen (WKName, "w"); /* Re-open the work file. */
- if (!workFile)
- goto no_workfile;
- }
- newsFile = fopen (TmpBuf, "r");
- }
-
- /*
- * newsFileName is invalid after this except for boolean checks
- */
-
- if (newsFileName == NULL || newsFile == NULL)
- continue;
-
- /*
- * Handle news file. Delete Xref: lines, modify Path: lines,
- * copy rest. Filesize is modified at seekback.
- */
-
- workPos = ftell (workFile);
- fprintf (workFile, "#! rnews %06ld\n", 0); /* rewritten later */
- fileSize = 0;
-
- while (fgets (TmpBuf, sizeof (TmpBuf) - 16, newsFile)) {
- if (strnicmp (TmpBuf, "Xref:", 5) == 0)
- continue;
- if (strnicmp (TmpBuf, "Path:", 5) == 0) {
- char
- *ptr = TmpBuf + 5;
-
- while (*ptr == ' ' || *ptr == '\t')
- ++ptr;
- strins (ptr, "!");
- strins (ptr, domainpath);
- strins (ptr, nodename);
- D (("new Path %s\n", TmpBuf));
- }
- fputs (TmpBuf, workFile);
- fileSize += strlen (TmpBuf);
- if (TmpBuf [0] == '\n')
- break;
- }
-
- while (fgets (TmpBuf, sizeof (TmpBuf) - 16, newsFile)) {
- fputs (TmpBuf, workFile);
- fileSize += strlen (TmpBuf);
- }
-
- fclose (newsFile);
- totalSize += fileSize;
- fseek (workFile, workPos, 0);
- fprintf (workFile,"#! rnews %06ld\n", fileSize);
- fseek (workFile, 0, 2);
- }
-
- done:
- if (workFile) {
- fclose (workFile);
- if (ret == 0 && totalSize)
- SpoolBatch (systemName);
- }
- if (batchFile) {
- fclose (batchFile);
- remove (batchFileName);
- }
- free (fib);
- remove (WKName);
-
- D (("exit\n"));
- return;
- }
-
- void
- SpoolBatch (const char *systemName)
- {
- FILE
- *fo;
- int
- r = -1;
-
- PROC ("SpoolBatch");
- D (("compressing file '%s' bits = %ld\n", WKName, (int) Bits));
-
- sprintf (TmpBuf2, "%s.Z", WKName);
- if (fo = fopen (TmpBuf2, "w")) {
- fputs ("#! cunbatch\n", fo);
- fflush (fo);
- r = compress_from_file (WKName, fo, Bits);
- fclose (fo);
- }
-
- if (r == 0) {
- remove (WKName);
- rename (TmpBuf2, WKName);
-
- }
- else {
- remove (TmpBuf2);
- ulog (-1, "compress failed, low memory or uncompressable file");
- ulog (-1, "will proceed with an uncompressed batch");
- }
-
- /* Submit it to uux for transmission to target system. */
- sprintf (TmpBuf2, "%s %s \"%s!rnews\"",
- GetConfigProgram (UUX),
- WKName,
- systemName
- );
-
- D (("command '%s'\n", TmpBuf2));
- system (TmpBuf2);
-
- D (("exit\n"));
- return;
- }
-