]>
git.ipfire.org Git - thirdparty/sarg.git/blob - index.c
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
6 * please look at http://sarg.sourceforge.net/donations.php
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
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.
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.
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.
27 #include "include/conf.h"
28 #include "include/defs.h"
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
);
38 struct dirent
* direntp
;
41 if ( LastLog
> 0 ) mklastlog ( outdir
);
43 if ( Index
== INDEX_NO
) {
44 sprintf ( wdir
, "%sindex.html" , outdir
);
45 if ( access ( wdir
, R_OK
) == 0 ) {
47 debuga ( _ ( "Cannot delete \" %s \" : %s \n " ), wdir
, strerror ( errno
));
54 if ( debug
) debuga ( _ ( "Making index.html \n " ));
56 // convert any old report hierarchy
57 if (( dirp
= opendir ( outdir
)) == NULL
) {
58 debuga ( _ ( "Failed to open directory %s - %s \n " ), outdir
, strerror ( errno
));
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
);
66 date_index_to_file_index ( direntp
-> d_name
);
71 if ( IndexTree
== INDEX_TREE_DATE
) {
78 static void make_date_index ( void )
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
];
88 char monthindex
[ MAXLEN
];
89 char monthdir
[ MAXLEN
];
90 char monthname1
[ 9 ], monthname2
[ 9 ];
93 char dayindex
[ MAXLEN
];
108 sprintf ( yearindex
, "%sindex.html" , outdir
);
111 if (( dirp
= opendir ( outdir
)) == NULL
) {
112 debuga ( _ ( "Failed to open directory %s - %s \n " ), outdir
, strerror ( errno
));
115 while (( direntp
= readdir ( dirp
)) != NULL
) {
116 if ( strlen ( direntp
-> d_name
) > 4 || ! isdigit ( direntp
-> d_name
[ 0 ]) || ! isdigit ( direntp
-> d_name
[ 1 ]) ||
117 ! isdigit ( direntp
-> d_name
[ 2 ]) || ! isdigit ( direntp
-> d_name
[ 3 ])) continue ;
118 year
= atoi ( direntp
-> d_name
);
119 if ( nyears
>= sizeof ( yearsort
)/ sizeof ( yearsort
[ 0 ])) {
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.
125 if ( year
> yearsort
[ 0 ]) {
126 for ( i
= 1 ; i
< nyears
&& year
> yearsort
[ i
] ; i
++)
127 yearsort
[ i
- 1 ]= yearsort
[ i
];
131 for ( i
= nyears
; i
> 0 && year
< yearsort
[ i
- 1 ] ; i
--) {
132 yearsort
[ i
]= yearsort
[ i
- 1 ];
140 order
=( strcmp ( IndexSortOrder
, "A" ) == 0 ) ? 1 : - 1 ;
142 if (( fp_ou
= fopen ( yearindex
, "w" ))== NULL
) {
143 debuga ( _ ( "(index) Cannot open file %s: %s \n " ), yearindex
, strerror ( errno
));
146 write_html_header ( fp_ou
, 0 , ngettext ( "SARG report" , "SARG reports" , nyears
), HTML_JS_NONE
);
147 close_html_header ( fp_ou
);
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
);
153 for ( y
= 0 ; y
< nyears
; y
++) {
157 year
= yearsort
[ nyears
- 1 - y
];
158 sprintf ( yearnum
, "%04d" , year
);
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
);
163 sprintf ( yeardir
, "%s%s" , outdir
, yearnum
);
166 if (( dirp2
= opendir ( yeardir
)) == NULL
) {
167 debuga ( _ ( "Failed to open directory %s - %s \n " ), yeardir
, strerror ( errno
));
170 while (( direntp2
= readdir ( dirp2
)) != NULL
) {
171 if (! isdigit ( direntp2
-> d_name
[ 0 ]) || ! isdigit ( direntp2
-> d_name
[ 1 ])) continue ;
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' ) {
181 if ( nmonths
>= sizeof ( monthsort
)/ sizeof ( monthsort
[ 0 ])) {
182 debuga ( _ ( "Too many month directories in %s \n Supernumerary entries are ignored \n " ), yeardir
);
186 for ( i
= nmonths
; i
> 0 && month
< monthsort
[ i
- 1 ] ; i
--) {
187 monthsort
[ i
]= monthsort
[ i
- 1 ];
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
));
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
++) {
207 month
= monthsort
[ nmonths
- 1 - m
];
209 if ( month
% 16 != 0 ) {
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
);
218 sprintf ( nmonth
, "%02d" , m1
);
219 sprintf ( monthnum
, "%02d" , m1
);
220 name_month ( nmonth
, sizeof ( nmonth
));
222 fprintf ( fp_ou2
, "<tr><td class= \" data2 \" ><a href= \" %s/index.html \" >%s %s</a></td></tr> \n " , monthnum
, yearnum
, nmonth
);
224 sprintf ( monthdir
, "%s/%s" , yeardir
, monthnum
);
227 if (( dirp3
= opendir ( monthdir
)) == NULL
) {
228 debuga ( _ ( "Failed to open directory %s - %s \n " ), monthdir
, strerror ( errno
));
231 while (( direntp3
= readdir ( dirp3
)) != NULL
) {
232 if (! isdigit ( direntp3
-> d_name
[ 0 ]) && ! isdigit ( direntp3
-> d_name
[ 1 ])) continue ;
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' ) {
242 if ( ndays
>= sizeof ( daysort
)/ sizeof ( daysort
[ 0 ])) {
243 debuga ( _ ( "Too many day directories in %s \n Supernumerary entries are ignored \n " ), monthdir
);
247 for ( i
= ndays
; i
> 0 && day
< daysort
[ i
- 1 ] ; i
--) {
248 daysort
[ i
]= daysort
[ i
- 1 ];
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
));
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
++) {
268 day
= daysort
[ ndays
- 1 - d
];
272 sprintf ( daynum
, "%02d-%02d" , d1
, d2
);
274 sprintf ( daynum
, "%02d" , d1
);
276 fprintf ( fp_ou3
, "<tr><td class= \" data2 \" ><a href= \" %s/index.html \" >%s %s %s</a></td></tr> \n " , daynum
, yearnum
, nmonth
, daynum
);
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 ( _ ( "Write error in %s: %s \n " ), dayindex
, strerror ( errno
));
286 fputs ( "</table></div> \n " , fp_ou2
);
287 if ( write_html_trailer ( fp_ou2
)< 0 )
288 debuga ( _ ( "Write error in the index %s \n " ), monthindex
);
289 if ( fclose ( fp_ou2
)== EOF
) {
290 debuga ( _ ( "Write error in %s: %s \n " ), monthindex
, strerror ( errno
));
295 fputs ( "</table></div> \n " , fp_ou
);
296 if ( write_html_trailer ( fp_ou
)< 0 )
297 debuga ( _ ( "Write error in the index %s \n " ), yearindex
);
298 if ( fclose ( fp_ou
)== EOF
) {
299 debuga ( _ ( "Write error in %s: %s \n " ), yearindex
, strerror ( errno
));
304 static void make_file_index ( void )
306 #define MAX_CREATION_DATE 15
309 struct dirent
* direntp
;
313 char day
[ 6 ], mon
[ 8 ], year
[ 40 ], hour
[ 10 ];
314 long long int tbytes
;
316 int iyear
, imonth
, iday
, ihour
, iminute
, isecond
, idst
;
322 struct getwordstruct gwarea
;
325 int year
, month
, day
, sortnum
;
326 char creationdate
[ MAX_CREATION_DATE
];
329 } ** sortlist
, * item
, ** tempsort
;
331 sprintf ( wdir
, "%sindex.html" , outdir
);
333 order
=( strcmp ( IndexSortOrder
, "A" ) == 0 ) ? 1 : - 1 ;
335 if (( dirp
= opendir ( outdir
)) == NULL
) {
336 debuga ( _ ( "Failed to open directory %s - %s \n " ), outdir
, strerror ( errno
));
343 while (( direntp
= readdir ( dirp
)) != NULL
) {
344 if ( strchr ( direntp
-> d_name
, '-' ) == 0 ) continue ;
345 if ( obtdate ( outdir
, direntp
-> d_name
, data
)< 0 ) {
346 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
);
349 item
= malloc ( sizeof (* item
));
351 debuga ( _ ( "not enough memory to sort the index \n " ));
355 item
-> year
= atoi ( direntp
-> d_name
);
356 item
-> month
= conv_month ( direntp
-> d_name
+ 4 );
357 item
-> day
= atoi ( direntp
-> d_name
+ 7 );
359 item
-> year
= atoi ( direntp
-> d_name
+ 5 );
360 item
-> month
= conv_month ( direntp
-> d_name
+ 2 );
361 item
-> day
= atoi ( direntp
-> d_name
);
363 item
-> sortnum
=( item
-> year
* 16 + item
-> month
)* 32 + item
-> day
;
364 if ( sscanf ( data
, "%d-%d-%d %d:%d:%d %d" ,& iyear
,& imonth
,& iday
,& ihour
,& iminute
,& isecond
,& idst
)== 7 ) {
365 formatdate ( data
, sizeof ( data
), iyear
, imonth
, iday
, ihour
, iminute
, isecond
, idst
);
366 snprintf ( item
-> creationdate
, sizeof ( item
-> creationdate
), "%04d%02d%02d%02d%02d%02d" , iyear
, imonth
, iday
, ihour
, iminute
, isecond
);
369 Old code to parse a date stored by sarg before 2.2.6.1 in the sarg-date file of each report directory.
371 getword_start (& gwarea
, data
);
372 if ( getword_skip ( 16 ,& gwarea
, ' ' )< 0 ) {
373 debuga ( _ ( "Maybe you have a broken week day in your %s%s/sarg-date file \n " ), outdir
, direntp
-> d_name
);
376 if ( getword_multisep ( mon
, sizeof ( mon
),& gwarea
, ' ' )< 0 ) {
377 debuga ( _ ( "Maybe you have a broken month in your %s%s/sarg-date file \n " ), outdir
, direntp
-> d_name
);
380 if ( getword_multisep ( day
, sizeof ( day
),& gwarea
, ' ' )< 0 ) {
381 debuga ( _ ( "Maybe you have a broken day in your %s%s/sarg-date file \n " ), outdir
, direntp
-> d_name
);
384 if ( getword_multisep ( hour
, sizeof ( hour
),& gwarea
, ' ' )< 0 ) {
385 debuga ( _ ( "Maybe you have a broken time in your %s%s/sarg-date file \n " ), outdir
, direntp
-> d_name
);
389 if ( getword_multisep ( year
, sizeof ( year
),& gwarea
, ' ' )< 0 ) {
390 debuga ( _ ( "Maybe you have a broken year in your %s%s/sarg-date file \n " ), outdir
, direntp
-> d_name
);
393 } while ( year
[ 0 ] && ! isdigit ( year
[ 0 ])); //skip time zone information with spaces until the year is found
394 if ( sscanf ( hour
, "%d:%d:%d" ,& ihour
,& iminute
,& isecond
)!= 3 ) {
395 debuga ( _ ( "Maybe you have a broken time in your %s%s/sarg-date file \n " ), outdir
, direntp
-> d_name
);
398 buildymd ( day
, mon
, year
, ftime
, sizeof ( ftime
));
399 snprintf ( item
-> creationdate
, sizeof ( item
-> creationdate
), "%s%02d%02d%02d" , ftime
, ihour
, iminute
, isecond
);
401 item
-> dirname
= strdup ( direntp
-> d_name
);
402 if (! item
-> dirname
) {
403 debuga ( _ ( "Not enough memory to store the directory name \" %s \" in the index \n " ), direntp
-> d_name
);
406 safe_strcpy ( item
-> date
, data
, sizeof ( item
-> date
));
407 if ( nsort
+ 1 > nallocated
) {
409 tempsort
= realloc ( sortlist
, nallocated
* sizeof (* item
));
411 debuga ( _ ( "not enough memory to sort the index \n " ));
416 for ( i
= nsort
; i
> 0 ; i
--) {
417 if ( item
-> sortnum
> sortlist
[ i
- 1 ]-> sortnum
) break ;
418 if ( item
-> sortnum
== sortlist
[ i
- 1 ]-> sortnum
) {
419 if ( strcmp ( item
-> creationdate
, sortlist
[ i
- 1 ]-> creationdate
)>= 0 ) break ;
421 sortlist
[ i
]= sortlist
[ i
- 1 ];
429 if (( fp_ou
= fopen ( wdir
, "w" ))== NULL
) {
430 debuga ( _ ( "(index) Cannot open file %s: %s \n " ), wdir
, strerror ( errno
));
433 write_html_header ( fp_ou
, 0 , ngettext ( "SARG report" , "SARG reports" , nsort
), HTML_JS_SORTTABLE
);
434 close_html_header ( fp_ou
);
435 fputs ( "<div class= \" index \" ><table cellpadding= \" 1 \" cellspacing= \" 2 \" " , fp_ou
);
436 if ( SortTableJs
[ 0 ]) fputs ( " class= \" sortable \" " , fp_ou
);
438 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" ));
439 for ( i
= 0 ; i
< nsort
; i
++) {
443 item
= sortlist
[ nsort
- i
- 1 ];
444 tuser
= obtuser ( outdir
, item
-> dirname
);
445 obttotal ( outdir
, item
-> dirname
, tuser
,& tbytes
,& media
);
446 fputs ( "<tr><td class= \" data2 \" " , fp_ou
);
447 if ( SortTableJs
[ 0 ]) fprintf ( fp_ou
, " sorttable_customkey= \" %d \" " , item
-> sortnum
);
448 fprintf ( fp_ou
, "><a href='%s/%s'>%s</a></td>" , item
-> dirname
, ReplaceIndex
, item
-> dirname
);
449 fputs ( "<td class= \" data2 \" " , fp_ou
);
450 if ( SortTableJs
[ 0 ]) fprintf ( fp_ou
, " sorttable_customkey= \" %s \" " , item
-> creationdate
);
451 fprintf ( fp_ou
, ">%s</td>" , item
-> date
);
452 fprintf ( fp_ou
, "<td class= \" data \" >%d</td>" , tuser
);
453 fputs ( "<td class= \" data \" " , fp_ou
);
454 if ( SortTableJs
[ 0 ]) fprintf ( fp_ou
, " sorttable_customkey= \" %" PRId64
" \" " ,( int64_t ) tbytes
);
455 fprintf ( fp_ou
, ">%s</td>" , fixnum ( tbytes
, 1 ));
456 fputs ( "<td class= \" data \" " , fp_ou
);
457 if ( SortTableJs
[ 0 ]) fprintf ( fp_ou
, " sorttable_customkey= \" %" PRId64
" \" " ,( int64_t ) media
);
458 fprintf ( fp_ou
, ">%s</td></tr> \n " , fixnum ( media
, 1 ));
460 fputs ( "</table></div> \n " , fp_ou
);
461 if ( write_html_trailer ( fp_ou
)< 0 )
462 debuga ( _ ( "Write error in the index %s \n " ), wdir
);
463 if ( fclose ( fp_ou
)== EOF
)
464 debuga ( _ ( "Failed to close the index file %s - %s \n " ), wdir
, strerror ( errno
));
467 for ( i
= 0 ; i
< nsort
; i
++) {
468 free ( sortlist
[ i
]-> dirname
);
475 static void file_index_to_date_index ( const char * entry
)
477 int y1
, y2
, m1
, m2
, d1
, d2
;
482 char olddir
[ MAXLEN
], newdir
[ MAXLEN
];
484 if ( strlen ( entry
) < 19 ) return ;
488 memset ( sm1
, 0 , sizeof ( sm1
));
489 memset ( sm2
, 0 , sizeof ( sm2
));
494 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
495 y1
= y1
* 10 +( entry
[ i
++]- '0' );
497 for ( j
= 0 ; j
< sizeof ( sm1
)- 1 && entry
[ i
] && isalpha ( entry
[ i
]) ; j
++)
501 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
502 d1
= d1
* 10 +( entry
[ i
++]- '0' );
505 if ( entry
[ i
++]!= '-' ) return ;
507 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
508 y2
= y2
* 10 +( entry
[ i
++]- '0' );
510 for ( j
= 0 ; j
< sizeof ( sm2
)- 1 && entry
[ i
] && isalpha ( entry
[ i
]) ; j
++)
514 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
515 d2
= d2
* 10 +( entry
[ i
++]- '0' );
517 } else if ( df
== 'e' ) {
518 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
519 d1
= d1
* 10 +( entry
[ i
++]- '0' );
521 for ( j
= 0 ; j
< sizeof ( sm1
)- 1 && entry
[ i
] && isalpha ( entry
[ i
]) ; j
++)
525 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
526 y1
= y1
* 10 +( entry
[ i
++]- '0' );
529 if ( entry
[ i
++]!= '-' ) return ;
531 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
532 d2
= d2
* 10 +( entry
[ i
++]- '0' );
534 for ( j
= 0 ; j
< sizeof ( sm2
)- 1 && entry
[ i
] && isalpha ( entry
[ i
]) ; j
++)
538 for ( j
= 0 ; entry
[ i
] && isdigit ( entry
[ i
]) ; j
++)
539 y2
= y2
* 10 +( entry
[ i
++]- '0' );
546 ndirlen
= sprintf ( newdir
, "%s%04d" , outdir
, y1
);
547 if ( access ( newdir
, R_OK
) != 0 ) {
548 if ( mkdir ( newdir
, 0755 )) {
549 debuga ( _ ( "Cannot create directory %s - %s \n " ), newdir
, strerror ( errno
));
553 if ( m1
!= m2
) ndirlen
+= sprintf ( newdir
+ ndirlen
, "/%02d-%02d" , m1
, m2
);
554 else ndirlen
+= sprintf ( newdir
+ ndirlen
, "/%02d" , m1
);
555 if ( access ( newdir
, R_OK
) != 0 ) {
556 if ( mkdir ( newdir
, 0755 )) {
557 debuga ( _ ( "Cannot create directory %s - %s \n " ), newdir
, strerror ( errno
));
562 if ( d1
!= d2
) ndirlen
+= sprintf ( newdir
+ ndirlen
, "/%02d-%02d" , d1
, d2
);
563 else ndirlen
+= sprintf ( newdir
+ ndirlen
, "/%02d" , d1
);
565 sprintf ( olddir
, "%s%s" , outdir
, entry
);
566 if ( rename ( olddir
, newdir
)) {
567 debuga ( _ ( "(index) rename error from \" %s \" to \" %s \" - %s \n " ), olddir
, newdir
, strerror ( errno
));
571 strcpy ( newdir
+ monthlen
, "/images" );
572 if ( access ( newdir
, R_OK
) != 0 ) {
574 char linkdir
[ MAXLEN
];
576 sprintf ( linkdir
, "%simages" , outdir
);
577 if ( symlink ( linkdir
, newdir
)) {
578 debuga ( _ ( "failed to create link \" %s \" to \" %s \" - %s \n " ), linkdir
, newdir
, strerror ( errno
));
585 sprintf ( cmd
, "ln -s \" %simages \" \" %s/images \" " , outdir
, newdir
);
587 if (! WIFEXITED ( cstatus
) || WEXITSTATUS ( cstatus
)) {
588 debuga ( _ ( "command return status %d \n " ), WEXITSTATUS ( cstatus
));
589 debuga ( _ ( "command: %s \n " ), cmd
);
596 static void date_index_to_file_index ( const char * entry
)
604 const char * sm1
, * sm2
;
606 char newdir
[ MAXLEN
], olddir
[ MAXLEN
];
608 struct dirent
* direntp2
;
609 struct dirent
* direntp3
;
611 if ( strlen ( entry
) != 4 ) return ;
614 if ( sscanf ( entry
, "%d%n" ,& y1
,& next
)!= 1 || next
< 0 || entry
[ next
]) return ;
616 val1len
= snprintf ( val1
, sizeof ( val1
), "%s%s" , outdir
, entry
);
617 dirp2
= opendir ( val1
);
619 while (( direntp2
= readdir ( dirp2
)) != NULL
) {
620 if (! isdigit ( direntp2
-> d_name
[ 0 ]) || ! isdigit ( direntp2
-> d_name
[ 1 ])) continue ;
622 str
= direntp2
-> d_name
;
624 for ( j
= 0 ; j
< 2 && str
[ i
] && isdigit ( str
[ i
]) ; j
++)
625 m1
=( m1
* 10 )+( str
[ i
++]- '0' );
627 sm1
= conv_month_name ( m1
);
631 for ( j
= 0 ; j
< 2 && str
[ i
] && isdigit ( str
[ i
]) ; j
++)
632 m2
=( m2
* 10 )+( str
[ i
++]- '0' );
634 sm2
= conv_month_name ( m2
);
635 } else if (! str
[ i
]) {
641 sprintf ( val1
+ val1len
, "/%s" , direntp2
-> d_name
);
642 dirp3
= opendir ( val1
);
643 if (! dirp3
) continue ;
644 while (( direntp3
= readdir ( dirp3
)) != NULL
) {
645 if (! isdigit ( direntp3
-> d_name
[ 0 ]) || ! isdigit ( direntp3
-> d_name
[ 1 ])) continue ;
647 str
= direntp3
-> d_name
;
649 for ( j
= 0 ; str
[ i
] && isdigit ( str
[ i
]) ; j
++)
650 d1
= d1
* 10 +( str
[ i
++]- '0' );
655 for ( j
= 0 ; str
[ i
] && isdigit ( str
[ i
]) ; j
++)
656 d2
= d2
* 10 +( str
[ i
++]- '0' );
658 } else if (! str
[ i
]) {
664 if ( df
== 'u' ) sprintf ( newdir
, "%s%04d%s%02d-%04d%s%02d" , outdir
, y1
, sm1
, d1
, y1
, sm2
, d2
);
665 else if ( df
== 'e' ) sprintf ( newdir
, "%s%02d%s%04d-%02d%s%04d" , outdir
, d1
, sm1
, y1
, d2
, sm2
, y1
);
667 sprintf ( olddir
, "%s%04d/%s/%s" , outdir
, y1
, direntp2
-> d_name
, direntp3
-> d_name
);
668 if ( rename ( olddir
, newdir
)) {
669 debuga ( _ ( "(index) rename error from \" %s \" to \" %s \" - %s \n " ), olddir
, newdir
, strerror ( errno
));
678 \bug The links to the images in the reports are broken after moving the directories
679 as the the HTML files are not at the right level for the images any more.