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