/[monit]/monit/util.c
ViewVC logotype

Diff of /monit/util.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.132 by martinp, Thu Dec 9 17:02:44 2004 UTC revision 1.133 by hauk, Sun Dec 12 23:45:09 2004 UTC
# Line 86  Line 86 
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"
# Line 128  typedef struct myurlprotocol { Line 132  typedef struct myurlprotocol {
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          }
# Line 140  UrlProtocol_T protocol[]= Line 143  UrlProtocol_T protocol[]=
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    
# Line 171  char *stripfilename(char* path) { Line 165  char *stripfilename(char* path) {
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;
# Line 194  void chomp(char *string, int len) { Line 188  void chomp(char *string, int len) {
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        
# Line 211  char *trim(char *s) { Line 205  char *trim(char *s) {
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    
# Line 229  char *ltrim(char *s) { Line 223  char *ltrim(char *s) {
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    
# Line 237  char *rtrim(char *s) { Line 231  char *rtrim(char *s) {
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  }  }
# Line 247  char *rtrim(char *s) { Line 241  char *rtrim(char *s) {
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;
# Line 267  void trim_quotes(char *s) { Line 260  void trim_quotes(char *s) {
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';
# Line 288  void trim_quotes(char *s) { Line 279  void trim_quotes(char *s) {
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    
# Line 310  char *replace_char(char *s, char old, ch Line 301  char *replace_char(char *s, char old, ch
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            
# Line 349  char *replace_string(char **src, const c Line 340  char *replace_string(char **src, const c
340      FREE(*src);      FREE(*src);
341      *src= buf;      *src= buf;
342    }    }
343      
344    return *src;    return *src;
345        
346  }  }
# Line 360  char *replace_string(char **src, const c Line 351  char *replace_string(char **src, const c
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;
# Line 383  int count_words(char *s, const char *wor Line 374  int count_words(char *s, const char *wor
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    
# Line 402  int starts_with(const char *a, const cha Line 393  int starts_with(const char *a, const cha
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++;
# Line 461  void handle_string_escapes(char *buf) { Line 452  void handle_string_escapes(char *buf) {
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    
# Line 479  Service_T get_service(const char *name) Line 470  Service_T get_service(const char *name)
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    
# Line 499  int exist_service(const char *name) { Line 503  int exist_service(const char *name) {
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));
# Line 618  void printrunlist() { Line 605  void printrunlist() {
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;
# Line 927  void printservice(Service_T s) { Line 914  void printservice(Service_T s) {
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];
# Line 936  void printservicelist() { Line 923  void printservicelist() {
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    
# Line 946  void printservicelist() { Line 933  void printservicelist() {
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;
# Line 956  void printhash(char *filename) { Line 943  void printhash(char *filename) {
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  /**  /**
# Line 1029  fileerror: Line 987  fileerror:
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  }  }
# Line 1078  pid_t get_pid(char *pidfile) { Line 1023  pid_t get_pid(char *pidfile) {
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  }  }
# Line 1103  int is_process_running(Service_T s) { Line 1046  int is_process_running(Service_T s) {
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);
# Line 1128  char *get_RFC822date(long *date) { Line 1069  char *get_RFC822date(long *date) {
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;
# Line 1155  time_t get_process_uptime(char *pidfile) Line 1093  time_t get_process_uptime(char *pidfile)
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;
# Line 1167  char *get_uptime(time_t delta, char *sep Line 1105  char *get_uptime(time_t delta, char *sep
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;
# Line 1179  char *get_uptime(time_t delta, char *sep Line 1115  char *get_uptime(time_t delta, char *sep
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  }  }
# Line 1192  char *get_uptime(time_t delta, char *sep Line 1127  char *get_uptime(time_t delta, char *sep
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    
# Line 1265  char *get_checksum(char *file, int hasht Line 1185  char *get_checksum(char *file, int hasht
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;
# Line 1296  char *url_encode(char *uri) { Line 1216  char *url_encode(char *uri) {
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]);
# Line 1318  char *url_decode(char *url) { Line 1238  char *url_decode(char *url) {
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;
# Line 1335  Url_T url_parse(char *string) { Line 1255  Url_T url_parse(char *string) {
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 */
# Line 1452  error: Line 1372  error:
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");
# Line 1512  char *get_basic_authentication_header() Line 1417  char *get_basic_authentication_header()
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  }  }
# Line 1562  char *format(const char *s, va_list ap, Line 1456  char *format(const char *s, va_list ap,
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    
# Line 1578  void redirect_stdfd() { Line 1471  void redirect_stdfd() {
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.  */
# Line 1754  process_partial_block: Line 1625  process_partial_block:
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);
# Line 1763  process_partial_block: Line 1633  process_partial_block:
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    
# Line 1786  int check_service_status(Service_T s) { Line 1714  int check_service_status(Service_T s) {
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    
# Line 1802  static char *is_str_defined(char *var) { Line 1728  static char *is_str_defined(char *var) {
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    
# Line 1828  static int is_unsafe(unsigned char *c) { Line 1749  static int is_unsafe(unsigned char *c) {
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    
# Line 1844  static char x2c(char *hex) { Line 1761  static char x2c(char *hex) {
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 {

Legend:
Removed from v.1.132  
changed lines
  Added in v.1.133

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26