/*
June 14, 1999
Recover text articles from cyclic buffers
Articles start with "\0Path:"
and end with "\r\n.\r\n"
Tested with INND 2.2 under AIX 4.2
rifkin@uconn.edu
*/
/*
(1) Pull 16 bytes at a time
(2) Last 7 bytes must be \000\000\000Path
(3) When found, print "\nPath";
(4) print subsequent bytes until \r\n.\r\n found
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INFILE 1
#define FILEPREFIX 2
#define HEADER 3
#define STRING 4
/* String buffer size */
#define NBUFF 512
#define MAX_ART_SIZE 2200000
#define WRITEMSG printf ("File %s line %i\n", __FILE__, __LINE__); \
fflush(stdout);
#define WRITEVAR(VAR_NAME,VAR_TYPE) \
{ \
printf ("FILE %s LINE %i :", __FILE__, __LINE__); \
printf ("%s = ", #VAR_NAME); \
printf (#VAR_TYPE, (VAR_NAME) ); \
printf ("\n"); \
}
#define WRITETXT(TEXT) \
printf ("FILE %s LINE %i \"%s\"\n", __FILE__, __LINE__, TEXT); \
fflush(stdout);
#if 0
#define WRITEMSG
#define WRITEVAR(X,Y)
#endif
int WriteArticle (char *, int, char *, char *, char *, int);
char ArtHead[7] = {0, 0, 0, 'P', 'a', 't', 'h'};
char ArtTail[5] = {'\r', '\n', '.', '\r', '\n'};
int LenTail = 5;
int main (int argc, char *argv[])
{
FILE *Infile;
int NumTailCharFound;
bool ReadingArticle = false;
char buffer[32];
char *obuffer = NULL;
char *header = NULL;
char *string = NULL;
int osize = MAX_ART_SIZE;
int opos = 0;
int i;
int nchar;
int fileno = 0;
int artno = 0;
/* Check number of args */
if (argc<3)
{
printf ("Usage: pullart <cycbuff> <fileprefix> [<header> <string>]\n");
printf (" Read cycbuffer <cycbuff> and print all articles whose\n");
printf (" article header <header> contains <string>.\n");
printf (" Articles are written to files name <fileprefix>.nnnnnn\n");
printf (" where nnnnnn is numbered sequentially from 0.\n");
printf (" If <header> and <string> not specified, all articles\n");
printf (" are written.\n");
printf (" Examples:\n");
printf (" pullart /news3/cycbuff.3 alt.rec Newsgroup: alt.rec\n");
printf (" pullart /news3/cycbuff.3 all\n");
printf (" pullart firstbuff article Subject bluejay\n");
return 0;
}
/* Allocate output buffer */
obuffer = (char *) calloc (osize+1, sizeof(char));
if (obuffer==NULL)
{
printf ("Cannot allocate obuffer[]\n");
return 1;
}
/* Open input file */
Infile = fopen (argv[INFILE], "rb");
if (Infile==NULL)
{
printf ("Cannot open input file.\n");
return 1;
}
if (argc>=4) header = argv[HEADER];
if (argc>=5) string = argv[STRING];
if (*header=='\0') header=NULL;
if (*string=='\0') string=NULL;
/*test*/
printf ("filename <%s>\n", argv[INFILE]);
printf ("fileprefix <%s>\n", argv[FILEPREFIX]);
printf ("header <%s>\n", header);
printf ("string <%s>\n", string);
/* Skip first 0x38000 16byte buffers */
i = fseek (Infile, 0x38000L, SEEK_SET);
/* Read following 16 byte buffers */
ReadingArticle = false;
NumTailCharFound = 0;
nchar=0;
artno=0;
while ( 0!=fread(buffer, 16, 1, Infile) )
{
nchar+=16;
/* Found start of article, start writing to obuffer */
if (0==memcmp(buffer+9, ArtHead, 7))
{
ReadingArticle = true;
memcpy (obuffer, "Path", 4);
opos = 4;
continue;
}
/* Currnetly reading article */
if (ReadingArticle)
{
for (i=0; i<16; i++)
{
/* Article too big, drop it and move on */
if (opos>=osize)
{
printf
("article number %i bigger than buffer size %i.\n",
artno+1, osize);
artno++;
ReadingArticle=false;
break;
}
/* Add current character to output buffer, but remove \r */
if ('\r' != buffer[i])
obuffer[opos++] = buffer[i];
/* Check for article ending sequence */
if (buffer[i]==ArtTail[NumTailCharFound])
{
NumTailCharFound++;
}
else
NumTailCharFound=0;
/* End found, write article, reset for next */
if (NumTailCharFound==LenTail)
{
ReadingArticle = false;
NumTailCharFound = 0;
/* Add trailing \0 to buffer */
obuffer[opos+1] = '\0';
fileno += WriteArticle
(obuffer, opos, argv[FILEPREFIX],
header, string, fileno);
artno++;
break;
}
}
}
}
close (Infile);
return 0;
}
/*
Writes article stored in buff[] if it has a
"Newsgroups:" header line which contains *newsgroup
Write to a file named fileprefix.fileno
*/
int
WriteArticle
(char *buff, int n, char *fileprefix, char *headerin, char *string, int fileno)
{
char *begptr;
char *endptr;
char *newsptr;
char savechar;
char header[NBUFF];
char filename[NBUFF];
FILE *outfile;
/* Prevent buffer overflow due to fileprefix too long */
if (strlen(fileprefix)>384)
{
printf
("program error: cannot have file prefix greater then 384 characters\n");
exit(1);
}
/*
Is header here? Search if header string requested, leave if not found
*/
if (headerin!=NULL)
{
/* Find \nHEADER */
strlcpy(header, "\n", sizeof(header));
strlcat(header, headerin, sizeof(header));
begptr = strstr (buff, header);
/* return if Header name not found */
if (begptr==NULL)
{
return 0;
}
/*
Header found. What about string?
Search if string requested, leave if not found
*/
if (string!=NULL)
{
/* Find end of header line */
begptr++;
endptr = strchr (begptr, '\n');
/* Something is wrong, end of header not found, do not write
* article
*/
if (endptr==NULL)
return 0;
/* Temporarily make string end a null char */
savechar = *endptr;
*endptr = '\0';
newsptr = strstr (begptr, string);
/* Requested newsgroup not found */
if (newsptr==NULL)
return 0;
/* Restore character at end of header string */
*endptr = savechar;
}
/* No string specified */
}
/* No header specified */
/* Open file, write buffer, close file */
snprintf (filename, sizeof(filename), "%s.%06i", fileprefix, fileno);
outfile = fopen (filename, "wt");
if (outfile==NULL) {
printf ("Cannot open file name %s\n", filename);
exit(1);
}
while (n--)
fprintf (outfile, "%c", *buff++);
close (outfile);
/* Return number of files written */
return 1;
}
syntax highlighted by Code2HTML, v. 0.9.1