rob@mtdiablo.Concord.CA.US (Rob Bernardo) (03/18/91)
I've also had some difficulty lately with 'out of sync' unbatching problems. Unfortunately, Eamonn McManus's patchbatch didn't work. Below is a shell archive for a more robust program to fix batches with bad article character counts. Accompanying it are a makefile and a wrapper shell script, both of which you may need to tailor to your systems. The main significant difference between my and E.M.'s batch fixers is that mine does not presume that the correct article size is close to the article size given in the bad news batch file. Mine goes through the batch finding each article and recalculating it's size from scratch. The syntax of the command line is rebatch [-v] -i input_file -o output_file where the input file is a compressed newsbatch file (e.g. as found in your in.coming/bad directory and where the output file is not compressed. The wrapper shell script will take care of compressing the output file (so that you can just wait till cron next runs input/newsrun). I wrote this real quick this morning, and it worked for me. Please let me know of any problems or suggestions. #!/bin/sh # shar: Shell Archiver (v1.22) # Packed Sun Mar 17 18:30:16 PST 1991 by mtdiablo!rob # from directory /usr/local/src/rebatch # # Run the following text with /bin/sh to create: # Makefile # rebatch # dorebatch.c # 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 rebatch; then echo "File rebatch exists"; else echo "x - extracting rebatch (Text)" sed 's/^X//' << 'SHAR_EOF' > rebatch && X#! /bin/sh X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()= X. ${NEWSCONFIG-/usr/local/lib/news/bin/config} Xumask $NEWSUMASK X XPATH=$NEWSCTL/bin:$NEWSBIN/batch:$NEWSBIN:$NEWSPATH ; export PATH Xfor file in ${NEWSARTS}/in.coming/bad/* Xdo X barename=`basename $file` X newbatch=${NEWSARTS}/in.coming/$barename X echo "rebatching $barename" X dorebatch -i $file -o $newbatch && compress $newbatch && mv $newbatch.Z $newbatch && rm $file Xdone SHAR_EOF chmod 0644 rebatch || echo "restore of rebatch fails" set `wc -c rebatch`;Sum=$1 if test "$Sum" != "437" then echo original size 437, 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#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 zfile[BUFSIZ], command[BUFSIZ], dataline[BUFSIZ]; X char *infile = NULL, *outfile = NULL, *arttempfile; X FILE *infp, *outfp, *arttempfp; 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 data stream of infile uncompressed */ X strcpy(zfile, infile); X strcat(zfile, ".Z"); X if(link(infile, zfile) == 1) { X fprintf(stderr, "%s: link(%s, %s): %s\n", argv[0], X infile, zfile, ERRNO_MSG); X exit(errno); X } X sprintf(command, "%s %s\n", ZCAT, zfile); X if((infp = popen(command, "r")) == NULL) { X fprintf(stderr, "%s: popen(%s, \"r\") failed\n", argv[0], command); X unlink(zfile); 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 pclose(infp); X unlink(zfile); X exit(errno?errno:-1); X } X X /* Get file name for temp file to hold each article */ X arttempfile = tmpnam(NULL); 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 pclose(infp); X unlink(zfile); X exit(errno?errno:-1); X } X rnewslen = strlen(RNEWSSTRING); X if(strncmp(dataline, RNEWSSTRING, rnewslen)) { X fprintf(stderr, "%s: file %s not a compressed news archive\n", X argv[0], infile); X pclose(infp); X unlink(zfile); X exit(errno?errno:-1); X } 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 /* Open temp file for storing next article */ X if((arttempfp = fopen(arttempfile, "w+")) == NULL) { X fprintf(stderr, "%s: fopen(%s, \"w+\") failed\n", argv[0], X arttempfile); X pclose(infp); X unlink(zfile); X exit(errno?errno:-1); X } X X /* Read a line from pipe. If oef or end of article, X * write rnews line with count on output file, X * copy article (in tempfile) to output file and quite loop. X * Otherwise append this next line of article to end X * of temp file and continue with next line from pipe. X */ X while (1) { X if(fgets(dataline, BUFSIZ, infp) == NULL) X eofreached = 1; X X if(eofreached||(!strncmp(dataline, RNEWSSTRING, rnewslen))) { X X charcnt = ftell(arttempfp); X rewind(arttempfp); X fprintf(outfp, "%s %d\n", RNEWSSTRING, charcnt); X if(verbose) X printf("article %d charcnt %d\n", artcnt, charcnt); X X while(fgets(dataline, BUFSIZ, arttempfp)) { X if(fputs(dataline, outfp) == EOF) { X fprintf(stderr, "%s: fputs to %s failed\n", X argv[0], outfile); X pclose(infp); X unlink(zfile); X fclose(arttempfp); X unlink(arttempfile); X fclose(outfp); X exit(errno?errno:-1); X } X charcnt -= strlen(dataline); X } X if(charcnt) X fprintf(stderr, "%s: error in count by %d\n", argv[0], X charcnt); X X fclose(arttempfp); X artcnt++; X break; X X } else X fputs(dataline, arttempfp); X } X } X X pclose(infp); X unlink(zfile); X unlink(arttempfile); X fclose(outfp); X exit(0); X} SHAR_EOF chmod 0644 dorebatch.c || echo "restore of dorebatch.c fails" set `wc -c dorebatch.c`;Sum=$1 if test "$Sum" != "3789" then echo original size 3789, current size $Sum;fi fi exit 0 -- Rob Bernardo Mt. Diablo Software Solutions email: rob@mtdiablo.Concord.CA.US phone: (415) 827-4301