chiark / gitweb /
debugging for thing that crashed
[innduct.git] / contrib / pullart.c
1 /*
2 June 14, 1999
3
4 Recover text articles from cyclic buffers
5 Articles start with  "\0Path:"
6 and end with "\r\n.\r\n"
7
8 Tested with INND 2.2 under AIX 4.2
9
10 rifkin@uconn.edu
11 */
12 /*
13 (1) Pull 16 bytes at a time
14 (2) Last 7 bytes must be \000\000\000Path
15 (3) When found, print "\nPath";
16 (4) print subsequent bytes until \r\n.\r\n found
17 */
18
19 #include "config.h"
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #define INFILE     1
25 #define FILEPREFIX 2
26 #define HEADER     3
27 #define STRING     4
28
29 /*  String buffer size  */
30 #define NBUFF 512
31
32 #define MAX_ART_SIZE 2200000
33
34
35 #define WRITEMSG printf ("File %s line %i\n", __FILE__, __LINE__); \
36         fflush(stdout);
37
38 #define WRITEVAR(VAR_NAME,VAR_TYPE) \
39       { \
40       printf ("FILE %s LINE %i :", __FILE__, __LINE__); \
41       printf ("%s = ", #VAR_NAME); \
42       printf (#VAR_TYPE, (VAR_NAME) ); \
43       printf ("\n"); \
44       }
45
46 #define WRITETXT(TEXT)  \
47         printf ("FILE %s LINE %i \"%s\"\n", __FILE__, __LINE__, TEXT); \
48         fflush(stdout);
49
50 #if 0
51 #define WRITEMSG
52 #define WRITEVAR(X,Y)
53 #endif
54
55
56 int WriteArticle (char *, int, char *, char *, char *, int);
57
58
59 char ArtHead[7] = {0, 0, 0, 'P', 'a', 't', 'h'};
60 char ArtTail[5] = {'\r', '\n', '.', '\r', '\n'};
61 int  LenTail    = 5;
62
63 int main (int argc, char *argv[])
64         {
65         FILE *Infile;
66         int   NumTailCharFound;
67         bool  ReadingArticle = false;
68         char  buffer[32];
69         char *obuffer = NULL;
70         char *header  = NULL;
71         char *string  = NULL;
72         int   osize = MAX_ART_SIZE;
73         int   opos  = 0;
74         int   i;
75         int   nchar;
76         int   fileno = 0;
77         int   artno  = 0;
78         
79         /*  Check number of args  */
80         if (argc<3)
81                 {
82                 printf ("Usage: pullart <cycbuff> <fileprefix> [<header> <string>]\n");
83                 printf ("  Read cycbuffer <cycbuff> and print all articles whose\n");
84                 printf ("   article header <header> contains <string>.\n");
85                 printf ("  Articles are written to files name <fileprefix>.nnnnnn\n");
86                 printf ("   where nnnnnn is numbered sequentially from 0.\n");
87                 printf ("  If <header> and <string> not specified, all articles\n");
88                 printf ("   are written.\n");
89                 printf (" Examples:\n");
90                 printf ("  pullart /news3/cycbuff.3 alt.rec  Newsgroup: alt.rec\n");
91                 printf ("  pullart /news3/cycbuff.3  all\n");
92                 printf ("  pullart firstbuff  article Subject bluejay\n");
93                 return 0;
94                 }
95
96         /*  Allocate output buffer  */
97         obuffer = (char *) calloc (osize+1, sizeof(char));
98         if (obuffer==NULL)
99                 {
100                 printf ("Cannot allocate obuffer[]\n");
101                 return 1;
102                 }
103
104
105         /*  Open input file  */
106         Infile = fopen (argv[INFILE], "rb");
107         if (Infile==NULL)
108                 {
109                 printf ("Cannot open input file.\n");
110                 return 1;
111                 }
112
113
114 if (argc>=4) header = argv[HEADER];
115 if (argc>=5) string = argv[STRING];
116 if (*header=='\0') header=NULL;
117 if (*string=='\0') string=NULL;
118
119 /*test*/
120 printf ("filename <%s>\n", argv[INFILE]);
121 printf ("fileprefix <%s>\n", argv[FILEPREFIX]);
122 printf ("header <%s>\n", header);
123 printf ("string <%s>\n", string);
124
125
126         /*  Skip first 0x38000 16byte buffers  */
127         i = fseek (Infile, 0x38000L, SEEK_SET);
128
129         /*  Read following 16 byte buffers  */
130         ReadingArticle = false;
131         NumTailCharFound = 0;
132         nchar=0;
133         artno=0;
134         while ( 0!=fread(buffer, 16, 1, Infile) )
135                 {
136
137                 nchar+=16;
138
139                 /*  Found start of article, start writing to obuffer  */
140                 if (0==memcmp(buffer+9, ArtHead, 7))
141                         {
142                         ReadingArticle = true;
143                         memcpy (obuffer, "Path", 4);
144                         opos = 4;
145                         continue;
146                         }
147
148                 /*  Currnetly reading article  */
149                 if (ReadingArticle)
150                         {
151                         for (i=0; i<16; i++)
152                                 {
153
154                                 /*  Article too big, drop it and move on  */
155                                 if (opos>=osize)
156                                         {
157                                         printf 
158                                                 ("article number %i bigger than buffer size %i.\n", 
159                                                 artno+1, osize);
160                                         artno++;
161                                         ReadingArticle=false;
162                                         break;
163                                         }
164
165                                 /*  Add current character to output buffer, but remove \r  */
166                                 if ('\r' != buffer[i])
167                                         obuffer[opos++] = buffer[i];
168
169                                 /*  Check for article ending sequence  */
170                                 if (buffer[i]==ArtTail[NumTailCharFound])
171                                         {
172                                         NumTailCharFound++;
173                                         }
174                                 else
175                                         NumTailCharFound=0;
176
177                                 /*  End found, write article, reset for next  */
178                                 if (NumTailCharFound==LenTail)
179                                         {
180                                         ReadingArticle = false;
181                                         NumTailCharFound = 0;
182
183                                         /*  Add trailing \0 to buffer  */
184                                         obuffer[opos+1] = '\0';
185
186                                         fileno += WriteArticle 
187                                                 (obuffer, opos, argv[FILEPREFIX], 
188                                                 header, string, fileno);
189                                         artno++;
190                                         break;
191                                         }
192                                 }
193                         
194                         }
195
196                 }
197
198         close (Infile);
199
200         return 0;
201         }
202
203
204
205 /*
206 Writes article stored in buff[] if it has a
207 "Newsgroups:" header line which contains *newsgroup
208 Write to a file named  fileprefix.fileno
209 */
210 int
211 WriteArticle 
212 (char *buff, int n, char *fileprefix, char *headerin, char *string, int fileno)
213         {
214         char *begptr;
215         char *endptr;
216         char *newsptr;
217         char savechar;
218         char header[NBUFF];
219         char filename[NBUFF];
220         FILE *outfile;
221
222
223         /*  Prevent buffer overflow due to fileprefix too long  */
224         if (strlen(fileprefix)>384)
225                 {
226                 printf 
227                 ("program error: cannot have file prefix greater then 384 characters\n");
228                 exit(1);
229                 }
230
231         /*  
232         Is header here?  Search if header string requested, leave if not found  
233         */
234         if (headerin!=NULL)
235                 {
236                 /*  Find \nHEADER  */
237                 strlcpy(header, "\n", sizeof(header));
238                 strlcat(header, headerin, sizeof(header));
239
240                 begptr = strstr (buff, header);
241                 
242                 /*  return if Header name not found  */
243                 if (begptr==NULL)
244                         {
245                         return 0;
246                         }
247
248                 /*  
249                 Header found. What about string?
250                 Search if string requested, leave if not found  
251                 */
252                 if (string!=NULL)
253                         {
254                         /*  Find end of header line  */
255                         begptr++;
256                         endptr = strchr (begptr, '\n');
257
258                         /*  Something is wrong, end of header not found, do not write
259                          *  article  
260                         */
261                         if (endptr==NULL)
262                                 return 0;
263
264                         /*  Temporarily make string end a null char  */
265                         savechar = *endptr;
266                         *endptr = '\0';
267                         newsptr = strstr (begptr, string);
268
269                         /*  Requested newsgroup not found  */
270                         if (newsptr==NULL)
271                                 return 0;
272
273                         /*  Restore character at end of header string  */
274                         *endptr = savechar;
275                         }
276                         /*  No string specified  */
277
278                 }
279         /*  No header specified  */
280
281         /*  Open file, write buffer, close file  */
282         snprintf (filename, sizeof(filename), "%s.%06i", fileprefix, fileno);
283
284         outfile = fopen (filename, "wt");
285         if (outfile==NULL) {
286                 printf ("Cannot open file name %s\n", filename);
287                 exit(1);
288                 }
289
290         while (n--)
291                 fprintf (outfile, "%c", *buff++);
292
293         close (outfile);
294
295         /*  Return number of files written  */
296         return 1;
297         }