utility.c

Go to the documentation of this file.
00001 
00007 /* $Id: utility.c,v 1.17 2008/12/16 21:01:27 seymour Exp $ */
00008 /* $UTK_Copyright: $ */
00009 
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <string.h>
00013 #include <sys/stat.h>
00014 
00015 #include "portability.h"
00016 #include "utility.h"
00017 
00032 int
00033 gs_versions_incompatible(const char *ver1, const char *ver2)
00034 {
00035   int maj1, min1, rev1, maj2, min2, rev2, n1, n2;
00036 
00037   if(!ver1 || !ver2) {
00038     ERRPRINTF("Warning: bad args\n");
00039     return 1;
00040   }
00041 
00042   maj1 = min1 = rev1 = maj2 = min2 = rev2 = 0;
00043 
00044   n1 = sscanf(ver1, "%d.%d.%d", &maj1, &min1, &rev1);
00045   n2 = sscanf(ver2, "%d.%d.%d", &maj2, &min2, &rev2);
00046 
00047   if((n1 < 1) || (n2 < 1)) {
00048     ERRPRINTF("Warning: malformed version number\n");
00049     return 1;
00050   }
00051 
00052   return (maj1 != maj2) || (min1 != min2);
00053 }
00054 
00065 char *
00066 gs_get_line(FILE *in)
00067 {
00068 #define BUFSZ 400
00069   char buf[BUFSZ];
00070   char *rv, *line, *ltmp;
00071   int idx = 0, cur_size = BUFSZ;
00072 
00073   if(!in) return NULL;
00074 
00075   line = (char *)malloc(BUFSZ);
00076   *line = '\0';
00077 
00078   if(!line) return NULL;
00079 
00080   do {
00081     rv = fgets(buf, BUFSZ, in);
00082 
00083     if(!rv) {
00084       free(line);
00085       return NULL;
00086     }
00087 
00088     memcpy(line+idx, buf, BUFSZ);
00089     idx += strlen(buf);
00090 
00091     cur_size += BUFSZ;
00092     ltmp = realloc(line, cur_size);
00093 
00094     if(!ltmp) return NULL;
00095     line = ltmp;
00096   } while(buf[strlen(buf)-1] != '\n');
00097 
00098   return line;
00099 }
00100 
00112 char *
00113 gs_read_line(FILE *f, int *linecount)
00114 {
00115   char *tmp = NULL;
00116   do
00117   {
00118     if(tmp)
00119       free(tmp);
00120     tmp = gs_get_line(f);
00121     if(!tmp) 
00122       break;
00123     (*linecount)++;
00124   } while((tmp[0] == '\n')||(tmp[0] == '#'));
00125   return tmp;
00126 }
00127 
00138 int 
00139 gs_parse_config_file(char *filename, gs_info_t **tmp)
00140 {
00141   gs_info_t *sa_headNode;  /* server attribute list */
00142   int i = 0, linecount = 0;
00143   char *p, *line;
00144   FILE *sc_file;
00145 
00146   /* Open server configuration file */
00147   sc_file = fopen(filename, "r");
00148   if(!sc_file) {
00149     ERRPRINTF("Could not open %s file\n", filename);
00150     return -1;
00151   }
00152 
00153   /* 
00154    * parse each line with strtok "="
00155    * store into the linked list
00156    * also putenv each attribute
00157    */
00158  
00159   sa_headNode = (gs_info_t *)malloc(sizeof(gs_info_t));
00160   if(!sa_headNode) {
00161     fclose(sc_file);
00162     ERRPRINTF("Could not allocate memory for server attributes\n");
00163     return -1;
00164   }
00165   
00166   *tmp = sa_headNode;
00167   while((line = gs_read_line(sc_file, &linecount))) {
00168 
00169     (*tmp)->next   = (gs_info_t *)malloc(sizeof(gs_info_t));
00170     if(!(*tmp)->next){
00171       free(line);
00172       free(sa_headNode);
00173       fclose(sc_file);
00174       ERRPRINTF("Could not allocate memory for server attributes\n");
00175       return -1;
00176     }
00177     (*tmp) = (*tmp)->next;
00178 
00179     (*tmp)->value = strdup(strpbrk(line,"=")+1);
00180     if(!(*tmp)->value){
00181       free(line);
00182       free(sa_headNode);
00183       fclose(sc_file);
00184       ERRPRINTF("Could not strdup for (*tmp)->value\n");
00185       return -1;
00186     }
00187 
00188     (*tmp)->type = strdup(strtok(line,"="));
00189     if(!(*tmp)->type){
00190       free(line);
00191       free(sa_headNode);
00192       fclose(sc_file);
00193       ERRPRINTF("Could not strdup for (*tmp)->type\n");
00194       return -1;
00195     }
00196 
00197     (*tmp)->next= NULL;
00198   
00199     while(((*tmp)->value[strlen((*tmp)->value)-1] == ' ') ||
00200           ((*tmp)->value[strlen((*tmp)->value)-1] == '\n'))
00201       (*tmp)->value[strlen((*tmp)->value)-1] = '\0';
00202 
00203     i = strspn((*tmp)->value, " ");
00204     if(i >0){
00205       for (p = (*tmp)->value; ; p++){
00206         *p = *(p+i);
00207         if(*p == '\0') break;
00208       }
00209     }
00210 
00211     while((*tmp)->type[strlen((*tmp)->type)-1] == ' ')
00212       (*tmp)->type[strlen((*tmp)->type)-1] = '\0';
00213 
00214     sprintf(line,"%s=%s",(*tmp)->type,(*tmp)->value);
00215 
00216     if (putenv(strdup(line)) != 0){
00217       free(line);
00218       free(sa_headNode);
00219       fclose(sc_file);
00220       ERRPRINTF("Could not putenv \n");
00221       return -1;
00222     }
00223 
00224     free(line);
00225   }
00226   *tmp = sa_headNode->next;
00227   free(sa_headNode);
00228   fclose(sc_file);
00229   return 0;
00230 }
00231 
00232 
00233 #ifndef WIN32
00234 
00244 int
00245 gs_open_locked_file(char *filename, short lock_type, int flags)
00246 {
00247   int fd;
00248 
00249   if(!filename) {
00250     ERRPRINTF("Invalid arg: null filename\n");
00251     return -1;
00252   }
00253 
00254   if((fd = open(filename, flags, 0600)) == -1) {
00255     ERRPRINTF("open failed\n");
00256     perror("open");
00257     return -1;
00258   }
00259 
00260   
00261   /* lock file */
00262   if (gs_lock_fd(fd, lock_type) == -1) {
00263     perror("lock");
00264     close(fd);
00265     return -1;
00266   }
00267 
00268   return fd;
00269 }
00270 #endif
00271 
00280 int
00281 gs_unlock_file(int fd)
00282 {
00283   if(gs_unlock_fd(fd) == -1) {
00284     ERRPRINTF("Warning: could not unlock file\n");
00285     perror("unlock");
00286     return -1;
00287   }
00288 
00289   return 0;
00290 }
00291 
00298 static void 
00299 gs_alarm_catch(int sig)
00300 {
00301   return;
00302 }
00303 
00315 #ifndef WIN32
00316 int
00317 gs_open_locked_file_timeout(char *lockfile, short lock_type, int flags, int timeout)
00318 {
00319   struct itimerval tv = {{timeout, 0}, {timeout, 0}};
00320   struct itimerval cv = {{0, 0}, {0, 0}};
00321   struct sigaction act, oldact;
00322   sigset_t set, oldset;
00323   int fd;
00324 
00325   memset(&act, 0, sizeof(act));
00326   act.sa_handler = gs_alarm_catch;
00327   act.sa_flags = 0; /* no SA_RESTART */
00328   sigfillset(&act.sa_mask);
00329   if(sigaction(SIGALRM, &act, &oldact) == -1) {
00330     ERRPRINTF("error setting up SIGALRM\n");
00331     return -1;
00332   }
00333 
00334   sigemptyset(&set);
00335   sigaddset(&set, SIGALRM);
00336   if(sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1) {
00337     ERRPRINTF("sigprocmask failed\n");
00338     sigaction(SIGALRM, &oldact, NULL);
00339     return -1;
00340   }
00341 
00342   setitimer(ITIMER_REAL, &tv, 0);
00343 
00344   fd = gs_open_locked_file(lockfile, lock_type, flags);
00345 
00346   if(fd < 0) {
00347     setitimer(ITIMER_REAL, &cv, 0);
00348     sigprocmask(SIG_SETMASK, &oldset, NULL);
00349     return -1;
00350   }
00351 
00352   setitimer(ITIMER_REAL, &cv, 0);
00353   sigprocmask(SIG_SETMASK, &oldset, NULL);
00354   sigaction(SIGALRM, &oldact, NULL);
00355 
00356   return fd;
00357 }
00358 #endif
00359 
00369 long
00370 gs_seconds_since_modified(char *filename)
00371 {
00372   gs_struct_stat stbuf;
00373   struct timeval tv;
00374   long age;
00375 
00376   if(!filename)
00377     return -1;
00378   
00379   if(gs_stat(filename, &stbuf) < 0)
00380     return -1;
00381 
00382   gettimeofday(&tv, NULL);
00383 
00384   age = tv.tv_sec - stbuf.st_mtime;
00385 
00386   return age;
00387 }
00388 
00389 int
00390 gs_get_contents_of_file(char *name, char **contents)
00391 {
00392   struct stat stbuf;
00393   int cfd, nread;
00394   char *buf;
00395 
00396   if(stat(name, &stbuf) < 0)
00397     return -1;
00398 
00399   buf = malloc((int)stbuf.st_size+1);
00400 
00401   if(!buf) {
00402     ERRPRINTF("malloc failed\n");
00403     return -1;
00404   }
00405 
00406   cfd = open(name, O_RDONLY, 0600);
00407 
00408   if(cfd < 0) {
00409     ERRPRINTF("Warning: failed to open file '%s'\n", name);
00410     free(buf);
00411     return -1;
00412   }
00413 
00414   nread = read(cfd, buf, (int) stbuf.st_size + 1);
00415   buf[nread] = '\0';
00416 
00417   close(cfd);
00418 
00419   if(nread <= 0) {
00420     free(buf);
00421     return -1;
00422   }
00423 
00424   *contents = buf;
00425   return nread;
00426 }
00427 
00428 static float
00429 gs_popen_loadavg(char *cmd)
00430 {
00431   float tmpf = -1;
00432 #ifndef WIN32
00433   char buf[200], *tmp, tmp2[20];
00434   FILE *pstream;
00435 
00436   if((pstream = popen(cmd, "r")) == NULL)
00437     return -1;
00438 
00439   tmp = fgets(buf, 200, pstream);
00440   pclose(pstream);
00441 
00442   if(!tmp)
00443     return -1;
00444 
00445   tmp = strstr(buf, "average:");
00446   if(!tmp)
00447     return -1;
00448 
00449   if(sscanf(tmp, "%s %f", tmp2, &tmpf) != 2)
00450     return -1;
00451 
00452 #endif
00453   return tmpf;
00454 }
00455 
00456 static float
00457 gs_fopen_loadavg(char *filename)
00458 {
00459   FILE *loadavg_file;
00460   float tmpf;
00461   int n;
00462 
00463   if((loadavg_file = fopen(filename, "r")) == NULL)
00464     return -1;
00465 
00466   n = fscanf(loadavg_file, "%f", &tmpf);
00467 
00468   fclose(loadavg_file);
00469 
00470   if(n != 1)
00471     return -1;
00472 
00473   return tmpf;
00474 }
00475 
00484 int
00485 gs_get_workload()
00486 {
00487   char *commands[] = {"uptime", "w", NULL};
00488   char *files[] = {"/proc/loadavg", NULL};
00489   float workload;
00490   int i, scale;
00491 
00492   scale = 100;
00493 
00494   for(i=0;files[i];i++)
00495     if((workload = gs_fopen_loadavg(files[i])) >= 0)
00496       return (int) (scale * workload);
00497 
00498   for(i=0;commands[i];i++)
00499     if((workload = gs_popen_loadavg(commands[i])) >= 0)
00500       return (int) (scale * workload);
00501 
00502   return -1;
00503 }