rob@mtdiablo.Concord.CA.US (Rob Bernardo) (04/04/91)
I have updated rebatch to deal (only) with compressed news batches that end in .Z, as found with cnews of patchdate 24-Mar-1991. The wrapper shell script included in in this version of rebatch is **not** compatible with earlier versions of cnews that do not suffix compressed news batches with .Z. The C program dorebatch has been improved. It should work with the older rebatch wrapper shell script, but I have not tested them together. From the README file: This program will reform news batches that suffer from relaynews 'unbatcher out of sync' problems. It presumes that any line beginning with #! rnews is the beginning of a new article and reforms the news batches by parsing them into separate articles and recalculating the article character counts. This program consists of a C program dorebatch and a wrapper shell script. ---- Cut Here and unpack ---- #!/bin/sh # shar: Shell Archiver (v1.22) # Packed Wed Apr 3 18:59:08 PST 1991 by mtdiablo!rob # from directory /tmp/rebatch # # Run the following text with /bin/sh to create: # Makefile # README # dorebatch.c # rebatch # if test -f Makefile; then echo "File Makefile exists"; else echo "x - extracting Makefile (Text)" sed 's/^X//' << 'SHAR_EOF' > Makefile && XNEWSOWNER=bin XNEWSGRP=bin XMODE=755 XNEWSLIB=/usr/local/lib X Xall: dorebatch X Xinstall: dorebatch X install -g ${NEWSGRP} -o ${NEWSOWNER} -m ${MODE} rebatch ${NEWSLIB}/newsbin/batch X install -g ${NEWSGRP} -o ${NEWSOWNER} -m ${MODE} dorebatch ${NEWSLIB}/newsbin/batch SHAR_EOF chmod 0644 Makefile || echo "restore of Makefile fails" set `wc -c Makefile`;Sum=$1 if test "$Sum" != "262" then echo original size 262, current size $Sum;fi fi if test -f README; then echo "File README exists"; else echo "x - extracting README (Text)" sed 's/^X//' << 'SHAR_EOF' > README && X@(#)README 1.2 Delta Date 4/3/91 Mt. Diablo Software Solutions X XThis version of rebatch is compatible with cnews with a last patchdate of X24-Mar-1991. X XThis program will reform news batches that suffer from relaynews 'unbatcher Xout of sync' problems. It presumes that any line beginning with X #! rnews Xis the beginning of a new article and reforms the news batches by parsing Xthem into separate articles and recalculating the article character counts. X XThis program consists of a C program dorebatch and a wrapper shell Xscript. The command line syntax for dorebatch is X X dorebatch [-v] -i input_file -o output_file X Xwhere -v enables slightly verbose messages, and where input_file and Xoutput_file are the old and reformed *uncompressed* news archive files, Xrespectively. X XThe shell wrapper rebatch (used with no arguments), will run dorebatch Xon all *compressed* .Z files in the cnews in.coming/bad directory and Xwill create a reformed *compressed* news archive of the same name in Xin.coming/, where cnews newsrun can reprocess them again. If successful Xin reforming the batch, rebatch will remove the old .Z file in in.coming/bad. X XYou may need to tailor rebatch for you particular cnews configuration. X XA trivial makefile is supplied to compile and install dorebatch and rebatch, Xhowever it uses the SUN O/S flavor of install(1), which you may need to Xrework for you flavor of UNIX. SHAR_EOF chmod 0444 README || echo "restore of README fails" set `wc -c README`;Sum=$1 if test "$Sum" != "1388" then echo original size 1388, current size $Sum;fi fi if test -f dorebatch.c; then echo "File dorebatch.c exists"; else echo "x - extracting dorebatch.c (Text)" sed 's/^X//' << 'SHAR_EOF' > dorebatch.c && X#ifndef lint Xstatic char sccsid[] = "@(#)dorebatch.c 1.2 Delta Date 4/3/91 Mt. Diablo Software Solutions"; X#endif X X#define ZCAT "zcat" X#define RNEWSSTRING "#! rnews" X X#include <stdio.h> X Xint verbose; Xextern int errno; Xextern int sys_nerr; Xextern char *sys_errlist[]; X X#define ERRNO_MSG (errno < sys_nerr ? sys_errlist[errno] : "unknown errno") X Xmain(argc, argv) Xint argc; Xchar **argv; X{ X char dataline[BUFSIZ]; X char *infile = NULL, *outfile = NULL; X FILE *infp, *outfp; X long artbegin, artend, nextartbegin; X int eofreached, optret, rnewslen, charcnt, artcnt, argerr; X extern int optind; X extern char *optarg; X X /* Process command line */ X argerr = 0; X while ((optret = getopt(argc, argv, "vi:o:")) != -1) { X switch (optret) { X case 'v': X verbose = 1; X break; X case 'i': X infile = optarg; X break; X X case 'o': X outfile = optarg; X break; X X default: X argerr++; X } X } X X if(!infile || !outfile || argerr) { X fprintf(stderr, "%s: usage: %s -i [infile] -o [outfile]\n", X argv[0], argv[0]); X exit(-1); X } X X /* Open input file */ X if((infp = fopen(infile, "r")) == NULL) { X fprintf(stderr, "%s: fopen(%s, \"r\") failed\n", argv[0], infile); X exit(errno?errno:-1); X } X X /* Open output file */ X if((outfp = fopen(outfile, "w+")) == NULL) { X fprintf(stderr, "%s: fopen(%s, \"w+\") failed\n", argv[0], outfile); X fclose(infp); X exit(errno?errno:-1); X } X X /* Verify first line is rnews */ X if(fgets(dataline, BUFSIZ, infp) == NULL) { X fprintf(stderr, "%s: premature end of file %s\n", argv[0], infile); X fclose(infp); X exit(errno?errno:-1); X } X rnewslen = strlen(RNEWSSTRING); X if(strncmp(dataline, RNEWSSTRING, rnewslen)) { X fprintf(stderr, "%s: file %s not a news archive\n", X argv[0], infile); X fclose(infp); X exit(errno?errno:-1); X } X artbegin = artend = ftell(infp); X eofreached = 0; X artcnt = 0; X X if(verbose) X printf("input = %s output = %s\n", infile, outfile); X X /* Process each article in batch */ X while(!eofreached) { X X /* Read a line from input. If oef or end of article, X * capture begin point of next article, X * calculate article size from end and begin points X * of current article, X * write rnews line with size on output file, X * rewind to begin point of current article, X * copy article to output file and quite loop, X * and advance to new article begin point. X * Otherwise store current point as provisional X * end point of current article. X */ X while (1) { X if(fgets(dataline, BUFSIZ, infp) == NULL) X eofreached = 1; X X if(eofreached||(!strncmp(dataline, RNEWSSTRING, rnewslen))) { X X nextartbegin = ftell(infp); X charcnt = artend - artbegin; X fprintf(outfp, "%s %d\n", RNEWSSTRING, charcnt); X if(verbose) X printf("article %d charcnt %d\n", artcnt, charcnt); X if(fseek(infp, artbegin, 0) == -1) { X fprintf(stderr, "%s: fseek back to article beginning failed\n", argv[0]); X fclose(infp); X fclose(outfp); X exit(errno?errno:-1); X } X while(ftell(infp) < artend) { X if(fgets(dataline, BUFSIZ, infp) == NULL) { X fprintf(stderr, "%s: fgets from %s failed\n", X argv[0], infile); X fclose(infp); X fclose(outfp); X exit(errno?errno:-1); X } X if(fputs(dataline, outfp) == EOF) { X fprintf(stderr, "%s: fputs to %s failed\n", X argv[0], outfile); X fclose(infp); X fclose(outfp); X exit(errno?errno:-1); X } X } X artcnt++; X artbegin = artend = nextartbegin; X if(fseek(infp, artbegin, 0) == -1) { X fprintf(stderr, "%s: fseek back to article beginning failed\n", argv[0]); X fclose(infp); X fclose(outfp); X exit(errno?errno:-1); X } X break; X X } else X artend = ftell(infp); X } X } X X fclose(infp); X fclose(outfp); X exit(0); X} SHAR_EOF chmod 0444 dorebatch.c || echo "restore of dorebatch.c fails" set `wc -c dorebatch.c`;Sum=$1 if test "$Sum" != "3821" then echo original size 3821, current size $Sum;fi fi if test -f rebatch; then echo "File rebatch exists"; else echo "x - extracting rebatch (Text)" sed 's/^X//' << 'SHAR_EOF' > rebatch && X#! /bin/sh X# @(#)rebatch 1.3 Delta Date 4/3/91 Mt. Diablo Software Solutions X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/local/lib/news/bin/config} Xumask $NEWSUMASK X XPATH=$NEWSCTL/bin:$NEWSBIN/batch:$NEWSBIN:$NEWSPATH ; export PATH XTMP=/tmp/rebatch$$ Xfor file in ${NEWSARTS}/in.coming/bad/*.Z Xdo X barename=`basename $file` X newbatch=`echo "${NEWSARTS}/in.coming/$barename" | sed -e 's/.Z$//'` X echo "rebatching $barename" X zcat $file > $TMP && dorebatch -i $TMP -o $newbatch && compress $newbatch && rm $file X rm -f $TMP Xdone SHAR_EOF chmod 0444 rebatch || echo "restore of rebatch fails" set `wc -c rebatch`;Sum=$1 if test "$Sum" != "561" then echo original size 561, current size $Sum;fi fi exit 0 -- Rob Bernardo Mt. Diablo Software Solutions email: rob@mtdiablo.Concord.CA.US phone: (415) 827-4301