[news.software.anu-news] sending old articles to new client - BATCHNEWS 1/2

mark@infopiz.uucp (02/19/90)

In message <900216150419.03a@Janus.MtRoyal.AB.CA> posted to 
news.software.anu-news, rmf@JANUS.MTROYAL.AB.CA (Russ Forster) asks:
> 
>         I have a new client that I've just started serving.  One of
>         the things he wants are all the old articles already in the
>         database.  How do I tell news to send him the articles?
>      
>         /Russ
>      
>         ps.  its not the whole database, just a few groups within
>              the database.

What follows in this and the next VMS_SHARE format postings seems to be
just what the man wants. . . 

-- 
Mark Pizzolato - INFO COMM Computer Consulting, Redwood City, Ca
PHONE:	(415)369-9366	
UUCP:	mark@infopiz.UUCP or uunet!lupine!infopiz!mark

$! ...................... Cut between dotted lines and save. .....................
$!.............................................................................
$! VAX/VMS archive file created by VMS_SHARE V06.03 20-Oct-1988.
$!
$! VMS_SHARE was written by James Gray (Gray:OSBUSouth@Xerox.COM) from
$! VMS_SHAR by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au).
$!
$! To unpack, simply save, concatinate all parts into one file and
$! execute (@) that file.
$!
$! This archive was created by user SYSTEM
$! on 18-FEB-1990 17:07:40.57.
$!
$! ATTENTION: To keep each article below 31 blocks (15872 bytes), this
$!            program has been transmitted in 2 parts.  You should
$!            concatenate ALL parts to ONE file and execute (@) that file.
$!
$! It contains the following 3 files:
$!        MAKEBATCHNEWS.COM
$!        BATCHNEWS.C
$!        ARGPROC.C
$!
$!==============================================================================
$ SET SYMBOL/SCOPE=( NOLOCAL, NOGLOBAL )
$ VERSION = F$GETSYI( "VERSION" )
$ IF VERSION .GES "V4.4" THEN GOTO VERSION_OK
$ WRITE SYS$OUTPUT "You are running VMS ''VERSION'; ", -
    "VMS_SHARE V06.03 20-Oct-1988 requires VMS V4.4 or higher."
$ EXIT 44 
$VERSION_OK:
$ GOTO START
$
$UNPACK_FILE:
$ WRITE SYS$OUTPUT "Creating ''FILE_IS'"
$ DEFINE/USER_MODE SYS$OUTPUT NL:
$ EDIT/TPU/COMMAND=SYS$INPUT/NODISPLAY/OUTPUT='FILE_IS'/NOSECTION -
    VMS_SHARE_DUMMY.DUMMY

b_part := CREATE_BUFFER( "{Part}", GET_INFO( COMMAND_LINE, "file_name" ) );
s_file_spec := GET_INFO( COMMAND_LINE, "output_file" );SET( OUTPUT_FILE, b_part
, s_file_spec ); 
b_errors := CREATE_BUFFER( "{Errors}" );i_errors := 0; 
pat_beg_1 := ANCHOR & "-+-+-+ Beginning";
pat_beg_2 := LINE_BEGIN & "+-+-+-+ Beginning";
pat_end := ANCHOR & "+-+-+-+-+ End";
pat_trail := " " & LINE_END;POSITION( BEGINNING_OF( b_part ) ); LOOP b 
:= SEARCH( pat_trail, FORWARD); EXITIF b=0; POSITION( END_OF( b ) )
; LOOP MOVE_HORIZONTAL( -1 ); EXITIF CURRENT_CHARACTER <> ' '; ERASE_CHARACTER
( 1 ); EXITIF CURRENT_OFFSET=0; ENDLOOP; ENDLOOP; POSITION( BEGINNING_OF
( b_part ) ); i_append_line := 0; LOOP EXITIF MARK( NONE ) = END_OF( b_part )
; s_x := ERASE_CHARACTER( 1 ); 
  IF s_x = "+" THEN r_skip := SEARCH( pat_beg_1, FORWARD, EXACT ); IF r_skip <
> 0 THEN 
      s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); ERASE_LINE; ENDIF; ENDIF; 
  IF s_x = "-" THEN r_skip := SEARCH( pat_end, FORWARD, EXACT ); IF r_skip <
> 0 THEN 
      s_x := ""; MOVE_HORIZONTAL( -CURRENT_OFFSET ); m_skip := MARK( NONE )
; r_skip := SEARCH( pat_beg_2, FORWARD, EXACT ); IF r_skip <> 0 THEN POSITION
( END_OF( r_skip ) ); MOVE_HORIZONTAL( -CURRENT_OFFSET ); MOVE_VERTICAL( 1 )
; MOVE_HORIZONTAL( -1 ); ELSE POSITION( END_OF( b_part ) ); ENDIF; ERASE
( CREATE_RANGE( m_skip, MARK( NONE ), NONE ) ); ENDIF; ENDIF; 
  IF s_x = "V" THEN 
    s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL
( -CURRENT_OFFSET ); ENDIF; i_append_line := 1; MOVE_VERTICAL( 1 ); ENDIF; 
  IF s_x = "X" THEN 
    s_x := ""; IF i_append_line <> 0 THEN APPEND_LINE; MOVE_HORIZONTAL
( -CURRENT_OFFSET ); ENDIF; i_append_line := 0; MOVE_VERTICAL( 1 ); ENDIF; 
  IF s_x <> "" THEN i_errors := i_errors + 1; s_text := CURRENT_LINE; POSITION
( b_errors ); 
    COPY_TEXT( "The following line could not be unpacked properly:" )
; SPLIT_LINE; COPY_TEXT( s_x ); COPY_TEXT( s_text ); POSITION( b_part )
; MOVE_VERTICAL( 1 ); ENDIF; ENDLOOP; POSITION( BEGINNING_OF( b_part ) ); LOOP 
  r_x := SEARCH( "`", FORWARD, EXACT ); EXITIF r_x = 0; POSITION( r_x )
; ERASE_CHARACTER( 1 ); 
  IF CURRENT_CHARACTER = "`" THEN MOVE_HORIZONTAL( 1 ); ELSE COPY_TEXT( ASCII
( INT( ERASE_CHARACTER( 3 ) ) ) ); ENDIF; ENDLOOP; IF i_errors = 0 THEN SET
( NO_WRITE, b_errors, ON ); ELSE POSITION( BEGINNING_OF( b_errors ) ); 
  COPY_TEXT( FAO( "The following !UL errors were detected while unpacking !AS"
, i_errors, s_file_spec ) ); SPLIT_LINE; 
  SET( OUTPUT_FILE, b_errors, "SYS$COMMAND" );ENDIF; EXIT; 
$ DELETE VMS_SHARE_DUMMY.DUMMY;*
$ CHECKSUM 'FILE_IS
$ WRITE SYS$OUTPUT " CHECKSUM ", -
  F$ELEMENT( CHECKSUM_IS .EQ. CHECKSUM$CHECKSUM, ",", "failed!,passed." )
$ RETURN
$
$START:
$ FILE_IS = "MAKEBATCHNEWS.COM"
$ CHECKSUM_IS = 102705437
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X$ cc batchnews
X$ cc argproc
X$ link batchnews,argproc,sys$input:/opt
Xsys$share:vaxcrtl/share
$ GOSUB UNPACK_FILE
$ FILE_IS = "BATCHNEWS.C"
$ CHECKSUM_IS = 1732696845
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*
X *****************************************************************************
X *                                                                           *
X *  Copyright (C) 1989 by                                                    *
X *  Mark Pizzolato - INFO COMM, Redwood City, California  (415) 369-9366     *
X *                                                                           *
X *  Permission is hereby  granted for the reproduction of this software,     *
X *  on condition that this copyright notice is included in the reproduction, *
X *  and that such reproduction is not for purposes of profit or material     *
X *  gain.                                                                    *
X *                                                                           *
X *****************************************************************************
X */
X
X/* batchnews command
X
XNAME
X     batchnews - collect a set of news item files and "batch" them together.
X
XSYNOPSIS
X     batchnews [-b batchname] [-s size] [-d] [-v] files ...
X
XDESCRIPTION
X     batchnews is a utility useful to collect a potentially large set of
X     news item files into an "rnews" format news batch.  Suggested uses
X     include getting things started initially for new neighbor sites
X     or simple archival purposes.
X
XOPTIONS
X     Options specifed in standard "getopt" form, so they are '-' prefixed
X     letters, with the option byte following followed by optional whitespace
X     and then the option argument (if appropriate).
X
X     -b batchname
X          Specifies the name template of the output batch file.
X`009  If multiple sub batch files are created, the resulting files
X`009  are actually of the form 'batchname'nnn, where nnn is the
X`009  subfile number.  Note: The default batch is written to
X`009  standard output, and if so only a single output file
X`009  (not limited in size) will be produced.
X
X     -s size
X          Specifies that the size limit (in bytes) for sub batches is 'size'.
X`009  The default maximim batch size is essentially unlimited
X`009  (i.e. 0x7fffffff).  Note: The size limit specified is
X`009  checked AFTER each item is added to the output batch, so
X`009  sub batches will actually exceed 'size' bytes.
X
X     -v   Turns on 'verbose' mode and causes each item file batched
X`009  to be logged to standard error.
X
XBUGS
X     Wildcard expansion of file name arguments in a Unix environment is usually
X     done by the shell, and if attempts to batch large numbers of files is done
X     with shell wildcard expansion, the shell's command buffer is likely to
X     be exceeded.  No attempt is made by this program to internally expand
X     quoted wildcard file names.  NOTE: Wildcard expansion is done in VMS by
X     the routine "getredirection", so no such limitations exist.
X
X*/
X`012
X#include <stdio.h>`009`009/* Standarg I/O Definitions`009*/
X#include <stat.h>`009`009/* Stat Structure Definition`009*/
X
X#define BUFBLOCKS`009126`009/* Disk Blocks Per I/O Buffer`009*/
X
X#ifdef VMS
X#define NULL_DEVICE "_NLA0:"
X#else
X#define NULL_DEVICE "/dev/null"
X#endif
X
Xstruct buffer
X    `123
X    struct buffer *next;
X    int size;
X    char data[512*BUFBLOCKS];
X    `125;
X
Xint verbose = 0;`009`009/* Verbose mode - show whats up`009`009*/
Xint max_size = 0x7fffffff;`009/* Maximum Output Batch Size`009`009*/
Xchar *outname = NULL;`009`009/* Output File Name`009`009`009*/
Xint sub_num = 0;`009`009/* Sub-Batch Number for Output file`009*/
Xint cur_size = 0;`009`009/* Size of Current Output`009`009*/
X
Xextern int optind;`009`009/* GETOPT : Option Index`009`009*/
Xextern char *optarg;`009`009/* GETOPT : Option Value`009`009*/
X
Xint read_file(f, buf)
XFILE *f;
Xstruct buffer **buf;
X    `123
X    if ((*buf) == NULL)
X`009*buf = calloc(1, sizeof(**buf));
X    if (0 < ((*buf)->size = fread((*buf)->data, 1, sizeof((*buf)->data), f)))
X`009return((*buf)->size + read_file(f, &(*buf)->next));
X    `125
X
Xwrite_file(f, size, buf)
XFILE **f;
Xint size;
Xstruct buffer *buf;
X    `123
X    if (size == 0)
X`009`123
X`009if (verbose)
X`009    fprintf(stderr, "empty file, skipped\n");
X`009return;
X`009`125
X    cur_size += size;
X    if (verbose)
X`009fprintf(stderr, " -- %d bytes", size);
X    fprintf(*f, "#! rnews %d\n", size);
X    while (size > 0)
X`009`123
X`009fwrite(buf->data, 1, buf->size, *f);
X`009size -= buf->size;
X`009buf = buf->next;
X`009`125
X    if (verbose)
X`009fprintf(stderr, " - Done.\n");
X    if (cur_size >= max_size)
X`009`123
X`009char tmpname[L_tmpnam];
X
X`009sprintf(tmpname, "%s%03d", outname, ++sub_num);
X`009*f = freopen(NULL_DEVICE, "r", *f);
X`009rename(outname, tmpname);
X`009if (NULL == (*f = freopen(outname, "w", *f
X#ifdef VMS
X`009    `009`009`009`009`009  ,"mbc=64", "mbf=2"
X#endif
X`009`009`009`009`009`009`009)))
X`009    `123
X`009    perror(outname);
X`009    exit(0);
X`009    `125
X`009if (verbose)
X`009    fprintf(stderr, "Batch %s complete, %d bytes\n", tmpname, cur_size);
X`009cur_size = 0;
X`009`125
X    `125
X`012
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X    `123
X    FILE *in;
X    struct buffer *buf = NULL;
X    int size;
X    struct stat statb;
X    char c;
X
X#ifdef VMS
X    getredirection(&argc, &argv);
X#endif
X    while((c = getopt(argc, argv, "b:s:v")) != EOF)
X`009`123
X`009switch(c)
X`009    `123
X`009    case 'b': outname = optarg; break;
X`009    case 's': max_size = atoi(optarg); break;
X`009    case 'v': verbose = 1; break;
X `009    default : goto usage;
X`009    `125
X`009`125
X    /*
X     * Adjust ARGC and ARGV to account for args processed above.
X     */
X    argc -= (optind-1);
X    argv += (optind-1);
X    /*
X     * Open the output batch file if specified.
X     */
X    if (outname != NULL)
X`009`123
X`009if (NULL == (stdout = freopen(outname, "a", stdout
X#ifdef VMS
X`009    `009`009`009`009`009  ,"mbc=64", "mbf=2"
X#endif
X`009`009`009`009`009`009`009    )))
X`009    `123
X`009    perror(outname);
X`009    return;
X`009    `125
X`009if (0 != fstat(fileno(stdout), &statb))
X`009    `123
X`009    perror(outname);
X`009    fprintf(stderr, "Cannot Stat\n");
X`009    return;
X`009    `125
X`009cur_size = statb.st_size;
X`009while (1)
X`009    `123
X`009    char tmpname[L_tmpnam];
X
X`009    sprintf(tmpname, "%s%03d", outname, sub_num+1);
X`009    if (-1 == stat(tmpname, &statb))
X`009`009break;
X`009    else
X`009`009++sub_num;
X`009    `125
X`009`125
X    else
X`009max_size = 0x7fffffff;
X
X    if (argc > 1)
X`009while (--argc)
X`009    `123
X`009    ++argv;
X`009    if (NULL == (stdin = freopen(argv[0], "r", stdin
X#ifdef VMS
X`009    `009`009`009`009`009  ,"mbc=64", "mbf=2"
X#endif
X`009    `009`009`009`009`009`009`009)))
X`009`009`123
X`009`009perror(argv[0]);
X`009`009continue;
X`009`009`125
X`009    if (verbose)
X`009`009fprintf(stderr, "%s", argv[0]);
X`009    if (0 != fstat(fileno(stdin), &statb))
X`009`009`123
X`009`009perror(argv[0]);
X`009`009fprintf(stderr, "Cannot Stat\n");
X`009`009continue;
X`009`009`125
X`009    if (0 != (S_IFDIR&statb.st_mode))
X`009`009`123
X`009`009if (verbose)
X`009`009    fprintf(stderr, " - Skipping Directory File\n");
X`009`009continue;
X`009`009`125
X`009    size = read_file(stdin, &buf);
X`009    write_file(&stdout, size, buf);
X`009    `125
X    else
X`009`123
X`009size = read_file(stdin, &buf);
X`009write_file(&stdout, size, buf);
X`009`125
X    return;
X
Xusage:
V    fprintf(stderr, "batchnews usage: batchnews [-b batchname] [-s size] [-v] f
Xiles ...\n");
X    fprintf(stderr, "\t\toption\n");
X    fprintf(stderr, "\t\t\t-b output batch filename (prefix)\n");
X    fprintf(stderr, "\t\t\t-s maximum size of a sub-batch\n");
X    fprintf(stderr, "\t\t\t-v display what is happeningn\n");
X    `125
$ GOSUB UNPACK_FILE
$ FILE_IS = "ARGPROC.C"
$ CHECKSUM_IS = 795198030
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X/*
X * @(#)argproc.c 1.0 89/02/01`009`009Mark Pizzolato (mark@infopiz.uucp)`009
X */
X
X#ifndef lint
Xchar argproc_version[] = "@(#)argproc.c VMS uucp Version infopiz-1.0";
X#endif
X
X#include ctype`009`009`009/* Character Classification Defs*/
X#include descrip`009`009/* VMS Descraiptor Definitions`009*/
X#include dvidef`009`009`009/* VMS Device Volume Info Defs`009*/
X#include errno`009`009`009/* Error Definitions`009`009*/
X#include iodef`009`009`009/* VMS I/O Function Definitions`009*/
X#include stdio`009`009`009/* Standard I/O Definitions`009*/
X#include string`009`009`009/* String Function Definitions`009*/
X
X#define EXIT_OK 1`009`009/* image exit code */
X#define EXIT_ERR 0x10000000`009/* image exit code */
X`012
X/*
X * getredirection() is intended to aid in porting C programs
X * to VMS (Vax-11 C) which does not support '>' and '<'
X * I/O redirection, along with a command line pipe mechanism
X * using the '`124' AND background command execution '&'.
X * The piping mechanism will probably work with almost any 'filter' type
X * of program.  With suitable modification, it may useful for other
X * portability problems as well.
X *
X * Author:  Mark Pizzolato`009mark@infopiz.UUCP
X */
Xstruct list_item
X    `123
X    struct list_item *next;
X    char *value;
X    `125;
X
Xint
Xgetredirection(ac, av)
Xint`009`009*ac;
Xchar`009`009***av;
X/*
X * Process vms redirection arg's.  Exit if any error is seen.
X * If getredirection() processes an argument, it is erased
X * from the vector.  getredirection() returns a new argc and argv value.
X * In the event that a background command is requested (by a trailing "&"),
X * this routine creates a background subprocess, and simply exits the program.
X *
X * Warning: do not try to simplify the code for vms.  The code
X * presupposes that getredirection() is called before any data is
X * read from stdin or written to stdout.
X *
X * Normal usage is as follows:
X *
X *`009main(argc, argv)
X *`009int`009`009argc;
X *    `009char`009`009*argv[];
X *`009`123
X *`009`009getredirection(&argc, &argv);
X *`009`125
X */
X`123
X    int`009`009`009argc = *ac;`009/* Argument Count`009  */
X    char`009`009**argv = *av;`009/* Argument Vector`009  */
X    char`009`009*ap;   `009`009/* Argument pointer`009  */
X    int`009       `009`009j;`009`009/* argv[] index`009`009  */
X    extern int`009`009errno;`009`009/* Last vms i/o error `009  */
X    int`009`009`009item_count = 0;`009/* Count of Items in List */
X    struct list_item `009*list_head = 0;`009/* First Item in List`009    */
X    struct list_item`009*list_tail;`009/* Last Item in List`009    */
X    char `009`009*in = NULL;`009/* Input File Name`009    */
-+-+-+-+-+ End of part 1 +-+-+-+-+-