]> git.ipfire.org Git - thirdparty/sarg.git/blob - index.c
Use a global constant instead of the "index.html" file name in the code
[thirdparty/sarg.git] / index.c
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2013
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26
27 #include "include/conf.h"
28 #include "include/defs.h"
29
30 static void make_date_index(void);
31 static void make_file_index(void);
32 static void file_index_to_date_index(const char *entry);
33 static void date_index_to_file_index(const char *entry);
34
35 void make_index(void)
36 {
37 DIR *dirp;
38 struct dirent *direntp;
39 char wdir[MAXLEN];
40
41 if(LastLog > 0) mklastlog(outdir);
42
43 if(Index == INDEX_NO) {
44 sprintf(wdir,"%sindex.html",outdir);
45 if(access(wdir, R_OK) == 0) {
46 if (unlink(wdir)) {
47 debuga(_("Cannot delete \"%s\": %s\n"),wdir,strerror(errno));
48 exit(EXIT_FAILURE);
49 }
50 }
51 return;
52 }
53
54 if(debug) {
55 // TRANSLATORS: The %s is the name of the html index file (index.html).
56 debuga(_("Making %s\n"),INDEX_HTML_FILE);
57 }
58
59 // convert any old report hierarchy
60 if ((dirp = opendir(outdir)) == NULL) {
61 debuga(_("Failed to open directory %s - %s\n"),outdir,strerror(errno));
62 exit(EXIT_FAILURE);
63 }
64 while ((direntp = readdir( dirp )) != NULL) {
65 if(isdigit(direntp->d_name[0]) && isdigit(direntp->d_name[1])) {
66 if(IndexTree == INDEX_TREE_DATE)
67 file_index_to_date_index(direntp->d_name);
68 else
69 date_index_to_file_index(direntp->d_name);
70 }
71 }
72 closedir(dirp);
73
74 if(IndexTree == INDEX_TREE_DATE) {
75 make_date_index();
76 } else {
77 make_file_index();
78 }
79 }
80
81 static void make_date_index(void)
82 {
83 FILE *fp_ou, *fp_ou2, *fp_ou3;
84 DIR *dirp, *dirp2, *dirp3;
85 struct dirent *direntp;
86 struct dirent *direntp2;
87 struct dirent *direntp3;
88 char yearindex[MAXLEN];
89 char yeardir[MAXLEN];
90 char yearnum[10];
91 char monthindex[MAXLEN];
92 char monthdir[MAXLEN];
93 char monthname1[9], monthname2[9];
94 char nmonth[30];
95 char monthnum[10];
96 char dayindex[MAXLEN];
97 char daynum[10];
98 char title[80];
99 int yearsort[150];
100 int nyears;
101 int year;
102 int monthsort[144];
103 int nmonths;
104 int m1, m2, month;
105 int daysort[31*31];
106 int ndays;
107 int d1, d2, day;
108 int i, y, m, d;
109 int order;
110
111 sprintf(yearindex,"%sindex.html",outdir);
112
113 nyears=0;
114 if ((dirp = opendir(outdir)) == NULL) {
115 debuga(_("Failed to open directory %s - %s\n"),outdir,strerror(errno));
116 exit(EXIT_FAILURE);
117 }
118 while ((direntp = readdir( dirp )) != NULL) {
119 if(strlen(direntp->d_name) > 4 || !isdigit(direntp->d_name[0]) || !isdigit(direntp->d_name[1]) ||
120 !isdigit(direntp->d_name[2]) || !isdigit(direntp->d_name[3])) continue;
121 year=atoi(direntp->d_name);
122 if (nyears>=sizeof(yearsort)/sizeof(yearsort[0])) {
123 /*
124 If too many years are listed in the directory, we ignore the earliest years. The yearsort array
125 is big enough to accomodate the most ambitious use of sarg but this safety is added to prevent
126 a crash should the directory be polluted by other entries.
127 */
128 if (year>yearsort[0]) {
129 for (i=1 ; i<nyears && year>yearsort[i] ; i++)
130 yearsort[i-1]=yearsort[i];
131 yearsort[i-1]=year;
132 }
133 } else {
134 for (i=nyears ; i>0 && year<yearsort[i-1] ; i--) {
135 yearsort[i]=yearsort[i-1];
136 }
137 yearsort[i]=year;
138 nyears++;
139 }
140 }
141 closedir( dirp );
142
143 order=(strcmp(IndexSortOrder,"A") == 0) ? 1 : -1;
144
145 if((fp_ou=fopen(yearindex,"w"))==NULL) {
146 debuga(_("(index) Cannot open file %s: %s\n"),yearindex,strerror(errno));
147 exit(EXIT_FAILURE);
148 }
149 write_html_header(fp_ou,0,ngettext("SARG report","SARG reports",nyears),HTML_JS_NONE);
150 close_html_header(fp_ou);
151 fputs("<div class=\"index\"><table cellpadding=\"1\" cellspacing=\"2\">\n",fp_ou);
152 fprintf(fp_ou,"<tr><th class=\"header_l\">%s</th>",_("YEAR"));
153 if (IndexFields & INDEXFIELDS_DIRSIZE)
154 fprintf(fp_ou,"<th class=\"header_l\">%s</th>",_("SIZE"));
155 fputs("</tr>\n",fp_ou);
156 for (y=0 ; y<nyears ; y++) {
157 if (order>0)
158 year=yearsort[y];
159 else
160 year=yearsort[nyears-1-y];
161 sprintf(yearnum,"%04d",year);
162 fprintf(fp_ou,"<tr><td class=\"data2\"><a href=\"%s/%s\">%s</a></td>",yearnum,INDEX_HTML_FILE,yearnum);
163 if (IndexFields & INDEXFIELDS_DIRSIZE)
164 fprintf(fp_ou,"<td class=\"data2\">%s</td>",get_size(outdir,yearnum));
165 fputs("</tr>\n",fp_ou);
166 sprintf(yeardir,"%s%s",outdir,yearnum);
167 // Year dir
168 nmonths=0;
169 if ((dirp2 = opendir(yeardir)) == NULL) {
170 debuga(_("Failed to open directory %s - %s\n"),yeardir,strerror(errno));
171 exit(EXIT_FAILURE);
172 }
173 while ((direntp2 = readdir( dirp2 )) != NULL) {
174 if(!isdigit(direntp2->d_name[0]) || !isdigit(direntp2->d_name[1])) continue;
175 i=-1;
176 if (sscanf(direntp2->d_name,"%d%n",&m1,&i)!=1 || m1<=0 || m1>12 || i<0) continue;
177 if (direntp2->d_name[i]=='-') {
178 if (sscanf(direntp2->d_name+i+1,"%d",&m2)!=1 || m2<m1 || m2>12) continue;
179 } else if (direntp2->d_name[i]!='\0') {
180 continue;
181 } else {
182 m2=0;
183 }
184 if (nmonths>=sizeof(monthsort)/sizeof(monthsort[0])) {
185 debuga(_("Too many month directories in %s\nSupernumerary entries are ignored\n"),yeardir);
186 break;
187 }
188 month=m1*16+m2;
189 for (i=nmonths ; i>0 && month<monthsort[i-1] ; i--) {
190 monthsort[i]=monthsort[i-1];
191 }
192 monthsort[i]=month;
193 nmonths++;
194 }
195 closedir(dirp2);
196 sprintf(monthindex,"%s/"INDEX_HTML_FILE,yeardir);
197 if((fp_ou2=fopen(monthindex,"w"))==NULL) {
198 debuga(_("(index) Cannot open file %s: %s\n"),monthindex,strerror(errno));
199 exit(EXIT_FAILURE);
200 }
201 snprintf(title,sizeof(title),ngettext("SARG: report for %04d","SARG: reports for %04d",nmonths),year);
202 write_html_header(fp_ou2,1,title,HTML_JS_NONE);
203 close_html_header(fp_ou2);
204 fputs("<div class=\"index\"><table cellpadding=\"1\" cellspacing=\"2\">\n<tr><td></td><td></td></tr>\n",fp_ou2);
205 fprintf(fp_ou2,"<tr><th class=\"header_l\">%s/%s</th></tr>\n",_("YEAR"),_("MONTH"));
206 for (m=0 ; m<nmonths ; m++) {
207 if (order>0)
208 month=monthsort[m];
209 else
210 month=monthsort[nmonths-1-m];
211 m1=month / 16;
212 if(month % 16 != 0) {
213 m2=month % 16;
214 sprintf(monthnum,"%02d-%02d",m1,m2);
215 sprintf(monthname1,"%02d",m1);
216 sprintf(monthname2,"%02d",m2);
217 name_month(monthname1,sizeof(monthname1));
218 name_month(monthname2,sizeof(monthname2));
219 sprintf(nmonth,"%s-%s",monthname1,monthname2);
220 } else {
221 sprintf(nmonth,"%02d",m1);
222 sprintf(monthnum,"%02d",m1);
223 name_month(nmonth,sizeof(nmonth));
224 }
225 fprintf(fp_ou2,"<tr><td class=\"data2\"><a href=\"%s/%s\">%s %s</a></td></tr>\n",monthnum,INDEX_HTML_FILE,yearnum,nmonth);
226
227 sprintf(monthdir,"%s/%s",yeardir,monthnum);
228 // month dir
229 ndays=0;
230 if ((dirp3 = opendir(monthdir)) == NULL) {
231 debuga(_("Failed to open directory %s - %s\n"),monthdir,strerror(errno));
232 exit(EXIT_FAILURE);
233 }
234 while ((direntp3 = readdir( dirp3 )) != NULL) {
235 if(!isdigit(direntp3->d_name[0]) && !isdigit(direntp3->d_name[1])) continue;
236 i=-1;
237 if (sscanf(direntp3->d_name,"%d%n",&d1,&i)!=1 || d1<=0 || d1>31 || i<0) continue;
238 if (direntp3->d_name[i]=='-') {
239 if (sscanf(direntp3->d_name+i+1,"%d",&d2)!=1 || d2<d1 || d2>31) continue;
240 } else if (direntp3->d_name[i]!='\0') {
241 continue;
242 } else {
243 d2=0;
244 }
245 if (ndays>=sizeof(daysort)/sizeof(daysort[0])) {
246 debuga(_("Too many day directories in %s\nSupernumerary entries are ignored\n"),monthdir);
247 break;
248 }
249 day=d1*32+d2;
250 for (i=ndays ; i>0 && day<daysort[i-1] ; i--) {
251 daysort[i]=daysort[i-1];
252 }
253 daysort[i]=day;
254 ndays++;
255 }
256 closedir(dirp3);
257 sprintf(dayindex,"%s/"INDEX_HTML_FILE,monthdir);
258 if((fp_ou3=fopen(dayindex,"w"))==NULL) {
259 debuga(_("(index) Cannot open file %s: %s\n"),dayindex,strerror(errno));
260 exit(EXIT_FAILURE);
261 }
262 snprintf(title,sizeof(title),ngettext("SARG: report for %04d/%02d","SARG: reports for %04d/%02d",ndays),year,month);
263 write_html_header(fp_ou3,2,title,HTML_JS_NONE);
264 close_html_header(fp_ou3);
265 fputs("<div class=\"index\"><table cellpadding=\"1\" cellspacing=\"2\">\n<tr><td></td><td></td></tr>\n",fp_ou3);
266 fprintf(fp_ou3,"<tr><th class=\"header_l\">%s/%s/%s</th></tr>\n",_("YEAR"),_("MONTH"),_("DAYS"));
267 for (d=0 ; d<ndays ; d++) {
268 if (order>0)
269 day=daysort[d];
270 else
271 day=daysort[ndays-1-d];
272 d1=day / 32;
273 if(day % 32 != 0) {
274 d2=day % 32;
275 sprintf(daynum,"%02d-%02d",d1,d2);
276 } else {
277 sprintf(daynum,"%02d",d1);
278 }
279 fprintf(fp_ou3,"<tr><td class=\"data2\"><a href=\"%s/%s\">%s %s %s</a></td></tr>\n",daynum,INDEX_HTML_FILE,yearnum,nmonth,daynum);
280 }
281 fputs("</table></div>\n",fp_ou3);
282 if (write_html_trailer(fp_ou3)<0)
283 debuga(_("Write error in the index %s\n"),dayindex);
284 if (fclose(fp_ou3)==EOF) {
285 debuga(_("Write error in %s: %s\n"),dayindex,strerror(errno));
286 exit(EXIT_FAILURE);
287 }
288 }
289 fputs("</table></div>\n",fp_ou2);
290 if (write_html_trailer(fp_ou2)<0)
291 debuga(_("Write error in the index %s\n"),monthindex);
292 if (fclose(fp_ou2)==EOF) {
293 debuga(_("Write error in %s: %s\n"),monthindex,strerror(errno));
294 exit(EXIT_FAILURE);
295 }
296 }
297
298 fputs("</table></div>\n",fp_ou);
299 if (write_html_trailer(fp_ou)<0)
300 debuga(_("Write error in the index %s\n"),yearindex);
301 if (fclose(fp_ou)==EOF) {
302 debuga(_("Write error in %s: %s\n"),yearindex,strerror(errno));
303 exit(EXIT_FAILURE);
304 }
305 }
306
307 static void make_file_index(void)
308 {
309 #define MAX_CREATION_DATE 15
310 FILE *fp_ou;
311 DIR *dirp;
312 struct dirent *direntp;
313 char wdir[MAXLEN];
314 char data[80];
315 char ftime[128];
316 char day[6], mon[8], year[40], hour[10];
317 long long int tbytes;
318 long long int media;
319 int iyear, imonth, iday, ihour, iminute, isecond, idst;
320 int nsort;
321 int nallocated;
322 int order;
323 int i;
324 int tuser;
325 struct getwordstruct gwarea;
326 struct sortstruct
327 {
328 int year, month, day, sortnum;
329 char creationdate[MAX_CREATION_DATE];
330 char *dirname;
331 char date[60];
332 } **sortlist, *item, **tempsort;
333
334 sprintf(wdir,"%sindex.html",outdir);
335
336 order=(strcmp(IndexSortOrder,"A") == 0) ? 1 : -1;
337
338 if ((dirp = opendir(outdir)) == NULL) {
339 debuga(_("Failed to open directory %s - %s\n"),outdir,strerror(errno));
340 exit(EXIT_FAILURE);
341 }
342
343 nsort=0;
344 nallocated=0;
345 sortlist=NULL;
346 while ((direntp = readdir( dirp )) != NULL) {
347 if (strchr(direntp->d_name,'-') == 0) continue;
348 if (obtdate(outdir,direntp->d_name,data)<0) {
349 debuga(_("The directory \"%s%s\" looks like a report directory but doesn't contain a sarg-date file. You should delete it\n"),outdir,direntp->d_name);
350 continue;
351 }
352 item=malloc(sizeof(*item));
353 if (!item) {
354 debuga(_("not enough memory to sort the index\n"));
355 exit(EXIT_FAILURE);
356 }
357 if (df=='u') {
358 item->year=atoi(direntp->d_name);
359 item->month=conv_month(direntp->d_name+4);
360 item->day=atoi(direntp->d_name+7);
361 } else {
362 item->year=atoi(direntp->d_name+5);
363 item->month=conv_month(direntp->d_name+2);
364 item->day=atoi(direntp->d_name);
365 }
366 item->sortnum=(item->year*16+item->month)*32+item->day;
367 if (sscanf(data,"%d-%d-%d %d:%d:%d %d",&iyear,&imonth,&iday,&ihour,&iminute,&isecond,&idst)==7) {
368 formatdate(data,sizeof(data),iyear,imonth,iday,ihour,iminute,isecond,idst);
369 snprintf(item->creationdate,sizeof(item->creationdate),"%04d%02d%02d%02d%02d%02d",iyear,imonth,iday,ihour,iminute,isecond);
370 } else {
371 /*
372 Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
373 */
374 getword_start(&gwarea,data);
375 if (getword_skip(16,&gwarea,' ')<0) {
376 debuga(_("Maybe you have a broken week day in your %s%s/sarg-date file\n"),outdir,direntp->d_name);
377 exit(EXIT_FAILURE);
378 }
379 if (getword_multisep(mon,sizeof(mon),&gwarea,' ')<0) {
380 debuga(_("Maybe you have a broken month in your %s%s/sarg-date file\n"),outdir,direntp->d_name);
381 exit(EXIT_FAILURE);
382 }
383 if (getword_multisep(day,sizeof(day),&gwarea,' ')<0) {
384 debuga(_("Maybe you have a broken day in your %s%s/sarg-date file\n"),outdir,direntp->d_name);
385 exit(EXIT_FAILURE);
386 }
387 if (getword_multisep(hour,sizeof(hour),&gwarea,' ')<0) {
388 debuga(_("Maybe you have a broken time in your %s%s/sarg-date file\n"),outdir,direntp->d_name);
389 exit(EXIT_FAILURE);
390 }
391 do {
392 if (getword_multisep(year,sizeof(year),&gwarea,' ')<0) {
393 debuga(_("Maybe you have a broken year in your %s%s/sarg-date file\n"),outdir,direntp->d_name);
394 exit(EXIT_FAILURE);
395 }
396 } while (year[0] && !isdigit(year[0])); //skip time zone information with spaces until the year is found
397 if (sscanf(hour,"%d:%d:%d",&ihour,&iminute,&isecond)!=3) {
398 debuga(_("Maybe you have a broken time in your %s%s/sarg-date file\n"),outdir,direntp->d_name);
399 exit(EXIT_FAILURE);
400 }
401 buildymd(day,mon,year,ftime,sizeof(ftime));
402 snprintf(item->creationdate,sizeof(item->creationdate),"%s%02d%02d%02d",ftime, ihour, iminute, isecond);
403 }
404 item->dirname=strdup(direntp->d_name);
405 if (!item->dirname) {
406 debuga(_("Not enough memory to store the directory name \"%s\" in the index\n"),direntp->d_name);
407 exit(EXIT_FAILURE);
408 }
409 safe_strcpy(item->date,data,sizeof(item->date));
410 if (nsort+1>nallocated) {
411 nallocated+=10;
412 tempsort=realloc(sortlist,nallocated*sizeof(*item));
413 if (!tempsort) {
414 debuga(_("not enough memory to sort the index\n"));
415 exit(EXIT_FAILURE);
416 }
417 sortlist=tempsort;
418 }
419 for (i=nsort ; i>0 ; i--) {
420 if (item->sortnum>sortlist[i-1]->sortnum) break;
421 if (item->sortnum==sortlist[i-1]->sortnum) {
422 if (strcmp(item->creationdate,sortlist[i-1]->creationdate)>=0) break;
423 }
424 sortlist[i]=sortlist[i-1];
425 }
426 sortlist[i]=item;
427 nsort++;
428 }
429
430 closedir( dirp );
431
432 if((fp_ou=fopen(wdir,"w"))==NULL) {
433 debuga(_("(index) Cannot open file %s: %s\n"),wdir,strerror(errno));
434 exit(EXIT_FAILURE);
435 }
436 write_html_header(fp_ou,0,ngettext("SARG report","SARG reports",nsort),HTML_JS_SORTTABLE);
437 close_html_header(fp_ou);
438 fputs("<div class=\"index\"><table cellpadding=\"1\" cellspacing=\"2\"",fp_ou);
439 if (SortTableJs[0]) fputs(" class=\"sortable\"",fp_ou);
440 fputs(">\n",fp_ou);
441 fprintf(fp_ou,"<thead><tr><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th><th class=\"header_l\">%s</th></tr></thead>\n",_("FILE/PERIOD"),_("CREATION DATE"),_("USERS"),_("BYTES"),_("AVERAGE"));
442 for (i=0 ; i<nsort ; i++) {
443 if (order>0)
444 item=sortlist[i];
445 else
446 item=sortlist[nsort-i-1];
447 tuser=obtuser(outdir,item->dirname);
448 obttotal(outdir,item->dirname,tuser,&tbytes,&media);
449 fputs("<tr><td class=\"data2\"",fp_ou);
450 if (SortTableJs[0]) fprintf(fp_ou," sorttable_customkey=\"%d\"",item->sortnum);
451 fprintf(fp_ou,"><a href='%s/%s'>%s</a></td>",item->dirname,ReplaceIndex,item->dirname);
452 fputs("<td class=\"data2\"",fp_ou);
453 if (SortTableJs[0]) fprintf(fp_ou," sorttable_customkey=\"%s\"",item->creationdate);
454 fprintf(fp_ou,">%s</td>",item->date);
455 fprintf(fp_ou,"<td class=\"data\">%d</td>",tuser);
456 fputs("<td class=\"data\"",fp_ou);
457 if (SortTableJs[0]) fprintf(fp_ou," sorttable_customkey=\"%"PRId64"\"",(int64_t)tbytes);
458 fprintf(fp_ou,">%s</td>",fixnum(tbytes,1));
459 fputs("<td class=\"data\"",fp_ou);
460 if (SortTableJs[0]) fprintf(fp_ou," sorttable_customkey=\"%"PRId64"\"",(int64_t)media);
461 fprintf(fp_ou,">%s</td></tr>\n",fixnum(media,1));
462 }
463 fputs("</table></div>\n",fp_ou);
464 if (write_html_trailer(fp_ou)<0)
465 debuga(_("Write error in the index %s\n"),wdir);
466 if (fclose(fp_ou)==EOF)
467 debuga(_("Failed to close the index file %s - %s\n"),wdir,strerror(errno));
468
469 if (sortlist) {
470 for (i=0 ; i<nsort ; i++) {
471 free(sortlist[i]->dirname);
472 free(sortlist[i]);
473 }
474 free(sortlist);
475 }
476 }
477
478 static void file_index_to_date_index(const char *entry)
479 {
480 int y1, y2, m1, m2, d1, d2;
481 int i, j;
482 int ndirlen;
483 int monthlen;
484 char sm1[8], sm2[8];
485 char olddir[MAXLEN], newdir[MAXLEN];
486
487 if(strlen(entry) < 19) return;
488
489 y1=0;
490 y2=0;
491 memset(sm1,0,sizeof(sm1));
492 memset(sm2,0,sizeof(sm2));
493 d1=0;
494 d2=0;
495 i=0;
496 if (df=='u') {
497 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
498 y1=y1*10+(entry[i++]-'0');
499 if (j!=4) return;
500 for (j=0 ; j<sizeof(sm1)-1 && entry[i] && isalpha(entry[i]) ; j++)
501 sm1[j]=entry[i++];
502 if (j!=3) return;
503 sm1[j]='\0';
504 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
505 d1=d1*10+(entry[i++]-'0');
506 if (j!=2) return;
507
508 if (entry[i++]!='-') return;
509
510 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
511 y2=y2*10+(entry[i++]-'0');
512 if (j!=4) return;
513 for (j=0 ; j<sizeof(sm2)-1 && entry[i] && isalpha(entry[i]) ; j++)
514 sm2[j]=entry[i++];
515 if (j!=3) return;
516 sm2[j]='\0';
517 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
518 d2=d2*10+(entry[i++]-'0');
519 if (j!=2) return;
520 } else if (df=='e') {
521 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
522 d1=d1*10+(entry[i++]-'0');
523 if (j!=2) return;
524 for (j=0 ; j<sizeof(sm1)-1 && entry[i] && isalpha(entry[i]) ; j++)
525 sm1[j]=entry[i++];
526 if (j!=3) return;
527 sm1[j]='\0';
528 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
529 y1=y1*10+(entry[i++]-'0');
530 if (j!=4) return;
531
532 if (entry[i++]!='-') return;
533
534 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
535 d2=d2*10+(entry[i++]-'0');
536 if (j!=2) return;
537 for (j=0 ; j<sizeof(sm2)-1 && entry[i] && isalpha(entry[i]) ; j++)
538 sm2[j]=entry[i++];
539 if (j!=3) return;
540 sm2[j]='\0';
541 for (j=0 ; entry[i] && isdigit(entry[i]) ; j++)
542 y2=y2*10+(entry[i++]-'0');
543 if (j!=4) return;
544 } else
545 return;
546
547 m1=conv_month(sm1);
548 m2=conv_month(sm2);
549 ndirlen=sprintf(newdir,"%s%04d",outdir,y1);
550 if (access(newdir, R_OK) != 0) {
551 if (mkdir(newdir,0755)) {
552 debuga(_("Cannot create directory %s - %s\n"),newdir,strerror(errno));
553 exit(EXIT_FAILURE);
554 }
555 }
556 if(m1 != m2) ndirlen+=sprintf(newdir+ndirlen,"/%02d-%02d",m1,m2);
557 else ndirlen+=sprintf(newdir+ndirlen,"/%02d",m1);
558 if (access(newdir, R_OK) != 0) {
559 if (mkdir(newdir,0755)) {
560 debuga(_("Cannot create directory %s - %s\n"),newdir,strerror(errno));
561 exit(EXIT_FAILURE);
562 }
563 }
564 monthlen=ndirlen;
565 if(d1!=d2) ndirlen+=sprintf(newdir+ndirlen,"/%02d-%02d",d1,d2);
566 else ndirlen+=sprintf(newdir+ndirlen,"/%02d",d1);
567
568 sprintf(olddir,"%s%s",outdir,entry);
569 if (rename(olddir,newdir)) {
570 debuga(_("(index) rename error from \"%s\" to \"%s\" - %s\n"),olddir,newdir,strerror(errno));
571 exit(EXIT_FAILURE);
572 }
573
574 strcpy(newdir+monthlen,"/images");
575 if(access(newdir, R_OK) != 0) {
576 #ifdef HAVE_SYMLINK
577 char linkdir[MAXLEN];
578
579 sprintf(linkdir,"%simages",outdir);
580 if (symlink(linkdir,newdir)) {
581 debuga(_("failed to create link \"%s\" to \"%s\" - %s\n"),linkdir,newdir,strerror(errno));
582 exit(EXIT_FAILURE);
583 }
584 #else
585 char cmd[MAXLEN];
586 int cstatus;
587
588 sprintf(cmd,"ln -s \"%simages\" \"%s/images\"",outdir,newdir);
589 cstatus=system(cmd);
590 if (!WIFEXITED(cstatus) || WEXITSTATUS(cstatus)) {
591 debuga(_("command return status %d\n"),WEXITSTATUS(cstatus));
592 debuga(_("command: %s\n"),cmd);
593 exit(EXIT_FAILURE);
594 }
595 #endif
596 }
597 }
598
599 static void date_index_to_file_index(const char *entry)
600 {
601 int y1, next;
602 int m1, m2;
603 int d1, d2;
604 int val1len;
605 int i, j;
606 char val1[MAXLEN];
607 const char *sm1, *sm2;
608 char *str;
609 char newdir[MAXLEN], olddir[MAXLEN];
610 DIR *dirp2, *dirp3;
611 struct dirent *direntp2;
612 struct dirent *direntp3;
613
614 if(strlen(entry) != 4) return;
615
616 next=-1;
617 if (sscanf(entry,"%d%n",&y1,&next)!=1 || next<0 || entry[next]) return;
618
619 val1len=snprintf(val1,sizeof(val1),"%s%s",outdir,entry);
620 dirp2 = opendir(val1);
621 if (!dirp2) return;
622 while ((direntp2 = readdir( dirp2 )) != NULL) {
623 if(!isdigit(direntp2->d_name[0]) || !isdigit(direntp2->d_name[1])) continue;
624 i=0;
625 str=direntp2->d_name;
626 m1=0;
627 for (j=0 ; j<2 && str[i] && isdigit(str[i]) ; j++)
628 m1=(m1*10)+(str[i++]-'0');
629 if (j>=2) continue;
630 sm1=conv_month_name(m1);
631 if (str[i]=='-') {
632 i++;
633 m2=0;
634 for (j=0 ; j<2 && str[i] && isdigit(str[i]) ; j++)
635 m2=(m2*10)+(str[i++]-'0');
636 if (j>=2) continue;
637 sm2=conv_month_name(m2);
638 } else if (!str[i]) {
639 sm2=sm1;
640 } else {
641 continue;
642 }
643
644 sprintf(val1+val1len,"/%s",direntp2->d_name);
645 dirp3 = opendir(val1);
646 if (!dirp3) continue;
647 while ((direntp3 = readdir( dirp3 )) != NULL) {
648 if(!isdigit(direntp3->d_name[0]) || !isdigit(direntp3->d_name[1])) continue;
649 i=0;
650 str=direntp3->d_name;
651 d1=0;
652 for (j=0 ; str[i] && isdigit(str[i]) ; j++)
653 d1=d1*10+(str[i++]-'0');
654 if (j!=2) continue;
655 if (str[i]=='-') {
656 i++;
657 d2=0;
658 for (j=0 ; str[i] && isdigit(str[i]) ; j++)
659 d2=d2*10+(str[i++]-'0');
660 if (j!=2) continue;
661 } else if (!str[i]) {
662 d2=d1;
663 } else {
664 continue;
665 }
666
667 if (df=='u') sprintf(newdir,"%s%04d%s%02d-%04d%s%02d",outdir,y1,sm1,d1,y1,sm2,d2);
668 else if (df=='e') sprintf(newdir,"%s%02d%s%04d-%02d%s%04d",outdir,d1,sm1,y1,d2,sm2,y1);
669 else continue;
670 sprintf(olddir,"%s%04d/%s/%s",outdir,y1,direntp2->d_name,direntp3->d_name);
671 if(rename(olddir,newdir)) {
672 debuga(_("(index) rename error from \"%s\" to \"%s\" - %s\n"),olddir,newdir,strerror(errno));
673 exit(EXIT_FAILURE);
674 }
675 }
676 closedir( dirp3 );
677 }
678 closedir( dirp2 );
679
680 /*!
681 \bug The links to the images in the reports are broken after moving the directories
682 as the the HTML files are not at the right level for the images any more.
683 */
684 }
685