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 +-+-+-+-+-