86 |
#include <crypt.h> |
#include <crypt.h> |
87 |
#endif |
#endif |
88 |
|
|
89 |
|
#ifdef HAVE_ARPA_INET_H |
90 |
|
#include <arpa/inet.h> |
91 |
|
#endif |
92 |
|
|
93 |
#include "monitor.h" |
#include "monitor.h" |
94 |
#include "engine.h" |
#include "engine.h" |
95 |
#include "md5.h" |
#include "md5.h" |
132 |
|
|
133 |
|
|
134 |
/** Defines supported url protocol names and defaults */ |
/** Defines supported url protocol names and defaults */ |
135 |
UrlProtocol_T protocol[]= |
UrlProtocol_T protocol[]= { |
|
{ |
|
136 |
{PROTOCOL_HTTP, "http://", "http", PORT_HTTP }, |
{PROTOCOL_HTTP, "http://", "http", PORT_HTTP }, |
137 |
{PROTOCOL_HTTPS, "https://", "https", PORT_HTTPS }, |
{PROTOCOL_HTTPS, "https://", "https", PORT_HTTPS }, |
138 |
{PROTOCOL_NULL, NULL, NULL, 0 } |
{PROTOCOL_NULL, NULL, NULL, 0 } |
143 |
|
|
144 |
|
|
145 |
/** |
/** |
146 |
* @return TRUE if the string parameter is defined, otherwise FALSE |
* Return only the filename with leading directory components |
147 |
*/ |
* removed. This function does not modify the path string. |
|
int is_strdefined(char *p) { |
|
|
|
|
|
return(p && *p); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
* Strip the path and return only the filename |
|
148 |
* @param path A file path string |
* @param path A file path string |
149 |
* @return the basename |
* @return A pointer to the basename in path |
150 |
*/ |
*/ |
151 |
char *stripfilename(char* path) { |
char *Util_basename(char* path) { |
152 |
|
|
153 |
char *fname; |
char *fname; |
154 |
|
|
165 |
* Removes everything from the first newline (CR|LF) |
* Removes everything from the first newline (CR|LF) |
166 |
* @param string A string to be chomped |
* @param string A string to be chomped |
167 |
*/ |
*/ |
168 |
void chomp(char *string, int len) { |
void Util_chomp(char *string, int len) { |
169 |
|
|
170 |
char *p=string; |
char *p=string; |
171 |
int i; |
int i; |
188 |
* @param s A string |
* @param s A string |
189 |
* @return s with leading and trailing spaces removed |
* @return s with leading and trailing spaces removed |
190 |
*/ |
*/ |
191 |
char *trim(char *s) { |
char *Util_trim(char *s) { |
192 |
|
|
193 |
ASSERT(s); |
ASSERT(s); |
194 |
|
|
195 |
ltrim(s); |
Util_ltrim(s); |
196 |
rtrim(s); |
Util_rtrim(s); |
197 |
|
|
198 |
return s; |
return s; |
199 |
|
|
205 |
* @param s A string |
* @param s A string |
206 |
* @return s with leading spaces removed |
* @return s with leading spaces removed |
207 |
*/ |
*/ |
208 |
char *ltrim(char *s) { |
char *Util_ltrim(char *s) { |
209 |
|
|
210 |
char *t= s; |
char *t= s; |
211 |
|
|
223 |
* @param s A string |
* @param s A string |
224 |
* @return s with trailing spaces removed |
* @return s with trailing spaces removed |
225 |
*/ |
*/ |
226 |
char *rtrim(char *s) { |
char *Util_rtrim(char *s) { |
227 |
|
|
228 |
char *t= s; |
char *t= s; |
229 |
|
|
231 |
|
|
232 |
while(*s) s++; |
while(*s) s++; |
233 |
while(*--s==' ' || *s=='\t' || *s=='\r' || *s=='\n') *s= '\0'; |
while(*--s==' ' || *s=='\t' || *s=='\r' || *s=='\n') *s= '\0'; |
234 |
|
|
235 |
return t; |
return t; |
236 |
|
|
237 |
} |
} |
241 |
* @param s A string |
* @param s A string |
242 |
* @return s with any enclosed quotes removed |
* @return s with any enclosed quotes removed |
243 |
*/ |
*/ |
244 |
|
void Util_trimQuotes(char *s) { |
|
void trim_quotes(char *s) { |
|
245 |
|
|
246 |
char *t= s; |
char *t= s; |
247 |
char tmp=0; |
char tmp=0; |
260 |
} |
} |
261 |
|
|
262 |
while ( *t != tmp && *t != '\0' ) { |
while ( *t != tmp && *t != '\0' ) { |
|
|
|
263 |
*(t-1) = *t; |
*(t-1) = *t; |
264 |
t++; |
t++; |
|
|
|
265 |
} |
} |
266 |
|
|
267 |
*(t-1) = '\0'; |
*(t-1) = '\0'; |
279 |
* @param new The new char |
* @param new The new char |
280 |
* @return s where all occurrence of old are replaced with new |
* @return s where all occurrence of old are replaced with new |
281 |
*/ |
*/ |
282 |
char *replace_char(char *s, char old, char new) { |
char *Util_replace(char *s, char old, char new) { |
283 |
|
|
284 |
char *t= s; |
char *t= s; |
285 |
|
|
301 |
* @return src where all occurrences of the old sub-string are |
* @return src where all occurrences of the old sub-string are |
302 |
* replaced with the new sub-string. |
* replaced with the new sub-string. |
303 |
*/ |
*/ |
304 |
char *replace_string(char **src, const char *old, const char *new) { |
char *Util_replaceString(char **src, const char *old, const char *new) { |
305 |
|
|
306 |
int i; |
int i; |
307 |
int d; |
int d; |
308 |
|
|
309 |
ASSERT(src && *src && old && new); |
ASSERT(src && *src && old && new); |
310 |
|
|
311 |
i= count_words(*src, old); |
i= Util_countWords(*src, old); |
312 |
d= strlen(new)-strlen(old); |
d= strlen(new)-strlen(old); |
313 |
|
|
314 |
if(i==0) |
if(i==0) |
315 |
return *src; |
return *src; |
316 |
if(d>0) |
if(d>0) |
317 |
d*= i; |
d*= i; |
318 |
else |
else |
319 |
d= 0; |
d= 0; |
320 |
|
|
321 |
{ |
{ |
322 |
char *p, *q; |
char *p, *q; |
323 |
int l= strlen(old); |
int l= strlen(old); |
324 |
char *buf= xmalloc(strlen(*src)+d+1); |
char *buf= xmalloc(strlen(*src)+d+1); |
325 |
|
|
326 |
q= *src; |
q= *src; |
327 |
*buf= 0; |
*buf= 0; |
328 |
|
|
340 |
FREE(*src); |
FREE(*src); |
341 |
*src= buf; |
*src= buf; |
342 |
} |
} |
343 |
|
|
344 |
return *src; |
return *src; |
345 |
|
|
346 |
} |
} |
351 |
* @param s The String to search for word in |
* @param s The String to search for word in |
352 |
* @param word The sub-string to count in s |
* @param word The sub-string to count in s |
353 |
*/ |
*/ |
354 |
int count_words(char *s, const char *word) { |
int Util_countWords(char *s, const char *word) { |
355 |
|
|
356 |
int i= 0; |
int i= 0; |
357 |
char *p= s; |
char *p= s; |
374 |
* @param b The sub-string to test a against |
* @param b The sub-string to test a against |
375 |
* @return TRUE if a starts with b, otherwise FALSE |
* @return TRUE if a starts with b, otherwise FALSE |
376 |
*/ |
*/ |
377 |
int starts_with(const char *a, const char *b) { |
int Util_startsWith(const char *a, const char *b) { |
378 |
|
|
379 |
if((!a || !b) || *a!=*b) return FALSE; |
if((!a || !b) || *a!=*b) return FALSE; |
380 |
|
|
393 |
* Exchanges \escape sequences in a string |
* Exchanges \escape sequences in a string |
394 |
* @param buf A string |
* @param buf A string |
395 |
*/ |
*/ |
396 |
void handle_string_escapes(char *buf) { |
void Util_handleEscapes(char *buf) { |
397 |
|
|
398 |
int editpos; |
int editpos; |
399 |
int insertpos; |
int insertpos; |
400 |
|
|
401 |
ASSERT(buf); |
ASSERT(buf); |
402 |
|
|
403 |
for(editpos=insertpos=0; *(buf+editpos)!='\0'; editpos++, insertpos++) { |
for(editpos=insertpos=0; *(buf+editpos)!='\0'; editpos++, insertpos++) { |
404 |
|
|
405 |
if(*(buf+editpos) == '\\' ) { |
if(*(buf+editpos) == '\\' ) { |
406 |
|
|
407 |
switch(*(buf+editpos+1)) { |
switch(*(buf+editpos+1)) { |
408 |
|
|
409 |
case 'n': |
case 'n': |
410 |
*(buf+insertpos)='\n'; |
*(buf+insertpos)='\n'; |
411 |
editpos++; |
editpos++; |
452 |
* @param name A service name as stated in the config file |
* @param name A service name as stated in the config file |
453 |
* @return the named service or NULL if not found |
* @return the named service or NULL if not found |
454 |
*/ |
*/ |
455 |
Service_T get_service(const char *name) { |
Service_T Util_getService(const char *name) { |
456 |
|
|
457 |
Service_T s; |
Service_T s; |
458 |
|
|
470 |
|
|
471 |
|
|
472 |
/** |
/** |
473 |
|
* Get the length of the service list, that is; the number of services |
474 |
|
* managed by monit |
475 |
|
* @return The number of services monitored |
476 |
|
*/ |
477 |
|
int Util_getNumberOfServices() { |
478 |
|
int i= 0; |
479 |
|
Service_T s; |
480 |
|
for(s= servicelist; s; s= s->next) i+=1; |
481 |
|
return i; |
482 |
|
} |
483 |
|
|
484 |
|
|
485 |
|
/** |
486 |
* @param name A service name as stated in the config file |
* @param name A service name as stated in the config file |
487 |
* @return TRUE if the service name exist in the |
* @return TRUE if the service name exist in the |
488 |
* servicelist, otherwise FALSE |
* servicelist, otherwise FALSE |
489 |
*/ |
*/ |
490 |
int exist_service(const char *name) { |
int Util_existService(const char *name) { |
491 |
|
|
492 |
Service_T s; |
Service_T s; |
493 |
|
|
503 |
|
|
504 |
|
|
505 |
/** |
/** |
|
* Get the length of the service list, that is; the number of |
|
|
* services in the list. |
|
|
* @return The length of the service list |
|
|
*/ |
|
|
int get_service_list_length() { |
|
|
|
|
|
int i= 0; |
|
|
Service_T s; |
|
|
|
|
|
for(s= servicelist; s; s= s->next) i+=1; |
|
|
|
|
|
return i; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
506 |
* Print the Runtime object |
* Print the Runtime object |
507 |
*/ |
*/ |
508 |
void printrunlist() { |
void Util_printRunList() { |
509 |
|
|
510 |
printf("Runtime constants:\n"); |
printf("Runtime constants:\n"); |
511 |
printf(" %-18s = %s\n", "Control file", is_str_defined(Run.controlfile)); |
printf(" %-18s = %s\n", "Control file", is_str_defined(Run.controlfile)); |
605 |
* Print a service object |
* Print a service object |
606 |
* @param p A Service_T object |
* @param p A Service_T object |
607 |
*/ |
*/ |
608 |
void printservice(Service_T s) { |
void Util_printService(Service_T s) { |
609 |
|
|
610 |
Port_T n; |
Port_T n; |
611 |
Icmp_T i; |
Icmp_T i; |
914 |
/** |
/** |
915 |
* Print all the services in the servicelist |
* Print all the services in the servicelist |
916 |
*/ |
*/ |
917 |
void printservicelist() { |
void Util_printServiceList() { |
918 |
|
|
919 |
Service_T s; |
Service_T s; |
920 |
char ruler[STRLEN]; |
char ruler[STRLEN]; |
923 |
|
|
924 |
for(s= servicelist_conf; s; s= s->next_conf) { |
for(s= servicelist_conf; s; s= s->next_conf) { |
925 |
|
|
926 |
printservice(s); |
Util_printService(s); |
927 |
|
|
928 |
} |
} |
929 |
|
|
933 |
} |
} |
934 |
|
|
935 |
/** |
/** |
936 |
* Print file hashes from stdin or file |
* Print file hashes from stdin or from the given file |
937 |
*/ |
*/ |
938 |
void printhash(char *filename) { |
void Util_printHash(char *filename) { |
939 |
|
|
940 |
unsigned char buf[STRLEN], buf2[STRLEN]; |
unsigned char buf[STRLEN], buf2[STRLEN]; |
941 |
FILE * fhandle; |
FILE * fhandle; |
943 |
int i; |
int i; |
944 |
|
|
945 |
if (filename == NULL) { |
if (filename == NULL) { |
|
|
|
946 |
fhandle = stdin; |
fhandle = stdin; |
|
|
|
947 |
} else { |
} else { |
|
|
|
948 |
fhandle = fopen(filename, "r"); |
fhandle = fopen(filename, "r"); |
|
|
|
949 |
if ( fhandle == NULL ) { |
if ( fhandle == NULL ) { |
|
|
|
950 |
goto fileerror; |
goto fileerror; |
|
|
|
951 |
} |
} |
952 |
} |
} |
953 |
|
fresult=Util_getStreamDigests(fhandle, buf, buf2); |
|
fresult=sha_md5_stream(fhandle, buf, buf2); |
|
|
|
|
954 |
if(fresult) { |
if(fresult) { |
|
|
|
955 |
goto fileerror; |
goto fileerror; |
|
|
|
956 |
} |
} |
|
|
|
957 |
if (filename==NULL) { |
if (filename==NULL) { |
958 |
|
printf("SHA1(stdin) = "); |
|
printf("SHA1(stdin) = "); |
|
|
|
|
959 |
} else { |
} else { |
960 |
|
printf("SHA1(%s) = ", filename); |
961 |
printf("SHA1(%s) = ", filename); |
fclose(fhandle); |
|
|
|
|
fclose(fhandle); |
|
962 |
} |
} |
|
|
|
963 |
for(i= 0; i < 20; ++i) { |
for(i= 0; i < 20; ++i) { |
964 |
|
printf("%02x", buf[i]); |
|
printf("%02x", buf[i]); |
|
|
|
|
965 |
} |
} |
|
|
|
966 |
if (filename==NULL) { |
if (filename==NULL) { |
967 |
|
printf("\nMD5(stdin) = "); |
|
printf("\nMD5(stdin) = "); |
|
|
|
|
968 |
} else { |
} else { |
969 |
|
printf("\nMD5(%s) = ", filename); |
|
printf("\nMD5(%s) = ", filename); |
|
|
|
|
970 |
} |
} |
|
|
|
971 |
for(i= 0; i < 16; ++i) { |
for(i= 0; i < 16; ++i) { |
972 |
|
printf("%02x", buf2[i]); |
|
printf("%02x", buf2[i]); |
|
|
|
|
973 |
} |
} |
|
|
|
974 |
printf("\n"); |
printf("\n"); |
975 |
|
|
976 |
return; |
return; |
977 |
|
|
978 |
fileerror: |
fileerror: |
979 |
|
|
980 |
printf("monit: %s: %s\n", filename, strerror(errno)); |
printf("monit: %s: %s\n", filename, strerror(errno)); |
|
|
|
981 |
exit(1); |
exit(1); |
|
|
|
982 |
} |
} |
983 |
|
|
984 |
/** |
/** |
987 |
* @return the pid (TRUE) or FALSE if the pid could |
* @return the pid (TRUE) or FALSE if the pid could |
988 |
* not be read from the file |
* not be read from the file |
989 |
*/ |
*/ |
990 |
pid_t get_pid(char *pidfile) { |
pid_t Util_getPid(char *pidfile) { |
991 |
|
|
992 |
FILE *file= NULL; |
FILE *file= NULL; |
993 |
int pid= -1; |
int pid= -1; |
994 |
|
|
995 |
ASSERT(pidfile); |
ASSERT(pidfile); |
996 |
|
|
997 |
if(! exist_file(pidfile)) { |
if(! File_exist(pidfile)) { |
|
|
|
998 |
return(FALSE); |
return(FALSE); |
|
|
|
999 |
} |
} |
1000 |
|
if(! File_isFile(pidfile)) { |
|
if(! isreg_file(pidfile)) { |
|
|
|
|
1001 |
log("%s: pidfile '%s' is not a regular file\n",prog, pidfile); |
log("%s: pidfile '%s' is not a regular file\n",prog, pidfile); |
1002 |
return(FALSE); |
return(FALSE); |
|
|
|
1003 |
} |
} |
|
|
|
1004 |
if((file= fopen(pidfile,"r")) == (FILE *)NULL) { |
if((file= fopen(pidfile,"r")) == (FILE *)NULL) { |
|
|
|
1005 |
log("%s: Error opening the pidfile '%s' -- %s\n", |
log("%s: Error opening the pidfile '%s' -- %s\n", |
1006 |
prog, pidfile, STRERROR); |
prog, pidfile, STRERROR); |
1007 |
return(FALSE); |
return(FALSE); |
|
|
|
1008 |
} |
} |
|
|
|
1009 |
fscanf(file, "%d", &pid); |
fscanf(file, "%d", &pid); |
1010 |
fclose(file); |
fclose(file); |
|
|
|
1011 |
if(pid == -1) { |
if(pid == -1) { |
|
|
|
1012 |
log("%s: pidfile `%s' does not contain a valid pidnumber\n", |
log("%s: pidfile `%s' does not contain a valid pidnumber\n", |
1013 |
prog, pidfile); |
prog, pidfile); |
|
|
|
1014 |
return (FALSE); |
return (FALSE); |
|
|
|
1015 |
} |
} |
1016 |
|
|
1017 |
return (pid_t)pid; |
return (pid_t)pid; |
1018 |
|
|
1019 |
} |
} |
1023 |
* @return TRUE (i.e. the running pid id) if |
* @return TRUE (i.e. the running pid id) if |
1024 |
* the process is running, otherwise FALSE |
* the process is running, otherwise FALSE |
1025 |
*/ |
*/ |
1026 |
int is_process_running(Service_T s) { |
int Util_isProcessRunning(Service_T s) { |
1027 |
|
|
1028 |
pid_t pid; |
pid_t pid; |
1029 |
|
|
1030 |
ASSERT(s); |
ASSERT(s); |
1031 |
|
|
1032 |
errno= 0; |
errno= 0; |
1033 |
|
if((pid= Util_getPid(s->path))) |
|
if((pid= get_pid(s->path))) |
|
1034 |
if( (getpgid(pid) > -1) || (errno == EPERM) ) |
if( (getpgid(pid) > -1) || (errno == EPERM) ) |
1035 |
return pid; |
return pid; |
1036 |
|
Util_resetProcInfo(s); |
1037 |
reset_procinfo(s); |
|
|
|
|
1038 |
return FALSE; |
return FALSE; |
1039 |
|
|
1040 |
} |
} |
1046 |
* @param date |
* @param date |
1047 |
* @return a date string or NULL if an error occured |
* @return a date string or NULL if an error occured |
1048 |
*/ |
*/ |
1049 |
char *get_RFC822date(long *date) { |
char *Util_getRFC822Date(long *date) { |
1050 |
|
|
1051 |
char D[STRLEN]; |
char D[STRLEN]; |
1052 |
struct tm *tm_now; |
struct tm *tm_now; |
1053 |
time_t now= (date && *date>0)?*date:time(NULL); |
time_t now= (date && *date>0)?*date:time(NULL); |
1054 |
|
|
1055 |
tm_now= localtime(&now); |
tm_now= localtime(&now); |
1056 |
|
|
1057 |
if(strftime(D, STRLEN, "%a, %d %b %Y %H:%M:%S %z", tm_now) <= 0) { |
if(strftime(D, STRLEN, "%a, %d %b %Y %H:%M:%S %z", tm_now) <= 0) { |
|
|
|
1058 |
return NULL; |
return NULL; |
|
|
|
1059 |
} |
} |
1060 |
|
|
1061 |
return xstrdup(D); |
return xstrdup(D); |
1069 |
* @param pidfile A process pidfile |
* @param pidfile A process pidfile |
1070 |
* @return an uptime |
* @return an uptime |
1071 |
*/ |
*/ |
1072 |
time_t get_process_uptime(char *pidfile) { |
time_t Util_getProcessUptime(char *pidfile) { |
1073 |
|
|
1074 |
time_t ctime; |
time_t ctime; |
1075 |
|
|
1076 |
ASSERT(pidfile); |
ASSERT(pidfile); |
1077 |
|
|
1078 |
if( (ctime= get_timestamp(pidfile, S_IFREG)) ) { |
if((ctime= File_getTimestamp(pidfile, S_IFREG)) ) { |
|
|
|
1079 |
time_t now= time(&now); |
time_t now= time(&now); |
1080 |
time_t since= now-ctime; |
time_t since= now-ctime; |
|
|
|
1081 |
return since; |
return since; |
|
|
|
1082 |
} |
} |
1083 |
|
|
1084 |
return (time_t)-1; |
return (time_t)-1; |
1093 |
* @param sep string separator |
* @param sep string separator |
1094 |
* @return an uptime string |
* @return an uptime string |
1095 |
*/ |
*/ |
1096 |
char *get_uptime(time_t delta, char *sep) { |
char *Util_getUptime(time_t delta, char *sep) { |
1097 |
|
|
1098 |
static int min= 60; |
static int min= 60; |
1099 |
static int hour= 3600; |
static int hour= 3600; |
1105 |
char *p= buf; |
char *p= buf; |
1106 |
|
|
1107 |
*buf= 0; |
*buf= 0; |
|
|
|
1108 |
if(delta < 0) |
if(delta < 0) |
1109 |
return(xstrdup("")); |
return(xstrdup("")); |
|
|
|
1110 |
if((rest_d= delta/day)>0) { |
if((rest_d= delta/day)>0) { |
1111 |
p+= snprintf(p, STRLEN-(p-buf), "%ldd%s", rest_d,sep); |
p+= snprintf(p, STRLEN-(p-buf), "%ldd%s", rest_d,sep); |
1112 |
delta-= rest_d*day; |
delta-= rest_d*day; |
1115 |
p+= snprintf(p, STRLEN-(p-buf),"%ldh%s", rest_h,sep); |
p+= snprintf(p, STRLEN-(p-buf),"%ldh%s", rest_h,sep); |
1116 |
delta-= rest_h*hour; |
delta-= rest_h*hour; |
1117 |
} |
} |
|
|
|
1118 |
rest_m= delta/min; |
rest_m= delta/min; |
1119 |
p+= snprintf(p, STRLEN-(p-buf),"%ldm%s", rest_m,sep); |
p+= snprintf(p, STRLEN-(p-buf),"%ldm%s", rest_m,sep); |
1120 |
delta-= rest_m*min; |
delta-= rest_m*min; |
1121 |
|
|
1122 |
return xstrdup(buf); |
return xstrdup(buf); |
1123 |
|
|
1124 |
} |
} |
1127 |
/** |
/** |
1128 |
* @return a checksum for the given file, or NULL if error. |
* @return a checksum for the given file, or NULL if error. |
1129 |
*/ |
*/ |
1130 |
char *get_checksum(char *file, int hashtype) { |
char *Util_getChecksum(char *file, int hashtype) { |
1131 |
|
|
1132 |
int hashlength=16; |
int hashlength=16; |
1133 |
|
|
1134 |
ASSERT(file); |
ASSERT(file); |
1135 |
|
|
1136 |
switch(hashtype) { |
switch(hashtype) { |
1137 |
case HASH_MD5: |
case HASH_MD5: |
1138 |
hashlength=16; |
hashlength=16; |
1139 |
break; |
break; |
|
|
|
1140 |
case HASH_SHA1: |
case HASH_SHA1: |
1141 |
hashlength=20; |
hashlength=20; |
1142 |
break; |
break; |
|
|
|
1143 |
default: |
default: |
1144 |
return NULL; |
return NULL; |
1145 |
} |
} |
1146 |
|
|
1147 |
if(isreg_file(file)) { |
if(File_isFile(file)) { |
|
|
|
1148 |
FILE *f= fopen(file, "r"); |
FILE *f= fopen(file, "r"); |
|
|
|
1149 |
if(f) { |
if(f) { |
|
|
|
1150 |
int i; |
int i; |
1151 |
unsigned char buf[hashlength]; |
unsigned char buf[hashlength]; |
1152 |
char result[STRLEN]; |
char result[STRLEN]; |
1153 |
char *r= result; |
char *r= result; |
1154 |
int fresult=0; |
int fresult=0; |
1155 |
|
|
1156 |
*result=0; |
*result=0; |
1157 |
|
|
1158 |
switch(hashtype) { |
switch(hashtype) { |
1159 |
case HASH_MD5: |
case HASH_MD5: |
1160 |
fresult=md5_stream(f, buf); |
fresult=md5_stream(f, buf); |
1161 |
break; |
break; |
|
|
|
1162 |
case HASH_SHA1: |
case HASH_SHA1: |
1163 |
fresult=sha_stream(f, buf); |
fresult=sha_stream(f, buf); |
1164 |
break; |
break; |
1165 |
} |
} |
1166 |
|
|
1167 |
|
fclose(f); |
1168 |
if(fresult) { |
if(fresult) { |
|
|
|
|
fclose(f); |
|
|
|
|
1169 |
return NULL; |
return NULL; |
|
|
|
1170 |
} |
} |
|
|
|
|
fclose(f); |
|
|
|
|
1171 |
for(i= 0; i < hashlength; ++i) |
for(i= 0; i < hashlength; ++i) |
1172 |
r+= snprintf(r, STRLEN-(r-result) ,"%02x", buf[i]); |
r+= snprintf(r, STRLEN-(r-result) ,"%02x", buf[i]); |
1173 |
|
|
1174 |
return (xstrdup(result)); |
return (xstrdup(result)); |
1175 |
|
|
1176 |
} |
} |
|
|
|
1177 |
} |
} |
|
|
|
1178 |
return NULL; |
return NULL; |
|
|
|
1179 |
} |
} |
1180 |
|
|
1181 |
|
|
1185 |
* @param uri an uri string |
* @param uri an uri string |
1186 |
* @return the escaped string |
* @return the escaped string |
1187 |
*/ |
*/ |
1188 |
char *url_encode(char *uri) { |
char *Util_urlEncode(char *uri) { |
1189 |
|
|
1190 |
register int x, y; |
register int x, y; |
1191 |
unsigned char *str; |
unsigned char *str; |
1216 |
* @param url an escaped url string |
* @param url an escaped url string |
1217 |
* @return A pointer to the unescaped <code>url</code>string |
* @return A pointer to the unescaped <code>url</code>string |
1218 |
*/ |
*/ |
1219 |
char *url_decode(char *url) { |
char *Util_urlDecode(char *url) { |
1220 |
|
|
1221 |
register int x,y; |
register int x,y; |
1222 |
|
|
1223 |
if(!(url&&*url)) return url; |
if(!(url&&*url)) return url; |
1224 |
replace_char(url, '+', ' '); |
Util_replace(url, '+', ' '); |
1225 |
for(x=0,y=0;url[y];++x,++y) { |
for(x=0,y=0;url[y];++x,++y) { |
1226 |
if((url[x] = url[y]) == '%') { |
if((url[x] = url[y]) == '%') { |
1227 |
url[x]= x2c(&url[y+1]); |
url[x]= x2c(&url[y+1]); |
1238 |
* @param string an url string |
* @param string an url string |
1239 |
* @return A pointer to the structure which describes particular url parts |
* @return A pointer to the structure which describes particular url parts |
1240 |
*/ |
*/ |
1241 |
Url_T url_parse(char *string) { |
Url_T Util_parseURL(char *string) { |
1242 |
|
|
1243 |
int len; |
int len; |
1244 |
char *start; |
char *start; |
1255 |
|
|
1256 |
u->url = string; |
u->url = string; |
1257 |
|
|
1258 |
url_beg = start = url_encode(string); |
url_beg = start = Util_urlEncode(string); |
1259 |
url_end = url_beg + strlen(url_beg); |
url_end = url_beg + strlen(url_beg); |
1260 |
|
|
1261 |
/* Parse protocol */ |
/* Parse protocol */ |
1372 |
* @return a Basic Authentication Authorization string (RFC 2617), |
* @return a Basic Authentication Authorization string (RFC 2617), |
1373 |
* with credentials from the Run object, NULL if credentials are not defined. |
* with credentials from the Run object, NULL if credentials are not defined. |
1374 |
*/ |
*/ |
1375 |
char *get_basic_authentication_header() { |
char *Util_getBasicAuthHeader() { |
1376 |
|
|
1377 |
Auth_T c=Run.credentials; |
Auth_T c= Run.credentials; |
1378 |
|
|
1379 |
if (c==NULL) { |
if (c==NULL) { |
|
|
|
1380 |
return NULL; |
return NULL; |
|
|
|
1381 |
} |
} |
1382 |
|
|
1383 |
/* We find the first cleartext credential for authorization */ |
/* We find the first cleartext credential for authorization */ |
|
|
|
1384 |
while (c!= NULL) { |
while (c!= NULL) { |
|
|
|
1385 |
if (c->digesttype == DIGEST_CLEARTEXT) { |
if (c->digesttype == DIGEST_CLEARTEXT) { |
|
|
|
1386 |
break; |
break; |
|
|
|
1387 |
} |
} |
|
|
|
1388 |
c=c->next; |
c=c->next; |
|
|
|
1389 |
} |
} |
|
|
|
1390 |
if(c!=NULL) { |
if(c!=NULL) { |
|
|
|
1391 |
char *auth, *b64; |
char *auth, *b64; |
1392 |
char buf[STRLEN]; |
char buf[STRLEN]; |
|
|
|
1393 |
snprintf(buf, STRLEN, "%s:%s", |
snprintf(buf, STRLEN, "%s:%s", |
1394 |
c->uname, |
c->uname, |
1395 |
c->passwd); |
c->passwd); |
|
|
|
1396 |
if(! (b64= encode_base64(strlen(buf), (unsigned char *)buf)) ) { |
if(! (b64= encode_base64(strlen(buf), (unsigned char *)buf)) ) { |
1397 |
log("Failed to base64 encode authentication header\n"); |
log("Failed to base64 encode authentication header\n"); |
1398 |
return NULL; |
return NULL; |
1399 |
} |
} |
|
|
|
1400 |
auth= xcalloc(sizeof(char), STRLEN+1); |
auth= xcalloc(sizeof(char), STRLEN+1); |
1401 |
snprintf(auth, STRLEN, "Authorization: Basic %s\r\n", b64); |
snprintf(auth, STRLEN, "Authorization: Basic %s\r\n", b64); |
1402 |
FREE(b64); |
FREE(b64); |
|
|
|
1403 |
return auth; |
return auth; |
|
|
|
1404 |
} |
} |
1405 |
|
|
1406 |
log("Cleattext credentials needed for basic authorization!\n"); |
log("Cleattext credentials needed for basic authorization!\n"); |
1417 |
* may be different from the returned allocated buffer size |
* may be different from the returned allocated buffer size |
1418 |
* @return buffer with parsed string |
* @return buffer with parsed string |
1419 |
*/ |
*/ |
1420 |
char *format(const char *s, va_list ap, long *len) { |
char *Util_formatString(const char *s, va_list ap, long *len) { |
1421 |
|
|
1422 |
int n; |
int n; |
1423 |
int size= STRLEN; |
int size= STRLEN; |
1424 |
char *buf= xmalloc(size); |
char *buf= xmalloc(size); |
1425 |
|
|
1426 |
#ifdef HAVE_VA_COPY |
#ifdef HAVE_VA_COPY |
1427 |
va_list ap_copy; |
va_list ap_copy; |
1428 |
#endif |
#endif |
1429 |
|
|
1430 |
ASSERT(s); |
ASSERT(s); |
1431 |
|
|
1432 |
while(TRUE) { |
while(TRUE) { |
|
|
|
1433 |
#ifdef HAVE_VA_COPY |
#ifdef HAVE_VA_COPY |
1434 |
va_copy(ap_copy, ap); |
va_copy(ap_copy, ap); |
|
|
|
1435 |
n= vsnprintf(buf, size, s, ap_copy); |
n= vsnprintf(buf, size, s, ap_copy); |
|
|
|
1436 |
va_end(ap_copy); |
va_end(ap_copy); |
|
|
|
1437 |
#else |
#else |
|
|
|
1438 |
n= vsnprintf(buf, size, s, ap); |
n= vsnprintf(buf, size, s, ap); |
|
|
|
1439 |
#endif |
#endif |
|
|
|
1440 |
if(n > -1 && n < size) |
if(n > -1 && n < size) |
1441 |
break; |
break; |
|
|
|
1442 |
if(n > -1) |
if(n > -1) |
1443 |
size= n+1; |
size= n+1; |
1444 |
else |
else |
1445 |
size*= 2; |
size*= 2; |
|
|
|
1446 |
buf= xresize(buf, size); |
buf= xresize(buf, size); |
|
|
|
1447 |
} |
} |
|
|
|
1448 |
*len= n; |
*len= n; |
1449 |
|
|
1450 |
return buf; |
return buf; |
1451 |
|
|
1452 |
} |
} |
1456 |
* Redirect the standard file descriptors to /dev/null and route any |
* Redirect the standard file descriptors to /dev/null and route any |
1457 |
* error messages to the log file. |
* error messages to the log file. |
1458 |
*/ |
*/ |
1459 |
void redirect_stdfd() { |
void Util_redirectStdFds() { |
|
|
|
1460 |
int i; |
int i; |
1461 |
|
for(i= 0; i < 3; i++) { |
1462 |
for(i= 0; i < 3; i++) |
if(close(i) == -1 || open("/dev/null", O_RDWR) != i) { |
|
if(close(i) == -1 || open("/dev/null", O_RDWR) != i) |
|
1463 |
log("Cannot reopen standard file descriptor (%d) -- %s\n", i, STRERROR); |
log("Cannot reopen standard file descriptor (%d) -- %s\n", i, STRERROR); |
1464 |
|
} |
1465 |
|
} |
1466 |
} |
} |
1467 |
|
|
1468 |
|
|
1471 |
* seems to have getdtablesize, so we'll use it here, and back |
* seems to have getdtablesize, so we'll use it here, and back |
1472 |
* out to use 1024 if getdtablesize not available. |
* out to use 1024 if getdtablesize not available. |
1473 |
*/ |
*/ |
1474 |
void fd_close() { |
void Util_closeFds() { |
|
|
|
1475 |
int i; |
int i; |
1476 |
#ifdef HAVE_UNISTD_H |
#ifdef HAVE_UNISTD_H |
1477 |
int max_descriptors = getdtablesize(); |
int max_descriptors = getdtablesize(); |
1478 |
#else |
#else |
1479 |
int max_descriptors = 1024; |
int max_descriptors = 1024; |
1480 |
#endif |
#endif |
|
|
|
1481 |
for(i = 3; i < max_descriptors; i++) |
for(i = 3; i < max_descriptors; i++) |
1482 |
(void) close(i); |
(void) close(i); |
|
|
|
1483 |
errno= 0; |
errno= 0; |
|
|
|
1484 |
} |
} |
1485 |
|
|
1486 |
|
|
1487 |
/* |
/* |
1488 |
* Check if monit does have credentials for this user. If successful |
* Check if monit does have credentials for this user. If successful |
1489 |
* a pointer to the password is returned. |
* a pointer to the password is returned. |
1490 |
*/ |
*/ |
1491 |
Auth_T get_user_credentials(char *uname) { |
Auth_T Util_getUserCredentials(char *uname) { |
|
|
|
1492 |
Auth_T c= Run.credentials; |
Auth_T c= Run.credentials; |
|
|
|
1493 |
while ( c != NULL ) { |
while ( c != NULL ) { |
|
|
|
1494 |
if ( strcmp(c->uname, uname) == 0 ) { |
if ( strcmp(c->uname, uname) == 0 ) { |
|
|
|
1495 |
return c; |
return c; |
|
|
|
1496 |
} |
} |
|
|
|
1497 |
c=c->next; |
c=c->next; |
|
|
|
1498 |
} |
} |
|
|
|
1499 |
return NULL; |
return NULL; |
1500 |
} |
} |
1501 |
|
|
1502 |
|
|
1503 |
int compare_user_credentials(char *uname, char *outside) { |
/** |
1504 |
|
* Check if the given password match the registred password for the |
1505 |
Auth_T c= get_user_credentials(uname); |
* given username. |
1506 |
|
* @param uname Username |
1507 |
|
* @param outside The password to test |
1508 |
|
* @return TRUE if the passwords match for the given uname otherwise |
1509 |
|
* FALSE |
1510 |
|
*/ |
1511 |
|
int Util_checkCredentials(char *uname, char *outside) { |
1512 |
|
Auth_T c= Util_getUserCredentials(uname); |
1513 |
char outside_crypt[STRLEN]; |
char outside_crypt[STRLEN]; |
1514 |
|
if(c==NULL) { |
|
if ( c==NULL ) { |
|
|
|
|
1515 |
return FALSE; |
return FALSE; |
|
|
|
1516 |
} |
} |
1517 |
switch (c->digesttype) { |
switch (c->digesttype) { |
1518 |
case DIGEST_CLEARTEXT: |
case DIGEST_CLEARTEXT: |
1519 |
{ |
{ |
1520 |
strncpy(outside_crypt, outside, STRLEN); |
strncpy(outside_crypt, outside, STRLEN); |
1521 |
|
break; |
1522 |
break; |
} |
|
} |
|
1523 |
case DIGEST_MD5: |
case DIGEST_MD5: |
1524 |
{ |
{ |
1525 |
char id[STRLEN]; |
char id[STRLEN]; |
1526 |
char salt[STRLEN]; |
char salt[STRLEN]; |
1527 |
char * temp; |
char * temp; |
1528 |
|
/* A password looks like this, |
1529 |
/* A password looks like this, |
* $id$salt$digest |
1530 |
* $id$salt$digest |
* the '$' around the id are still part of the id. |
1531 |
* the '$' around the id are still part of the id. |
*/ |
1532 |
*/ |
strncpy(id, c->passwd, STRLEN); |
1533 |
|
temp= strchr(id+1, '$')+1; |
1534 |
strncpy(id, c->passwd, STRLEN); |
*temp= '\0'; |
1535 |
temp= strchr(id+1, '$')+1; |
strncpy(salt, c->passwd+strlen(id), STRLEN); |
1536 |
*temp= '\0'; |
temp= strchr(salt, '$'); |
1537 |
|
*temp= '\0'; |
1538 |
strncpy(salt, c->passwd+strlen(id), STRLEN); |
if (md5_crypt(outside, id, salt, outside_crypt, STRLEN) == NULL) { |
1539 |
temp= strchr(salt, '$'); |
log("Cannot generate MD5 digest error.\n"); |
1540 |
*temp= '\0'; |
return FALSE; |
1541 |
|
} |
1542 |
if (md5_crypt(outside, id, salt, outside_crypt, STRLEN) == NULL) { |
break; |
|
|
|
|
log("Cannot generate MD5 digest error.\n"); |
|
|
return FALSE; |
|
|
|
|
1543 |
} |
} |
|
|
|
|
break; |
|
|
} |
|
1544 |
case DIGEST_CRYPT: |
case DIGEST_CRYPT: |
1545 |
{ |
{ |
1546 |
char salt[3]; |
char salt[3]; |
1547 |
char * temp; |
char * temp; |
1548 |
snprintf(salt, 3, "%c%c", c->passwd[0], c->passwd[1]); |
snprintf(salt, 3, "%c%c", c->passwd[0], c->passwd[1]); |
1549 |
temp= crypt(outside, salt); |
temp= crypt(outside, salt); |
1550 |
strncpy(outside_crypt, temp, STRLEN); |
strncpy(outside_crypt, temp, STRLEN); |
1551 |
|
break; |
1552 |
break; |
} |
|
} |
|
|
|
|
1553 |
default: |
default: |
1554 |
log("Unknown password digestion method.\n"); |
log("Unknown password digestion method.\n"); |
1555 |
return FALSE; |
return FALSE; |
1556 |
} |
} |
1557 |
|
|
1558 |
if (strcmp(outside_crypt,c->passwd)==0) { |
if (strcmp(outside_crypt,c->passwd)==0) { |
1559 |
return TRUE; |
return TRUE; |
1560 |
} |
} |
|
|
|
1561 |
return FALSE; |
return FALSE; |
1562 |
} |
} |
1563 |
|
|
1564 |
|
|
1565 |
/* Compute SHA1 and MD5 message digests simultaneously for bytes read |
/** |
1566 |
from STREAM (suitable for stdin, which is not always rewindable). |
* Compute SHA1 and MD5 message digests simultaneously for bytes read |
1567 |
The resulting message digest numbers will be written into the first bytes |
* from STREAM (suitable for stdin, which is not always rewindable). |
1568 |
of resblock buffers. */ |
* The resulting message digest numbers will be written into the first |
1569 |
int sha_md5_stream (FILE *stream, void *sha_resblock, void *md5_resblock) |
* bytes of resblock buffers. |
1570 |
{ |
* @param stream The stream from where the digests are computed |
1571 |
/* Important: HASHBLOCKSIZE must be a multiple of 64. */ |
* @param sha_resblock The buffer to write the SHA1 result to |
1572 |
#define HASHBLOCKSIZE 4096 |
* @param md5_resblock The buffer to write the MD5 result to |
1573 |
|
*/ |
1574 |
|
int Util_getStreamDigests (FILE *stream, void *sha_resblock, void *md5_resblock) { |
1575 |
|
#define HASHBLOCKSIZE 4096 /* Important: must be a multiple of 64. */ |
1576 |
struct sha_ctx ctx_sha; |
struct sha_ctx ctx_sha; |
1577 |
struct md5_ctx ctx_md5; |
struct md5_ctx ctx_md5; |
1578 |
char buffer[HASHBLOCKSIZE + 72]; |
char buffer[HASHBLOCKSIZE + 72]; |
1579 |
size_t sum; |
size_t sum; |
1580 |
|
|
1581 |
/* Initialize the computation contexts. */ |
/* Initialize the computation contexts. */ |
1582 |
sha_init_ctx (&ctx_sha); |
sha_init_ctx (&ctx_sha); |
1583 |
md5_init_ctx (&ctx_md5); |
md5_init_ctx (&ctx_md5); |
1584 |
|
|
1585 |
/* Iterate over full file contents. */ |
/* Iterate over full file contents. */ |
1586 |
while (1) |
while (1) { |
1587 |
{ |
/* We read the file in blocks of HASHBLOCKSIZE bytes. One call of the |
1588 |
/* We read the file in blocks of HASHBLOCKSIZE bytes. One call of the |
computation function processes the whole buffer so that with the |
1589 |
computation function processes the whole buffer so that with the |
next round of the loop another block can be read. */ |
1590 |
next round of the loop another block can be read. */ |
size_t n; |
1591 |
size_t n; |
sum = 0; |
1592 |
sum = 0; |
|
1593 |
|
/* Read block. Take care for partial reads. */ |
1594 |
/* Read block. Take care for partial reads. */ |
while (1) { |
1595 |
while (1) |
n = fread (buffer + sum, 1, HASHBLOCKSIZE - sum, stream); |
1596 |
{ |
sum += n; |
1597 |
n = fread (buffer + sum, 1, HASHBLOCKSIZE - sum, stream); |
if (sum == HASHBLOCKSIZE) |
1598 |
|
break; |
1599 |
sum += n; |
if (n == 0) { |
1600 |
|
/* Check for the error flag IFF N == 0, so that we don't |
1601 |
if (sum == HASHBLOCKSIZE) |
exit the loop after a partial read due to e.g., EAGAIN |
1602 |
break; |
or EWOULDBLOCK. */ |
1603 |
|
if (ferror (stream)) |
1604 |
if (n == 0) |
return 1; |
1605 |
{ |
goto process_partial_block; |
1606 |
/* Check for the error flag IFF N == 0, so that we don't |
} |
1607 |
exit the loop after a partial read due to e.g., EAGAIN |
|
1608 |
or EWOULDBLOCK. */ |
/* We've read at least one byte, so ignore errors. But always |
1609 |
if (ferror (stream)) |
check for EOF, since feof may be true even though N > 0. |
1610 |
return 1; |
Otherwise, we could end up calling fread after EOF. */ |
1611 |
goto process_partial_block; |
if (feof (stream)) |
1612 |
} |
goto process_partial_block; |
|
|
|
|
/* We've read at least one byte, so ignore errors. But always |
|
|
check for EOF, since feof may be true even though N > 0. |
|
|
Otherwise, we could end up calling fread after EOF. */ |
|
|
if (feof (stream)) |
|
|
goto process_partial_block; |
|
|
} |
|
|
|
|
|
/* Process buffer with HASHBLOCKSIZE bytes. Note that |
|
|
HASHBLOCKSIZE % 64 == 0 |
|
|
*/ |
|
|
sha_process_block (buffer, HASHBLOCKSIZE, &ctx_sha); |
|
|
md5_process_block (buffer, HASHBLOCKSIZE, &ctx_md5); |
|
1613 |
} |
} |
1614 |
|
|
1615 |
|
/* Process buffer with HASHBLOCKSIZE bytes. Note that |
1616 |
|
HASHBLOCKSIZE % 64 == 0 */ |
1617 |
|
sha_process_block (buffer, HASHBLOCKSIZE, &ctx_sha); |
1618 |
|
md5_process_block (buffer, HASHBLOCKSIZE, &ctx_md5); |
1619 |
|
} |
1620 |
|
|
1621 |
process_partial_block: |
process_partial_block: |
1622 |
|
|
1623 |
/* Process any remaining bytes. */ |
/* Process any remaining bytes. */ |
1625 |
sha_process_bytes (buffer, sum, &ctx_sha); |
sha_process_bytes (buffer, sum, &ctx_sha); |
1626 |
md5_process_bytes (buffer, sum, &ctx_md5); |
md5_process_bytes (buffer, sum, &ctx_md5); |
1627 |
} |
} |
|
|
|
1628 |
/* Construct result in desired memory. */ |
/* Construct result in desired memory. */ |
1629 |
sha_finish_ctx (&ctx_sha, sha_resblock); |
sha_finish_ctx (&ctx_sha, sha_resblock); |
1630 |
md5_finish_ctx (&ctx_md5, md5_resblock); |
md5_finish_ctx (&ctx_md5, md5_resblock); |
1633 |
|
|
1634 |
|
|
1635 |
/** |
/** |
1636 |
* Reset process information structure |
* Reset the process information structure |
1637 |
*/ |
*/ |
1638 |
void reset_procinfo(Service_T s) { |
void Util_resetProcInfo(Service_T s) { |
|
|
|
1639 |
memset(s->inf, 0, sizeof *(s->inf)); |
memset(s->inf, 0, sizeof *(s->inf)); |
1640 |
|
} |
1641 |
|
|
1642 |
|
|
1643 |
|
/** |
1644 |
|
* Are service status data available? |
1645 |
|
* @param s The service to test |
1646 |
|
* @return TRUE if available otherwise FALSE |
1647 |
|
*/ |
1648 |
|
int Util_hasServiceStatus(Service_T s) { |
1649 |
|
return(!((s->monitor!=MONITOR_YES)|| |
1650 |
|
(s->error&EVENT_NONEXIST)|| |
1651 |
|
(s->error&EVENT_DATA) )); |
1652 |
} |
} |
1653 |
|
|
1654 |
|
|
1655 |
/* Test whether service status data are available. If not, return 0 */ |
/** |
1656 |
int check_service_status(Service_T s) { |
* Construct a HTTP/1.1 Host header utilizing information from the |
1657 |
|
* socket. The returned hostBuf is set to "hostname:port" or to the |
1658 |
|
* empty string if information is not available or not applicable. |
1659 |
|
* @param s A connected socket |
1660 |
|
* @param hostBuf the buffer to write the host-header to |
1661 |
|
* @param len Length of the hostBuf |
1662 |
|
* @return the hostBuffer |
1663 |
|
*/ |
1664 |
|
char *Util_getHTTPHostHeader(Socket_T s, char *hostBuf, int len) { |
1665 |
|
if(! strcmp(LOCALHOST, socket_get_remote_host(s)) || |
1666 |
|
inet_aton(socket_get_remote_host(s), NULL)) { |
1667 |
|
*hostBuf= 0; |
1668 |
|
} else { |
1669 |
|
snprintf(hostBuf, len, "%s:%d", |
1670 |
|
socket_get_remote_host(s), |
1671 |
|
socket_get_remote_port(s)); |
1672 |
|
} |
1673 |
|
return hostBuf; |
1674 |
|
} |
1675 |
|
|
1676 |
|
|
1677 |
return( !((s->monitor!=MONITOR_YES)|| |
/** |
1678 |
(s->error&EVENT_NONEXIST)|| |
* Evaluate a qualification expression. |
1679 |
(s->error&EVENT_DATA) )); |
* @param operator The qualification operator |
1680 |
|
* @param left Expression lval |
1681 |
|
* @param rightExpression rval |
1682 |
|
* Returns the boolean value of the expression |
1683 |
|
*/ |
1684 |
|
int Util_evalQExpression(int operator, int left, int right) { |
1685 |
|
|
1686 |
|
switch(operator) { |
1687 |
|
case OPERATOR_GREATER: |
1688 |
|
if(left > right) |
1689 |
|
return TRUE; |
1690 |
|
break; |
1691 |
|
case OPERATOR_LESS: |
1692 |
|
if(left < right) |
1693 |
|
return TRUE; |
1694 |
|
break; |
1695 |
|
case OPERATOR_EQUAL: |
1696 |
|
if(left == right) |
1697 |
|
return TRUE; |
1698 |
|
break; |
1699 |
|
case OPERATOR_NOTEQUAL: |
1700 |
|
if(left != right) |
1701 |
|
return TRUE; |
1702 |
|
break; |
1703 |
|
default: |
1704 |
|
log("Unknown comparison operator\n"); |
1705 |
|
return FALSE; |
1706 |
|
} |
1707 |
|
|
1708 |
|
return FALSE; |
1709 |
|
|
1710 |
} |
} |
1711 |
|
|
1712 |
|
|
1714 |
|
|
1715 |
|
|
1716 |
/** |
/** |
1717 |
* Returns the value of the variable if defined or the String |
* Returns the value of the parameter if defined or the String "(not |
1718 |
* "(not defined)" |
* defined)" |
1719 |
*/ |
*/ |
1720 |
static char *is_str_defined(char *var) { |
static char *is_str_defined(char *s) { |
1721 |
|
return ((s&&*s)?s:"(not defined)"); |
|
return (is_strdefined(var)?var:"(not defined)"); |
|
|
|
|
1722 |
} |
} |
1723 |
|
|
1724 |
|
|
1728 |
* @return TRUE if the char is in the set of unsafe URL Characters |
* @return TRUE if the char is in the set of unsafe URL Characters |
1729 |
*/ |
*/ |
1730 |
static int is_unsafe(unsigned char *c) { |
static int is_unsafe(unsigned char *c) { |
|
|
|
1731 |
int i; |
int i; |
1732 |
static unsigned char unsafe[]= "<>\"#{}|\\^~[]`"; |
static unsigned char unsafe[]= "<>\"#{}|\\^~[]`"; |
1733 |
|
|
1734 |
ASSERT(c); |
ASSERT(c); |
1735 |
|
|
1736 |
if(33>*c || *c>176) |
if(33>*c || *c>176) |
1737 |
return TRUE; |
return TRUE; |
|
|
|
1738 |
if(*c=='%') { |
if(*c=='%') { |
1739 |
if( isxdigit(*(c + 1)) && isxdigit(*(c + 2)) ) return FALSE; |
if( isxdigit(*(c + 1)) && isxdigit(*(c + 2)) ) return FALSE; |
1740 |
return TRUE; |
return TRUE; |
1741 |
} |
} |
|
|
|
1742 |
for(i=0; unsafe[i]; i++) |
for(i=0; unsafe[i]; i++) |
1743 |
if(*c==unsafe[i]) return TRUE; |
if(*c==unsafe[i]) return TRUE; |
|
|
|
1744 |
return FALSE; |
return FALSE; |
|
|
|
1745 |
} |
} |
1746 |
|
|
1747 |
|
|
1749 |
* Convert a hex char to a char |
* Convert a hex char to a char |
1750 |
*/ |
*/ |
1751 |
static char x2c(char *hex) { |
static char x2c(char *hex) { |
|
|
|
1752 |
register char digit; |
register char digit; |
|
|
|
1753 |
digit = ((hex[0] >= 'A') ? ((hex[0] & 0xdf) - 'A')+10 : (hex[0] - '0')); |
digit = ((hex[0] >= 'A') ? ((hex[0] & 0xdf) - 'A')+10 : (hex[0] - '0')); |
1754 |
digit *= 16; |
digit *= 16; |
1755 |
digit += (hex[1] >= 'A' ? ((hex[1] & 0xdf) - 'A')+10 : (hex[1] - '0')); |
digit += (hex[1] >= 'A' ? ((hex[1] & 0xdf) - 'A')+10 : (hex[1] - '0')); |
|
|
|
1756 |
return(digit); |
return(digit); |
|
|
|
1757 |
} |
} |
1758 |
|
|
1759 |
|
|
1761 |
* Print registered events list |
* Print registered events list |
1762 |
*/ |
*/ |
1763 |
static void printevents(unsigned int events) { |
static void printevents(unsigned int events) { |
|
|
|
1764 |
if(events == (~((unsigned int)0))) { |
if(events == (~((unsigned int)0))) { |
1765 |
printf("All events"); |
printf("All events"); |
1766 |
} else { |
} else { |