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