util.c (sarg-2.3.11) | : | util.c (sarg-2.4.0) | ||
---|---|---|---|---|
/* | /* | |||
* SARG Squid Analysis Report Generator http://sarg.sourceforge.net | * SARG Squid Analysis Report Generator http://sarg.sourceforge.net | |||
* 1998, 2013 | * 1998, 2015 | |||
* | * | |||
* SARG donations: | * SARG donations: | |||
* please look at http://sarg.sourceforge.net/donations.php | * please look at http://sarg.sourceforge.net/donations.php | |||
* Support: | * Support: | |||
* http://sourceforge.net/projects/sarg/forums/forum/363374 | * http://sourceforge.net/projects/sarg/forums/forum/363374 | |||
* --------------------------------------------------------------------- | * --------------------------------------------------------------------- | |||
* | * | |||
* This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | |||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | |||
* the Free Software Foundation; either version 2 of the License, or | * the Free Software Foundation; either version 2 of the License, or | |||
skipping to change at line 33 | skipping to change at line 33 | |||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. | |||
* | * | |||
*/ | */ | |||
// #define LEGACY_MY_ATOLL | // #define LEGACY_MY_ATOLL | |||
// #define LEGACY_TESTVALIDUSERCHAR | // #define LEGACY_TESTVALIDUSERCHAR | |||
#include "include/conf.h" | #include "include/conf.h" | |||
#include "include/defs.h" | #include "include/defs.h" | |||
#if defined(__MINGW32__) && defined(HAVE_DIRECT_H) | ||||
#define NO_OLDNAMES 1 | ||||
#include <direct.h> | ||||
#endif | ||||
#if defined(HAVE_BACKTRACE) | #if defined(HAVE_BACKTRACE) | |||
#define USE_GETWORD_BACKTRACE 1 | #define USE_GETWORD_BACKTRACE 1 | |||
#else | #else | |||
#define USE_GETWORD_BACKTRACE 0 | #define USE_GETWORD_BACKTRACE 0 | |||
#endif | #endif | |||
static char mtab1[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep", "Oct","Nov","Dec"}; | static char mtab1[12][4]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep", "Oct","Nov","Dec"}; | |||
//! The list of the HTTP codes to exclude from the report. | //! The list of the HTTP codes to exclude from the report. | |||
static char *excludecode=NULL; | static char *excludecode=NULL; | |||
//! Directory where the images are stored. | ||||
char ImageDir[MAXLEN]=IMAGEDIR; | ||||
extern char *CurrentLocale; | extern char *CurrentLocale; | |||
#if USE_GETWORD_BACKTRACE | #if USE_GETWORD_BACKTRACE | |||
static void getword_backtrace(void) | static void getword_backtrace(void) | |||
{ | { | |||
void *buffer[5]; | void *buffer[5]; | |||
int i, n; | int i, n; | |||
char **calls; | char **calls; | |||
n=backtrace(buffer,sizeof(buffer)/sizeof(buffer[0])); | n=backtrace(buffer,sizeof(buffer)/sizeof(buffer[0])); | |||
if (n<=0) return; | if (n<=0) return; | |||
calls=backtrace_symbols(buffer,n); | calls=backtrace_symbols(buffer,n); | |||
if (calls) { | if (calls) { | |||
/* TRANSLATORS: "getword" is the function displaying | debuga(__FILE__,__LINE__,_("getword backtrace:\n")); | |||
* the backtrace leading to its execution. | ||||
*/ | ||||
debuga(_("getword backtrace:\n")); | ||||
for (i=0 ; i<n ; i++) { | for (i=0 ; i<n ; i++) { | |||
fprintf(stderr,"SARG: %d:%s\n",i+1,calls[i]); | fprintf(stderr,"SARG: %d:%s\n",i+1,calls[i]); | |||
} | } | |||
free(calls); | free(calls); | |||
} | } | |||
} | } | |||
#endif //USE_GETWORD_BACKTRACE | #endif //USE_GETWORD_BACKTRACE | |||
void getword_start(struct getwordstruct *gwarea, const char *line) | void getword_start(struct getwordstruct *gwarea, const char *line) | |||
{ | { | |||
gwarea->beginning=line; | gwarea->beginning=line; | |||
gwarea->current=line; | gwarea->current=line; | |||
gwarea->modified=0; | gwarea->modified=0; | |||
} | } | |||
void getword_restart(struct getwordstruct *gwarea) | void getword_restart(struct getwordstruct *gwarea) | |||
{ | { | |||
if (gwarea->modified) { | if (gwarea->modified) { | |||
debuga(_("Cannot parse again the line as it was modified\n")); | debuga(__FILE__,__LINE__,_("Cannot parse again the line as it was modified\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
gwarea->current=gwarea->beginning; | gwarea->current=gwarea->beginning; | |||
} | } | |||
int getword(char *word, int limit, struct getwordstruct *gwarea, char stop) | int getword(char *word, int limit, struct getwordstruct *gwarea, char stop) | |||
{ | { | |||
int x; | int x; | |||
for(x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++) { | for (x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++) { | |||
if(x>=limit) { | if (x>=limit) { | |||
/* TRANSLATORS: %s is the name of the function reporting | /* | |||
this error. | TRANSLATORS: The %s is the name of the function reportin | |||
g the | ||||
error message. | ||||
*/ | */ | |||
debuga(_("Loop detected in %s after %d bytes.\n"),__func_ | debuga(__FILE__,__LINE__,_("End of word not found in %s a | |||
_,x); | fter %d bytes.\n"),__func__,x); | |||
debuga(_("Line=\"%s\"\n"),gwarea->beginning); | debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->begin | |||
debuga(_("Record=\"%s\"\n"),gwarea->current); | ning); | |||
debuga(_("searching for \'x%x\'\n"),stop); | debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->cur | |||
rent); | ||||
debuga(__FILE__,__LINE__,_("searching for \'x%x\'\n"),sto | ||||
p); | ||||
word[(limit>0) ? limit-1 : 0]='\0'; | word[(limit>0) ? limit-1 : 0]='\0'; | |||
#if USE_GETWORD_BACKTRACE | #if USE_GETWORD_BACKTRACE | |||
getword_backtrace(); | getword_backtrace(); | |||
#endif | #endif | |||
return(-1); | return(-1); | |||
} | } | |||
word[x] = gwarea->current[x]; | word[x] = gwarea->current[x]; | |||
} | } | |||
word[x] = '\0'; | word[x] = '\0'; | |||
if (gwarea->current[x]) ++x; | if (gwarea->current[x]) ++x; | |||
gwarea->current+=x; | gwarea->current+=x; | |||
return(0); | return(0); | |||
} | } | |||
int getword_limit(char *word, int limit, struct getwordstruct *gwarea, char stop ) | int getword_limit(char *word, int limit, struct getwordstruct *gwarea, char stop ) | |||
{ | { | |||
int x; | int x; | |||
limit--; | limit--; | |||
for(x=0; x<limit && gwarea->current[x] && gwarea->current[x] != stop ;x++ ) { | for (x=0; x<limit && gwarea->current[x] && gwarea->current[x] != stop ;x+ +) { | |||
word[x] = gwarea->current[x]; | word[x] = gwarea->current[x]; | |||
} | } | |||
word[x] = '\0'; | word[x] = '\0'; | |||
gwarea->current+=x; | gwarea->current+=x; | |||
while (*gwarea->current && *gwarea->current != stop) gwarea->current++; | while (*gwarea->current && *gwarea->current != stop) gwarea->current++; | |||
if (*gwarea->current) ++gwarea->current; | if (*gwarea->current) ++gwarea->current; | |||
return(0); | return(0); | |||
} | } | |||
int getword_multisep(char *word, int limit, struct getwordstruct *gwarea, char s top) | int getword_multisep(char *word, int limit, struct getwordstruct *gwarea, char s top) | |||
{ | { | |||
int x; | int x; | |||
for(x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++) { | for (x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++) { | |||
if(x>=limit) { | if (x>=limit) { | |||
/* TRANSLATORS: %s is the name of the function reporting | debuga(__FILE__,__LINE__,_("End of word not found in %s a | |||
this error. | fter %d bytes.\n"),__func__,x); | |||
*/ | debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->begin | |||
debuga(_("Loop detected in %s after %d bytes.\n"),__func_ | ning); | |||
_,x); | debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->cur | |||
debuga(_("Line=\"%s\"\n"),gwarea->beginning); | rent); | |||
debuga(_("Record=\"%s\"\n"),gwarea->current); | debuga(__FILE__,__LINE__,_("searching for \'x%x\'\n"),sto | |||
debuga(_("searching for \'x%x\'\n"),stop); | p); | |||
if (limit>0) word[limit-1]='\0'; | if (limit>0) word[limit-1]='\0'; | |||
#if USE_GETWORD_BACKTRACE | #if USE_GETWORD_BACKTRACE | |||
getword_backtrace(); | getword_backtrace(); | |||
#endif | #endif | |||
//exit(EXIT_FAILURE); | //exit(EXIT_FAILURE); | |||
return(-1); | return(-1); | |||
} | } | |||
word[x] = gwarea->current[x]; | word[x] = gwarea->current[x]; | |||
} | } | |||
word[x] = '\0'; | word[x] = '\0'; | |||
while (gwarea->current[x] && gwarea->current[x]==stop) ++x; | while (gwarea->current[x] && gwarea->current[x]==stop) ++x; | |||
gwarea->current+=x; | gwarea->current+=x; | |||
return(0); | return(0); | |||
} | } | |||
int getword_skip(int limit, struct getwordstruct *gwarea, char stop) | int getword_skip(int limit, struct getwordstruct *gwarea, char stop) | |||
{ | { | |||
int x; | int x; | |||
for(x=0;(gwarea->current[x] && (gwarea->current[x] != stop ));x++) { | for (x=0;(gwarea->current[x] && (gwarea->current[x] != stop ));x++) { | |||
if(x>=limit) { | if (x>=limit) { | |||
/* TRANSLATORS: %s is the name of the function reporting | debuga(__FILE__,__LINE__,_("End of word not found in %s a | |||
this error. | fter %d bytes.\n"),__func__,x); | |||
*/ | debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->begin | |||
debuga(_("Loop detected in %s after %d bytes.\n"),__func_ | ning); | |||
_,x); | debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->cur | |||
debuga(_("Line=\"%s\"\n"),gwarea->beginning); | rent); | |||
debuga(_("Record=\"%s\"\n"),gwarea->current); | debuga(__FILE__,__LINE__,_("searching for \'x%x\'\n"),sto | |||
debuga(_("searching for \'x%x\'\n"),stop); | p); | |||
#if USE_GETWORD_BACKTRACE | #if USE_GETWORD_BACKTRACE | |||
getword_backtrace(); | getword_backtrace(); | |||
#endif | #endif | |||
return(-1); | return(-1); | |||
} | } | |||
} | } | |||
if (gwarea->current[x]) ++x; | if (gwarea->current[x]) ++x; | |||
gwarea->current+=x; | gwarea->current+=x; | |||
return(0); | return(0); | |||
skipping to change at line 192 | skipping to change at line 195 | |||
int sign=+1; | int sign=+1; | |||
int digit; | int digit; | |||
if (gwarea->current[0] == '-') { | if (gwarea->current[0] == '-') { | |||
gwarea->current++; | gwarea->current++; | |||
sign=-1; | sign=-1; | |||
} else if (gwarea->current[0] == '+') { | } else if (gwarea->current[0] == '+') { | |||
gwarea->current++; | gwarea->current++; | |||
} | } | |||
*number=0LL; | *number=0LL; | |||
for(x=0;isdigit(gwarea->current[x]);x++) { | for (x=0;isdigit(gwarea->current[x]);x++) { | |||
digit=gwarea->current[x]-'0'; | digit=gwarea->current[x]-'0'; | |||
if (*number >= (LLONG_MAX-digit)/10) { | if (*number >= (LLONG_MAX-digit)/10) { | |||
/* TRANSLATORS: The first %s is the name of the function | /* | |||
displaying | TRANSLATORS: The first %s is the function name (in the s | |||
* this message. | ource code) where the | |||
*/ | overflow is detected. | |||
debuga(_("Integer overflow detected in %s in line \"%s\"\ | */ | |||
n"),__func__,gwarea->beginning); | debuga(__FILE__,__LINE__,_("Integer overflow detected in | |||
%s in line %s\n"),__func__,gwarea->beginning); | ||||
return(-1); | return(-1); | |||
} | } | |||
*number=(*number * 10) + digit; | *number=(*number * 10) + digit; | |||
} | } | |||
if(gwarea->current[x] && gwarea->current[x]!=stop) { | if (gwarea->current[x] && gwarea->current[x]!=stop) { | |||
/* TRANSLATORS: %s is the name of the function reporting this err | /* | |||
or. | TRANSLATORS: The %s is the function name, in the source code, wh | |||
*/ | ere the problem occured. | |||
debuga(_("Loop detected in %s after %d bytes.\n"),__func__,x); | */ | |||
debuga(_("Line=\"%s\"\n"),gwarea->beginning); | debuga(__FILE__,__LINE__,_("End of number not found in %s after % | |||
debuga(_("Record=\"%s\"\n"),gwarea->current); | d bytes.\n"),__func__,x); | |||
debuga(_("searching for \'x%x\'\n"),stop); | debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->beginning); | |||
debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->current); | ||||
debuga(__FILE__,__LINE__,_("searching for \'x%x\'\n"),stop); | ||||
#if USE_GETWORD_BACKTRACE | #if USE_GETWORD_BACKTRACE | |||
getword_backtrace(); | getword_backtrace(); | |||
#endif | #endif | |||
return(-1); | return(-1); | |||
} | } | |||
*number*=sign; | *number*=sign; | |||
if (gwarea->current[x]) ++x; | if (gwarea->current[x]) ++x; | |||
gwarea->current+=x; | gwarea->current+=x; | |||
return(0); | return(0); | |||
skipping to change at line 235 | skipping to change at line 240 | |||
int sign=+1; | int sign=+1; | |||
int digit; | int digit; | |||
if (gwarea->current[0] == '-') { | if (gwarea->current[0] == '-') { | |||
gwarea->current++; | gwarea->current++; | |||
sign=-1; | sign=-1; | |||
} else if (gwarea->current[0] == '+') { | } else if (gwarea->current[0] == '+') { | |||
gwarea->current++; | gwarea->current++; | |||
} | } | |||
*number=0; | *number=0; | |||
for(x=0;isdigit(gwarea->current[x]);x++) { | for (x=0;isdigit(gwarea->current[x]);x++) { | |||
digit=gwarea->current[x]-'0'; | digit=gwarea->current[x]-'0'; | |||
if (*number > (INT_MAX-digit)/10) { | if (*number > (INT_MAX-digit)/10) { | |||
/* TRANSLATORS: The first %s is the name of the function | debuga(__FILE__,__LINE__,_("Integer overflow detected in | |||
displaying | %s in line %s\n"),__func__,gwarea->beginning); | |||
* this message. | ||||
*/ | ||||
debuga(_("Integer overflow detected in %s in line \"%s\"\ | ||||
n"),__func__,gwarea->beginning); | ||||
return(-1); | return(-1); | |||
} | } | |||
*number=(*number * 10) + digit; | *number=(*number * 10) + digit; | |||
} | } | |||
if(gwarea->current[x] && gwarea->current[x]!=stop) { | if (gwarea->current[x] && gwarea->current[x]!=stop) { | |||
/* TRANSLATORS: %s is the name of the function reporting this err | debuga(__FILE__,__LINE__,_("End of number not found in %s after % | |||
or. | d bytes.\n"),__func__,x); | |||
*/ | debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->beginning); | |||
debuga(_("Loop detected in %s after %d bytes.\n"),__func__,x); | debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->current); | |||
debuga(_("Line=\"%s\"\n"),gwarea->beginning); | debuga(__FILE__,__LINE__,_("searching for \'x%x\'\n"),stop); | |||
debuga(_("Record=\"%s\"\n"),gwarea->current); | #if USE_GETWORD_BACKTRACE | |||
debuga(_("searching for \'x%x\'\n"),stop); | getword_backtrace(); | |||
#endif | ||||
return(-1); | ||||
} | ||||
*number*=sign; | ||||
if (gwarea->current[x]) ++x; | ||||
gwarea->current+=x; | ||||
return(0); | ||||
} | ||||
int getword_atol(long int *number, struct getwordstruct *gwarea, char stop) | ||||
{ | ||||
int x; | ||||
long int sign=+1; | ||||
int digit; | ||||
if (gwarea->current[0] == '-') { | ||||
gwarea->current++; | ||||
sign=-1; | ||||
} else if (gwarea->current[0] == '+') { | ||||
gwarea->current++; | ||||
} | ||||
*number=0; | ||||
for (x=0;isdigit(gwarea->current[x]);x++) { | ||||
digit=gwarea->current[x]-'0'; | ||||
if (*number > (LONG_MAX-digit)/10) { | ||||
debuga(__FILE__,__LINE__,_("Integer overflow detected in | ||||
%s in line %s\n"),__func__,gwarea->beginning); | ||||
return(-1); | ||||
} | ||||
*number=(*number * 10) + digit; | ||||
} | ||||
if (gwarea->current[x] && gwarea->current[x]!=stop) { | ||||
debuga(__FILE__,__LINE__,_("End of number not found in %s after % | ||||
d bytes.\n"),__func__,x); | ||||
debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->beginning); | ||||
debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->current); | ||||
debuga(__FILE__,__LINE__,_("searching for \'x%x\'\n"),stop); | ||||
#if USE_GETWORD_BACKTRACE | #if USE_GETWORD_BACKTRACE | |||
getword_backtrace(); | getword_backtrace(); | |||
#endif | #endif | |||
return(-1); | return(-1); | |||
} | } | |||
*number*=sign; | *number*=sign; | |||
if (gwarea->current[x]) ++x; | if (gwarea->current[x]) ++x; | |||
gwarea->current+=x; | gwarea->current+=x; | |||
return(0); | return(0); | |||
} | } | |||
int getword_atolu(unsigned long int *number, struct getwordstruct *gwarea, char | ||||
stop) | ||||
{ | ||||
int x; | ||||
int digit; | ||||
if (gwarea->current[0] == '-') { | ||||
debuga(__FILE__,__LINE__,_("getword_atolu got a negative number.\ | ||||
n")); | ||||
debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->beginning); | ||||
debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->current); | ||||
return(-1); | ||||
} | ||||
if (gwarea->current[0] == '+') { | ||||
gwarea->current++; | ||||
} | ||||
*number=0; | ||||
for (x=0;isdigit(gwarea->current[x]);x++) { | ||||
digit=gwarea->current[x]-'0'; | ||||
if (*number > (ULONG_MAX-digit)/10) { | ||||
debuga(__FILE__,__LINE__,_("Integer overflow detected in | ||||
%s in line %s\n"),__func__,gwarea->beginning); | ||||
return(-1); | ||||
} | ||||
*number=(*number * 10) + digit; | ||||
} | ||||
if (gwarea->current[x] && gwarea->current[x]!=stop) { | ||||
debuga(__FILE__,__LINE__,_("End of number not found in %s after % | ||||
d bytes.\n"),__func__,x); | ||||
debuga(__FILE__,__LINE__,_("Line=\"%s\"\n"),gwarea->beginning); | ||||
debuga(__FILE__,__LINE__,_("Record=\"%s\"\n"),gwarea->current); | ||||
debuga(__FILE__,__LINE__,_("searching for \'x%x\'\n"),stop); | ||||
#if USE_GETWORD_BACKTRACE | ||||
getword_backtrace(); | ||||
#endif | ||||
return(-1); | ||||
} | ||||
if (gwarea->current[x]) ++x; | ||||
gwarea->current+=x; | ||||
return(0); | ||||
} | ||||
int getword_ptr(char *orig_line,char **word, struct getwordstruct *gwarea, char stop) | int getword_ptr(char *orig_line,char **word, struct getwordstruct *gwarea, char stop) | |||
{ | { | |||
/*! | /*! | |||
\note Why pass the original buffer to the function ? Because we must modi fy it to | \note Why pass the original buffer to the function ? Because we must modi fy it to | |||
insert the terminating ASCII zero for the word we return and that's not c ompatible | insert the terminating ASCII zero for the word we return and that's not c ompatible | |||
with getword_restart(). Moreover, getword_start() sometime works on const ant strings | with getword_restart(). Moreover, getword_start() sometime works on const ant strings | |||
so this function require the original buffer to detect any missuse. | so this function require the original buffer to detect any missuse. | |||
*/ | */ | |||
int x; | int x; | |||
int sep; | int sep; | |||
int start; | int start; | |||
if (orig_line && orig_line!=gwarea->beginning) { | if (orig_line && orig_line!=gwarea->beginning) { | |||
debuga(_("Invalid buffer passed to getword_ptr\n")); | debuga(__FILE__,__LINE__,_("Invalid buffer passed to getword_ptr\ n")); | |||
return(-1); | return(-1); | |||
} | } | |||
start=(gwarea->current-gwarea->beginning); | start=(gwarea->current-gwarea->beginning); | |||
if (word && orig_line) *word=orig_line+start; | if (word && orig_line) *word=orig_line+start; | |||
for(x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++); | for (x=0;((gwarea->current[x]) && (gwarea->current[x] != stop ));x++); | |||
sep=(gwarea->current[x]!='\0'); | sep=(gwarea->current[x]!='\0'); | |||
if (word && orig_line) orig_line[start+x] = '\0'; | if (word && orig_line) orig_line[start+x] = '\0'; | |||
if (sep) ++x; | if (sep) ++x; | |||
gwarea->current+=x; | gwarea->current+=x; | |||
gwarea->modified=1; | gwarea->modified=1; | |||
return(0); | return(0); | |||
} | } | |||
#define MAXLLL 30 //!< Maximum number of digits in long long (a guess). | #define MAXLLL 30 //!< Maximum number of digits in long long (a guess). | |||
long long int my_atoll (const char *nptr) | long long int my_atoll (const char *nptr) | |||
skipping to change at line 319 | skipping to change at line 396 | |||
{ | { | |||
returnval = ( returnval * 10 ) + ( *nptr++ - '0' ) ; | returnval = ( returnval * 10 ) + ( *nptr++ - '0' ) ; | |||
} | } | |||
return returnval; | return returnval; | |||
} | } | |||
int is_absolute(const char *path) | int is_absolute(const char *path) | |||
{ | { | |||
if (*path=='/') return(1); | if (*path=='/') return(1); | |||
#ifdef WINDOWS | #ifdef _WIN32 | |||
if (isalpha(path[0]) && path[1]==':') return(1); | if (isalpha(path[0]) && path[1]==':') return(1); | |||
#endif | #endif | |||
return(0); | return(0); | |||
} | } | |||
void my_mkdir(const char *name) | int PortableMkDir(const char *path,int mode) | |||
{ | ||||
#if defined(__linux__) | ||||
int mkerror=mkdir(path,mode); | ||||
#else //mingw | ||||
(void)mode; | ||||
int mkerror=_mkdir(path); | ||||
#endif | ||||
return(mkerror); | ||||
} | ||||
/*! | ||||
* Recursively create a path by adding missing directory until the whole path is | ||||
created. | ||||
* \param name The path to create. | ||||
* \return True if the directory was created or false if it already existed | ||||
*/ | ||||
bool my_mkdir(const char *name) | ||||
{ | { | |||
char w0[MAXLEN]; | char w0[MAXLEN]; | |||
int i; | int i; | |||
int chars; | int chars; | |||
bool created = false; | ||||
struct stat st; | ||||
if(!is_absolute(name)) { | if (!is_absolute(name)) { | |||
debuga(_("Invalid path \"%s\". Please, use absolute paths only.\n | debuga(__FILE__,__LINE__,_("Invalid path (%s). Please, use absolu | |||
"),name); | te paths only.\n"),name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
chars=0; | chars=0; | |||
for (i=0 ; name[i] ; i++) { | for (i=0 ; name[i] ; i++) { | |||
if (i>=sizeof(w0)) { | if (i>=sizeof(w0)) { | |||
debuga(_("Path too long: ")); | debuga(__FILE__,__LINE__,_("Path too long: ")); | |||
debuga_more("%s\n",name); | debuga_more("%s\n",name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (chars>0 && name[i] == '/') { | if (chars>0 && name[i] == '/') { | |||
w0[i] = '\0'; | w0[i] = '\0'; | |||
if (access(w0, R_OK) != 0) { | if (access(w0, R_OK) != 0) { | |||
if (mkdir(w0,0755)) { | if (PortableMkDir(w0,0755)) { | |||
debuga(_("Cannot create directory \"%s\": | debuga(__FILE__,__LINE__,_("Cannot create | |||
%s\n"),w0,strerror(errno)); | directory \"%s\": %s\n"),w0,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} | } | |||
} | } | |||
if (name[i] != '/') chars++; | if (name[i] != '/') chars++; | |||
w0[i] = name[i]; | w0[i] = name[i]; | |||
} | } | |||
if (access(name, R_OK) != 0) { | if (access(name, R_OK) != 0) { | |||
if (mkdir(name,0755)) { | if (PortableMkDir(name,0755)) { | |||
debuga(_("Cannot create directory \"%s\": %s\n"),name,str | debuga(__FILE__,__LINE__,_("Cannot create directory \"%s\ | |||
error(errno)); | ": %s\n"),name,strerror(errno)); | |||
exit(EXIT_FAILURE); | ||||
} | ||||
created = true; | ||||
} | ||||
if (!created) { | ||||
/* | ||||
* Check the final path is a directory (symlink to a directory is | ||||
ok). | ||||
*/ | ||||
if (stat(name, &st)) { | ||||
debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"), n | ||||
ame, strerror(errno)); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
if (!S_ISDIR(st.st_mode)) { | ||||
debuga(__FILE__,__LINE__,_("Directory \"%s\" can't be cre | ||||
ated because the path already exists and is not a directory\n"), name); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} | } | |||
return created; | ||||
} | ||||
void makeTmpDir(const char *tmp) | ||||
{ | ||||
/* | ||||
* We must ensure the temporary directory is ours. In particular, we must | ||||
make sure no malicious | ||||
* users managed to create or replace the temporary directory with a syml | ||||
ink to a system directory. | ||||
* As sarg purges the content of the temporary directory upon exit, shoul | ||||
d the temporary directory | ||||
* be hijacked, sarg could be tricked in deleting system files such as /b | ||||
in or users files in /home | ||||
* or logs in /var/log. | ||||
* | ||||
* The code first create the temporary directory. If it wasn't created, t | ||||
he content is checked and | ||||
* purged if it looks safe to delete every file and directory it contains | ||||
. | ||||
*/ | ||||
if (!my_mkdir(tmp)) { | ||||
if (debug) debuga(__FILE__, __LINE__, _("Purging temporary direct | ||||
ory \"%s\"\n"), tmp); | ||||
emptytmpdir(tmp); | ||||
} | ||||
} | } | |||
void my_lltoa(unsigned long long int n, char *s, int ssize, int len) | void my_lltoa(unsigned long long int n, char *s, int ssize, int len) | |||
{ | { | |||
int i; | int i; | |||
int slen = 0; | int slen = 0; | |||
int j; | int j; | |||
char c; | char c; | |||
ssize--; | ssize--; | |||
if (len>ssize) { | if (len>ssize) { | |||
debuga(_("The requested number of digits passed to my_lltoa (%d) is bigger than the output buffer size (%d)\n"),len,ssize); | debuga(__FILE__,__LINE__,_("The requested number of digits passed to my_lltoa (%d) is bigger than the output buffer size (%d)\n"),len,ssize); | |||
abort(); | abort(); | |||
} | } | |||
do { | do { | |||
s[slen++] = (n % 10) + '0'; | s[slen++] = (n % 10) + '0'; | |||
} while ((n /= 10) > 0 && slen<ssize); | } while ((n /= 10) > 0 && slen<ssize); | |||
s[slen] = '\0'; | s[slen] = '\0'; | |||
for (i = 0, j = slen-1; i<j; i++, j--) { | for (i = 0, j = slen-1; i<j; i++, j--) { | |||
c = s[i]; | c = s[i]; | |||
s[i] = s[j]; | s[i] = s[j]; | |||
s[j] = c; | s[j] = c; | |||
} | } | |||
if(len>slen) { | if (len>slen) { | |||
i=len-slen; | i=len-slen; | |||
for(j=slen; j>=0; j--) | for (j=slen; j>=0; j--) | |||
s[j+i]=s[j]; | s[j+i]=s[j]; | |||
for(j=0 ; j<i ; j++) | for (j=0 ; j<i ; j++) | |||
s[j]='0'; | s[j]='0'; | |||
} | } | |||
} | } | |||
int month2num(const char *month) | int month2num(const char *month) | |||
{ | { | |||
int m; | int m; | |||
for(m=0 ; m<12 && strcmp(mtab1[m],month) != 0; m++); | for (m=0 ; m<12 && strcmp(mtab1[m],month) != 0; m++); | |||
return(m); | return(m); | |||
} | } | |||
int builddia(int day, int month, int year) | int builddia(int day, int month, int year) | |||
{ | { | |||
return(year*10000+month*100+day); | return(year*10000+month*100+day); | |||
} | } | |||
/*! | ||||
Compare two dates. | ||||
\param date1 The first date to compare. | ||||
\param date2 The second date to compare. | ||||
\retval -1 If date1<date2. | ||||
\retval 0 If date1==date2. | ||||
\retval 1 if date1>date2. | ||||
*/ | ||||
int compare_date(const struct tm *date1,const struct tm *date2) | ||||
{ | ||||
if (date1->tm_year<date2->tm_year) return(-1); | ||||
if (date1->tm_year>date2->tm_year) return(1); | ||||
if (date1->tm_mon<date2->tm_mon) return(-1); | ||||
if (date1->tm_mon>date2->tm_mon) return(1); | ||||
if (date1->tm_mday<date2->tm_mday) return(-1); | ||||
if (date1->tm_mday>date2->tm_mday) return(1); | ||||
if (date1->tm_hour<date2->tm_hour) return(-1); | ||||
if (date1->tm_hour>date2->tm_hour) return(1); | ||||
if (date1->tm_min<date2->tm_min) return(-1); | ||||
if (date1->tm_min>date2->tm_min) return(1); | ||||
if (date1->tm_sec<date2->tm_sec) return(-1); | ||||
if (date1->tm_sec>date2->tm_sec) return(1); | ||||
return(0); | ||||
} | ||||
void buildymd(const char *dia, const char *mes, const char *ano, char *wdata,int wdata_size) | void buildymd(const char *dia, const char *mes, const char *ano, char *wdata,int wdata_size) | |||
{ | { | |||
int nmes; | int nmes; | |||
nmes=month2num(mes); | nmes=month2num(mes); | |||
snprintf(wdata,wdata_size,"%04d%02d%02d",atoi(ano),nmes+1,atoi(dia)); | snprintf(wdata,wdata_size,"%04d%02d%02d",atoi(ano),nmes+1,atoi(dia)); | |||
} | } | |||
int conv_month(const char *month) | int conv_month(const char *month) | |||
{ | { | |||
int x; | int x; | |||
for(x=0; x<12 && strncmp(mtab1[x],month,3)!=0; x++); | for (x=0; x<12 && strncmp(mtab1[x],month,3)!=0; x++); | |||
return(x+1); | return(x+1); | |||
} | } | |||
const char *conv_month_name(int month) | const char *conv_month_name(int month) | |||
{ | { | |||
static char str[4]; | static char str[4]; | |||
if (month<1 || month>12) { | if (month<1 || month>12) { | |||
snprintf(str,sizeof(str),"%03d",month); | snprintf(str,sizeof(str),"%03d",month); | |||
return(str); | return(str); | |||
} | } | |||
return(mtab1[month-1]); | return(mtab1[month-1]); | |||
} | } | |||
void name_month(char *month,int month_len) | ||||
{ | ||||
int x, z=atoi(month)-1; | ||||
char m[255]; | ||||
char w[20]; | ||||
struct getwordstruct gwarea; | ||||
strcpy(m,_("January,February,March,April,May,June,July,August,September,O | ||||
ctober,November,December")); | ||||
getword_start(&gwarea,m); | ||||
for(x=0; x<z; x++) | ||||
if (getword_multisep(w,sizeof(w),&gwarea,',')<0) { | ||||
debuga(_("The internal list of month names is invalid. Pl | ||||
ease report this bug to the translator.\n")); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
if (getword_multisep(month,month_len,&gwarea,',')<0) { | ||||
debuga(_("The internal list of month names is invalid. Please rep | ||||
ort this bug to the translator.\n")); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
} | ||||
/*! | /*! | |||
Write a debug message to stderr. The message is prefixed by "SARG:" to identify its origin. | Write a debug message to stderr. The message is prefixed by "SARG:" to identify its origin. | |||
\param msg The printf like message to format. | \param msg The printf like message to format. | |||
\param ... The arguments to format in the message. | \param ... The arguments to format in the message. | |||
*/ | */ | |||
void debuga(const char *msg,...) | void debuga(const char *File,int Line,const char *msg,...) | |||
{ | { | |||
va_list ap; | va_list ap; | |||
fputs(_("SARG: "),stderr); | if (debugz>=LogLevel_Source) { | |||
/* The path is removed because every source file is in the same d | ||||
irectory. | ||||
* There is no point in reporting the full path from the build di | ||||
rectory. | ||||
*/ | ||||
const char *ptr=strrchr(File,'/'); | ||||
if (!ptr) ptr=File; | ||||
/* TRANSLATORS: This is the prefix to stderr messages when the de | ||||
bug level is | ||||
set to display the source file (%s) and the line number (%d). */ | ||||
fprintf(stderr,_("SARG(%s:%d): "),ptr,Line); | ||||
} else { | ||||
/* TRANSLATORS: This is the prefix to stderr messages when the de | ||||
bug level | ||||
is low. */ | ||||
fputs(_("SARG: "),stderr); | ||||
} | ||||
va_start(ap,msg); | va_start(ap,msg); | |||
vfprintf(stderr,msg,ap); | vfprintf(stderr,msg,ap); | |||
va_end(ap); | va_end(ap); | |||
} | } | |||
/*! | /*! | |||
Write a debug message to stderr. The message is supposed | Write a debug message to stderr. The message is supposed | |||
to be displayed after a message from debuga(). | to be displayed after a message from debuga(). | |||
\param msg The printf like message to format. | \param msg The printf like message to format. | |||
skipping to change at line 491 | skipping to change at line 638 | |||
void debuga_more(const char *msg,...) | void debuga_more(const char *msg,...) | |||
{ | { | |||
va_list ap; | va_list ap; | |||
va_start(ap,msg); | va_start(ap,msg); | |||
vfprintf(stderr,msg,ap); | vfprintf(stderr,msg,ap); | |||
va_end(ap); | va_end(ap); | |||
} | } | |||
/*! | /*! | |||
Write a debug message to stderr. The message is prefixed by "SARG:" to identify | ||||
its origin. | ||||
\param pos Where, in the source code, this message comes from. | ||||
\param msg The printf like message to format. | ||||
\param ... The arguments to format in the message. | ||||
*/ | ||||
void debugapos(const char *pos,const char *msg,...) | ||||
{ | ||||
va_list ap; | ||||
/* TRANSLATORS: This text is printed on the console before any message fr | ||||
om | ||||
* the debug log with level "debug". | ||||
*/ | ||||
fputs(_("SARG: "),stderr); | ||||
fprintf(stderr,"(%s) ",pos); | ||||
va_start(ap,msg); | ||||
vfprintf(stderr,msg,ap); | ||||
va_end(ap); | ||||
} | ||||
/*! | ||||
Write a debug message to stderr. The message is prefixed by "SARG: (info)". | Write a debug message to stderr. The message is prefixed by "SARG: (info)". | |||
\param msg The printf like message to format. | \param msg The printf like message to format. | |||
\param ... The arguments to format in the message. | \param ... The arguments to format in the message. | |||
*/ | */ | |||
void debugaz(const char *msg,...) | void debugaz(const char *File,int Line,const char *msg,...) | |||
{ | { | |||
va_list ap; | va_list ap; | |||
/* TRANSLATORS: This text is printed on the console before any message fr | if (debugz>=LogLevel_Source) { | |||
om | /* The path is removed because every source file is in the same d | |||
* the debug log with level "info". | irectory. | |||
*/ | * There is no point in reporting the full path from the build di | |||
fputs(_("SARG: (info) "),stderr); | rectory. | |||
*/ | ||||
const char *ptr=strrchr(File,'/'); | ||||
if (!ptr) ptr=File; | ||||
/* TRANSLATORS: This is the prefix to information messages when t | ||||
he debug level is | ||||
set to display the source file (%s) and the line number (%d). */ | ||||
fprintf(stderr,_("SARG(%s:%d): (info) "),ptr,Line); | ||||
} else { | ||||
/* TRANSLATORS: This is the prefix to information messages when t | ||||
he debug level | ||||
is low. */ | ||||
fputs(_("SARG: (info) "),stderr); | ||||
} | ||||
va_start(ap,msg); | va_start(ap,msg); | |||
vfprintf(stderr,msg,ap); | vfprintf(stderr,msg,ap); | |||
va_end(ap); | va_end(ap); | |||
} | } | |||
char *fixnum(long long int value, int n) | char *fixnum(long long int value, int n) | |||
{ | { | |||
#define MAXLEN_FIXNUM 256 | #define MAXLEN_FIXNUM 256 | |||
char num[MAXLEN_FIXNUM]=""; | char num[MAXLEN_FIXNUM]=""; | |||
char buf[MAXLEN_FIXNUM * 2]; | char buf[MAXLEN_FIXNUM * 2]; | |||
char *pbuf; | char *pbuf; | |||
static char ret[MAXLEN_FIXNUM * 2]; | static char ret[MAXLEN_FIXNUM * 2]; | |||
char *pret; | char *pret; | |||
register int i, j, k; | register int i, j, k; | |||
int numlen; | int numlen; | |||
static char abbrev[30]; | static char abbrev[30]=""; | |||
my_lltoa(value, num, sizeof(num), 0); | my_lltoa(value, num, sizeof(num), 0); | |||
if(DisplayedValues==DISPLAY_ABBREV) { | if (DisplayedValues==DISPLAY_ABBREV) { | |||
numlen = strlen(num); | numlen = strlen(num); | |||
if(numlen <= 3) | if (numlen <= 3) | |||
sprintf(abbrev,"%s",num); | strcpy(abbrev,num); | |||
if(numlen == 4 || numlen == 7 || numlen == 10 || numlen == 13) { | else if (numlen%3 == 1) { | |||
snprintf(abbrev,2,"%s",num); | abbrev[0]=num[0]; | |||
strncat(abbrev,".",1); | abbrev[1]=(UseComma) ? ',' : '.'; | |||
strncat(abbrev,num+1,2); | abbrev[2]=num[1]; | |||
if(!n) return(abbrev); | abbrev[3]=num[2]; | |||
if(numlen == 4) | abbrev[4]='\0'; | |||
strncat(abbrev,"K",1); | } | |||
else if(numlen == 7) | else if (numlen%3 == 2) { | |||
strncat(abbrev,"M",1); | abbrev[0]=num[0]; | |||
else if(numlen == 10) | abbrev[1]=num[1]; | |||
strncat(abbrev,"G",1); | abbrev[2]=(UseComma) ? ',' : '.'; | |||
else if(numlen == 13) | abbrev[3]=num[2]; | |||
strncat(abbrev,"T",1); | abbrev[4]=num[3]; | |||
} | abbrev[5]='\0'; | |||
if(numlen == 5 || numlen == 8 || numlen == 11 || numlen == 14) { | } | |||
snprintf(abbrev,3,"%s",num); | else if (numlen%3 == 0) { | |||
strncat(abbrev,".",1); | abbrev[0]=num[0]; | |||
strncat(abbrev,num+2,2); | abbrev[1]=num[1]; | |||
if(!n) return(abbrev); | abbrev[2]=num[2]; | |||
if(numlen == 5) | abbrev[3]=(UseComma) ? ',' : '.'; | |||
strncat(abbrev,"K",1); | abbrev[4]=num[3]; | |||
else if(numlen == 8) | abbrev[5]=num[4]; | |||
strncat(abbrev,"M",1); | abbrev[6]='\0'; | |||
else if(numlen == 11) | } | |||
strncat(abbrev,"G",1); | if (n) { | |||
else if(numlen == 14) | if (numlen <= 3) { | |||
strncat(abbrev,"T",1); | //no prefix | |||
} | } | |||
if(numlen == 6 || numlen == 9 || numlen == 12 || numlen == 15) { | else if (numlen <= 6) | |||
snprintf(abbrev,4,"%s",num); | strcat(abbrev,"K"); | |||
strncat(abbrev,".",1); | else if (numlen <= 9) | |||
strncat(abbrev,num+3,2); | strcat(abbrev,"M"); | |||
if(!n) return(abbrev); | else if (numlen <= 12) | |||
if(numlen == 6) | strcat(abbrev,"G"); | |||
strncat(abbrev,"K",1); | else if (numlen <= 15) | |||
else if(numlen == 9) | strcat(abbrev,"T"); | |||
strncat(abbrev,"M",1); | else if (numlen >= 18) | |||
else if(numlen == 12) | strcat(abbrev,"P"); | |||
strncat(abbrev,"G",1); | else if (numlen <= 21) | |||
else if(numlen == 15) | strcat(abbrev,"E"); | |||
strncat(abbrev,"T",1); | else if (numlen <= 24) | |||
strcat(abbrev,"Z"); | ||||
else if (numlen <= 27) | ||||
strcat(abbrev,"Y"); | ||||
else | ||||
strcat(abbrev,"???"); | ||||
} | } | |||
return(abbrev); | return(abbrev); | |||
} | } | |||
bzero(buf, MAXLEN_FIXNUM*2); | memset(buf,0,MAXLEN_FIXNUM*2); | |||
pbuf = buf; | pbuf = buf; | |||
pret = ret; | pret = ret; | |||
k = 0; | k = 0; | |||
for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) { | for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) { | |||
if ( k == 2 && i != 0 ) { | if ( k == 2 && i != 0 ) { | |||
k = 0; | k = 0; | |||
pbuf[j++] = num[i]; | pbuf[j++] = num[i]; | |||
pbuf[j++] = (UseComma) ? ',' : '.'; | pbuf[j++] = (UseComma) ? ',' : '.'; | |||
skipping to change at line 633 | skipping to change at line 773 | |||
{ | { | |||
#define MAXLEN_FIXNUM2 1024 | #define MAXLEN_FIXNUM2 1024 | |||
char num[MAXLEN_FIXNUM2]; | char num[MAXLEN_FIXNUM2]; | |||
char buf[MAXLEN_FIXNUM2 * 2]; | char buf[MAXLEN_FIXNUM2 * 2]; | |||
char *pbuf; | char *pbuf; | |||
static char ret[MAXLEN_FIXNUM2 * 2]; | static char ret[MAXLEN_FIXNUM2 * 2]; | |||
char *pret; | char *pret; | |||
register int i, j, k; | register int i, j, k; | |||
my_lltoa(value, num, sizeof(num), 0); | my_lltoa(value, num, sizeof(num), 0); | |||
bzero(buf, MAXLEN_FIXNUM2*2); | memset(buf,0,MAXLEN_FIXNUM2*2); | |||
pbuf = buf; | pbuf = buf; | |||
pret = ret; | pret = ret; | |||
k = 0; | k = 0; | |||
for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) { | for ( i = strlen(num) - 1, j = 0 ; i > -1; i--) { | |||
if ( k == 2 && i != 0 ) { | if ( k == 2 && i != 0 ) { | |||
k = 0; | k = 0; | |||
pbuf[j++] = num[i]; | pbuf[j++] = num[i]; | |||
pbuf[j++] = (UseComma) ? ',' : '.'; | pbuf[j++] = (UseComma) ? ',' : '.'; | |||
skipping to change at line 694 | skipping to change at line 834 | |||
\retval 0 No error. | \retval 0 No error. | |||
\retval -1 File not found. | \retval -1 File not found. | |||
*/ | */ | |||
int obtdate(const char *dirname, const char *name, char *data) | int obtdate(const char *dirname, const char *name, char *data) | |||
{ | { | |||
FILE *fp_in; | FILE *fp_in; | |||
char wdir[MAXLEN]; | char wdir[MAXLEN]; | |||
if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-date",dirname,name)>=sizeof(wdi r)) { | if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-date",dirname,name)>=sizeof(wdi r)) { | |||
debuga(_("Buffer to small to store %s%s/sarg-date"),dirname,name) | debuga(__FILE__,__LINE__,_("Buffer too small to store ")); | |||
; | debuga_more("%s%s/sarg-date",dirname,name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((fp_in = fopen(wdir, "rt")) == 0) { | if ((fp_in = fopen(wdir, "rt")) == 0) { | |||
if (snprintf(wdir,sizeof(wdir),"%s%s/date",dirname,name)>=sizeof( wdir)) { | if (snprintf(wdir,sizeof(wdir),"%s%s/date",dirname,name)>=sizeof( wdir)) { | |||
debuga(_("Buffer to small to store %s%s/date"),dirname,na | debuga(__FILE__,__LINE__,_("Buffer too small to store ")) | |||
me); | ; | |||
debuga_more("%s%s/date",dirname,name); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((fp_in = fopen(wdir, "rt")) == 0) { | if ((fp_in = fopen(wdir, "rt")) == 0) { | |||
data[0]='\0'; | data[0]='\0'; | |||
return(-1); | return(-1); | |||
} | } | |||
} | } | |||
if (!fgets(data,80,fp_in)) { | if (!fgets(data,80,fp_in)) { | |||
/* TRANSLATORS: %s is a file name. | debuga(__FILE__,__LINE__,_("Failed to read the date in file \"%s\ | |||
*/ | "\n"),wdir); | |||
debuga(_("Failed to read the date in \"%s\"\n"),wdir); | exit(EXIT_FAILURE); | |||
} | ||||
if (fclose(fp_in)==EOF) { | ||||
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wdir,str | ||||
error(errno)); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
fclose(fp_in); | ||||
fixendofline(data); | fixendofline(data); | |||
return(0); | return(0); | |||
} | } | |||
void formatdate(char *date,int date_size,int year,int month,int day,int hour,int minute,int second,int dst) | void formatdate(char *date,int date_size,int year,int month,int day,int hour,int minute,int second,int dst) | |||
{ | { | |||
struct tm ltm; | struct tm ltm; | |||
time_t unixtime; | time_t unixtime; | |||
struct tm *fulltm; | struct tm *fulltm; | |||
skipping to change at line 756 | skipping to change at line 899 | |||
} | } | |||
int obtuser(const char *dirname, const char *name) | int obtuser(const char *dirname, const char *name) | |||
{ | { | |||
FILE *fp_in; | FILE *fp_in; | |||
char wdir[MAXLEN]; | char wdir[MAXLEN]; | |||
char tuser[20]; | char tuser[20]; | |||
int nuser; | int nuser; | |||
if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-users",dirname,name)>=sizeof(wd ir)) { | if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-users",dirname,name)>=sizeof(wd ir)) { | |||
debuga(_("Buffer too small to store %s%s/sarg-users"),dirname,nam | debuga(__FILE__,__LINE__,_("Buffer too small to store ")); | |||
e); | debuga_more("%s%s/sarg-users",dirname,name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if((fp_in=fopen(wdir,"r"))==NULL) { | if ((fp_in=fopen(wdir,"r"))==NULL) { | |||
if (snprintf(wdir,sizeof(wdir),"%s%s/users",dirname,name)>=sizeof (wdir)) { | if (snprintf(wdir,sizeof(wdir),"%s%s/users",dirname,name)>=sizeof (wdir)) { | |||
debuga(_("Buffer too small to store %s%s/users"),dirname, | debuga(__FILE__,__LINE__,_("Buffer too small to store ")) | |||
name); | ; | |||
debuga_more("%s%s/users",dirname,name); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if((fp_in=fopen(wdir,"r"))==NULL) { | if ((fp_in=fopen(wdir,"r"))==NULL) { | |||
return(0); | return(0); | |||
} | } | |||
} | } | |||
if (!fgets(tuser,sizeof(tuser),fp_in)) { | if (!fgets(tuser,sizeof(tuser),fp_in)) { | |||
/* TRANSLATORS: %s is a file name. | debuga(__FILE__,__LINE__,_("Failed to read the number of users in | |||
*/ | file \"%s\"\n"),wdir); | |||
debuga(_("Failed to read the number of users in \"%s\"\n"),wdir); | exit(EXIT_FAILURE); | |||
} | ||||
if (fclose(fp_in)==EOF) { | ||||
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wdir,str | ||||
error(errno)); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
fclose(fp_in); | ||||
nuser=atoi(tuser); | nuser=atoi(tuser); | |||
return(nuser); | return(nuser); | |||
} | } | |||
void obttotal(const char *dirname, const char *name, int nuser, long long int *t bytes, long long int *media) | void obttotal(const char *dirname, const char *name, int nuser, long long int *t bytes, long long int *media) | |||
{ | { | |||
FILE *fp_in; | FileObject *fp_in; | |||
char *buf; | char *buf; | |||
char wdir[MAXLEN]; | char wdir[MAXLEN]; | |||
char user[MAX_USER_LEN]; | char user[MAX_USER_LEN]; | |||
char sep; | char sep; | |||
struct getwordstruct gwarea; | struct getwordstruct gwarea; | |||
longline line; | longline line; | |||
*tbytes=0; | *tbytes=0; | |||
*media=0; | *media=0; | |||
if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-general",dirname,name)>=sizeof( wdir)) { | if (snprintf(wdir,sizeof(wdir),"%s%s/sarg-general",dirname,name)>=sizeof( wdir)) { | |||
debuga(_("Buffer too small to store %s%s/sarg-general"),dirname,n | debuga(__FILE__,__LINE__,_("Buffer too small to store ")); | |||
ame); | debuga_more("%s%s/sarg-general",dirname,name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((fp_in = fopen(wdir, "r")) == 0) { | if ((fp_in = FileObject_Open(wdir)) == NULL) { | |||
if (snprintf(wdir,sizeof(wdir),"%s%s/general",dirname,name)>=size of(wdir)) { | if (snprintf(wdir,sizeof(wdir),"%s%s/general",dirname,name)>=size of(wdir)) { | |||
debuga(_("Buffer too small to store %s%s/general"),dirnam | debuga(__FILE__,__LINE__,_("Buffer too small to store ")) | |||
e,name); | ; | |||
debuga_more("%s%s/general",dirname,name); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((fp_in = fopen(wdir, "r")) == 0) { | if ((fp_in = FileObject_Open(wdir)) == NULL) { | |||
return; | return; | |||
} | } | |||
} | } | |||
if ((line=longline_create())==NULL) { | if ((line=longline_create())==NULL) { | |||
debuga(_("Not enough memory to read file \"%s\"\n"),wdir); | debuga(__FILE__,__LINE__,_("Not enough memory to read file \"%s\" \n"),wdir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
while((buf=longline_read(fp_in,line))!=NULL) { | while((buf=longline_read(fp_in,line))!=NULL) { | |||
if (strncmp(buf,"TOTAL\t",6) == 0) | if (strncmp(buf,"TOTAL\t",6) == 0) | |||
sep='\t'; //new file | sep='\t'; //new file | |||
else if (strncmp(buf,"TOTAL ",6) == 0) | else if (strncmp(buf,"TOTAL ",6) == 0) | |||
sep=' '; //old file | sep=' '; //old file | |||
else | else | |||
continue; | continue; | |||
getword_start(&gwarea,buf); | getword_start(&gwarea,buf); | |||
if (getword(user,sizeof(user),&gwarea,sep)<0) { | if (getword(user,sizeof(user),&gwarea,sep)<0) { | |||
debuga(_("Invalid user in file \"%s\"\n"),wdir); | debuga(__FILE__,__LINE__,_("Invalid user in file \"%s\"\n "),wdir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if(strcmp(user,"TOTAL") != 0) | if (strcmp(user,"TOTAL") != 0) | |||
continue; | continue; | |||
if (getword_skip(MAXLEN,&gwarea,sep)<0) { | if (getword_skip(MAXLEN,&gwarea,sep)<0) { | |||
debuga(_("Invalid total number of accesses in file \"%s\" \n"),wdir); | debuga(__FILE__,__LINE__,_("Invalid total number of acces ses in file \"%s\"\n"),wdir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (getword_atoll(tbytes,&gwarea,sep)<0) { | if (getword_atoll(tbytes,&gwarea,sep)<0) { | |||
debuga(_("Invalid number of bytes in file \"%s\"\n"),wdir ); | debuga(__FILE__,__LINE__,_("Invalid number of bytes in fi le \"%s\"\n"),wdir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
break; | break; | |||
} | } | |||
fclose(fp_in); | if (FileObject_Close(fp_in)) { | |||
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),wdir,Fil | ||||
eObject_GetLastCloseError()); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
longline_destroy(&line); | longline_destroy(&line); | |||
if (nuser <= 0) | if (nuser <= 0) | |||
return; | return; | |||
*media=*tbytes / nuser; | *media=*tbytes / nuser; | |||
return; | return; | |||
} | } | |||
int getperiod_fromsarglog(const char *arqtt,struct periodstruct *period) | int getperiod_fromsarglog(const char *arqtt,struct periodstruct *period) | |||
skipping to change at line 868 | skipping to change at line 1019 | |||
str+=5; | str+=5; | |||
if (!isdigit(str[0]) || !isdigit(str[1])) continue; | if (!isdigit(str[0]) || !isdigit(str[1])) continue; | |||
day0=(str[0]-'0')*10+(str[1]-'0'); | day0=(str[0]-'0')*10+(str[1]-'0'); | |||
if (day0<1 || day0>31) continue; | if (day0<1 || day0>31) continue; | |||
str+=2; | str+=2; | |||
month0=(str[0]-'0')*10+(str[1]-'0')-1; | month0=(str[0]-'0')*10+(str[1]-'0')-1; | |||
if (month0<0 || month0>11) continue; | if (month0<0 || month0>11) continue; | |||
str+=2; | str+=2; | |||
year0=0; | year0=0; | |||
for (i=0 ; isdigit(str[i]) && i<4 ; i++) year0=year0*10+(str[i]-' 0'); | for (i=0 ; isdigit(str[i]) && i<4 ; i++) year0=year0*10+(str[i]-' 0'); | |||
if (i!=4) continue; | if (i!=4 || year0<1900) continue; | |||
str+=4; | str+=4; | |||
if (str[0]!='_') continue; | if (str[0]!='_') continue; | |||
str++; | str++; | |||
if (!isdigit(str[0]) || !isdigit(str[1])) continue; | if (!isdigit(str[0]) || !isdigit(str[1])) continue; | |||
hour0=(str[0]-'0')*10+(str[1]-'0'); | hour0=(str[0]-'0')*10+(str[1]-'0'); | |||
str+=2; | str+=2; | |||
if (!isdigit(str[0]) || !isdigit(str[1])) continue; | if (!isdigit(str[0]) || !isdigit(str[1])) continue; | |||
minute0=(str[0]-'0')*10+(str[1]-'0'); | minute0=(str[0]-'0')*10+(str[1]-'0'); | |||
str+=2; | str+=2; | |||
skipping to change at line 892 | skipping to change at line 1043 | |||
if (!isdigit(str[0]) || !isdigit(str[1])) continue; | if (!isdigit(str[0]) || !isdigit(str[1])) continue; | |||
day1=(str[0]-'0')*10+(str[1]-'0'); | day1=(str[0]-'0')*10+(str[1]-'0'); | |||
if (day1<1 || day1>31) continue; | if (day1<1 || day1>31) continue; | |||
str+=2; | str+=2; | |||
month1=(str[0]-'0')*10+(str[1]-'0')-1; | month1=(str[0]-'0')*10+(str[1]-'0')-1; | |||
if (month1<0 || month1>11) continue; | if (month1<0 || month1>11) continue; | |||
str+=2; | str+=2; | |||
year1=0; | year1=0; | |||
for (i=0 ; isdigit(str[i]) && i<4 ; i++) year1=year1*10+(str[i]-' 0'); | for (i=0 ; isdigit(str[i]) && i<4 ; i++) year1=year1*10+(str[i]-' 0'); | |||
if (i!=4) continue; | if (i!=4 || year1<1900) continue; | |||
str+=4; | str+=4; | |||
if (str[0]!='_') continue; | if (str[0]!='_') continue; | |||
str++; | str++; | |||
if (!isdigit(str[0]) || !isdigit(str[1])) continue; | if (!isdigit(str[0]) || !isdigit(str[1])) continue; | |||
hour1=(str[0]-'0')*10+(str[1]-'0'); | hour1=(str[0]-'0')*10+(str[1]-'0'); | |||
str+=2; | str+=2; | |||
if (!isdigit(str[0]) || !isdigit(str[1])) continue; | if (!isdigit(str[0]) || !isdigit(str[1])) continue; | |||
minute1=(str[0]-'0')*10+(str[1]-'0'); | minute1=(str[0]-'0')*10+(str[1]-'0'); | |||
skipping to change at line 920 | skipping to change at line 1071 | |||
period->end.tm_mday=day1; | period->end.tm_mday=day1; | |||
period->end.tm_mon=month1; | period->end.tm_mon=month1; | |||
period->end.tm_year=year1-1900; | period->end.tm_year=year1-1900; | |||
period->end.tm_hour=hour1; | period->end.tm_hour=hour1; | |||
period->end.tm_min=minute1; | period->end.tm_min=minute1; | |||
return(0); | return(0); | |||
} | } | |||
return(-1); | return(-1); | |||
} | } | |||
void getperiod_fromrange(struct periodstruct *period,int dfrom,int duntil) | /*! | |||
Fill the period with the specified range. | ||||
\param period The period to change. | ||||
\param ReadFilter Filter containing the date range to write into the period. | ||||
*/ | ||||
void getperiod_fromrange(struct periodstruct *period,const struct ReadLogDataStr | ||||
uct *ReadFilter) | ||||
{ | { | |||
int dfrom=ReadFilter->StartDate; | ||||
int duntil=ReadFilter->EndDate; | ||||
memset(&period->start,0,sizeof(period->start)); | memset(&period->start,0,sizeof(period->start)); | |||
period->start.tm_mday=dfrom%100; | period->start.tm_mday=dfrom%100; | |||
period->start.tm_mon=(dfrom/100)%100-1; | period->start.tm_mon=(dfrom/100)%100-1; | |||
period->start.tm_year=(dfrom/10000)-1900; | period->start.tm_year=(dfrom/10000)-1900; | |||
memset(&period->end,0,sizeof(period->end)); | memset(&period->end,0,sizeof(period->end)); | |||
period->end.tm_mday=duntil%100; | period->end.tm_mday=duntil%100; | |||
period->end.tm_mon=(duntil/100)%100-1; | period->end.tm_mon=(duntil/100)%100-1; | |||
period->end.tm_year=(duntil/10000)-1900; | period->end.tm_year=(duntil/10000)-1900; | |||
} | } | |||
/*! | ||||
Get the range from a period. | ||||
\param period The period to convert to a range. | ||||
\param dfrom The variable to store the range beginning. It can be NULL. | ||||
\param duntil The variable to store the range end. It can be NULL. | ||||
*/ | ||||
void getperiod_torange(const struct periodstruct *period,int *dfrom,int *duntil) | ||||
{ | ||||
if (dfrom) | ||||
*dfrom=(period->start.tm_year+1900)*10000+(period->start.tm_mon+1 | ||||
)*100+period->start.tm_mday; | ||||
if (duntil) | ||||
*duntil=(period->end.tm_year+1900)*10000+(period->end.tm_mon+1)*1 | ||||
00+period->end.tm_mday; | ||||
} | ||||
/*! | ||||
Update the \a main period to encompass the period in \a candidate. | ||||
*/ | ||||
void getperiod_merge(struct periodstruct *main,struct periodstruct *candidate) | ||||
{ | ||||
int cdate; | ||||
int mdate; | ||||
mdate=(main->start.tm_year)*10000+(main->start.tm_mon)*100+main->start.tm | ||||
_mday; | ||||
cdate=(candidate->start.tm_year)*10000+(candidate->start.tm_mon)*100+cand | ||||
idate->start.tm_mday; | ||||
if (mdate==0 || cdate<mdate) memcpy(&main->start,&candidate->start,sizeof | ||||
(struct tm)); | ||||
mdate=(main->end.tm_year)*10000+(main->end.tm_mon)*100+main->end.tm_mday; | ||||
cdate=(candidate->end.tm_year)*10000+(candidate->end.tm_mon)*100+candidat | ||||
e->end.tm_mday; | ||||
if (cdate>mdate) memcpy(&main->end,&candidate->end,sizeof(struct tm)); | ||||
} | ||||
int getperiod_buildtext(struct periodstruct *period) | int getperiod_buildtext(struct periodstruct *period) | |||
{ | { | |||
int i; | int i; | |||
int range; | int range; | |||
char text1[40], text2[40]; | char text1[40], text2[40]; | |||
if(df[0]=='u') { | if (df=='u') { | |||
i=strftime(text1, sizeof(text1), "%Y %b %d", &period->start); | i=strftime(text1, sizeof(text1), "%Y %b %d", &period->start); | |||
}else if(df[0]=='e') { | } else if (df=='e') { | |||
i=strftime(text1, sizeof(text1), "%d %b %Y", &period->start); | i=strftime(text1, sizeof(text1), "%d %b %Y", &period->start); | |||
} else /*if(df[0]=='w')*/ { | } else /*if (df=='w')*/ { | |||
IndexTree=INDEX_TREE_FILE; | IndexTree=INDEX_TREE_FILE; | |||
i=strftime(text1, sizeof(text1), "%Y.%U", &period->start); | i=strftime(text1, sizeof(text1), "%Y.%U", &period->start); | |||
} | } | |||
if (i == 0) return(-1); | if (i == 0) return(-1); | |||
range=(period->start.tm_year!=period->end.tm_year || | range=(period->start.tm_year!=period->end.tm_year || | |||
period->start.tm_mon!=period->end.tm_mon || | period->start.tm_mon!=period->end.tm_mon || | |||
period->start.tm_mday!=period->end.tm_mday); | period->start.tm_mday!=period->end.tm_mday); | |||
if (range) { | if (range) { | |||
if(df[0]=='u') { | if (df=='u') { | |||
i=strftime(text2, sizeof(text2)-i, "%Y %b %d", &period->e nd); | i=strftime(text2, sizeof(text2)-i, "%Y %b %d", &period->e nd); | |||
} else if(df[0]=='e') { | } else if (df=='e') { | |||
i=strftime(text2, sizeof(text2)-i, "%d %b %Y", &period->e nd); | i=strftime(text2, sizeof(text2)-i, "%d %b %Y", &period->e nd); | |||
} else { | } else { | |||
i=strftime(text2, sizeof(text2)-i, "%Y.%U", &period->end) ; | i=strftime(text2, sizeof(text2)-i, "%Y.%U", &period->end) ; | |||
} | } | |||
if (i == 0) return(-1); | if (i == 0) return(-1); | |||
} | } | |||
if (range) { | if (range) { | |||
snprintf(period->text,sizeof(period->text),"%s-%s",text1,text2); | snprintf(period->text,sizeof(period->text),"%s-%s",text1,text2); | |||
snprintf(period->html,sizeof(period->html),"%s—%s",text1,te xt2); | snprintf(period->html,sizeof(period->html),"%s—%s",text1,te xt2); | |||
skipping to change at line 977 | skipping to change at line 1169 | |||
safe_strcpy(period->text,text1,sizeof(period->text)); | safe_strcpy(period->text,text1,sizeof(period->text)); | |||
safe_strcpy(period->html,text1,sizeof(period->html)); | safe_strcpy(period->html,text1,sizeof(period->html)); | |||
} | } | |||
return(0); | return(0); | |||
} | } | |||
static void copy_images(void) | static void copy_images(void) | |||
{ | { | |||
FILE *img_in, *img_ou; | FILE *img_in, *img_ou; | |||
char images[512]; | char images[512]; | |||
char imgdir[MAXLEN]; | ||||
char srcfile[MAXLEN]; | char srcfile[MAXLEN]; | |||
char dstfile[MAXLEN]; | char dstfile[MAXLEN]; | |||
DIR *dirp; | DIR *dirp; | |||
struct dirent *direntp; | struct dirent *direntp; | |||
char buffer[MAXLEN]; | char buffer[MAXLEN]; | |||
size_t nread; | size_t nread; | |||
struct stat info; | struct stat info; | |||
if (snprintf(images,sizeof(images),"%simages",outdir)>=sizeof(images)) { | if (snprintf(images,sizeof(images),"%simages",outdir)>=sizeof(images)) { | |||
debuga(_("Path too long: ")); | debuga(__FILE__,__LINE__,_("Cannot copy images to target director | |||
debuga_more("%simages\n",outdir); | y %simages\n"),outdir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (access(images,R_OK)!=0) { | if (access(images,R_OK)!=0) { | |||
if (mkdir(images,0755)) { | if (PortableMkDir(images,0755)) { | |||
debuga(_("Cannot create directory \"%s\": %s\n"),images,s | debuga(__FILE__,__LINE__,_("Cannot create directory \"%s\ | |||
trerror(errno)); | ": %s\n"),images,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} | } | |||
strcpy(imgdir,IMAGEDIR); | dirp = opendir(ImageDir); | |||
dirp = opendir(imgdir); | if (dirp==NULL) { | |||
if(dirp==NULL) { | debuga(__FILE__,__LINE__,_("Cannot open directory \"%s\": %s\n"), | |||
debugapos("util",_("Cannot open directory \"%s\": %s\n"),imgdir,s | ImageDir,strerror(errno)); | |||
trerror(errno)); | ||||
return; | return; | |||
} | } | |||
while ((direntp = readdir( dirp )) != NULL ){ | while ((direntp = readdir( dirp )) != NULL ){ | |||
if(direntp->d_name[0]=='.') | if (direntp->d_name[0]=='.') | |||
continue; | continue; | |||
if (snprintf(srcfile,sizeof(srcfile),"%s/%s",imgdir,direntp->d_na | if (snprintf(srcfile,sizeof(srcfile),"%s/%s",ImageDir,direntp->d_ | |||
me)>=sizeof(srcfile)) { | name)>=sizeof(srcfile)) { | |||
debuga(_("Buffer too small to store %s/%s"),imgdir,dirent | debuga(__FILE__,__LINE__,_("Buffer too small to store ")) | |||
p->d_name); | ; | |||
debuga_more("%s/%s",ImageDir,direntp->d_name); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (stat(srcfile,&info)) { | if (stat(srcfile,&info)) { | |||
debuga(_("Cannot stat \"%s\": %s\n"),srcfile,strerror(err no)); | debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),sr cfile,strerror(errno)); | |||
continue; | continue; | |||
} | } | |||
if (S_ISREG(info.st_mode)) { | if (S_ISREG(info.st_mode)) { | |||
if (snprintf(dstfile,sizeof(dstfile),"%s/%s",images,diren tp->d_name)>=sizeof(dstfile)) { | if (snprintf(dstfile,sizeof(dstfile),"%s/%s",images,diren tp->d_name)>=sizeof(dstfile)) { | |||
debuga(_("Buffer too small to store %s/%s"),image | debuga(__FILE__,__LINE__,_("Buffer too small to s | |||
s,direntp->d_name); | tore ")); | |||
debuga_more("%s/%s",images,direntp->d_name); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
img_in = fopen(srcfile, "rb"); | img_in = fopen(srcfile, "rb"); | |||
if(img_in!=NULL) { | if (img_in!=NULL) { | |||
img_ou = fopen(dstfile, "wb"); | img_ou = fopen(dstfile, "wb"); | |||
if(img_ou!=NULL) { | if (img_ou!=NULL) { | |||
while ((nread = fread(buffer,1,sizeof(buf fer),img_in))>0) { | while ((nread = fread(buffer,1,sizeof(buf fer),img_in))>0) { | |||
if (fwrite(buffer,1,nread,img_ou) !=nread) { | if (fwrite(buffer,1,nread,img_ou) !=nread) { | |||
debuga(_("Failed to copy image \"%s\" to \"%s\"\n"),srcfile,dstfile); | debuga(__FILE__,__LINE__, _("Failed to copy image \"%s\" to \"%s\"\n"),srcfile,dstfile); | |||
break; | break; | |||
} | } | |||
} | } | |||
fclose(img_ou); | if (fclose(img_ou)==EOF) { | |||
debuga(__FILE__,__LINE__,_("Write | ||||
error in \"%s\": %s\n"),dstfile,strerror(errno)); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
} else | } else | |||
debugapos("util",_("Cannot open file \"%s | debuga(__FILE__,__LINE__,_("Cannot open f | |||
\": %s\n"), dstfile, strerror(errno)); | ile \"%s\": %s\n"), dstfile, strerror(errno)); | |||
fclose(img_in); | if (fclose(img_in)==EOF) { | |||
debuga(__FILE__,__LINE__,_("Read error in | ||||
\"%s\": %s\n"),srcfile,strerror(errno)); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
} else | } else | |||
debugapos("util",_("Cannot open file \"%s\": %s\n "),srcfile, strerror(errno)); | debuga(__FILE__,__LINE__,_("Cannot open file \"%s \": %s\n"), srcfile, strerror(errno)); | |||
} | } | |||
} | } | |||
(void) closedir(dirp); | (void) closedir(dirp); | |||
return; | return; | |||
} | } | |||
int vrfydir(const struct periodstruct *per1, const char *addr, const char *site, | /*! | |||
const char *us, const char *form) | * Check if the proposed file name conforms to the directory structure layed out | |||
* as a file tree. It is used to check if the file name enumerated while scannin | ||||
g | ||||
* a directory content may have been created by sarg running with IndexTree set | ||||
to | ||||
* INDEX_TREE_FILE. | ||||
*/ | ||||
bool IsTreeFileDirName(const char *Name) | ||||
{ | ||||
char DateFormat; | ||||
int i; | ||||
// start year (date format u) or start day (date format e) | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
if (isdigit(Name[2]) && isdigit(Name[3])) | ||||
{ | ||||
// date format is either u or w | ||||
if (Name[4]=='.') | ||||
{ | ||||
// date format is w | ||||
if (!isdigit(Name[5]) || !isdigit(Name[6])) return(false) | ||||
; | ||||
return(true);//date format w is confirmed | ||||
} | ||||
// date format is u | ||||
Name+=4; | ||||
// start month | ||||
if (!isalpha(Name[0]) || !isalpha(Name[1]) || !isalpha(Name[2])) | ||||
return(false); | ||||
for (i=11 ; i>=0 && memcmp(mtab1[i],Name,3) ; i--); | ||||
if (i<0) return(false); | ||||
Name+=3; | ||||
// start day | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
Name+=2; | ||||
DateFormat='u'; | ||||
} | ||||
else if (isalpha(Name[2]) && isalpha(Name[3]) && isalpha(Name[4])) | ||||
{ | ||||
// date format is e | ||||
Name+=2; | ||||
// start month | ||||
if (!isalpha(Name[0]) || !isalpha(Name[1]) || !isalpha(Name[2])) | ||||
return(false); | ||||
for (i=11 ; i>=0 && memcmp(mtab1[i],Name,3) ; i--); | ||||
if (i<0) return(false); | ||||
Name+=3; | ||||
// start day | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1]) || !isdigit(Name[2]) | | ||||
| !isdigit(Name[3])) return(false); | ||||
Name+=4; | ||||
DateFormat='e'; | ||||
} | ||||
else | ||||
return(false); | ||||
if (Name[0]!='-') return(false); | ||||
Name++; | ||||
if (DateFormat=='u') | ||||
{ | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1]) || !isdigit(Name[2]) | | ||||
| !isdigit(Name[3])) return(false); | ||||
Name+=4; | ||||
if (!isalpha(Name[0]) || !isalpha(Name[1]) || !isalpha(Name[2])) | ||||
return(false); | ||||
for (i=11 ; i>=0 && memcmp(mtab1[i],Name,3) ; i--); | ||||
if (i<0) return(false); | ||||
Name+=3; | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
Name+=2; | ||||
} | ||||
else //DateFormat=='e' | ||||
{ | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
Name+=2; | ||||
if (!isalpha(Name[0]) || !isalpha(Name[1]) || !isalpha(Name[2])) | ||||
return(false); | ||||
for (i=11 ; i>=0 && memcmp(mtab1[i],Name,3) ; i--); | ||||
if (i<0) return(false); | ||||
Name+=3; | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1]) || !isdigit(Name[2]) | | ||||
| !isdigit(Name[3])) return(false); | ||||
Name+=4; | ||||
} | ||||
/* | ||||
* The directory name may contains additional characters such as a counte | ||||
r if | ||||
* a previous report is never overwritten. | ||||
*/ | ||||
return(true); | ||||
} | ||||
/*! | ||||
* Check if the proposed file name can be the year part of a report tree build w | ||||
ith | ||||
* IndexTree set to INDEX_TREE_DATE. | ||||
*/ | ||||
bool IsTreeYearFileName(const char *Name) | ||||
{ | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1]) || !isdigit(Name[2]) || !isdig | ||||
it(Name[3])) return(false); | ||||
Name+=4; | ||||
if (Name[0]=='-') | ||||
{ | ||||
Name++; | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1]) || !isdigit(Name[2]) | | ||||
| !isdigit(Name[3])) return(false); | ||||
Name+=4; | ||||
} | ||||
if (Name[0]) return(false); | ||||
return(true); | ||||
} | ||||
/*! | ||||
* Check if the proposed file name can be the month part of a report tree build | ||||
with | ||||
* IndexTree set to INDEX_TREE_DATE. | ||||
*/ | ||||
bool IsTreeMonthFileName(const char *Name) | ||||
{ | ||||
int m; | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
m=(Name[0]-'0')*10+(Name[1]-'0'); | ||||
if (m<1 || m>12) return(false); | ||||
Name+=2; | ||||
if (Name[0]=='-') | ||||
{ | ||||
Name++; | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
m=(Name[0]-'0')*10+(Name[1]-'0'); | ||||
if (m<1 || m>12) return(false); | ||||
Name+=2; | ||||
} | ||||
if (Name[0]) return(false); | ||||
return(true); | ||||
} | ||||
/*! | ||||
* Check if the proposed file name can be the day part of a report tree build wi | ||||
th | ||||
* IndexTree set to INDEX_TREE_DATE. | ||||
*/ | ||||
bool IsTreeDayFileName(const char *Name) | ||||
{ | ||||
int d; | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
d=(Name[0]-'0')*10+(Name[1]-'0'); | ||||
if (d<1 || d>31) return(false); | ||||
if (Name[2]=='-') | ||||
{ | ||||
Name+=3; | ||||
if (!isdigit(Name[0]) || !isdigit(Name[1])) return(false); | ||||
d=(Name[0]-'0')*10+(Name[1]-'0'); | ||||
if (d<1 || d>31) return(false); | ||||
} | ||||
/* | ||||
* The directory name may contains additional characters such as a counte | ||||
r if | ||||
* a previous report is never overwritten. | ||||
*/ | ||||
return(true); | ||||
} | ||||
/*! | ||||
* Create a directory to generate a report for the specified connection data | ||||
* and populate it with the a <tt>sarg-date</tt> file containing the current | ||||
* date. | ||||
* | ||||
* The function also create an <tt>images</tt> directory in \a dir and copy all | ||||
* the files from the <tt>SYSCONFDIR/images</tt> into that directory. | ||||
* | ||||
* \param per1 The date range in the form: YYYYMMMDD-YYYYMMMDD or DDMMMYYYY-DDMM | ||||
MYYYY depending on the value of | ||||
* ::DateFormat. | ||||
* \param addr The ip address or host name to which the report is limited. If th | ||||
e string is empty, all the addresses are accepted. | ||||
* \param site The destination site to which the report is limited. If the strin | ||||
g is empty, all the sites are accepted. | ||||
* \param us The user to whom the report is limited. It is an empty string if al | ||||
l the users are accepted. | ||||
*/ | ||||
int vrfydir(const struct periodstruct *per1, const char *addr, const char *site, | ||||
const char *us) | ||||
{ | { | |||
FILE *fp_ou; | FILE *fp_ou; | |||
int num=1, count=0; | ||||
char wdir[MAXLEN]; | char wdir[MAXLEN]; | |||
char dirname2[MAXLEN]; | ||||
int y1, y2; | int y1, y2; | |||
int m1, m2; | int m1, m2; | |||
int d1, d2; | int d1, d2; | |||
int wlen, wlen2; | int wlen, wlen2; | |||
time_t curtime; | time_t curtime; | |||
struct tm *loctm; | struct tm *loctm; | |||
strcpy(wdir,outdir); | strcpy(wdir,outdir); | |||
wlen=strlen(wdir); | wlen=strlen(wdir); | |||
y1=per1->start.tm_year+1900; | y1=per1->start.tm_year+1900; | |||
y2=per1->end.tm_year+1900; | y2=per1->end.tm_year+1900; | |||
m1=per1->start.tm_mon+1; | m1=per1->start.tm_mon+1; | |||
m2=per1->end.tm_mon+1; | m2=per1->end.tm_mon+1; | |||
d1=per1->start.tm_mday; | d1=per1->start.tm_mday; | |||
d2=per1->end.tm_mday; | d2=per1->end.tm_mday; | |||
if(IndexTree == INDEX_TREE_DATE) { | if (IndexTree == INDEX_TREE_DATE) { | |||
wlen+=sprintf(wdir+wlen,"%04d",y1); | wlen+=sprintf(wdir+wlen,"%04d",y1); | |||
if(y1!=y2) wlen+=sprintf(wdir+wlen,"-%04d",y2); | if (y1!=y2) wlen+=sprintf(wdir+wlen,"-%04d",y2); | |||
if(access(wdir, R_OK) != 0) | if (access(wdir, R_OK) != 0) | |||
my_mkdir(wdir); | my_mkdir(wdir); | |||
wlen+=sprintf(wdir+wlen,"/%02d",m1); | wlen+=sprintf(wdir+wlen,"/%02d",m1); | |||
if(m1 != m2) wlen+=sprintf(wdir+wlen,"-%02d",m2); | if (m1 != m2) wlen+=sprintf(wdir+wlen,"-%02d",m2); | |||
if(access(wdir, R_OK) != 0) | if (access(wdir, R_OK) != 0) | |||
my_mkdir(wdir); | my_mkdir(wdir); | |||
wlen+=sprintf(wdir+wlen,"/%02d",d1); | wlen+=sprintf(wdir+wlen,"/%02d",d1); | |||
if(d1!=d2) wlen+=sprintf(wdir+wlen,"-%02d",d2); | if (d1!=d2) wlen+=sprintf(wdir+wlen,"-%02d",d2); | |||
} else { | } else { | |||
if(df[0] == 'u') { | if (df == 'u') { | |||
wlen=snprintf(wdir+wlen,sizeof(wdir)-wlen,"%04d%s%02d-%04 d%s%02d",y1, | wlen=snprintf(wdir+wlen,sizeof(wdir)-wlen,"%04d%s%02d-%04 d%s%02d",y1, | |||
conv_month_name(m1),d1,y2,conv_month_name(m2),d2) ; | conv_month_name(m1),d1,y2,conv_month_name(m2),d2) ; | |||
} else if(df[0] == 'e') { | } else if (df == 'e') { | |||
wlen=snprintf(wdir+wlen,sizeof(wdir)-wlen,"%02d%s%04d-%02 d%s%04d",d1, | wlen=snprintf(wdir+wlen,sizeof(wdir)-wlen,"%02d%s%04d-%02 d%s%04d",d1, | |||
conv_month_name(m1),y1,d2,conv_month_name(m2),y2) ; | conv_month_name(m1),y1,d2,conv_month_name(m2),y2) ; | |||
} else if(df[0] == 'w') { | } else if (df == 'w') { | |||
wlen2=strftime(wdir+wlen, sizeof(wdir)-wlen, "%Y.%U", &pe r1->start); | wlen2=strftime(wdir+wlen, sizeof(wdir)-wlen, "%Y.%U", &pe r1->start); | |||
if (wlen2==0) return(-1); | if (wlen2==0) return(-1); | |||
wlen+=wlen2; | wlen+=wlen2; | |||
} | } | |||
} | } | |||
if(us[0] != '\0') { | if (us[0] != '\0') { | |||
struct userinfostruct *uinfo=userinfo_find_from_id(us); | struct userinfostruct *uinfo=userinfo_find_from_id(us); | |||
if (uinfo) { | if (uinfo) { | |||
strcat(wdir,"-"); | strcat(wdir,"-"); | |||
strcat(wdir,uinfo->filename); | strcat(wdir,uinfo->filename); | |||
} | } | |||
} | } | |||
if(addr[0] != '\0') { | if (addr[0] != '\0') { | |||
strcat(wdir,"-"); | strcat(wdir,"-"); | |||
strcat(wdir,addr); | strcat(wdir,addr); | |||
} | } | |||
if(site[0] != '\0') { | if (site[0] != '\0') { | |||
strcat(wdir,"-"); | strcat(wdir,"-"); | |||
strcat(wdir,site); | strcat(wdir,site); | |||
} | } | |||
strcpy(outdirname,wdir); | strcpy(outdirname,wdir); | |||
if(IndexTree != INDEX_TREE_DATE) { | // manufacture a new unique name if configured to keep old reports or ove | |||
if(!OverwriteReport) { | rwrite old report if configured to do so | |||
while(num) { | if (!OverwriteReport) { | |||
if(access(wdir,R_OK) == 0) { | int num=1; | |||
sprintf(wdir,"%s.%d",outdirname,num); | ||||
num++; | while (access(wdir,R_OK)==0 || errno==EACCES) //file exist or can | |||
count++; | 't be read | |||
} else | { | |||
break; | format_path(__FILE__, __LINE__, wdir, sizeof(wdir), "%s.% | |||
} | d", outdirname, num); | |||
num++; | ||||
if(count > 0) { | } | |||
if(debug) | if (num>1) { | |||
debuga(_("File \"%s\" already exists, mov | if (debug) | |||
ed to \"%s\"\n"),outdirname,wdir); | debuga(__FILE__,__LINE__,_("File \"%s\" already e | |||
rename(outdirname,wdir); | xists, moved to \"%s\"\n"),outdirname,wdir); | |||
} | rename(outdirname,wdir); | |||
} else { | ||||
if(access(outdirname,R_OK) == 0) { | ||||
unlinkdir(outdirname,1); | ||||
} | ||||
} | } | |||
my_mkdir(outdirname); | ||||
} else { | } else { | |||
strcpy(dirname2,wdir); | if (access(outdirname,R_OK) == 0) { | |||
if(!OverwriteReport) { | unlinkdir(outdirname,1); | |||
while(num) { | ||||
if(access(wdir,R_OK) == 0) { | ||||
sprintf(wdir,"%s.%d",dirname2,num); | ||||
num++; | ||||
count++; | ||||
} else | ||||
break; | ||||
} | ||||
if(count > 0) { | ||||
if(debug) | ||||
debuga(_("File \"%s\" already exists, mov | ||||
ed to \"%s\"\n"),dirname2,wdir); | ||||
rename(dirname2,wdir); | ||||
strcpy(dirname2,wdir); | ||||
} | ||||
} else { | ||||
if(access(wdir,R_OK) == 0) { | ||||
unlinkdir(wdir,1); | ||||
} | ||||
} | } | |||
if(access(wdir, R_OK) != 0) | ||||
my_mkdir(wdir); | ||||
} | } | |||
my_mkdir(outdirname); | ||||
strcpy(dirname2,wdir); | // create sarg-date to keep track of the report creation date | |||
if (snprintf(wdir,sizeof(wdir),"%s/sarg-date",outdirname)>=sizeof(wdir)) { | if (snprintf(wdir,sizeof(wdir),"%s/sarg-date",outdirname)>=sizeof(wdir)) { | |||
debuga(_("Buffer too small to store %s/sarg-date"),outdirname); | debuga(__FILE__,__LINE__,_("Buffer too small to store ")); | |||
debuga_more("%s/sarg-date",outdirname); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((fp_ou = fopen(wdir, "wt")) == 0) { | if ((fp_ou = fopen(wdir, "wt")) == 0) { | |||
debuga(_("Cannot open file \"%s\": %s\n"),wdir,strerror(errno)); | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),wdir, strerror(errno)); | |||
perror("SARG:"); | perror("SARG:"); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
time(&curtime); | time(&curtime); | |||
//strftime(wdir,sizeof(wdir),"%a %b %d %H:%M:%S %Z %Y",localtime(&curtime )); | //strftime(wdir,sizeof(wdir),"%a %b %d %H:%M:%S %Z %Y",localtime(&curtime )); | |||
loctm=localtime(&curtime); | loctm=localtime(&curtime); | |||
strftime(wdir,sizeof(wdir),"%Y-%m-%d %H:%M:%S",loctm); | strftime(wdir,sizeof(wdir),"%Y-%m-%d %H:%M:%S",loctm); | |||
if (fprintf(fp_ou,"%s %d\n",wdir,loctm->tm_isdst)<0) { | if (fprintf(fp_ou,"%s %d\n",wdir,loctm->tm_isdst)<0) { | |||
debuga(_("Failed to write the date in \"%s\"\n"),wdir); | debuga(__FILE__,__LINE__,_("Failed to write the date in \"%s\"\n" ),wdir); | |||
perror("SARG:"); | perror("SARG:"); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (fclose(fp_ou)==EOF) { | if (fclose(fp_ou)==EOF) { | |||
debuga(_("Failed to close file \"%s\": %s\n"),wdir,strerror(errno | debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),wdir,st | |||
)); | rerror(errno)); | |||
perror("SARG:"); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
copy_images(); | copy_images(); | |||
return(0); | return(0); | |||
} | } | |||
/*! | /*! | |||
Copy a string without overflowing the buffer. The copied string | Copy a string without overflowing the buffer. The copied string | |||
is properly terminated by an ASCII zero. | is properly terminated by an ASCII zero. | |||
\param dest The destination buffer. | \param dest The destination buffer. | |||
\param src The source buffer. | \param src The source buffer. | |||
\param length The size of the destination buffer. The program is aborted | \param length The size of the destination buffer. The program is aborted | |||
if the length is negative or zero. | if the length is negative or zero. | |||
*/ | */ | |||
void safe_strcpy(char *dest,const char *src,int length) | void safe_strcpy(char *dest,const char *src,int length) | |||
{ | { | |||
if (length<=0) { | if (length<=0) { | |||
debuga(_("Invalid buffer length passed to the function to safely copy a string\n")); | debuga(__FILE__,__LINE__,_("Invalid buffer length passed to the f unction to safely copy a string\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
strncpy(dest,src,length-1); | strncpy(dest,src,length-1); | |||
dest[length-1]='\0'; | dest[length-1]='\0'; | |||
} | } | |||
void strip_latin(char *line) | void strip_latin(char *line) | |||
{ | { | |||
int i,j; | int i,j; | |||
int skip; | int skip; | |||
skipping to change at line 1229 | skipping to change at line 1570 | |||
if (line[i]=='&') | if (line[i]=='&') | |||
skip=1; | skip=1; | |||
else | else | |||
line[j++]=line[i]; | line[j++]=line[i]; | |||
} | } | |||
} | } | |||
line[j]='\0'; | line[j]='\0'; | |||
return; | return; | |||
} | } | |||
void zdate(char *ftime,int ftimesize, const char *DateFormat) | void zdate(char *ftime,int ftimesize, char DateFormat) | |||
{ | { | |||
time_t t; | time_t t; | |||
struct tm *local; | struct tm *local; | |||
t = time(NULL); | t = time(NULL); | |||
local = localtime(&t); | local = localtime(&t); | |||
if(strcmp(DateFormat,"u") == 0) | if (DateFormat=='u') | |||
strftime(ftime, ftimesize, "%b/%d/%Y %H:%M", local); | strftime(ftime, ftimesize, "%b/%d/%Y %H:%M", local); | |||
if(strcmp(DateFormat,"e") == 0) | else if (DateFormat=='e') | |||
strftime(ftime, ftimesize, "%d/%b/%Y-%H:%M", local); | strftime(ftime, ftimesize, "%d/%b/%Y-%H:%M", local); | |||
if(strcmp(DateFormat,"w") == 0) | else if (DateFormat=='w') | |||
strftime(ftime, ftimesize, "%W-%H-%M", local); | strftime(ftime, ftimesize, "%W-%H-%M", local); | |||
return; | return; | |||
} | } | |||
char *fixtime(long long int elap) | char *fixtime(long long int elap) | |||
{ | { | |||
long int num = elap / 1000LL; | long int num = elap / 1000LL; | |||
int hor = 0; | int hor = 0; | |||
int min = 0; | int min = 0; | |||
int sec = 0; | int sec = 0; | |||
static char buf[20]; | static char buf[20]; | |||
hor=num / 3600L; | hor=num / 3600L; | |||
min=(num % 3600L) / 60L; | min=(num % 3600L) / 60L; | |||
sec=num % 60L; | sec=num % 60L; | |||
if(hor==0 && min==0 && sec==0) | if (hor==0 && min==0 && sec==0) | |||
strcpy(buf,"0"); | strcpy(buf,"0"); | |||
else | else | |||
snprintf(buf,sizeof(buf),"%d:%02d:%02d",hor,min,sec); | snprintf(buf,sizeof(buf),"%d:%02d:%02d",hor,min,sec); | |||
return buf; | return buf; | |||
} | } | |||
void date_from(char *date,int date_size, int *dfrom, int *duntil) | void date_from(struct ReadLogDataStruct *ReadFilter) | |||
{ | { | |||
int d0=0; | int d0=0; | |||
int m0=0; | int m0=0; | |||
int y0=0; | int y0=0; | |||
int d1=0; | int d1=0; | |||
int m1=0; | int m1=0; | |||
int y1=0; | int y1=0; | |||
if (isdigit(date[0])) { | if (isdigit(ReadFilter->DateRange[0])) { | |||
int next=-1; | int next=-1; | |||
if (sscanf(date,"%d/%d/%d%n",&d0,&m0,&y0,&next)!=3 || y0<100 || m | if (sscanf(ReadFilter->DateRange,"%d/%d/%d%n",&d0,&m0,&y0,&next)! | |||
0<1 || m0>12 || d0<1 || d0>31 || next<0) { | =3 || y0<100 || m0<1 || m0>12 || d0<1 || d0>31 || next<0) { | |||
debuga(_("The date passed as argument is not formated as | debuga(__FILE__,__LINE__,_("The date passed as argument i | |||
dd/mm/yyyy or dd/mm/yyyy-dd/mm/yyyy\n")); | s not formated as dd/mm/yyyy or dd/mm/yyyy-dd/mm/yyyy\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (date[next]=='-') { | if (ReadFilter->DateRange[next]=='-') { | |||
if (sscanf(date+next+1,"%d/%d/%d",&d1,&m1,&y1)!=3 || y1<1 | if (sscanf(ReadFilter->DateRange+next+1,"%d/%d/%d",&d1,&m | |||
00 || m1<1 || m1>12 || d1<1 || d1>31) { | 1,&y1)!=3 || y1<100 || m1<1 || m1>12 || d1<1 || d1>31) { | |||
debuga(_("The date range passed as argument is no | debuga(__FILE__,__LINE__,_("The date range passed | |||
t formated as dd/mm/yyyy or dd/mm/yyyy-dd/mm/yyyy\n")); | as argument is not formated as dd/mm/yyyy or dd/mm/yyyy-dd/mm/yyyy\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} else if (date[next]!='\0') { | } else if (ReadFilter->DateRange[next]!='\0') { | |||
debuga(_("The date range passed as argument is not format | debuga(__FILE__,__LINE__,_("The date range passed as argu | |||
ed as dd/mm/yyyy or dd/mm/yyyy-dd/mm/yyyy\n")); | ment is not formated as dd/mm/yyyy or dd/mm/yyyy-dd/mm/yyyy\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} else { | } else { | |||
d1=d0; | d1=d0; | |||
m1=m0; | m1=m0; | |||
y1=y0; | y1=y0; | |||
} | } | |||
} else { | } else { | |||
int i; | int i; | |||
time_t Today,t1; | time_t Today,t1; | |||
struct tm *Date0,Date1; | struct tm *Date0,Date1; | |||
if (time(&Today)==(time_t)-1) { | if (time(&Today)==(time_t)-1) { | |||
debuga(_("Failed to get the current time\n")); | debuga(__FILE__,__LINE__,_("Failed to get the current tim e\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (sscanf(date,"day-%d",&i)==1) { | if (sscanf(ReadFilter->DateRange,"day-%d",&i)==1) { | |||
if (i<0) { | if (i<0) { | |||
debuga(_("Invalid number of days in -d parameter\ n")); | debuga(__FILE__,__LINE__,_("Invalid number of day s in -d parameter\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
Today-=i*24*60*60; | Today-=i*24*60*60; | |||
Date0=localtime(&Today); | Date0=localtime(&Today); | |||
if (Date0==NULL) { | if (Date0==NULL) { | |||
debuga(_("Cannot convert local time: %s\n"),strer ror(errno)); | debuga(__FILE__,__LINE__,_("Cannot convert local time: %s\n"),strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
y0=y1=Date0->tm_year+1900; | y0=y1=Date0->tm_year+1900; | |||
m0=m1=Date0->tm_mon+1; | m0=m1=Date0->tm_mon+1; | |||
d0=d1=Date0->tm_mday; | d0=d1=Date0->tm_mday; | |||
} else if (sscanf(date,"week-%d",&i)==1) { | } else if (sscanf(ReadFilter->DateRange,"week-%d",&i)==1) { | |||
/* | /* | |||
There is no portable way to find the first day of the wee k even though the | There is no portable way to find the first day of the wee k even though the | |||
information is available in the locale. nl_langinfo has t he unofficial | information is available in the locale. nl_langinfo has t he unofficial | |||
parameters _NL_TIME_FIRST_WEEKDAY and _NL_TIME_WEEK_1STDA Y but they are | parameters _NL_TIME_FIRST_WEEKDAY and _NL_TIME_WEEK_1STDA Y but they are | |||
undocumented as is their return value and it is discourag ed to use them. | undocumented as is their return value and it is discourag ed to use them. | |||
Beside, nl_langinfo isn't available on windows and the fi rst day of the | Beside, nl_langinfo isn't available on windows and the fi rst day of the | |||
week isn't available at all on that system. | week isn't available at all on that system. | |||
*/ | */ | |||
const int FirstWeekDay=1; | const int FirstWeekDay=1; | |||
time_t WeekBegin; | time_t WeekBegin; | |||
if (i<0) { | if (i<0) { | |||
debuga(_("Invalid number of weeks in -d parameter \n")); | debuga(__FILE__,__LINE__,_("Invalid number of wee ks in -d parameter\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
Date0=localtime(&Today); | Date0=localtime(&Today); | |||
if (Date0==NULL) { | if (Date0==NULL) { | |||
debuga(_("Cannot convert local time: %s\n"),strer ror(errno)); | debuga(__FILE__,__LINE__,_("Cannot convert local time: %s\n"),strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
WeekBegin=Today-((Date0->tm_wday-FirstWeekDay+7)%7)*24*60 *60; | WeekBegin=Today-((Date0->tm_wday-FirstWeekDay+7)%7)*24*60 *60; | |||
WeekBegin-=i*7*24*60*60; | WeekBegin-=i*7*24*60*60; | |||
Date0=localtime(&WeekBegin); | Date0=localtime(&WeekBegin); | |||
if (Date0==NULL) { | if (Date0==NULL) { | |||
debuga(_("Cannot convert local time: %s\n"),strer ror(errno)); | debuga(__FILE__,__LINE__,_("Cannot convert local time: %s\n"),strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
y0=Date0->tm_year+1900; | y0=Date0->tm_year+1900; | |||
m0=Date0->tm_mon+1; | m0=Date0->tm_mon+1; | |||
d0=Date0->tm_mday; | d0=Date0->tm_mday; | |||
WeekBegin+=6*24*60*60; | WeekBegin+=6*24*60*60; | |||
Date0=localtime(&WeekBegin); | Date0=localtime(&WeekBegin); | |||
if (Date0==NULL) { | if (Date0==NULL) { | |||
debuga(_("Cannot convert local time: %s\n"),strer ror(errno)); | debuga(__FILE__,__LINE__,_("Cannot convert local time: %s\n"),strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
y1=Date0->tm_year+1900; | y1=Date0->tm_year+1900; | |||
m1=Date0->tm_mon+1; | m1=Date0->tm_mon+1; | |||
d1=Date0->tm_mday; | d1=Date0->tm_mday; | |||
} else if (sscanf(date,"month-%d",&i)==1) { | } else if (sscanf(ReadFilter->DateRange,"month-%d",&i)==1) { | |||
if (i<0) { | if (i<0) { | |||
debuga(_("Invalid number of months in -d paramete r\n")); | debuga(__FILE__,__LINE__,_("Invalid number of mon ths in -d parameter\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
Date0=localtime(&Today); | Date0=localtime(&Today); | |||
if (Date0==NULL) { | if (Date0==NULL) { | |||
debuga(_("Cannot convert local time: %s\n"),strer ror(errno)); | debuga(__FILE__,__LINE__,_("Cannot convert local time: %s\n"),strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (Date0->tm_mon<i%12) { | if (Date0->tm_mon<i%12) { | |||
y0=Date0->tm_year+1900-i/12-1; | y0=Date0->tm_year+1900-i/12-1; | |||
m0=(Date0->tm_mon+12-i%12)%12+1; | m0=(Date0->tm_mon+12-i%12)%12+1; | |||
d0=1; | d0=1; | |||
} else { | } else { | |||
y0=Date0->tm_year+1900-i/12; | y0=Date0->tm_year+1900-i/12; | |||
m0=Date0->tm_mon-i%12+1; | m0=Date0->tm_mon-i%12+1; | |||
d0=1; | d0=1; | |||
skipping to change at line 1393 | skipping to change at line 1734 | |||
Date1.tm_mon=0; | Date1.tm_mon=0; | |||
Date1.tm_year=y0-1900+1; | Date1.tm_year=y0-1900+1; | |||
} | } | |||
t1=mktime(&Date1); | t1=mktime(&Date1); | |||
t1-=24*60*60; | t1-=24*60*60; | |||
Date0=localtime(&t1); | Date0=localtime(&t1); | |||
y1=Date0->tm_year+1900; | y1=Date0->tm_year+1900; | |||
m1=Date0->tm_mon+1; | m1=Date0->tm_mon+1; | |||
d1=Date0->tm_mday; | d1=Date0->tm_mday; | |||
} else { | } else { | |||
debuga(_("Invalid date range passed on command line\n")); | debuga(__FILE__,__LINE__,_("Invalid date range passed on command line\n")); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} | } | |||
*dfrom=y0*10000+m0*100+d0; | ReadFilter->StartDate=y0*10000+m0*100+d0; | |||
*duntil=y1*10000+m1*100+d1; | ReadFilter->EndDate=y1*10000+m1*100+d1; | |||
snprintf(date,date_size,"%02d/%02d/%04d-%02d/%02d/%04d",d0,m0,y0,d1,m1,y1 | snprintf(ReadFilter->DateRange,sizeof(ReadFilter->DateRange),"%02d/%02d/% | |||
); | 04d-%02d/%02d/%04d",d0,m0,y0,d1,m1,y1); | |||
return; | return; | |||
} | } | |||
char *strlow(char *string) | char *strlow(char *string) | |||
{ | { | |||
char *s; | char *s; | |||
if (string) | if (string) | |||
{ | { | |||
for (s = string; *s; ++s) | for (s = string; *s; ++s) | |||
skipping to change at line 1435 | skipping to change at line 1776 | |||
} | } | |||
return string; | return string; | |||
} | } | |||
void removetmp(const char *outdir) | void removetmp(const char *outdir) | |||
{ | { | |||
FILE *fp_gen; | FILE *fp_gen; | |||
char filename[256]; | char filename[256]; | |||
if(!RemoveTempFiles) | if (!RemoveTempFiles) | |||
return; | return; | |||
if(debug) { | if (debug) { | |||
debuga(_("Purging temporary file sarg-general\n")); | debuga(__FILE__,__LINE__,_("Purging temporary file sarg-general\n | |||
")); | ||||
} | } | |||
if (snprintf(filename,sizeof(filename),"%s/sarg-general",outdir)>=sizeof( filename)) { | if (snprintf(filename,sizeof(filename),"%s/sarg-general",outdir)>=sizeof( filename)) { | |||
debugapos("removetmp",_("Path too long: ")); | debuga(__FILE__,__LINE__,_("Path too long: ")); | |||
debuga_more("%s/sarg-period\n",outdir); | debuga_more("%s/sarg-period\n",outdir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if((fp_gen=fopen(filename,"w"))==NULL){ | if ((fp_gen=fopen(filename,"w"))==NULL){ | |||
debugapos("removetmp",_("Cannot open file \"%s\": %s\n"),filename | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),filen | |||
,strerror(errno)); | ame,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
totalger(fp_gen,filename); | totalger(fp_gen,filename); | |||
if (fclose(fp_gen)==EOF) { | if (fclose(fp_gen)==EOF) { | |||
debuga(_("Failed to close file \"%s\": %s\n"),filename,strerror(e rrno)); | debuga(__FILE__,__LINE__,_("Write error in \"%s\": %s\n"),filenam e,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} | } | |||
void load_excludecodes(const char *ExcludeCodes) | void load_excludecodes(const char *ExcludeCodes) | |||
{ | { | |||
FILE *fp_in; | FILE *fp_in; | |||
char data[80]; | char data[80]; | |||
int i; | int i; | |||
int Stored; | int Stored; | |||
long int MemSize; | long int MemSize; | |||
if(ExcludeCodes[0] == '\0') | if (ExcludeCodes[0] == '\0') | |||
return; | return; | |||
if((fp_in=fopen(ExcludeCodes,"r"))==NULL) { | if ((fp_in=fopen(ExcludeCodes,"r"))==NULL) { | |||
debugapos("util",_("Cannot open file \"%s\": %s\n"),ExcludeCodes, | debuga(__FILE__,__LINE__,_("Cannot open file \"%s\": %s\n"),Exclu | |||
strerror(errno)); | deCodes,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (fseek(fp_in, 0, SEEK_END)==-1) { | if (fseek(fp_in, 0, SEEK_END)==-1) { | |||
debuga(_("Failed to move till the end of file \"%s\": %s\n"),Excl udeCodes,strerror(errno)); | debuga(__FILE__,__LINE__,_("Failed to move till the end of file \ "%s\": %s\n"),ExcludeCodes,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
MemSize = ftell(fp_in); | MemSize = ftell(fp_in); | |||
if (MemSize<0) { | if (MemSize<0) { | |||
debuga(_("Cannot get the size of file \"%s\": %s\n"),ExcludeCodes ,strerror(errno)); | debuga(__FILE__,__LINE__,_("Cannot get the size of file \"%s\"\n" ),ExcludeCodes); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (fseek(fp_in, 0, SEEK_SET)==-1) { | if (fseek(fp_in, 0, SEEK_SET)==-1) { | |||
debuga(_("Failed to rewind file \"%s\": %s\n"),ExcludeCodes,strer ror(errno)); | debuga(__FILE__,__LINE__,_("Failed to rewind file \"%s\": %s\n"), ExcludeCodes,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
MemSize+=1; | MemSize+=1; | |||
if((excludecode=(char *) malloc(MemSize))==NULL) { | if ((excludecode=(char *) malloc(MemSize))==NULL) { | |||
debuga(_("malloc failed to allocate %ld bytes\n"),MemSize); | debuga(__FILE__,__LINE__,_("malloc error (%ld bytes required)\n") | |||
,MemSize); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
memset(excludecode,0,MemSize); | memset(excludecode,0,MemSize); | |||
Stored=0; | Stored=0; | |||
while(fgets(data,sizeof(data),fp_in)!=NULL) { | while(fgets(data,sizeof(data),fp_in)!=NULL) { | |||
if (data[0]=='#') continue; | if (data[0]=='#') continue; | |||
for (i=strlen(data)-1 ; i>=0 && (unsigned char)data[i]<=' ' ; i-- ) data[i]='\0'; | for (i=strlen(data)-1 ; i>=0 && (unsigned char)data[i]<=' ' ; i-- ) data[i]='\0'; | |||
if (i<0) continue; | if (i<0) continue; | |||
if (Stored+i+2>=MemSize) { | if (Stored+i+2>=MemSize) { | |||
debuga(_("Too many codes to exclude in file \"%s\"\n"),Ex cludeCodes); | debuga(__FILE__,__LINE__,_("Too many codes to exclude in file \"%s\"\n"),ExcludeCodes); | |||
break; | break; | |||
} | } | |||
strcat(excludecode,data); | strcat(excludecode,data); | |||
strcat(excludecode,";"); | strcat(excludecode,";"); | |||
Stored+=i+1; | Stored+=i+1; | |||
} | } | |||
fclose(fp_in); | if (fclose(fp_in)==EOF) { | |||
debuga(__FILE__,__LINE__,_("Read error in \"%s\": %s\n"),ExcludeC | ||||
odes,strerror(errno)); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
return; | return; | |||
} | } | |||
void free_excludecodes(void) | void free_excludecodes(void) | |||
{ | { | |||
if (excludecode) { | if (excludecode) { | |||
free(excludecode); | free(excludecode); | |||
excludecode=NULL; | excludecode=NULL; | |||
} | } | |||
} | } | |||
skipping to change at line 1543 | skipping to change at line 1887 | |||
} | } | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
void fixnone(char *str) | void fixnone(char *str) | |||
{ | { | |||
int i; | int i; | |||
for (i=strlen(str)-1 ; i>=0 && (unsigned char)str[i]<=' ' ; i--); | for (i=strlen(str)-1 ; i>=0 && (unsigned char)str[i]<=' ' ; i--); | |||
if(i==3 && strncmp(str,"none",4) == 0) | if (i==3 && strncmp(str,"none",4) == 0) | |||
str[0]='\0'; | str[0]='\0'; | |||
return; | return; | |||
} | } | |||
void fixendofline(char *str) | void fixendofline(char *str) | |||
{ | { | |||
int i; | int i; | |||
for (i=strlen(str)-1 ; i>=0 && (unsigned char)str[i]<=' ' ; i--) str[i]=0 ; | for (i=strlen(str)-1 ; i>=0 && (unsigned char)str[i]<=' ' ; i--) str[i]=0 ; | |||
} | } | |||
#ifdef LEGACY_TESTVALIDUSERCHAR | #ifdef LEGACY_TESTVALIDUSERCHAR | |||
int testvaliduserchar(const char *user) | int testvaliduserchar(const char *user) | |||
{ | { | |||
int x=0; | int x=0; | |||
int y=0; | int y=0; | |||
for (y=0; y<strlen(UserInvalidChar); y++) { | for (y=0; y<strlen(UserInvalidChar); y++) { | |||
for (x=0; x<strlen(user); x++) { | for (x=0; x<strlen(user); x++) { | |||
if(user[x] == UserInvalidChar[y]) | if (user[x] == UserInvalidChar[y]) | |||
return 1; | return 1; | |||
} | } | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
#else | #else | |||
int testvaliduserchar(const char *user) | int testvaliduserchar(const char *user) | |||
{ | { | |||
char * p_UserInvalidChar = UserInvalidChar ; | char * p_UserInvalidChar = UserInvalidChar ; | |||
const char * p_user ; | const char * p_user ; | |||
while( *p_UserInvalidChar ) { | while( *p_UserInvalidChar ) { | |||
p_user = user ; | p_user = user ; | |||
while ( *p_user ) { | while ( *p_user ) { | |||
if( *p_UserInvalidChar == *p_user ) | if ( *p_UserInvalidChar == *p_user ) | |||
return 1; | return 1; | |||
p_user++ ; | p_user++ ; | |||
} | } | |||
p_UserInvalidChar++ ; | p_UserInvalidChar++ ; | |||
} | } | |||
return 0; | return 0; | |||
} | } | |||
#endif | #endif | |||
int compar( const void *a, const void *b ) | int compar( const void *a, const void *b ) | |||
{ | { | |||
if( *(int *)a > *(int *)b ) return 1; | if ( *(int *)a > *(int *)b ) return 1; | |||
if( *(int *)a < *(int *)b ) return -1; | if ( *(int *)a < *(int *)b ) return -1; | |||
return 0; | return 0; | |||
} | } | |||
int getnumlist( char *buf, numlist *list, const int len, const int maxvalue ) | /*! | |||
* Store a range in a list. | ||||
* | ||||
* \param paramname Name of the configuration parameter providing the list. | ||||
* \param list List where to store the numbers. | ||||
* \param d0 Start range or -1 to store only one value. | ||||
* \param d End range if d0>=0 or the single value to store. | ||||
*/ | ||||
static void storenumlist(const char *paramname, int *list, int d0, int d) | ||||
{ | { | |||
int i, j, d, flag, r1, r2; | if (d0<0) | |||
char *pbuf, **bp, *strbufs[ 24 ]; | { | |||
list[d]=1; | ||||
bp = strbufs; | ||||
strtok( buf, " \t" ); | ||||
for( *bp = strtok( NULL, "," ), list->len = 0; *bp; *bp = strtok( NULL, " | ||||
," ) ) { | ||||
if( ++bp >= &strbufs[ 24 ] ) | ||||
break; | ||||
list->len++; | ||||
} | } | |||
if( ! list->len ) | else | |||
return -1; | { | |||
d = 0; | int i; | |||
for( i = 0; i < list->len; i++ ) { | ||||
if( strchr( strbufs[ i ], '-' ) != 0 ) { | if (d<d0) | |||
pbuf = strbufs[ i ]; | { | |||
strtok( pbuf, "-" ); | debuga(__FILE__,__LINE__,_("Ending value %d is less than | |||
pbuf = strtok( NULL, "\0" ); | or equal to starting value %d in parameter \"%s\"\n"),d,d0,paramname); | |||
r1 = atoi( strbufs[ i ] ); | exit(EXIT_FAILURE); | |||
if( ( r2 = atoi( pbuf ) ) >= maxvalue || r1 >= r2 ) | ||||
return -1; | ||||
if( i + d + ( r2 - r1 ) + 1 <= len ) { | ||||
for( j = r1; j <= r2; j++ ) | ||||
list->list[ i + d++ ] = j; | ||||
d--; | ||||
} | ||||
} | } | |||
else | for (i=d0 ; i<=d ; i++) list[i]=1; | |||
if( ( list->list[ i + d ] = atoi( strbufs[ i ] ) ) >= max | ||||
value ) | ||||
return 1; | ||||
} | } | |||
list->len += d; | ||||
qsort( list->list, list->len, sizeof( int ), compar ); | ||||
do { | ||||
flag = 0; | ||||
for( i = 0; i < list->len - 1; i++ ) | ||||
if( list->list[ i ] == list->list[ i + 1 ] ) { | ||||
for( j = i + 1; j < list->len; j++ ) | ||||
list->list[ j - 1 ] = list->list[ j ]; | ||||
list->len--; | ||||
flag = 1; | ||||
break; | ||||
} | ||||
} while( flag ); | ||||
return 0; | ||||
} | } | |||
char *get_size(const char *path, const char *file) | /*! | |||
{ | Get a comma separated list of numbers and split them into separate values taking | |||
FILE *fp; | into account | |||
static char response[255]; | that no value may be greater than a maximum. If a value is a range, it is expend | |||
char cmd[255]; | ed. | |||
char *ptr; | ||||
Any duplicate value is removed. | ||||
\param paramname Name of the configuration parameter providing the list. | ||||
\param buffer The string with the list of numbers. | ||||
\param list List where to store the numbers. | ||||
\param maxvalue The maximum value allowed in the list. | ||||
if (snprintf(cmd,sizeof(cmd),"du -skh \"%s%s\"",path,file)>=sizeof(cmd)) | The function terminate the application with an error message if the list is inva | |||
{ | lid. | |||
debuga(_("Cannot get disk space because the path \"%s%s\" is too | */ | |||
long\n"),path,file); | void getnumlist(const char *paramname, const char *buffer, int *list, int maxval | |||
ue) | ||||
{ | ||||
int i, d, d0; | ||||
int digitcount; | ||||
int nvalues=0; | ||||
// skip parameter name | ||||
while (*buffer && *buffer!=' ' && *buffer!='\t') buffer++; | ||||
if (!*buffer) | ||||
{ | ||||
debuga(__FILE__,__LINE__,_("Missing values for parameter \"%s\"\n | ||||
"),paramname); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if ((fp = popen(cmd, "r")) == NULL) { | ||||
debuga(_("Cannot get disk space with command %s\n"),cmd); | // clear list | |||
exit(EXIT_FAILURE); | for (i=0 ; i<maxvalue ; i++) list[i]=0; | |||
// get values | ||||
d=0; | ||||
d0=-1; | ||||
digitcount=0; | ||||
for ( ; *buffer ; buffer++) | ||||
{ | ||||
if (isdigit(*buffer)) | ||||
{ | ||||
d=d*10+(*buffer-'0'); | ||||
if (d>=maxvalue) | ||||
{ | ||||
debuga(__FILE__,__LINE__,_("Value too big found i | ||||
n parameter \"%s\" (max value is %d)\n"),paramname,maxvalue-1); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
digitcount++; | ||||
} | ||||
else if (*buffer=='-') | ||||
{ | ||||
if (!digitcount) | ||||
{ | ||||
debuga(__FILE__,__LINE__,_("Missing start value b | ||||
efore \"-\" in parameter \"%s\"\n"),paramname); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
d0=d; | ||||
d=0; | ||||
digitcount=0; | ||||
} | ||||
else if (*buffer==',') | ||||
{ | ||||
if (!digitcount) | ||||
{ | ||||
debuga(__FILE__,__LINE__,_("Missing value before | ||||
\",\" in parameter \"%s\"\n"),paramname); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
storenumlist(paramname,list,d0,d); | ||||
nvalues++; | ||||
d0=-1; | ||||
d=0; | ||||
digitcount=0; | ||||
} | ||||
else if (*buffer=='\r' || *buffer=='\n') | ||||
{ | ||||
break; | ||||
} | ||||
else if (*buffer!=' ' && *buffer!='\t') | ||||
{ | ||||
debuga(__FILE__,__LINE__,_("Invalid character \"%c\" foun | ||||
d in parameter \"%s\"\n"),*buffer,paramname); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
} | ||||
if (digitcount>0) | ||||
{ | ||||
storenumlist(paramname,list,d0,d); | ||||
nvalues++; | ||||
} | } | |||
if (!fgets(response, sizeof(response), fp)) { | else if (d0>=0) | |||
debuga(_("Cannot get disk size with command %s\n"),cmd); | { | |||
debuga(__FILE__,__LINE__,_("Missing ending value in range for par | ||||
ameter \"%s\"\n"),paramname); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
ptr=strchr(response,'\t'); | if (!nvalues) | |||
if (ptr==NULL) { | { | |||
/* TRANSLATORS: First %s is the command to get the occuped disk s | debuga(__FILE__,__LINE__,_("Parameter \"%s\" is empty\n"),paramna | |||
ize (namely, du -skh "..."). | me); | |||
* The second %s is the string returned by the command. | ||||
*/ | ||||
debuga(_("The command to compute the occupied disk size (%s) retu | ||||
rned the unknown string %s\n"),cmd,response); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
pclose(fp); | } | |||
*ptr='\0'; | ||||
return (response); | /*! | |||
* Search if the \a list contains the \a value. | ||||
* | ||||
* \param list The list to search for a value. | ||||
* \param maxvalue The maximum value of the list. | ||||
* \param value The value to search for. | ||||
* | ||||
* \return \c True if the value is enabled in the list. | ||||
*/ | ||||
bool numlistcontains(const int *list, int maxvalue, int value) | ||||
{ | ||||
if (value<0 || value>=maxvalue) return(false); | ||||
return(list[value]!=0); | ||||
} | } | |||
void show_info(FILE *fp_ou) | void show_info(FILE *fp_ou) | |||
{ | { | |||
char ftime[127]; | char ftime[127]; | |||
char pgmurl[250]; | ||||
if(!ShowSargInfo) return; | if (!ShowSargInfo) return; | |||
zdate(ftime, sizeof(ftime), DateFormat); | zdate(ftime, sizeof(ftime), df); | |||
fputs("<div class=\"info\">",fp_ou); | fputs("<div class=\"info\">",fp_ou); | |||
snprintf(pgmurl,sizeof(pgmurl),"<a href='%s'>%s-%s</a>",URL,PGM,VERSION); | fprintf(fp_ou,_("Generated by <a href=\"%s\">%s-%s</a> on %s"),URL,PGM,VE | |||
fprintf(fp_ou,_("Generated by %s on %s"),pgmurl,ftime); | RSION,ftime); | |||
fputs("</div>\n",fp_ou); | fputs("</div>\n",fp_ou); | |||
} | } | |||
void show_sarg(FILE *fp_ou, int depth) | void show_sarg(FILE *fp_ou, int depth) | |||
{ | { | |||
int i; | int i; | |||
if(!ShowSargLogo) return; | if (!ShowSargLogo) return; | |||
fputs("<div class=\"logo\"><a href=\"http://sarg.sourceforge.net\"><img s rc=\"",fp_ou); | fputs("<div class=\"logo\"><a href=\"http://sarg.sourceforge.net\"><img s rc=\"",fp_ou); | |||
for (i=0 ; i<depth ; i++) | for (i=0 ; i<depth ; i++) | |||
fputs("../",fp_ou); | fputs("../",fp_ou); | |||
fputs("images/sarg.png\" title=\"SARG, Squid Analysis Report Generator. L ogo by Osamu Matsuzaki\" alt=\"Sarg\"></a> Squid Analysis Report Generator< /div>\n",fp_ou); | fputs("images/sarg.png\" title=\"SARG, Squid Analysis Report Generator. L ogo by Osamu Matsuzaki\" alt=\"Sarg\"></a> Squid Analysis Report Generator< /div>\n",fp_ou); | |||
} | } | |||
void write_logo_image(FILE *fp_ou) | void write_logo_image(FILE *fp_ou) | |||
{ | { | |||
if(LogoImage[0]!='\0') | if (LogoImage[0]!='\0') | |||
fprintf(fp_ou, "<div class=\"logo\"><img src=\"%s\" width=\"%s\" height=\"%s\" alt=\"Logo\"> %s</div>\n",LogoImage,Width,Height,LogoText); | fprintf(fp_ou, "<div class=\"logo\"><img src=\"%s\" width=\"%s\" height=\"%s\" alt=\"Logo\"> %s</div>\n",LogoImage,Width,Height,LogoText); | |||
} | } | |||
void write_html_head(FILE *fp_ou, int depth, const char *page_title,int javascri pt) | void write_html_head(FILE *fp_ou, int depth, const char *page_title,int javascri pt) | |||
{ | { | |||
int i; | int i; | |||
fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w 3.org/TR/html4/strict.dtd\">\n<html>\n",fp_ou); | fputs("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w 3.org/TR/html4/strict.dtd\">\n<html>\n",fp_ou); | |||
fprintf(fp_ou, "<head>\n <meta http-equiv=\"Content-Type\" content=\"tex t/html; charset=%s\">\n",CharSet); | fprintf(fp_ou, "<head>\n <meta http-equiv=\"Content-Type\" content=\"tex t/html; charset=%s\">\n",CharSet); | |||
if (page_title) fprintf(fp_ou,"<title>%s</title>\n",page_title); | if (page_title) fprintf(fp_ou,"<title>%s</title>\n",page_title); | |||
skipping to change at line 1740 | skipping to change at line 2139 | |||
write_logo_image(fp_ou); | write_logo_image(fp_ou); | |||
show_sarg(fp_ou, depth); | show_sarg(fp_ou, depth); | |||
fprintf(fp_ou,"<div class=\"title\"><table cellpadding=\"0\" cellspacing= \"0\">\n<tr><th class=\"title_c\">%s</th></tr>\n",Title); | fprintf(fp_ou,"<div class=\"title\"><table cellpadding=\"0\" cellspacing= \"0\">\n<tr><th class=\"title_c\">%s</th></tr>\n",Title); | |||
} | } | |||
void close_html_header(FILE *fp_ou) | void close_html_header(FILE *fp_ou) | |||
{ | { | |||
fputs("</table></div>\n",fp_ou); | fputs("</table></div>\n",fp_ou); | |||
} | } | |||
int write_html_trailer(FILE *fp_ou) | void write_html_trailer(FILE *fp_ou) | |||
{ | { | |||
show_info(fp_ou); | show_info(fp_ou); | |||
if (fputs("</body>\n</html>\n",fp_ou)==EOF) return(-1); | fputs("</body>\n</html>\n",fp_ou); | |||
return(0); | ||||
} | } | |||
void output_html_string(FILE *fp_ou,const char *str,int maxlen) | void output_html_string(FILE *fp_ou,const char *str,int maxlen) | |||
{ | { | |||
int i=0; | int i=0; | |||
while (*str && (maxlen<=0 || i<maxlen)) { | while (*str && (maxlen<=0 || i<maxlen)) { | |||
switch (*str) { | switch (*str) { | |||
case '&': | case '&': | |||
fputs("&",fp_ou); | fputs("&",fp_ou); | |||
skipping to change at line 1821 | skipping to change at line 2219 | |||
fputs("</a>",fp_ou); | fputs("</a>",fp_ou); | |||
} | } | |||
} | } | |||
void url_module(const char *url, char *w2) | void url_module(const char *url, char *w2) | |||
{ | { | |||
int x, y; | int x, y; | |||
char w[255]; | char w[255]; | |||
y=0; | y=0; | |||
for(x=strlen(url)-1; x>=0; x--) { | for (x=strlen(url)-1; x>=0; x--) { | |||
if(url[x] == '/' || y>=sizeof(w)-1) break; | if (url[x] == '/' || y>=sizeof(w)-1) break; | |||
w[y++]=url[x]; | w[y++]=url[x]; | |||
} | } | |||
if (x<0) { | if (x<0) { | |||
w2[0]='\0'; | w2[0]='\0'; | |||
return; | return; | |||
} | } | |||
x=0; | x=0; | |||
for(y=y-1; y>=0; y--) { | for (y=y-1; y>=0; y--) { | |||
w2[x++]=w[y]; | w2[x++]=w[y]; | |||
} | } | |||
w2[x]='\0'; | w2[x]='\0'; | |||
} | } | |||
void url_to_file(const char *url,char *file,int filesize) | /*! | |||
Mangle an URL to produce a part that can be used as an anchor in | ||||
a html <a name=""> tag. | ||||
\param url The URL to mangle. | ||||
\param anchor The buffer to write the mangled URL. | ||||
\param size The size of the buffer. | ||||
*/ | ||||
void url_to_anchor(const char *url,char *anchor,int size) | ||||
{ | { | |||
int i,skip; | int i,j; | |||
bool skip; | ||||
filesize--; | // find url end | |||
skip=0; | for (i=0 ; url[i] && url[i]!='/' && url[i]!='?' ; i++); | |||
for(i=0; i<filesize && *url; url++) { | i--; | |||
if(isalnum(*url) || *url=='-' || *url=='_' || *url=='.' || *url== | if (i<=0) { | |||
'%') { | anchor[0]='\0'; | |||
file[i++]=*url; | return; | |||
skip=0; | } | |||
// only keep really safe characters | ||||
skip=false; | ||||
j=size-1; | ||||
anchor[j]='\0'; | ||||
while (j>0 && i>=0) | ||||
{ | ||||
if (isalnum(url[i]) || url[i]=='-' || url[i]=='_' || url[i]=='.') | ||||
{ | ||||
anchor[--j]=url[i]; | ||||
skip=false; | ||||
} else { | } else { | |||
if (!skip) file[i++]='_'; | if (!skip) anchor[--j]='_'; | |||
skip=1; | skip=true; | |||
} | } | |||
i--; | ||||
} | ||||
if (j>0) | ||||
{ | ||||
while ( anchor[j]) | ||||
{ | ||||
*anchor=anchor[j]; | ||||
anchor++; | ||||
} | ||||
*anchor='\0'; | ||||
} | } | |||
file[i]='\0'; | ||||
} | } | |||
void version(void) | void version(void) | |||
{ | { | |||
printf(_("SARG version: %s\n"),VERSION); | printf(_("SARG Version: %s\n"),VERSION); | |||
#if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H) | #if defined(ENABLE_NLS) && defined(HAVE_LOCALE_H) | |||
if (debug) { | if (debug) { | |||
printf(_("\nFor the translation to work, a valid message file sho uld be installed as " | printf(_("\nFor the translation to work, a valid message file sho uld be copied to " | |||
"\"%s/<Locale>/LC_MESSAGES/%s.mo\" where <Locale > is derived from the effective locale.\n"),LOCALEDIR,PACKAGE_NAME); | "\"%s/<Locale>/LC_MESSAGES/%s.mo\" where <Locale > is derived from the effective locale.\n"),LOCALEDIR,PACKAGE_NAME); | |||
if (CurrentLocale) { | if (CurrentLocale) { | |||
printf(_("Currently effective locale is \"%s\".\n"),Curre ntLocale); | printf(_("Currently effective locale is \"%s\".\n"),Curre ntLocale); | |||
} else { | } else { | |||
printf(_("Locale is not set in the environment variable.\ n")); | printf(_("Locale is not set in the environment variable.\ n")); | |||
} | } | |||
// TRANSLATORS: You may change this message to tell the reader th at the language is correctly supported. | // TRANSLATORS: You may change this message to tell the reader th at the language is correctly supported. | |||
printf(_("If this message is in English, then your language is no t supported or not correctly installed.\n")); | printf(_("If this message is in English, then your language is no t supported or not correctly installed.\n")); | |||
} | } | |||
#endif | #endif | |||
if (debug) { | ||||
#ifdef HAVE_GLOB_H | ||||
printf(_("File globbing compiled in.\n")); | ||||
#else | ||||
printf(_("File globbing NOT compiled in.\n")); | ||||
#endif | ||||
} | ||||
exit(EXIT_SUCCESS); | exit(EXIT_SUCCESS); | |||
} | } | |||
char *get_param_value(const char *param,char *line) | char *get_param_value(const char *param,char *line) | |||
{ | { | |||
int plen; | int plen; | |||
while (*line==' ' || *line=='\t') line++; | while (*line==' ' || *line=='\t') line++; | |||
plen=strlen(param); | plen=strlen(param); | |||
if (strncasecmp(line,param,plen)) return(NULL); | if (strncasecmp(line,param,plen)) return(NULL); | |||
skipping to change at line 1902 | skipping to change at line 2336 | |||
char dname[MAXLEN]; | char dname[MAXLEN]; | |||
int err; | int err; | |||
dirp=opendir(dir); | dirp=opendir(dir); | |||
if (!dirp) return; | if (!dirp) return; | |||
while ((direntp = readdir(dirp)) != NULL) { | while ((direntp = readdir(dirp)) != NULL) { | |||
if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' || | if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' || | |||
(direntp->d_name[1] == '.' && direntp->d_name[2] == '\0'))) | (direntp->d_name[1] == '.' && direntp->d_name[2] == '\0'))) | |||
continue; | continue; | |||
if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=si zeof(dname)) { | if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=si zeof(dname)) { | |||
debuga(_("Path too long: ")); | debuga(__FILE__,__LINE__,_("Path too long: ")); | |||
debuga_more("%s/%s\n",dir,direntp->d_name); | debuga_more("%s/%s\n",dir,direntp->d_name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
#ifdef HAVE_LSTAT | #ifdef HAVE_LSTAT | |||
err=lstat(dname,&st); | err=lstat(dname,&st); | |||
#else | #else | |||
err=stat(dname,&st); | err=stat(dname,&st); | |||
#endif | #endif | |||
if (err) { | if (err) { | |||
debuga(_("Cannot stat \"%s\": %s\n"),dname,strerror(errno )); | debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),dn ame,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (S_ISREG(st.st_mode)) { | if (S_ISREG(st.st_mode)) { | |||
if (unlink(dname)) { | if (unlink(dname)) { | |||
debuga(_("Cannot delete \"%s\": %s\n"),dname,stre rror(errno)); | debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),dname,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} else if (S_ISDIR(st.st_mode)) { | } else if (S_ISDIR(st.st_mode)) { | |||
unlinkdir(dname,0); | unlinkdir(dname,0); | |||
} else { | } else { | |||
debuga(_("Unknown path type \"%s\"\n"),dname); | debuga(__FILE__,__LINE__,_("Don't know how to delete \"%s \" (not a regular file nor a directory)\n"),dname); | |||
} | } | |||
} | } | |||
closedir(dirp); | closedir(dirp); | |||
if (!contentonly) { | if (!contentonly) { | |||
if (rmdir(dir)) { | if (rmdir(dir)) { | |||
debuga(_("Cannot delete \"%s\": %s\n"),dir,strerror(errno )); | debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"), dir,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} | } | |||
} | } | |||
/*! | /*! | |||
Delete every file from the temporary directory where sarg is told to store its | Delete every file from the temporary directory where sarg is told to store its | |||
temporary files. | temporary files. | |||
As any stray file left over by a previous run would be included in the report, w e | As any stray file left over by a previous run would be included in the report, w e | |||
skipping to change at line 1968 | skipping to change at line 2402 | |||
int i; | int i; | |||
static const char *TmpExt[]= | static const char *TmpExt[]= | |||
{ | { | |||
".int_unsort", | ".int_unsort", | |||
".int_log", | ".int_log", | |||
".day", | ".day", | |||
"htmlrel.txt", | "htmlrel.txt", | |||
".user_unsort", | ".user_unsort", | |||
".user_log", | ".user_log", | |||
".utmp", | ".utmp", | |||
".ip" | ".ip", | |||
"lastlog1", | ||||
"lastlog", | ||||
"emailrep" | ||||
}; | }; | |||
dirp=opendir(dir); | dirp=opendir(dir); | |||
if (!dirp) return; | if (!dirp) return; | |||
// make sure the temporary directory contains only our files | // make sure the temporary directory contains only our files | |||
while ((direntp = readdir(dirp)) != NULL) { | while ((direntp = readdir(dirp)) != NULL) { | |||
if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' || | if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' || | |||
(direntp->d_name[1] == '.' && direntp->d_name[2] == '\0'))) | (direntp->d_name[1] == '.' && direntp->d_name[2] == '\0'))) | |||
continue; | continue; | |||
// is it one of our files | // is it one of our files | |||
dlen=strlen(direntp->d_name); | dlen=strlen(direntp->d_name); | |||
for (i=sizeof(TmpExt)/sizeof(TmpExt[0])-1 ; i>=0 ; i--) { | for (i=sizeof(TmpExt)/sizeof(TmpExt[0])-1 ; i>=0 ; i--) { | |||
elen=strlen(TmpExt[i]); | elen=strlen(TmpExt[i]); | |||
if (dlen>=elen && strcasecmp(direntp->d_name+dlen-elen,Tm pExt[i])==0) break; | if (dlen>=elen && strcasecmp(direntp->d_name+dlen-elen,Tm pExt[i])==0) break; | |||
} | } | |||
if (i<0) { | if (i<0) { | |||
debuga(_("Unknown file \"%s\" found in temporary director y \"%s\". It is not one of our files. " | debuga(__FILE__,__LINE__,_("Unknown file \"%s\" found in temporary directory \"%s\". It is not one of our files. " | |||
"Please check the temporary directory you gave to sarg. A djust the path to a safe " | "Please check the temporary directory you gave to sarg. A djust the path to a safe " | |||
"directory or manually delete the content of \"%s\"\n"),d irentp->d_name,dir,dir); | "directory or manually delete the content of \"%s\"\n"),d irentp->d_name,dir,dir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=si zeof(dname)) { | if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=si zeof(dname)) { | |||
debuga(_("Path too long: ")); | debuga(__FILE__,__LINE__,_("Path too long: ")); | |||
debuga_more("%s/%s\n",dir,direntp->d_name); | debuga_more("%s/%s\n",dir,direntp->d_name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
#ifdef HAVE_LSTAT | #ifdef HAVE_LSTAT | |||
err=lstat(dname,&st); | err=lstat(dname,&st); | |||
#else | #else | |||
err=stat(dname,&st); | err=stat(dname,&st); | |||
#endif | #endif | |||
if (err) { | if (err) { | |||
debuga(_("Cannot stat \"%s\": %s\n"),dname,strerror(errno )); | debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),dn ame,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (S_ISDIR(st.st_mode)) { | if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode)) { | |||
unlinkdir(dname,0); | debuga(__FILE__,__LINE__,_("Unknown path type for \"%s\". | |||
} else if (!S_ISREG(st.st_mode)) { | Check temporary directory\n"),dname); | |||
debuga(_("Unknown path type \"%s\". Check your temporary | ||||
directory\n"),dname); | ||||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} | } | |||
rewinddir(dirp); | rewinddir(dirp); | |||
// now delete our files | // now delete our files | |||
while ((direntp = readdir(dirp)) != NULL) { | while ((direntp = readdir(dirp)) != NULL) { | |||
if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' || | if (direntp->d_name[0] == '.' && (direntp->d_name[1] == '\0' || | |||
(direntp->d_name[1] == '.' && direntp->d_name[2] == '\0'))) | (direntp->d_name[1] == '.' && direntp->d_name[2] == '\0'))) | |||
continue; | continue; | |||
// is it one of our files | // is it one of our files | |||
dlen=strlen(direntp->d_name); | dlen=strlen(direntp->d_name); | |||
for (i=sizeof(TmpExt)/sizeof(TmpExt[0])-1 ; i>=0 ; i--) { | for (i=sizeof(TmpExt)/sizeof(TmpExt[0])-1 ; i>=0 ; i--) { | |||
elen=strlen(TmpExt[i]); | elen=strlen(TmpExt[i]); | |||
if (dlen>=elen && strcasecmp(direntp->d_name+dlen-elen,Tm pExt[i])==0) break; | if (dlen>=elen && strcasecmp(direntp->d_name+dlen-elen,Tm pExt[i])==0) break; | |||
} | } | |||
if (i<0) { | if (i<0) { | |||
debuga(_("Unknown file \"%s\" found in temporary director y \"%s\". It is not one of our files. " | debuga(__FILE__,__LINE__,_("Unknown file \"%s\" found in temporary directory \"%s\". It is not one of our files. " | |||
"Please check the temporary directory you gave to sarg. A djust the path to a safe " | "Please check the temporary directory you gave to sarg. A djust the path to a safe " | |||
"directory or manually delete the content of \"%s\"\n"),d irentp->d_name,dir,dir); | "directory or manually delete the content of \"%s\"\n"),d irentp->d_name,dir,dir); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=si zeof(dname)) { | if (snprintf(dname,sizeof(dname),"%s/%s",dir,direntp->d_name)>=si zeof(dname)) { | |||
debuga(_("Path too long: ")); | debuga(__FILE__,__LINE__,_("Path too long: ")); | |||
debuga_more("%s/%s\n",dir,direntp->d_name); | debuga_more("%s/%s\n",dir,direntp->d_name); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
#ifdef HAVE_LSTAT | #ifdef HAVE_LSTAT | |||
err=lstat(dname,&st); | err=lstat(dname,&st); | |||
#else | #else | |||
err=stat(dname,&st); | err=stat(dname,&st); | |||
#endif | #endif | |||
if (err) { | if (err) { | |||
debuga(_("Cannot stat \"%s\": %s\n"),dname,strerror(errno )); | debuga(__FILE__,__LINE__,_("Cannot stat \"%s\": %s\n"),dn ame,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
if (S_ISREG(st.st_mode)) { | if (S_ISDIR(st.st_mode)) { | |||
unlinkdir(dname,0); | ||||
} else if (S_ISREG(st.st_mode)) { | ||||
if (unlink(dname)) { | if (unlink(dname)) { | |||
debuga(_("Cannot delete \"%s\": %s\n"),dname,stre rror(errno)); | debuga(__FILE__,__LINE__,_("Cannot delete \"%s\": %s\n"),dname,strerror(errno)); | |||
exit(EXIT_FAILURE); | exit(EXIT_FAILURE); | |||
} | } | |||
} else { | } else { | |||
debuga(_("Unknown path type \"%s\"\n"),dname); | debuga(__FILE__,__LINE__,_("Don't know how to delete \"%s \" (not a regular file)\n"),dname); | |||
} | } | |||
} | } | |||
closedir(dirp); | closedir(dirp); | |||
} | } | |||
/*! | /*! | |||
Extract an url, IPv4 or IPv6 from a buffer. The IP addresses may end with a | Extract an url, IPv4 or IPv6 from a buffer. The IP addresses may end with a | |||
prefix size. | prefix size. | |||
\param buf The buffer to parse. | \param buf The buffer to parse. | |||
skipping to change at line 2209 | skipping to change at line 2646 | |||
while (i<pad_pos) | while (i<pad_pos) | |||
ipv6[j++]=(unsigned short int)addr[i++]; | ipv6[j++]=(unsigned short int)addr[i++]; | |||
pad_len=8-addr_len; | pad_len=8-addr_len; | |||
while (j<pad_pos+pad_len) | while (j<pad_pos+pad_len) | |||
ipv6[j++]=0; | ipv6[j++]=0; | |||
} | } | |||
while (i<addr_len) | while (i<addr_len) | |||
ipv6[j++]=(unsigned short int)addr[i++]; | ipv6[j++]=(unsigned short int)addr[i++]; | |||
return(3); | return(3); | |||
} | } | |||
int format_path(const char *file, int line, char *output_buffer, int buffer_size | ||||
, const char *format,...) | ||||
{ | ||||
va_list ap; | ||||
int output_length; | ||||
va_start(ap, format); | ||||
output_length = vsnprintf(output_buffer, buffer_size, format, ap); | ||||
if (output_length >= buffer_size) { | ||||
debuga(file, line, _("Path too long: ")); | ||||
vfprintf(stderr, format, ap); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
va_end(ap); | ||||
return output_length; | ||||
} | ||||
void append_to_path(char *base_path, int base_path_size, const char *append) | ||||
{ | ||||
int length = strlen(base_path); | ||||
int append_length; | ||||
if (append[0] == '/') append++; | ||||
if (length > 0 && base_path[length-1] != '/') { | ||||
if (length+1 >= base_path_size) { | ||||
debuga(__FILE__, __LINE__, _("Path too long: ")); | ||||
fprintf(stderr, "%s/%s", base_path, append); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
base_path[length++] = '/'; | ||||
} | ||||
append_length = strlen(append); | ||||
if (length+append_length >= base_path_size) { | ||||
debuga(__FILE__, __LINE__, _("Path too long: ")); | ||||
base_path[length] = '\0'; | ||||
fprintf(stderr, "%s%s", base_path, append); | ||||
exit(EXIT_FAILURE); | ||||
} | ||||
strcpy(base_path + length, append); | ||||
} | ||||
End of changes. 203 change blocks. | ||||
505 lines changed or deleted | 1013 lines changed or added |