~bkerensa/ubuntu/trusty/webalizer/merge-from-debian

« back to all changes in this revision

Viewing changes to .pc/24_gettext_generated.diff/parser.c

  • Committer: Benjamin Kerensa
  • Date: 2013-10-23 17:55:52 UTC
  • mfrom: (6.1.5 sid)
  • Revision ID: bkerensa@gmail.com-20131023175552-z2vvko6ws2o2ckjb
MergingĀ fromĀ Debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    webalizer - a web server log analysis program
3
 
 
4
 
    Copyright (C) 1997-2011  Bradford L. Barrett
5
 
 
6
 
    This program is free software; you can redistribute it and/or modify
7
 
    it under the terms of the GNU General Public License as published by
8
 
    the Free Software Foundation; either version 2 of the License, or
9
 
    (at your option) any later version, and provided that the above
10
 
    copyright and permission notice is included with all distributed
11
 
    copies of this or derived software.
12
 
 
13
 
    This program is distributed in the hope that it will be useful,
14
 
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
    GNU General Public License for more details.
17
 
 
18
 
    You should have received a copy of the GNU General Public License
19
 
    along with this program; if not, write to the Free Software
20
 
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21
 
 
22
 
*/
23
 
 
24
 
/*********************************************/
25
 
/* STANDARD INCLUDES                         */
26
 
/*********************************************/
27
 
 
28
 
#include <time.h>
29
 
#include <stdio.h>
30
 
#include <stdlib.h>
31
 
#include <string.h>
32
 
#include <unistd.h>                           /* normal stuff             */
33
 
#include <ctype.h>
34
 
#include <sys/utsname.h>
35
 
 
36
 
/* ensure sys/types */
37
 
#ifndef _SYS_TYPES_H
38
 
#include <sys/types.h>
39
 
#endif
40
 
 
41
 
/* need socket header? */
42
 
#ifdef HAVE_SYS_SOCKET_H
43
 
#include <sys/socket.h>
44
 
#endif
45
 
 
46
 
/* some systems need this */
47
 
#ifdef HAVE_MATH_H
48
 
#include <math.h>
49
 
#endif
50
 
 
51
 
#include "webalizer.h"                        /* main header              */
52
 
#include "lang.h"
53
 
#include "parser.h"
54
 
 
55
 
/* internal function prototypes */
56
 
void fmt_logrec(char *);
57
 
int  parse_record_clf(char *);
58
 
int  parse_record_ftp(char *);
59
 
int  parse_record_squid(char *);
60
 
int  parse_record_w3c(char *);
61
 
 
62
 
/*********************************************/
63
 
/* FMT_LOGREC - terminate log fields w/zeros */
64
 
/*********************************************/
65
 
 
66
 
void fmt_logrec(char *buffer)
67
 
{
68
 
   char *cp=buffer;
69
 
   int  q=0,b=0,p=0;
70
 
 
71
 
   while (*cp != '\0')
72
 
   {
73
 
      /* break record up, terminate fields with '\0' */
74
 
      switch (*cp)
75
 
      {
76
 
       case '\t': if (b || q || p) break; *cp='\0';   break;
77
 
       case ' ': if (b || q || p) break; *cp='\0';    break;
78
 
       case '"': if (*(cp-1)=='\\') break; else q^=1; break;
79
 
       case '[': if (q) break; b++;                   break;
80
 
       case ']': if (q) break; if (b>0) b--;          break;
81
 
       case '(': if (q) break; p++;                   break;
82
 
       case ')': if (q) break; if (p>0) p--;          break;
83
 
      }
84
 
      cp++;
85
 
   }
86
 
}
87
 
 
88
 
/*********************************************/
89
 
/* PARSE_RECORD - uhhh, you know...          */
90
 
/*********************************************/
91
 
 
92
 
int parse_record(char *buffer)
93
 
{
94
 
   /* clear out structure */
95
 
   memset(&log_rec,0,sizeof(struct log_struct));
96
 
 
97
 
   /* call appropriate handler */
98
 
   switch (log_type)
99
 
   {
100
 
      default:
101
 
      case LOG_CLF:   return parse_record_clf(buffer);   break; /* clf   */
102
 
      case LOG_FTP:   return parse_record_ftp(buffer);   break; /* ftp   */
103
 
      case LOG_SQUID: return parse_record_squid(buffer); break; /* squid */
104
 
      case LOG_W3C:   return parse_record_w3c(buffer);   break; /* w3c   */
105
 
   }
106
 
}
107
 
 
108
 
/*********************************************/
109
 
/* PARSE_RECORD_FTP - ftp log handler        */
110
 
/*********************************************/
111
 
 
112
 
int parse_record_ftp(char *buffer)
113
 
{
114
 
   int size;
115
 
   int i,j,count;
116
 
   char *cp1, *cp2, *cpx, *cpy, *eob;
117
 
 
118
 
   size = strlen(buffer);                 /* get length of buffer        */
119
 
   eob = buffer+size;                     /* calculate end of buffer     */
120
 
   fmt_logrec(buffer);                    /* seperate fields with \0's   */
121
 
 
122
 
   /* Start out with date/time       */
123
 
   cp1=buffer;
124
 
   while (*cp1!=0 && cp1<eob) cp1++;
125
 
   while (*cp1==0 && cp1<eob) cp1++;
126
 
   cpx=cp1;       /* save month name */
127
 
   while (*cp1!=0 && cp1<eob) cp1++;
128
 
   while (*cp1==0 && cp1<eob) cp1++;
129
 
   i=atoi(cp1);   /* get day number  */
130
 
   while (*cp1!=0 && cp1<eob) cp1++;
131
 
   while (*cp1==0 && cp1<eob) cp1++;
132
 
   cpy=cp1;       /* get timestamp   */
133
 
   while (*cp1!=0 && cp1<eob) cp1++;
134
 
   while (*cp1==0 && cp1<eob) cp1++;
135
 
   j=atoi(cp1);   /* get year        */
136
 
 
137
 
   /* minimal sanity check */
138
 
   if (*(cpy+2)!=':' || *(cpy+5)!=':') return 0;
139
 
   if (j<1990 || j>2100) return 0;
140
 
   if (i<1 || i>31) return 0;
141
 
 
142
 
   /* format date/time field         */
143
 
   snprintf(log_rec.datetime,sizeof(log_rec.datetime),
144
 
            "[%02d/%s/%4d:%s -0000]",i,cpx,j,cpy);
145
 
 
146
 
   /* skip seconds... */
147
 
   while (*cp1!=0 && cp1<eob) cp1++;
148
 
   while (*cp1==0 && cp1<eob) cp1++;
149
 
   while (*cp1!=0 && cp1<eob) cp1++;
150
 
 
151
 
   /* get hostname */
152
 
   if (*(cp1+1)==0)
153
 
   {
154
 
      /* Blank? That's weird.. */
155
 
      strcpy(log_rec.hostname,"NONE");
156
 
      if (debug_mode) fprintf(stderr, "Warning: Blank hostname found!\n");
157
 
   }
158
 
   else
159
 
   {
160
 
      /* good hostname */
161
 
      strncpy(log_rec.hostname, ++cp1, MAXHOST);
162
 
      log_rec.hostname[MAXHOST-1]=0;
163
 
      while (*cp1!=0 && cp1<eob) cp1++;
164
 
   }
165
 
   while (*cp1==0 && cp1<eob) cp1++;
166
 
 
167
 
   /* get filesize */
168
 
   if (*cp1<'0'||*cp1>'9') log_rec.xfer_size=0;
169
 
   else log_rec.xfer_size = strtoul(cp1,NULL,10);
170
 
 
171
 
   /* URL stuff */
172
 
   while (*cp1!=0 && cp1<eob) cp1++;
173
 
   while (*cp1==0 && cp1<eob) cp1++;
174
 
   cpx=cp1;
175
 
   /* get next field for later */
176
 
   while (*cp1!=0 && cp1<eob) cp1++;
177
 
   while (*cp1==0 && cp1<eob) cp1++;
178
 
 
179
 
   /* skip next two */
180
 
   while (*cp1!=0 && cp1<eob) cp1++;
181
 
   while (*cp1==0) cp1++;
182
 
   while (*cp1!=0 && cp1<eob) cp1++;
183
 
   while (*cp1==0) cp1++;
184
 
 
185
 
   /* fabricate an appropriate request string based on direction */
186
 
   if (*cp1=='i')
187
 
      snprintf(log_rec.url,sizeof(log_rec.url),"\"POST %s\"",cpx);
188
 
   else
189
 
      snprintf(log_rec.url,sizeof(log_rec.url),"\"GET %s\"",cpx);
190
 
 
191
 
   if (cp1<eob) cp1++;
192
 
   if (cp1<eob) cp1++;
193
 
   while (*cp1!=0 && cp1<eob) cp1++;
194
 
   if (cp1<eob) cp1++;
195
 
   cp2=log_rec.ident;count=MAXIDENT-1;
196
 
   while (*cp1!=0 && cp1<eob && count) { *cp2++ = *cp1++; count--; }
197
 
   *cp2='\0';
198
 
 
199
 
   /* return appropriate response code */
200
 
   log_rec.resp_code=(*(eob-2)=='i')?206:200;
201
 
 
202
 
   /* don't worry about I/O bytes in FTP */
203
 
   log_rec.ixfer_size=log_rec.oxfer_size=0;
204
 
 
205
 
   return 1;
206
 
}
207
 
 
208
 
/*********************************************/
209
 
/* PARSE_RECORD_CLF - CLF web log handler    */
210
 
/*********************************************/
211
 
 
212
 
int parse_record_clf(char *buffer)
213
 
{
214
 
   int size;
215
 
   char *cp1, *cp2, *cpx, *eob, *eos;
216
 
 
217
 
   size = strlen(buffer);                 /* get length of buffer        */
218
 
   eob = buffer+size;                     /* calculate end of buffer     */
219
 
   fmt_logrec(buffer);                    /* seperate fields with \0's   */
220
 
 
221
 
   /* HOSTNAME */
222
 
   cp1 = cpx = buffer; cp2=log_rec.hostname;
223
 
   eos = (cp1+MAXHOST)-1;
224
 
   if (eos >= eob) eos=eob-1;
225
 
 
226
 
   while ( (*cp1 != '\0') && (cp1 != eos) ) *cp2++ = *cp1++;
227
 
   *cp2 = '\0';
228
 
   if (*cp1 != '\0')
229
 
   {
230
 
      if (verbose)
231
 
      {
232
 
         fprintf(stderr,"%s",msg_big_host);
233
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
234
 
         else fprintf(stderr,"\n");
235
 
      }
236
 
      while (*cp1 != '\0') cp1++;
237
 
   }
238
 
   if (cp1 < eob) cp1++;
239
 
 
240
 
   /* skip next field (ident) */
241
 
   while ( (*cp1 != '\0') && (cp1 < eob) ) cp1++;
242
 
   if (cp1 < eob) cp1++;
243
 
 
244
 
   /* IDENT (authuser) field */
245
 
   cpx = cp1;
246
 
   cp2 = log_rec.ident;
247
 
   eos = (cp1+MAXIDENT-1);
248
 
   if (eos >= eob) eos=eob-1;
249
 
 
250
 
   while ( (*cp1 != '[') && (cp1 < eos) ) /* remove embeded spaces */
251
 
   {
252
 
      if (*cp1=='\0') *cp1=' ';
253
 
      *cp2++=*cp1++;
254
 
   }
255
 
   *cp2--='\0';
256
 
 
257
 
   if (cp1 >= eob) return 0;
258
 
 
259
 
   /* check if oversized username */
260
 
   if (*cp1 != '[')
261
 
   {
262
 
      if (verbose)
263
 
      {
264
 
         fprintf(stderr,"%s",msg_big_user);
265
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
266
 
         else fprintf(stderr,"\n");
267
 
      }
268
 
      while ( (*cp1 != '[') && (cp1 < eob) ) cp1++;
269
 
   }
270
 
 
271
 
   /* strip trailing space(s) */
272
 
   while (*cp2==' ') *cp2--='\0';
273
 
 
274
 
   /* date/time string */
275
 
   cpx = cp1;
276
 
   cp2 = log_rec.datetime;
277
 
   eos = (cp1+28);
278
 
   if (eos >= eob) eos=eob-1;
279
 
 
280
 
   while ( (*cp1 != '\0') && (cp1 != eos) ) *cp2++ = *cp1++;
281
 
   *cp2 = '\0';
282
 
   if (*cp1 != '\0')
283
 
   {
284
 
      if (verbose)
285
 
      {
286
 
         fprintf(stderr,"%s",msg_big_date);
287
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
288
 
         else fprintf(stderr,"\n");
289
 
      }
290
 
      while (*cp1 != '\0') cp1++;
291
 
   }
292
 
   if (cp1 < eob) cp1++;
293
 
 
294
 
   /* minimal sanity check on timestamp */
295
 
   if ( (log_rec.datetime[0] != '[') ||
296
 
        (log_rec.datetime[3] != '/') ||
297
 
        (cp1 >= eob))  return 0;
298
 
 
299
 
   /* HTTP request */
300
 
   cpx = cp1;
301
 
   cp2 = log_rec.url;
302
 
   eos = (cp1+MAXURL-1);
303
 
   if (eos >= eob) eos = eob-1;
304
 
 
305
 
   while ( (*cp1 != '\0') && (cp1 != eos) ) *cp2++ = *cp1++;
306
 
   *cp2 = '\0';
307
 
   if (*cp1 != '\0')
308
 
   {
309
 
      if (verbose)
310
 
      {
311
 
         fprintf(stderr,"%s",msg_big_req);
312
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
313
 
         else fprintf(stderr,"\n");
314
 
      }
315
 
      while (*cp1 != '\0') cp1++;
316
 
   }
317
 
   if (cp1 < eob) cp1++;
318
 
 
319
 
   if ( (log_rec.url[0] != '"') ||
320
 
        (cp1 >= eob) ) return 0;
321
 
 
322
 
   /* Strip off HTTP version from URL */
323
 
   if ( (cp2=strstr(log_rec.url,"HTTP"))!=NULL )
324
 
   {
325
 
      *cp2='\0';          /* Terminate string */
326
 
      *(--cp2)='"';       /* change <sp> to " */
327
 
   }
328
 
 
329
 
   /* response code */
330
 
   log_rec.resp_code = atoi(cp1);
331
 
 
332
 
   /* xfer size */
333
 
   while ( (*cp1 != '\0') && (cp1 < eob) ) cp1++;
334
 
   if (cp1 < eob) cp1++;
335
 
   if (*cp1<'0'||*cp1>'9') log_rec.xfer_size=0;
336
 
   else log_rec.xfer_size = strtoul(cp1,NULL,10);
337
 
 
338
 
   /* done with CLF record */
339
 
   if (cp1>=eob) return 1;
340
 
 
341
 
   while ( (*cp1 != '\0') && (*cp1 != '\n') && (cp1 < eob) ) cp1++;
342
 
   if (cp1 < eob) cp1++;
343
 
   /* get referrer if present */
344
 
   cpx = cp1;
345
 
   cp2 = log_rec.refer;
346
 
   eos = (cp1+MAXREF-1);
347
 
   if (eos >= eob) eos = eob-1;
348
 
 
349
 
   while ( (*cp1 != '\0') && (*cp1 != '\n') && (cp1 != eos) ) *cp2++ = *cp1++;
350
 
   *cp2 = '\0';
351
 
   if (*cp1 != '\0')
352
 
   {
353
 
      if (verbose)
354
 
      {
355
 
         fprintf(stderr,"%s",msg_big_ref);
356
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
357
 
         else fprintf(stderr,"\n");
358
 
      }
359
 
      while (*cp1 != '\0') cp1++;
360
 
   }
361
 
   if (cp1 < eob) cp1++;
362
 
 
363
 
   cpx = cp1;
364
 
   cp2 = log_rec.agent;
365
 
   eos = cp1+(MAXAGENT-1);
366
 
   if (eos >= eob) eos = eob-1;
367
 
 
368
 
   while ( (*cp1 != '\0') && (cp1 != eos) ) *cp2++ = *cp1++;
369
 
   *cp2 = '\0';
370
 
 
371
 
   /* IN xfer size */
372
 
   while ( (*cp1 != '\0') && (cp1 < eob) ) cp1++;
373
 
   if (cp1 < eob) cp1++;
374
 
   if (*cp1<'0'||*cp1>'9') log_rec.ixfer_size=0;
375
 
   else log_rec.ixfer_size = strtoul(cp1,NULL,10);
376
 
 
377
 
   /* OUT xfer size */
378
 
   while ( (*cp1 != '\0') && (cp1 < eob) ) cp1++;
379
 
   if (cp1 < eob) cp1++;
380
 
   if (*cp1<'0'||*cp1>'9') log_rec.oxfer_size=0;
381
 
   else log_rec.oxfer_size = strtoul(cp1,NULL,10);
382
 
 
383
 
   return 1;     /* maybe a valid record, return with TRUE */
384
 
}
385
 
 
386
 
/*********************************************/
387
 
/* PARSE_RECORD_SQUID - squid log handler    */
388
 
/*********************************************/
389
 
 
390
 
int parse_record_squid(char *buffer)
391
 
{
392
 
   int size, slash_count=0;
393
 
   time_t i;
394
 
   char *cp1, *cp2, *cpx, *eob, *eos;
395
 
 
396
 
   size = strlen(buffer);                 /* get length of buffer        */
397
 
   eob = buffer+size;                     /* calculate end of buffer     */
398
 
   fmt_logrec(buffer);                    /* seperate fields with \0's   */
399
 
 
400
 
   /* date/time */
401
 
   cp1=buffer;
402
 
   i=atoi(cp1);         /* get timestamp */
403
 
 
404
 
   /* format date/time field */
405
 
   strftime(log_rec.datetime,sizeof(log_rec.datetime),
406
 
            "[%d/%b/%Y:%H:%M:%S -0000]",localtime(&i));
407
 
 
408
 
   while (*cp1!=0 && cp1<eob) cp1++;
409
 
   while (*cp1==0) cp1++;
410
 
 
411
 
   /* skip request size */
412
 
   while (*cp1!=0 && cp1<eob) cp1++;
413
 
   while (*cp1==0) cp1++;
414
 
 
415
 
   /* HOSTNAME */
416
 
   cpx = cp1; cp2=log_rec.hostname;
417
 
   eos = (cp1+MAXHOST)-1;
418
 
   if (eos >= eob) eos=eob-1;
419
 
 
420
 
   while ((*cp1 != '\0') && (cp1 != eos)) *cp2++ = *cp1++;
421
 
   *cp2='\0';
422
 
   if (*cp1 != '\0')
423
 
   {
424
 
      if (verbose)
425
 
      {
426
 
         fprintf(stderr,"%s",msg_big_host);
427
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
428
 
         else fprintf(stderr,"\n");
429
 
      }
430
 
      while (*cp1 != '\0') cp1++;
431
 
   }
432
 
   if (cp1 < eob) cp1++;
433
 
 
434
 
   /* skip cache status */
435
 
   while (*cp1!=0 && cp1<eob && *cp1!='/') cp1++;
436
 
   cp1++;
437
 
 
438
 
   /* response code */
439
 
   log_rec.resp_code = atoi(cp1);
440
 
   while (*cp1!=0 && cp1<eob) cp1++;
441
 
   while (*cp1==0) cp1++;
442
 
 
443
 
   /* xfer size */
444
 
   if (*cp1<'0'||*cp1>'9') log_rec.xfer_size=0;
445
 
   else log_rec.xfer_size = strtoul(cp1,NULL,10);
446
 
 
447
 
   while (*cp1!=0 && cp1<eob) cp1++;
448
 
   while (*cp1==0) cp1++;
449
 
 
450
 
   /* HTTP request type */
451
 
   cpx = cp1;
452
 
   cp2 = log_rec.url;
453
 
   *cp2++ = '\"';
454
 
   eos = (cp1+MAXURL-1);
455
 
   if (eos >= eob) eos = eob-1;
456
 
 
457
 
   while ( (*cp1 != '\0') && (cp1 != eos) ) *cp2++ = *cp1++;
458
 
   *cp2 = '\0';
459
 
   if (*cp1 != '\0')
460
 
   {
461
 
      if (verbose)
462
 
      {
463
 
         fprintf(stderr,"%s",msg_big_req);
464
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
465
 
         else fprintf(stderr,"\n");
466
 
      }
467
 
      while (*cp1 != '\0') cp1++;
468
 
   }
469
 
   if (cp1 < eob) cp1++;
470
 
 
471
 
   *cp2++ = ' ';
472
 
 
473
 
   /* HTTP URL requested */
474
 
   cpx = cp1;
475
 
 
476
 
   if (trimsquid>0)
477
 
   {
478
 
      slash_count=trimsquid+2;
479
 
      while ( (*cp1 != '\0') && (cp1 != eos) && slash_count)
480
 
      {
481
 
         *cp2++ = *cp1++;
482
 
         if (*cp1 == '/') slash_count--;
483
 
      }
484
 
   }
485
 
   else while ( (*cp1 != '\0') && (cp1 != eos) ) *cp2++ = *cp1++;
486
 
 
487
 
   *cp2 = '\0';
488
 
   if ((*cp1 != '\0' && trimsquid==0) || (trimsquid && slash_count) )
489
 
   {
490
 
      if (verbose)
491
 
      {
492
 
         fprintf(stderr,"%s",msg_big_req);
493
 
         if (debug_mode) fprintf(stderr,": %s\n",cpx);
494
 
         else fprintf(stderr,"\n");
495
 
      }
496
 
      while (*cp1 != '\0') cp1++;
497
 
   }
498
 
   if (cp1 < eob) cp1++;
499
 
 
500
 
   *cp2++ = '\"';
501
 
 
502
 
   /* IDENT (authuser) field */
503
 
   cpx = cp1;
504
 
   cp2 = log_rec.ident;
505
 
   eos = (cp1+MAXIDENT-1);
506
 
   if (eos >= eob) eos=eob-1;
507
 
 
508
 
   while (*cp1 == ' ') cp1++; /* skip white space */
509
 
 
510
 
   while ( (*cp1 != ' ' && *cp1!='\0') && (cp1 < eos) )  *cp2++=*cp1++;
511
 
 
512
 
   *cp2--='\0';
513
 
 
514
 
   if (cp1 >= eob) return 0;
515
 
 
516
 
   /* strip trailing space(s) */
517
 
   while (*cp2==' ') *cp2--='\0';
518
 
 
519
 
   /* don't do this for squid */
520
 
   log_rec.ixfer_size=log_rec.oxfer_size=0;
521
 
 
522
 
   /* we have no interest in the remaining fields */
523
 
   return 1;
524
 
}
525
 
 
526
 
/*********************************************/
527
 
/* PARSE_RECORD_W3C - w3c log handler        */
528
 
/*********************************************/
529
 
 
530
 
/* field index structure */
531
 
struct  field_index_struct
532
 
{  
533
 
   int date;       /* Date field index                */
534
 
   int time;       /* Time field index                */
535
 
   int ip;         /* IP field index                  */
536
 
   int username;   /* Username field index            */
537
 
   int method;     /* Method field index              */
538
 
   int url;        /* URL field index                 */
539
 
   int query;      /* Querystring field index         */
540
 
   int status;     /* Status code field index         */
541
 
   int size;       /* Size field index                */
542
 
   int referer;    /* Referrer field index            */
543
 
   int agent;      /* User agent field index          */
544
 
   int fields;     /* Number of fields in this format */
545
 
};
546
 
 
547
 
/* field structure */
548
 
struct  fields_struct
549
 
{  
550
 
   char *date;     /* Date field       */
551
 
   char *time;     /* Time field       */
552
 
   char *ip;       /* IP field         */
553
 
   char *username; /* Username field   */
554
 
   char *method;   /* Method field     */
555
 
   char *url;      /* URL field        */
556
 
   char *query;    /* Querystring      */
557
 
   char *status;   /* Status code      */
558
 
   char *size;     /* Size field       */
559
 
   char *referer;  /* Referrer field   */
560
 
   char *agent;    /* User agent field */
561
 
};
562
 
 
563
 
int parse_record_w3c(char *buffer)
564
 
{
565
 
   int size;
566
 
   char *eob;
567
 
   char *cp;
568
 
   int index;
569
 
   static struct field_index_struct field_index;
570
 
   struct fields_struct fields;
571
 
   struct tm gm_time, *local_time;
572
 
   time_t timestamp;
573
 
 
574
 
   memset(&gm_time, 0, sizeof(struct tm));
575
 
   size = strlen(buffer);                 /* get length of buffer        */
576
 
   eob = buffer + size;                   /* calculate end of buffer     */
577
 
 
578
 
   /* remove line end markers, reduce eob accordingly */
579
 
   cp = eob;
580
 
   while(cp>buffer)
581
 
   {
582
 
      cp--;
583
 
      if (*cp == '\r' || *cp=='\n')
584
 
      {
585
 
         *cp = '\0';
586
 
         eob--;
587
 
      }
588
 
      else
589
 
         break;
590
 
   }
591
 
 
592
 
   fmt_logrec(buffer);                    /* seperate fields with \0's   */
593
 
 
594
 
   cp = buffer;
595
 
 
596
 
   /* Check if the line is empty or a line suffers from the IIS 
597
 
      Null-Character bug and abort parsing if found. */
598
 
   if (*cp == '\0') return 0;
599
 
 
600
 
   /* If it's a header line ignore it or parse the Fields header if found */
601
 
   if (*cp == '#')
602
 
   {
603
 
      cp++;
604
 
      if (!strcmp(cp, "Fields:"))
605
 
      {
606
 
         /* Reset the field indices */
607
 
         memset(&field_index, 0, sizeof(struct field_index_struct));
608
 
         while (*cp) cp++;
609
 
         cp++;
610
 
         index = 1;
611
 
         while (cp < eob)
612
 
         {
613
 
            /* Set the field index */
614
 
            if (!strcmp(cp, "date"))           field_index.date     = index;
615
 
            if (!strcmp(cp, "time"))           field_index.time     = index;
616
 
            if (!strcmp(cp, "c-ip"))           field_index.ip       = index;
617
 
            if (!strcmp(cp, "cs-method"))      field_index.method   = index;
618
 
            if (!strcmp(cp, "cs-uri-stem"))    field_index.url      = index;
619
 
            if (!strcmp(cp, "cs-uri-query"))   field_index.query    = index;
620
 
            if (!strcmp(cp, "sc-status"))      field_index.status   = index;
621
 
            if (!strcmp(cp, "cs(Referer)"))    field_index.referer  = index;
622
 
            if (!strcmp(cp, "sc-bytes"))       field_index.size     = index;
623
 
            if (!strcmp(cp, "cs(User-Agent)")) field_index.agent    = index;
624
 
            if (!strcmp(cp, "cs-username"))    field_index.username = index;
625
 
            
626
 
            /* Continue with the next field */
627
 
            while (*cp) cp++;
628
 
            cp++;
629
 
            index++;
630
 
         }
631
 
         field_index.fields = index -1;
632
 
      }
633
 
 
634
 
      /* Return because this header line is completely parsed */
635
 
      return 0;
636
 
   }
637
 
 
638
 
   /* A data line has been found */
639
 
 
640
 
   /* Check if the number of entries in this line are conform to the
641
 
      format specified in the header */
642
 
   index = 1;
643
 
   while (cp < eob)
644
 
   {
645
 
      while (*cp) cp++;
646
 
      cp++;
647
 
      index++;
648
 
   }
649
 
   if (index-1 != field_index.fields) return 0;
650
 
   
651
 
   /* Reset pointer */
652
 
   cp = buffer;
653
 
   
654
 
   /* Reset the field pointers and begin parsing the data line */
655
 
   memset(&fields, 0, sizeof(struct fields_struct));
656
 
   index = 1;
657
 
   while (cp < eob)
658
 
   {
659
 
      /* Set the field pointers */
660
 
      if (index == field_index.date)     fields.date      = cp;
661
 
      if (index == field_index.time)     fields.time      = cp;
662
 
      if (index == field_index.ip)       fields.ip        = cp;
663
 
      if (index == field_index.method)   fields.method    = cp;
664
 
      if (index == field_index.url)      fields.url       = cp;
665
 
      if (index == field_index.query)    fields.query     = cp;
666
 
      if (index == field_index.status)   fields.status    = cp;
667
 
      if (index == field_index.referer)  fields.referer   = cp;
668
 
      if (index == field_index.size)     fields.size      = cp;
669
 
      if (index == field_index.agent)    fields.agent     = cp;
670
 
      if (index == field_index.username) fields.username  = cp;
671
 
      
672
 
      /* Continue with the next data field */
673
 
      while (*cp) cp++;
674
 
      cp++;
675
 
      index++;
676
 
   }
677
 
   
678
 
   /* Save URL */
679
 
   if (fields.url)
680
 
   {
681
 
      cp = fields.url;
682
 
      while (*cp) { if (*cp=='+') *cp=' '; cp++; }
683
 
 
684
 
      /* If no HTTP Method, force to "NONE" */
685
 
      if (fields.method && (fields.method[0]=='-'))
686
 
         fields.method="NONE";
687
 
 
688
 
      if (fields.query && (fields.query[0]!='-'))
689
 
           snprintf(log_rec.url, MAXURL, "\"%s %s?%s\"",
690
 
                    fields.method, fields.url, fields.query);
691
 
      else snprintf(log_rec.url, MAXURL, "\"%s %s\"",
692
 
                    fields.method, fields.url);
693
 
   }
694
 
   else return 0;
695
 
 
696
 
   /* Save hostname */
697
 
   if (fields.ip) strncpy(log_rec.hostname, fields.ip, MAXHOST - 1);
698
 
      
699
 
   /* Save response code */
700
 
   if (fields.status) log_rec.resp_code = atoi(fields.status);
701
 
   
702
 
   /* Save referer */
703
 
   if (fields.referer) strncpy(log_rec.refer, fields.referer, MAXREF - 1);
704
 
   
705
 
   /* Save transfer size */
706
 
   if (fields.size) log_rec.xfer_size = strtoul(fields.size, NULL, 10);
707
 
   
708
 
   /* Save user agent */
709
 
   if (fields.agent)
710
 
   {
711
 
      cp = fields.agent;
712
 
      while (*cp) { if (*cp=='+') *cp=' '; cp++; }
713
 
      strncpy(log_rec.agent, fields.agent, MAXAGENT - 1);
714
 
   }
715
 
   
716
 
   /* Save auth username */
717
 
   if (fields.username) strncpy(log_rec.ident, fields.username, MAXIDENT - 1);
718
 
   
719
 
   /* Parse date and time and save it */
720
 
   if (fields.date)
721
 
   {
722
 
      gm_time.tm_year = atoi(fields.date);
723
 
      if (gm_time.tm_year > 1900) gm_time.tm_year-=1900;
724
 
      while ((fields.date[0] != '\0') && (fields.date[0] != '-')) fields.date++;
725
 
      if (fields.date[0] == '\0') return 0;
726
 
      fields.date++;
727
 
      gm_time.tm_mon = atoi(fields.date) - 1;
728
 
      while ((fields.date[0] != '\0') && (fields.date[0] != '-')) fields.date++;
729
 
      if (fields.date[0] == '\0') return 0;
730
 
      fields.date++;
731
 
      gm_time.tm_mday = atoi(fields.date);
732
 
   }
733
 
   if (fields.time)
734
 
   {
735
 
      gm_time.tm_hour = atoi(fields.time);
736
 
      while ((fields.time[0] != '\0') && (fields.time[0] != ':')) fields.time++;
737
 
      if (fields.time[0] == '\0') return 0;
738
 
      fields.time++;
739
 
      gm_time.tm_min = atoi(fields.time);
740
 
      while ((fields.time[0] != '\0') && (fields.time[0] != ':')) fields.time++;
741
 
      if (fields.time[0] == '\0') return 0;
742
 
      fields.time++;
743
 
      gm_time.tm_sec = atoi(fields.time);
744
 
   }
745
 
   
746
 
   /* Convert GMT to localtime */
747
 
   gm_time.tm_isdst = -1;                              /* force dst check   */
748
 
   timestamp = mktime(&gm_time);                       /* get time in sec   */
749
 
#ifdef HAVE_ALTZONE
750
 
   timestamp-=(gm_time.tm_isdst)?altzone:timezone;     /* solaris & friends */
751
 
#else
752
 
   timestamp = mktime(&gm_time)+gm_time.tm_gmtoff;     /* glibc systems     */
753
 
#endif
754
 
   local_time = localtime(&timestamp);                 /* update tm struct  */
755
 
   strftime(log_rec.datetime, sizeof(log_rec.datetime),/* and format sting  */
756
 
     "[%d/%b/%Y:%H:%M:%S -0000]", local_time);         /* for log_rec field */
757
 
   return 1;
758
 
}