1 /*
2 AWFFull - A Webalizer Fork, Full o' features
3
4 preserve.c
5 preserve 'state' between runs
6
7 Copyright (C) 1997-2001 Bradford L. Barrett (brad@mrunix.net)
8 Copyright (C) 2004-2008 by Stephen McInerney (spm@stedee.id.au)
9 Copyright (C) 2006 by Alexander Lazic (al-awffull@none.at)
10
11 This file is part of AWFFull.
12
13 AWFFull is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 AWFFull is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with AWFFull. If not, see <http://www.gnu.org/licenses/>.
25
26 This software uses the gd graphics library, which is copyright by
27 Quest Protein Database Center, Cold Spring Harbor Labs. Please
28 see the documentation supplied with the library for additional
29 information and license terms, or visit www.boutell.com/gd/ for the
30 most recent version of the library and supporting documentation.
31
32 */
33
34 #include "awffull.h" /* main header */
35
36 /* local variables */
37 struct history history_list[MAXHISTLEN]; /* Complete Array for the history */
38
39 int hist_month[12], hist_year[12]; /* arrays for monthly total */
40 unsigned long hist_hit[12]; /* calculations: used to */
41 unsigned long hist_files[12]; /* produce index.html */
42 unsigned long hist_site[12]; /* these are read and saved */
43 double hist_xfer[12]; /* in the history file */
44 unsigned long hist_page[12];
45 unsigned long hist_visit[12];
46
47 int hist_fday[12], hist_lday[12]; /* first/last day arrays */
48
49 /************************************************
50 * cmp_history *
51 * submit to qsort for sorting the history *
52 * sorts by year & month, oldest first *
53 ************************************************/
54 int
cmp_history(const void * h1,const void * h2)55 cmp_history(const void *h1, const void *h2)
56 {
57 struct history *history1 = (struct history *) h1;
58 struct history *history2 = (struct history *) h2;
59 int cmp_rtn = 0; /* Value to return */
60
61 if (history1->year < history2->year) {
62 cmp_rtn = -1;
63 } else if (history1->year > history2->year) {
64 cmp_rtn = 1;
65 } else {
66 /* Same year, compare for month */
67 if (history1->month < history2->month) {
68 cmp_rtn = -1;
69 } else if (history1->month > history2->month) {
70 cmp_rtn = 1;
71 }
72 }
73 return (cmp_rtn);
74 }
75
76
77 /*********************************************
78 * GET_HISTORY - load in history file *
79 *********************************************/
80 void
get_history()81 get_history()
82 {
83 int i = 0;
84 int numfields = 0; /* Number of fields returned from each line */
85
86 /* Used to verify if an older history file */
87 int nbr_hist_entries = 0; /* How many lines out of the history file have been read */
88
89 FILE *hist_fp;
90 char buffer[BUFSIZE];
91
92 /* first initalize the history array */
93 for (i = 0; i < MAXHISTLEN; i++) {
94 history_list[i].year = 0;
95 history_list[i].month = 0;
96 history_list[i].hit = 0;
97 history_list[i].file = 0;
98 history_list[i].site = 0;
99 history_list[i].xfer = 0.0;
100 history_list[i].page = 0;
101 history_list[i].visit = 0;
102 history_list[i].first_day = 0;
103 history_list[i].last_day = 0;
104 }
105
106 /* Open History file and Process */
107 hist_fp = fopen(g_settings.settings.history_filename, "r");
108 if (hist_fp) {
109 VPRINT(VERBOSE1, "%s %s\n", _("Reading history file..."), g_settings.settings.history_filename);
110 while ((fgets(buffer, BUFSIZE, hist_fp)) != NULL) {
111 /* month# year# requests files sites xfer firstday lastday */
112 numfields = sscanf(buffer, "%d %d %lu %lu %lu %lf %d %d %lu %lu",
113 &history_list[nbr_hist_entries].month,
114 &history_list[nbr_hist_entries].year,
115 &history_list[nbr_hist_entries].hit,
116 &history_list[nbr_hist_entries].file,
117 &history_list[nbr_hist_entries].site,
118 &history_list[nbr_hist_entries].xfer, &history_list[nbr_hist_entries].first_day, &history_list[nbr_hist_entries].last_day,
119 &history_list[nbr_hist_entries].page, &history_list[nbr_hist_entries].visit);
120 if (numfields == 8) { /* kludge for reading 1.20.xx history files */
121 history_list[nbr_hist_entries].page = 0;
122 history_list[nbr_hist_entries].visit = 0;
123 }
124
125 nbr_hist_entries++;
126 if (nbr_hist_entries > MAXHISTLEN) {
127 ERRVPRINT(VERBOSE1, "%s (mth=%d)\n", _("Error: Ignoring invalid history record"), nbr_hist_entries + 1);
128 break;
129 }
130 }
131 fclose(hist_fp);
132 /* Sort the history array. We only need to sort those entries we've just received */
133 qsort(history_list, nbr_hist_entries, sizeof(struct history), cmp_history);
134 if (nbr_hist_entries > 0) {
135 g_counters.month.first_day = history_list[nbr_hist_entries - 1].first_day;
136 g_counters.month.last_day = history_list[nbr_hist_entries - 1].last_day;
137 }
138 VPRINT(VERBOSE2, "History Read. %d Entries\n", nbr_hist_entries);
139 } else {
140 VPRINT(VERBOSE1, "%s\n", _("History file not found..."));
141 }
142 }
143
144
145 /*********************************************
146 * PUT_HISTORY - write out history file *
147 *********************************************/
148 void
put_history()149 put_history()
150 {
151 int i;
152 FILE *hist_fp;
153
154 hist_fp = fopen(g_settings.settings.history_filename, "w");
155
156 if (hist_fp) {
157 VPRINT(VERBOSE1, "%s\n", _("Saving history information..."));
158 for (i = 0; i < MAXHISTLEN && i < (g_settings.settings.history_index + 1); i++) {
159 fprintf(hist_fp, "%d %d %lu %lu %lu %.0f %d %d %lu %lu\n",
160 history_list[i].month, history_list[i].year, history_list[i].hit, history_list[i].file, history_list[i].site, history_list[i].xfer, history_list[i].first_day,
161 history_list[i].last_day, history_list[i].page, history_list[i].visit);
162 }
163 fclose(hist_fp);
164 } else {
165 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error: Unable to write history file"), g_settings.settings.history_filename);
166 }
167 }
168
169
170 /************************************************************************
171 * update_history_array *
172 * *
173 * Updates the history Structure Array. *
174 * Should be run at the end of every month processed. *
175 * *
176 ************************************************************************/
177 void
update_history_array(void)178 update_history_array(void)
179 {
180 unsigned int year_index, month_index, history_index;
181 unsigned int i, j;
182
183 VPRINT(VERBOSE2, "Updating History \"by month\" structure\n");
184 g_settings.settings.history_index = 0;
185 if (history_list[0].year == 0) {
186 VPRINT(VERBOSE2, "History Init!\n");
187 /* Empty History; Create 1st entry. */
188 history_list[0].year = g_cur_year;
189 history_list[0].month = g_cur_month;
190 history_list[0].hit = g_counters.month.hit;
191 history_list[0].file = g_counters.month.file;
192 history_list[0].site = g_counters.month.site;
193 history_list[0].xfer = g_counters.month.vol / VOLUMEBASE;
194 history_list[0].first_day = g_counters.month.first_day;
195 history_list[0].last_day = g_counters.month.last_day;
196 history_list[0].page = g_counters.month.page;
197 history_list[0].visit = g_counters.month.visit;
198 } else {
199 history_index = ((g_cur_year - history_list[0].year) * 12) + g_cur_month - history_list[0].month;
200 if (history_index >= MAXHISTLEN) {
201 /* We've managed to exceed the size of the history list!
202 * shuffle everything down */
203 VPRINT(VERBOSE2, "History Shuffle! Max: %u --> %u\n", MAXHISTLEN, history_index);
204 j = history_index - MAXHISTLEN + 1;
205 for (i = 0; i < MAXHISTLEN; i++) {
206 // VPRINT(0, "Index %u - %u From: %d/%d ", i,j,history_list[i].year, history_list[i].month);
207 if ((i + j) >= MAXHISTLEN) {
208 // VPRINT(0, " to %d/%d ZERO\n", 0, 0);
209 history_list[i].year = 0;
210 history_list[i].month = 0;
211 history_list[i].hit = 0;
212 history_list[i].file = 0;
213 history_list[i].site = 0;
214 history_list[i].xfer = 0;
215 history_list[i].first_day = 0;
216 history_list[i].last_day = 0;
217 history_list[i].page = 0;
218 history_list[i].visit = 0;
219 } else {
220 // VPRINT(0, " to %d/%d COPY\n", history_list[i + j].year, history_list[i + j].month);
221 history_list[i].year = history_list[i + j].year;
222 history_list[i].month = history_list[i + j].month;
223 history_list[i].hit = history_list[i + j].hit;
224 history_list[i].file = history_list[i + j].file;
225 history_list[i].site = history_list[i + j].site;
226 history_list[i].xfer = history_list[i + j].xfer;
227 history_list[i].first_day = history_list[i + j].first_day;
228 history_list[i].last_day = history_list[i + j].last_day;
229 history_list[i].page = history_list[i + j].page;
230 history_list[i].visit = history_list[i + j].visit;
231 }
232 }
233 history_index = MAXHISTLEN - 1;
234 }
235 // VPRINT(0, " DONE!\n");
236 history_list[history_index].year = g_cur_year;
237 history_list[history_index].month = g_cur_month;
238 history_list[history_index].hit = g_counters.month.hit;
239 history_list[history_index].file = g_counters.month.file;
240 history_list[history_index].site = g_counters.month.site;
241 history_list[history_index].xfer = g_counters.month.vol / VOLUMEBASE;
242 history_list[history_index].first_day = g_counters.month.first_day;
243 history_list[history_index].last_day = g_counters.month.last_day;
244 history_list[history_index].page = g_counters.month.page;
245 history_list[history_index].visit = g_counters.month.visit;
246
247 g_settings.settings.history_index = history_index;
248 }
249
250 history_index = 0;
251 month_index = history_list[0].month;
252 year_index = history_list[0].year;
253 for (i = 0; i < MAXHISTLEN; i++) {
254 history_list[i].year = year_index;
255 history_list[i].month = month_index;
256 month_index++;
257 if (month_index > 12) {
258 month_index = 1;
259 year_index++;
260 }
261 }
262
263 if (g_settings.settings.verbosity >= VERBOSE3) {
264 VPRINT(VERBOSE3, "History Table Dump: --\n");
265 for (i = 0; i < MAXHISTLEN; i++) {
266 VPRINT(VERBOSE3, "%d %d %lu %lu %lu %.0f %d %d %lu %lu\n",
267 history_list[i].month, history_list[i].year, history_list[i].hit, history_list[i].file, history_list[i].site, history_list[i].xfer, history_list[i].first_day,
268 history_list[i].last_day, history_list[i].page, history_list[i].visit);
269 }
270 VPRINT(VERBOSE3, " --\n");
271 }
272 }
273
274
275 /*********************************************/
276 /* SAVE_STATE - save internal data structs */
277 /*********************************************/
278 int
save_state()279 save_state()
280 {
281 HNODEPTR hptr;
282 UNODEPTR uptr;
283 RNODEPTR rptr;
284 ANODEPTR aptr;
285 SNODEPTR sptr;
286 INODEPTR iptr;
287 ENODEPTR eptr;
288 SEGNODEPTR segptr;
289
290 FILE *fp;
291 int i;
292
293 char buffer[BUFSIZE];
294
295 /* Open data file for write */
296 fp = fopen(g_settings.settings.state_filename, "w");
297 if (fp == NULL)
298 return 1;
299
300 /* Saving current run data... */
301 snprintf(buffer, sizeof(buffer), "%04d/%02d/%02d %02d:%02d:%02d", g_cur_year, g_cur_month, g_cur_day, g_cur_hour, g_cur_min, g_cur_sec);
302 VPRINT(VERBOSE1, "%s [%s]\n", _("Saving current run data..."), buffer);
303
304 /* first, save the easy stuff */
305 /* Header record */
306 snprintf(buffer, sizeof(buffer), "# AWFFull V%s Incremental Data - %02d/%02d/%04d %02d:%02d:%02d\n", version, g_cur_month, g_cur_day, g_cur_year, g_cur_hour, g_cur_min,
307 g_cur_sec);
308 if (fputs(buffer, fp) == EOF)
309 return 1; /* error exit */
310
311 /* Current date/time */
312 snprintf(buffer, sizeof(buffer), "%d %d %d %d %d %d\n", g_cur_year, g_cur_month, g_cur_day, g_cur_hour, g_cur_min, g_cur_sec);
313 if (fputs(buffer, fp) == EOF)
314 return 1; /* error exit */
315
316 /* Monthly totals for sites, urls, etc... */
317 snprintf(buffer, sizeof(buffer), "%lu %lu %lu %lu %lu %lu %llu %lu %lu %lu %d %lu %lu\n", g_counters.month.hit, g_counters.month.file, g_counters.month.site,
318 g_counters.month.url, g_counters.month.ref, g_counters.month.agent, g_counters.month.vol, g_counters.month.page, g_counters.month.visit, g_counters.month.user, 0,
319 g_counters.generic.bad_month, g_counters.generic.ignored_month);
320 if (fputs(buffer, fp) == EOF)
321 return 1; /* error exit */
322
323 /* Daily totals for sites, urls, etc... */
324 snprintf(buffer, sizeof(buffer), "%u %lu %lu %d %d\n", 0, ht_hit, mh_hit, g_counters.month.first_day, g_counters.month.last_day);
325 if (fputs(buffer, fp) == EOF)
326 return 1; /* error exit */
327
328 /* Monthly (by day) total array */
329 for (i = 0; i < 31; i++) {
330 snprintf(buffer, sizeof(buffer), "%lu %lu %llu %lu %lu %lu %d\n", g_counters.day.hit[i], g_counters.day.file[i], g_counters.day.vol[i], g_counters.day.site[i],
331 g_counters.day.page[i], g_counters.day.visit[i], 0);
332 if (fputs(buffer, fp) == EOF)
333 return 1; /* error exit */
334 }
335
336 /* Daily (by hour) total array */
337 for (i = 0; i < 24; i++) {
338 snprintf(buffer, sizeof(buffer), "%lu %lu %llu %lu %lu\n", g_counters.hour.hit[i], g_counters.hour.file[i], g_counters.hour.vol[i], g_counters.hour.page[i],
339 g_counters.hour.site[i]);
340 if (fputs(buffer, fp) == EOF)
341 return 1; /* error exit */
342 }
343
344 /* Response codes */
345 for (i = 0; i < TOTAL_RC; i++) {
346 snprintf(buffer, sizeof(buffer), "%lu\n", response[i].count);
347 if (fputs(buffer, fp) == EOF)
348 return 1; /* error exit */
349 }
350
351 /* now we need to save our linked lists */
352 /* URL list */
353 if (fputs("# -urls- \n", fp) == EOF)
354 return 1; /* error exit */
355 for (i = 0; i < MAXHASH; i++) {
356 uptr = um_htab[i];
357 while (uptr != NULL) {
358 snprintf(buffer, sizeof(buffer), "%s\n%d %lu %lu %llu %lu %lu %lu %llu %lu\n", uptr->string, uptr->flag, uptr->count, uptr->files, uptr->xfer, uptr->entry, uptr->exit,
359 uptr->pcount, uptr->pxfer, uptr->single_access);
360 if (fputs(buffer, fp) == EOF)
361 return 1;
362 uptr = uptr->next;
363 }
364 }
365 if (fputs("# End Of Table - urls\n", fp) == EOF)
366 return 1; /* error exit */
367
368 /* daily hostname list */
369 if (fputs("# -sites- (monthly)\n", fp) == EOF)
370 return 1; /* error exit */
371
372 for (i = 0; i < MAXHASH; i++) {
373 hptr = sm_htab[i];
374 while (hptr != NULL) {
375 snprintf(buffer, sizeof(buffer), "%s\n%d %lu %lu %llu %lu %lu %lu %d\n%s\n", hptr->string, hptr->flag, hptr->count, hptr->files, hptr->xfer, hptr->visit, hptr->pages,
376 hptr->tstamp, hptr->lasturl_is_entry, (hptr->lasturl == blank_str) ? "-" : hptr->lasturl);
377 if (fputs(buffer, fp) == EOF)
378 return 1; /* error exit */
379 hptr = hptr->next;
380 }
381 }
382 if (fputs("# End Of Table - sites (monthly)\n", fp) == EOF)
383 return 1;
384
385 /* hourly hostname list */
386 if (fputs("# -sites- (daily)\n", fp) == EOF)
387 return 1; /* error exit */
388 for (i = 0; i < MAXHASH; i++) {
389 hptr = sd_htab[i];
390 while (hptr != NULL) {
391 snprintf(buffer, sizeof(buffer), "%s\n%d %lu %lu %llu %lu %lu %lu %d\n%s\n", hptr->string, hptr->flag, hptr->count, hptr->files, hptr->xfer, hptr->visit, hptr->pages,
392 hptr->tstamp, hptr->lasturl_is_entry, (hptr->lasturl == blank_str) ? "-" : hptr->lasturl);
393 if (fputs(buffer, fp) == EOF)
394 return 1;
395 hptr = hptr->next;
396 }
397 }
398 if (fputs("# End Of Table - sites (daily)\n", fp) == EOF)
399 return 1;
400
401 /* Referrer list */
402 if (fputs("# -referrers- \n", fp) == EOF)
403 return 1; /* error exit */
404 if (g_counters.month.ref != 0) {
405 for (i = 0; i < MAXHASH; i++) {
406 rptr = rm_htab[i];
407 while (rptr != NULL) {
408 snprintf(buffer, sizeof(buffer), "%s\n%d %lu\n", rptr->string, rptr->flag, rptr->count);
409 if (fputs(buffer, fp) == EOF)
410 return 1; /* error exit */
411 rptr = rptr->next;
412 }
413 }
414 }
415 if (fputs("# End Of Table - referrers\n", fp) == EOF)
416 return 1;
417
418 /* User agent list */
419 if (fputs("# -agents- \n", fp) == EOF)
420 return 1; /* error exit */
421 if (g_counters.month.agent != 0) {
422 for (i = 0; i < MAXHASH; i++) {
423 aptr = am_htab[i];
424 while (aptr != NULL) {
425 snprintf(buffer, sizeof(buffer), "%s\n%d %lu\n", aptr->string, aptr->flag, aptr->count);
426 if (fputs(buffer, fp) == EOF)
427 return 1; /* error exit */
428 aptr = aptr->next;
429 }
430 }
431 }
432 if (fputs("# End Of Table - agents\n", fp) == EOF)
433 return 1;
434
435 /* Search String list */
436 if (fputs("# -search strings- \n", fp) == EOF)
437 return 1; /* error exit */
438 for (i = 0; i < MAXHASH; i++) {
439 sptr = sr_htab[i];
440 while (sptr != NULL) {
441 snprintf(buffer, sizeof(buffer), "%s\n%lu\n", sptr->string, sptr->count);
442 if (fputs(buffer, fp) == EOF)
443 return 1; /* error exit */
444 sptr = sptr->next;
445 }
446 }
447 if (fputs("# End Of Table - search strings\n", fp) == EOF)
448 return 1;
449
450 /* username list */
451 if (fputs("# -usernames- \n", fp) == EOF)
452 return 1; /* error exit */
453
454 for (i = 0; i < MAXHASH; i++) {
455 iptr = im_htab[i];
456 while (iptr != NULL) {
457 snprintf(buffer, sizeof(buffer), "%s\n%d %lu %lu %llu %lu %lu\n", iptr->string, iptr->flag, iptr->count, iptr->files, iptr->xfer, iptr->visit, iptr->tstamp);
458 if (fputs(buffer, fp) == EOF)
459 return 1; /* error exit */
460 iptr = iptr->next;
461 }
462 }
463 if (fputs("# End Of Table - usernames\n", fp) == EOF)
464 return 1;
465
466 /* ErrorPages list */
467 if (fputs("# -404errors- \n", fp) == EOF)
468 return 1; /* error exit */
469
470 for (i = 0; i < MAXHASH; i++) {
471 eptr = ep_htab[i];
472 while (eptr != NULL) {
473 snprintf(buffer, sizeof(buffer), "%s\n%lu\n%s\n", eptr->url, eptr->count, eptr->referer);
474 if (fputs(buffer, fp) == EOF)
475 return 1;
476 eptr = eptr->next;
477 }
478 }
479 if (fputs("# End Of Table - 404errors\n", fp) == EOF)
480 return 1; /* error exit */
481
482 /* Save Segmenting Data. */
483 if (fputs("# -segmenting_referers- \n", fp) == EOF)
484 return 1; /* error exit */
485
486 for (i = 0; i < MAXHASH; i++) {
487 segptr = seg_ref_htab[i];
488 while (segptr != NULL) {
489 snprintf(buffer, sizeof(buffer), "%s\n%lu\n", segptr->string, segptr->tstamp);
490 if (fputs(buffer, fp) == EOF)
491 return 1; /* error exit */
492 segptr = segptr->next;
493 }
494 }
495 if (fputs("# End Of Table - segmenting_referers\n", fp) == EOF)
496 return 1;
497
498 fclose(fp); /* close data file... */
499 return 0; /* successful, return with good return code */
500 }
501
502
503 /*********************************************
504 * RESTORE_STATE - reload internal run data
505 *
506 * Returns:
507 * 0 on successful load
508 * -1 on no file too load
509 * > 0 on any error in the load
510 *********************************************/
511 int
restore_state()512 restore_state()
513 {
514 FILE *fp;
515 int i;
516 struct hnode t_hnode; /* Temporary hash nodes */
517 struct unode t_unode;
518 struct rnode t_rnode;
519 struct anode t_anode;
520 struct snode t_snode;
521 struct inode t_inode;
522 struct enode t_enode;
523 struct seg_node t_segnode;
524
525 char buffer[BUFSIZE];
526 char buffer2[BUFSIZE], buffer3[BUFSIZE];
527
528 struct tm time_rec; /* Gotta convert that string'ed time into a timerec first */
529
530 unsigned long ul_bogus = 0;
531
532 unsigned int tmp_version_major = 0; /* Scan in the version of the Current Run Data file. Use int's as a float scan was not consistant */
533 unsigned int tmp_version_minor = 0;
534 unsigned int tmp_version_micro = 0;
535 unsigned long rundata_version = 0; /* The webalizer version from the file header */
536 int ssout; /* sscanf return result for checking */
537
538 unsigned long ignore_this_value = 0; /* Ignore this value - was old save, now dropped */
539 bool ignore_this_bool = false;
540
541 fp = fopen(g_settings.settings.state_filename, "r");
542 if (fp == NULL) {
543 /* Previous run data not found... */
544 VPRINT(VERBOSE1, "%s\n", _("Previous run data not found..."));
545 return -1; /* return with Not Found code */
546 }
547
548 /* Reading previous run data... */
549 VPRINT(VERBOSE1, "%s %s\n", _("Reading previous run data.."), g_settings.settings.state_filename);
550
551 /* get easy stuff */
552 /* Header record */
553 if ((fgets(buffer, BUFSIZE, fp)) != NULL) {
554 ssout = sscanf(buffer, "# AWFFull V%u.%u.%u", &tmp_version_major, &tmp_version_minor, &tmp_version_micro);
555 if (ssout <= 0) {
556 /* Possibly Webalizer format header? */
557 ssout = sscanf(buffer, "# Webalizer V%u.%u", &tmp_version_major, &tmp_version_minor);
558 if (ssout <= 0) {
559 return (1);
560 }
561 }
562 /* Version level = Major x 10,000 + Minor x 100 + Micro
563 * Micro is *always* > 0
564 * Gives us 99 levels in Minor and Micro
565 * 3.3.1 = 30301
566 */
567 if (tmp_version_micro == 0) { /* Old Webalizer Format, early awffull */
568 rundata_version = tmp_version_major * 100 + tmp_version_minor;
569 } else {
570 rundata_version = tmp_version_major * 10000 + tmp_version_minor * 100 + tmp_version_micro;
571 }
572
573 VPRINT(VERBOSE1, "%s %lu\n", _("Previous Run Version:"), rundata_version);
574 if (rundata_version < 201) { /* Check for version compatibility */
575 return 99;
576 }
577 if (rundata_version < 301) {
578 ERRVPRINT(VERBOSE0, "%s\n", _("Warning: Changes to Referrals & User Agents count methods. See README!"));
579 }
580 } /* bad magic? */
581 else
582 return 98; /* error exit */
583
584 /* Current date/time */
585 if ((fgets(buffer, BUFSIZE, fp)) != NULL) {
586 memset(&time_rec, 0, sizeof(time_rec));
587 strptime(buffer, "%Y %m %d %H %M %S", &time_rec);
588 /* calculate current timestamp (seconds since epoch) and setup current time globals */
589 time_rec.tm_isdst = -1; /* stop mktime from resetting for daylight savings */
590 cur_tstamp = mktime(&time_rec);
591 VPRINT(VERBOSE1, "%s %lu", _("Previous Final Timestamp:"), cur_tstamp);
592 g_cur_year = time_rec.tm_year + 1900;
593 g_cur_month = time_rec.tm_mon + 1;
594 g_cur_day = time_rec.tm_mday;
595 g_cur_hour = time_rec.tm_hour;
596 g_cur_min = time_rec.tm_min;
597 g_cur_sec = time_rec.tm_sec;
598 VPRINT(VERBOSE1, " %d-%d-%d:%d:%d:%d\n", g_cur_year, g_cur_month, g_cur_day, g_cur_hour, g_cur_min, g_cur_sec);
599 } else
600 return 2; /* error exit */
601
602 /* Monthly totals for sites, urls, etc... */
603 if ((fgets(buffer, BUFSIZE, fp)) != NULL) {
604 if (rundata_version < 302) {
605 sscanf(buffer, "%lu %lu %lu %lu %lu %lu %llu %lu %lu %lu", &g_counters.month.hit, &g_counters.month.file, &g_counters.month.site, &g_counters.month.url,
606 &g_counters.month.ref, &g_counters.month.agent, &g_counters.month.vol, &g_counters.month.page, &g_counters.month.visit, &g_counters.month.user);
607 } else {
608 sscanf(buffer, "%lu %lu %lu %lu %lu %lu %llu %lu %lu %lu %lu %lu %lu", &g_counters.month.hit, &g_counters.month.file, &g_counters.month.site, &g_counters.month.url,
609 &g_counters.month.ref, &g_counters.month.agent, &g_counters.month.vol, &g_counters.month.page, &g_counters.month.visit, &g_counters.month.user,
610 &ignore_this_value, &g_counters.generic.bad_month, &g_counters.generic.ignored_month);
611 }
612 } else
613 return 3; /* error exit */
614
615 /* Daily totals for sites, urls, etc... */
616 if ((fgets(buffer, BUFSIZE, fp)) != NULL) {
617 sscanf(buffer, "%lu %lu %lu %d %d", &ignore_this_value, &ht_hit, &mh_hit, &g_counters.month.first_day, &g_counters.month.last_day);
618 } else
619 return 4; /* error exit */
620
621 /* Monthly (by day) total array */
622 for (i = 0; i < 31; i++) {
623 if ((fgets(buffer, BUFSIZE, fp)) != NULL) {
624 if (rundata_version < 302) {
625 sscanf(buffer, "%lu %lu %llu %lu %lu %lu", &g_counters.day.hit[i], &g_counters.day.file[i], &g_counters.day.vol[i], &g_counters.day.site[i],
626 &g_counters.day.page[i], &g_counters.day.visit[i]);
627 } else {
628 sscanf(buffer, "%lu %lu %llu %lu %lu %lu %lu", &g_counters.day.hit[i], &g_counters.day.file[i], &g_counters.day.vol[i], &g_counters.day.site[i],
629 &g_counters.day.page[i], &g_counters.day.visit[i], &ignore_this_value);
630 }
631 } else
632 return 5; /* error exit */
633 }
634
635 /* Daily (by hour) total array */
636 for (i = 0; i < 24; i++) {
637 if ((fgets(buffer, BUFSIZE, fp)) != NULL) {
638 if (rundata_version < 302) {
639 sscanf(buffer, "%lu %lu %llu %lu", &g_counters.hour.hit[i], &g_counters.hour.file[i], &g_counters.hour.vol[i], &g_counters.hour.page[i]);
640 } else if (rundata_version < 30801) {
641 sscanf(buffer, "%lu %lu %llu %lu %lu", &g_counters.hour.hit[i], &g_counters.hour.file[i], &g_counters.hour.vol[i], &g_counters.hour.page[i], &ignore_this_value);
642 } else {
643 sscanf(buffer, "%lu %lu %llu %lu %lu", &g_counters.hour.hit[i], &g_counters.hour.file[i], &g_counters.hour.vol[i], &g_counters.hour.page[i],
644 &g_counters.hour.site[i]);
645 }
646 } else
647 return 6; /* error exit */
648 }
649
650 /* Response codes */
651 for (i = 0; i < TOTAL_RC; i++) {
652 if ((fgets(buffer, BUFSIZE, fp)) != NULL)
653 sscanf(buffer, "%lu", &response[i].count);
654 else
655 return 7; /* error exit */
656 }
657
658
659 /* now we need to restore our linked lists */
660 /* URL list */
661
662 /* Kludge for V2.01-06 TOTAL_RC off by one bug */
663 if (!strncmp(buffer, "# -urls- ", 9))
664 response[TOTAL_RC - 1].count = 0;
665 else {
666 /* now do hash tables */
667
668 /* url table */
669 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
670 if (strncmp(buffer, "# -urls- ", 9))
671 return 8;
672 } /* (url) */
673 else
674 return 8; /* error exit */
675 }
676
677 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
678 if (!strncmp(buffer2, "# End Of Table ", 15))
679 break;
680 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
681
682 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
683 return 9; /* error exit */
684 if (!isdigit((int) buffer[0]))
685 return 9; /* error exit */
686
687 /* Zero values not used in loads of older data */
688 t_unode.single_access = 0;
689 t_unode.pcount = 0;
690 t_unode.pxfer = 0;
691 /* load temporary node data */
692 if (rundata_version >= 30801) {
693 sscanf(buffer, "%d %lu %lu %llu %lu %lu %lu %llu %lu", &t_unode.flag, &t_unode.count, &t_unode.files, &t_unode.xfer, &t_unode.entry, &t_unode.exit, &t_unode.pcount,
694 &t_unode.pxfer, &t_unode.single_access);
695 } else if (rundata_version > 30403) {
696 sscanf(buffer, "%d %lu %lu %llu %lu %lu %lu %llu", &t_unode.flag, &t_unode.count, &t_unode.files, &t_unode.xfer, &t_unode.entry, &t_unode.exit, &t_unode.pcount,
697 &t_unode.pxfer);
698 } else {
699 sscanf(buffer, "%d %lu %lu %llu %lu %lu", &t_unode.flag, &t_unode.count, &t_unode.files, &t_unode.xfer, &t_unode.entry, &t_unode.exit);
700 }
701
702 /* Good record, insert into hash table */
703 if (put_unode(buffer2, t_unode.flag, t_unode.count, t_unode.xfer, &ul_bogus, t_unode.entry, t_unode.exit, t_unode.single_access, 0, um_htab)) {
704 /* Error adding URL node, skipping ... */
705 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding URL node, skipping"), buffer2);
706 }
707 }
708
709 /* daily hostname list */
710 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
711 if (strncmp(buffer, "# -sites- ", 10))
712 return 10;
713 } /* (monthly) */
714 else
715 return 10; /* error exit */
716
717 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
718 /* Check for end of table */
719 if (!strncmp(buffer2, "# End Of Table ", 15))
720 break;
721 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
722
723 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
724 return 11; /* error exit */
725 if (!isdigit((int) buffer[0]))
726 return 11; /* error exit */
727
728 /* Zero values not used in loads of older data */
729 t_hnode.pages = 0;
730 t_hnode.lasturl_is_entry = false;
731 /* load temporary node data */
732 if (rundata_version < 300) {
733 sscanf(buffer, "%d %lu %lu %llu %lu %lu", &t_hnode.flag, &t_hnode.count, &t_hnode.files, &t_hnode.xfer, &t_hnode.visit, &t_hnode.tstamp);
734 t_hnode.pages = 0;
735 } else if (rundata_version < 30801) {
736 sscanf(buffer, "%d %lu %lu %llu %lu %lu %lu", &t_hnode.flag, &t_hnode.count, &t_hnode.files, &t_hnode.xfer, &t_hnode.visit, &t_hnode.pages, &t_hnode.tstamp);
737 } else { /* version 3.00, aka 300, included t_hnode.pages in the output */
738 sscanf(buffer, "%d %lu %lu %llu %lu %lu %lu %hhd", &t_hnode.flag, &t_hnode.count, &t_hnode.files, &t_hnode.xfer, &t_hnode.visit, &t_hnode.pages, &t_hnode.tstamp,
739 &t_hnode.lasturl_is_entry);
740 }
741
742 /* get last url */
743 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
744 return 11; /* error exit */
745 if (buffer[0] == '-')
746 t_hnode.lasturl = blank_str;
747 else {
748 buffer[strlen(buffer) - 1] = 0;
749 t_hnode.lasturl = find_url(buffer);
750 }
751
752 /* Good record, insert into hash table */
753 if (put_hnode
754 (buffer2, t_hnode.flag, t_hnode.count, t_hnode.files, t_hnode.xfer, &ul_bogus, t_hnode.visit, t_hnode.pages, t_hnode.tstamp, "", t_hnode.lasturl, sm_htab,
755 t_hnode.lasturl_is_entry, false, &ignore_this_bool)) {
756 /* Error adding host node (monthly), skipping .... */
757 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding Host node (monthly), skipping"), buffer2);
758 }
759 }
760
761 /* hourly hostname list */
762 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
763 if (strncmp(buffer, "# -sites- ", 10))
764 return 12;
765 } /* (daily) */
766 else
767 return 12; /* error exit */
768
769 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
770 /* Check for end of table */
771 if (!strncmp(buffer2, "# End Of Table ", 15))
772 break;
773 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
774
775 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
776 return 13; /* error exit */
777 if (!isdigit((int) buffer[0]))
778 return 13; /* error exit */
779
780 /* Zero values not used in loads of older data */
781 t_hnode.pages = 0;
782 t_hnode.lasturl_is_entry = false;
783 /* load temporary node data */
784 if (rundata_version < 300) {
785 sscanf(buffer, "%d %lu %lu %llu %lu %lu", &t_hnode.flag, &t_hnode.count, &t_hnode.files, &t_hnode.xfer, &t_hnode.visit, &t_hnode.tstamp);
786 t_hnode.pages = 0;
787 } else if (rundata_version < 30801) { /* version 3.00, aka 300, included t_hnode.pages in the output */
788 sscanf(buffer, "%d %lu %lu %llu %lu %lu %lu", &t_hnode.flag, &t_hnode.count, &t_hnode.files, &t_hnode.xfer, &t_hnode.visit, &t_hnode.pages, &t_hnode.tstamp);
789 } else { /* version 3.8.1, aka 30801, included t_hnode.lasturl_is_entry in the output */
790 sscanf(buffer, "%d %lu %lu %llu %lu %lu %lu %hhd", &t_hnode.flag, &t_hnode.count, &t_hnode.files, &t_hnode.xfer, &t_hnode.visit, &t_hnode.pages, &t_hnode.tstamp,
791 &(t_hnode.lasturl_is_entry));
792 }
793
794
795 /* get last url */
796 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
797 return 13; /* error exit */
798 if (buffer[0] == '-')
799 t_hnode.lasturl = blank_str;
800 else {
801 buffer[strlen(buffer) - 1] = 0;
802 t_hnode.lasturl = find_url(buffer);
803 }
804
805 /* Good record, insert into hash table */
806 if (put_hnode
807 (buffer2, t_hnode.flag, t_hnode.count, t_hnode.files, t_hnode.xfer, &ul_bogus, t_hnode.visit, t_hnode.pages, t_hnode.tstamp, "", t_hnode.lasturl, sd_htab,
808 t_hnode.lasturl_is_entry, false, &ignore_this_bool)) {
809 /* Error adding host node (daily), skipping .... */
810 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding Host node (daily), skipping"), buffer2);
811 }
812 }
813
814 /* Referrer list */
815 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
816 if (strncmp(buffer, "# -referrers- ", 14))
817 return 14;
818 } else
819 return 14; /* error exit */
820
821 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
822 if (!strncmp(buffer2, "# End Of Table ", 15))
823 break;
824 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
825
826 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
827 return 15; /* error exit */
828 if (!isdigit((int) buffer[0]))
829 return 15; /* error exit */
830
831 /* load temporary node data */
832 sscanf(buffer, "%d %lu", &t_rnode.flag, &t_rnode.count);
833
834 /* insert node */
835 if (put_rnode(buffer2, t_rnode.flag, t_rnode.count, &ul_bogus, rm_htab)) {
836 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding Referrer node, skipping"), buffer2);
837 }
838 }
839
840 /* User agent list */
841 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
842 if (strncmp(buffer, "# -agents- ", 11))
843 return 16;
844 } else
845 return 16; /* error exit */
846
847 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
848 if (!strncmp(buffer2, "# End Of Table ", 15))
849 break;
850 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
851
852 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
853 return 17; /* error exit */
854 if (!isdigit((int) buffer[0]))
855 return 17; /* error exit */
856
857 /* load temporary node data */
858 sscanf(buffer, "%d %lu", &t_anode.flag, &t_anode.count);
859
860 /* insert node */
861 if (put_anode(buffer2, t_anode.flag, t_anode.count, &ul_bogus, am_htab)) {
862 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding User Agent node, skipping"), buffer2);
863 }
864 }
865
866 /* Search Strings table */
867 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
868 if (strncmp(buffer, "# -search string", 16))
869 return 18;
870 } else
871 return 18; /* error exit */
872
873 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
874 if (!strncmp(buffer2, "# End Of Table ", 15))
875 break;
876 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
877
878 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
879 return 19; /* error exit */
880 if (!isdigit((int) buffer[0]))
881 return 19; /* error exit */
882
883 /* load temporary node data */
884 sscanf(buffer, "%lu", &t_snode.count);
885
886 /* insert node */
887 if (put_snode(buffer2, t_snode.count, sr_htab)) {
888 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding Search String Node, skipping"), buffer2);
889 }
890 }
891
892 /* usernames table */
893 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
894 if (strncmp(buffer, "# -usernames- ", 10))
895 return 20;
896 } else
897 return 20; /* error exit */
898
899 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
900 /* Check for end of table */
901 if (!strncmp(buffer2, "# End Of Table ", 15))
902 break;
903 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
904
905 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
906 return 21; /* error exit */
907 if (!isdigit((int) buffer[0]))
908 return 21; /* error exit */
909
910 /* load temporary node data */
911 sscanf(buffer, "%d %lu %lu %llu %lu %lu", &t_inode.flag, &t_inode.count, &t_inode.files, &t_inode.xfer, &t_inode.visit, &t_inode.tstamp);
912
913 /* Good record, insert into hash table */
914 if (put_inode(buffer2, t_inode.flag, t_inode.count, t_inode.files, t_inode.xfer, &ul_bogus, t_inode.visit, t_inode.tstamp, im_htab, false)) {
915 /* Error adding username node, skipping .... */
916 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding Username node, skipping"), buffer2);
917 }
918 }
919
920 if (rundata_version > 302) {
921 /* 404 table */
922 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
923 if (strncmp(buffer, "# -404errors- ", 14))
924 return 22;
925 } else
926 return 22; /* error exit */
927
928 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
929 if (!strncmp(buffer2, "# End Of Table ", 15))
930 break;
931 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
932
933 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
934 return 23; /* error exit */
935 if (!isdigit((int) buffer[0]))
936 return 23; /* error exit */
937
938 /* load temporary node data */
939 sscanf(buffer, "%lu", &t_enode.count);
940
941 if ((fgets(buffer3, BUFSIZE, fp)) == NULL)
942 return 23; /* error exit */
943 buffer3[strlen(buffer3) - 1] = '\0'; /* Chop off trailing newline */
944
945 /* Good record, insert into hash table */
946 if (put_enode(buffer2, buffer3, OBJ_REG, t_enode.count, &g_counters.generic.error_month, ep_htab)) {
947 /* Error adding URL node, skipping ... */
948 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding URL node, skipping"), buffer2);
949 }
950 }
951 }
952
953
954 /* Restore Segmenting Data. */
955 if (rundata_version >= 30901) {
956 if ((fgets(buffer, BUFSIZE, fp)) != NULL) { /* Table header */
957 if (strncmp(buffer, "# -segmenting_referers- ", 10))
958 return 24;
959 } else
960 return 24; /* error exit */
961
962 while ((fgets(buffer2, BUFSIZE, fp)) != NULL) {
963 /* Check for end of table */
964 if (!strncmp(buffer2, "# End Of Table ", 15))
965 break;
966 buffer2[strlen(buffer2) - 1] = '\0'; /* Chop off trailing newline */
967
968 if ((fgets(buffer, BUFSIZE, fp)) == NULL)
969 return 25; /* error exit */
970 if (!isdigit((int) buffer[0]))
971 return 25; /* error exit */
972
973 /* load temporary node data */
974 sscanf(buffer, "%lu", &t_segnode.tstamp);
975
976 /* Good record, insert into hash table */
977 if (!put_segnode(buffer2, t_segnode.tstamp, seg_ref_htab)) {
978 /* Error adding segmenting by referrer node, skipping .... */
979 ERRVPRINT(VERBOSE1, "%s %s\n", _("Error adding Segmenting By Referrer node, skipping"), buffer2);
980 }
981 }
982 }
983
984 fclose(fp);
985 g_settings.flags.is_first_run = false; /* First run is false, as we're effectively mid-run */
986 return 0; /* return with ok code */
987 }
988
989
990 /************************************************************************
991 ************************************************************************
992 * END OF FILE *
993 ************************************************************************
994 ************************************************************************/
995