nfs-ganesha 1.4

shell_utils.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  * ---------------------------------------
00024  */
00025 
00058 #ifdef HAVE_CONFIG_H
00059 #include "config.h"
00060 #endif
00061 
00062 #include <unistd.h>
00063 
00064 #include "cmd_tools.h"
00065 #include <errno.h>
00066 #include "shell_utils.h"
00067 #include "Getopt.h"
00068 #include <string.h>
00069 
00070 #include "abstract_mem.h"
00071 
00072 #include <sys/time.h>
00073 
00074 /*--------------------------
00075  *    Timer management.
00076  *-------------------------*/
00077 
00078 /* start time */
00079 static struct timeval timer_start = { 0, 0 };
00080 
00081 /* stop time */
00082 static struct timeval timer_end = { 0, 0 };
00083 
00084 /* timer state (0=OFF, 1=ON) */
00085 static int timer_state = 0;
00086 
00087 /* The timer command */
00088 
00089 int util_timer(int argc,        /* IN : number of args in argv */
00090                char **argv,     /* IN : arg list               */
00091                FILE * output    /* IN : output stream          */
00092     )
00093 {
00094 
00095   if(argc != 2)
00096     {
00097       fprintf(output, "Usage: %s start|print|stop.\n", argv[0]);
00098       return -1;
00099     }
00100 
00101   /* Timer start command */
00102 
00103   if(!strcmp(argv[1], "start"))
00104     {
00105 
00106       if(timer_state)
00107         {
00108           fprintf(output, "Timer already started.\n");
00109           return -1;
00110         }
00111 
00112       if(gettimeofday(&timer_start, NULL) == -1)
00113         {
00114           fprintf(output, "Error retrieving system time.\n");
00115           return -1;
00116         }
00117 
00118       fprintf(output, "Timer start time: ");
00119       print_timeval(output, timer_start);
00120 
00121       timer_state = 1;
00122       return 0;
00123     }
00124 
00125   /* Timer stop command */
00126 
00127   if(!strcmp(argv[1], "stop"))
00128     {
00129 
00130       if(!timer_state)
00131         {
00132           fprintf(output, "Timer is not started.\n");
00133           return -1;
00134         }
00135 
00136       if(gettimeofday(&timer_end, NULL) == -1)
00137         {
00138           fprintf(output, "Error retrieving system time.\n");
00139           return -1;
00140         }
00141 
00142       fprintf(output, "Timer stop time: ");
00143       print_timeval(output, timer_end);
00144 
00145       timer_state = 0;
00146       return 0;
00147     }
00148 
00149   /* Timer print command */
00150 
00151   if(!strcmp(argv[1], "print"))
00152     {
00153 
00154       if(timer_state)
00155         {
00156 
00157           struct timeval timer_tmp;
00158 
00159           /* timer is running, print current enlapsed time */
00160           if(gettimeofday(&timer_tmp, NULL) == -1)
00161             {
00162               fprintf(output, "Error retrieving system time.\n");
00163               return -1;
00164             }
00165 
00166           timer_tmp = time_diff(timer_start, timer_tmp);
00167           print_timeval(output, timer_tmp);
00168 
00169         }
00170       else
00171         {
00172 
00173           struct timeval timer_tmp;
00174 
00175           timer_tmp = time_diff(timer_start, timer_end);
00176           print_timeval(output, timer_tmp);
00177 
00178         }
00179       return 0;
00180     }
00181 
00182   /* unknown timer command */
00183   fprintf(output, "Usage: %s start|print|stop.\n", argv[0]);
00184   return -1;
00185 
00186 }                               /* util_timer */
00187 
00188 /*--------------------------
00189  *      System utils.
00190  *-------------------------*/
00191 
00192 int util_sleep(int argc,        /* IN : number of args in argv */
00193                char **argv,     /* IN : arg list               */
00194                FILE * output    /* IN : output stream          */
00195     )
00196 {
00197 
00198   unsigned long sleep_time;
00199   int rc;
00200 
00201   if(argc != 2)
00202     {
00203       fprintf(output, "Usage: %s <int value>\n", argv[0]);
00204       return -1;
00205     }
00206 
00207   /* conversion */
00208   rc = my_atoi(argv[1]);
00209 
00210   if(rc < 0)
00211     {
00212       fprintf(output, "Usage: %s <int value> (%s is not a positive integer)\n", argv[0],
00213               argv[1]);
00214       return -1;
00215     }
00216 
00217   sleep_time = (unsigned long)rc;
00218 
00219   fprintf(output, "sleep: suspending execution for %lu s...\n", sleep_time);
00220 
00221   /* sleeping */
00222 
00223   sleep(sleep_time);
00224 
00225   return 0;
00226 
00227 }
00228 
00229 int util_shell(int argc,        /* IN : number of args in argv */
00230                char **argv,     /* IN : arg list               */
00231                FILE * output    /* IN : output stream          */
00232     )
00233 {
00234 
00235   FILE *cmd_output;
00236   int i;
00237   char command_line[1024] = "";
00238   char buffer[1024];
00239 
00240   if(argc < 2)
00241     {
00242       fprintf(output, "Usage: %s <shell_cmd> [arg1 arg2 ...]\n", argv[0]);
00243       return -1;
00244     }
00245 
00246   /* builds the command line */
00247 
00248   for(i = 1; i < argc; i++)
00249     {
00250       strncat(command_line, argv[i], strlen(command_line) - 1024 - 1);
00251       if(i != argc - 1)
00252         strncat(command_line, " ", strlen(command_line) - 1024 - 1);
00253     }
00254 
00255   /* launch the command */
00256 
00257   cmd_output = popen(command_line, "r");
00258 
00259   if(cmd_output == NULL)
00260     {
00261       fprintf(output, "shell: popen error %d\n", errno);
00262       return -1;
00263     }
00264 
00265   /* copy the shell ouput to the command output stream */
00266 
00267   while(fgets(buffer, sizeof(buffer), cmd_output) != NULL)
00268     {
00269       fputs(buffer, output);
00270     }
00271 
00272   /* get returned status */
00273 
00274   return pclose(cmd_output);
00275 
00276 }                               /* util_shell */
00277 
00278 int util_meminfo(int argc,      /* IN : number of args in argv */
00279                  char **argv,   /* IN : arg list               */
00280                  FILE * output  /* IN : output stream          */
00281     )
00282 {
00283   return 0;
00284 
00285 }                               /* util_meminfo */
00286 
00287 /*----------------------
00288  *    String utils.
00289  *----------------------*/
00290 
00291 int util_cmp(int argc,          /* IN : number of args in argv */
00292              char **argv,       /* IN : arg list               */
00293              FILE * output      /* IN : output stream          */
00294     )
00295 {
00296 
00297   static char *format = "hinv";
00298   static char *help_cmp =
00299       "Usage: %s [ -h | -i | -n | -v ]  <expr1> <expr2>\n"
00300       "     -h: print this help\n"
00301       "     -i: case insensitive comparison\n"
00302       "     -n: numerical comparison\n" "     -v: verbose mode\n";
00303 
00304   int err_flag = 0;             /* error parsing options */
00305   int flag_h = 0;               /* help */
00306   int flag_i = 0;               /* case insensitive compare */
00307   int flag_n = 0;               /* numerical compare */
00308   int flag_v = 0;               /* verbose */
00309 
00310   int option, rc = 0;
00311 
00312   char *str1 = NULL;            /* arg1 */
00313   char *str2 = NULL;            /* arg2 */
00314 
00315   /* the value to been returned, according to argv[0] */
00316   int value_if_equal = FALSE;
00317 
00318   if(!strcmp(argv[0], "eq"))
00319     value_if_equal = TRUE;
00320   else if(!strcmp(argv[0], "ne"))
00321     value_if_equal = FALSE;
00322   else if(!strcmp(argv[0], "cmp"))
00323     value_if_equal = FALSE;
00324   /* unexpected !!! */
00325   else
00326     exit(1);
00327 
00328   /* disables Getopt error message */
00329   Opterr = 0;
00330 
00331   /* reinits Getopt processing */
00332   Optind = 1;
00333 
00334   while((option = Getopt(argc, argv, format)) != -1)
00335     {
00336       switch (option)
00337         {
00338         case 'h':
00339           if(flag_h)
00340             fprintf(output,
00341                     "%s: warning: option 'h' has been specified more than once.\n",
00342                     argv[0]);
00343           else
00344             flag_h++;
00345           break;
00346 
00347         case 'i':
00348           if(flag_i)
00349             fprintf(output,
00350                     "%s: warning: option 'i' has been specified more than once.\n",
00351                     argv[0]);
00352           else
00353             flag_i++;
00354           break;
00355 
00356         case 'n':
00357           if(flag_n)
00358             fprintf(output,
00359                     "%s: warning: option 'n' has been specified more than once.\n",
00360                     argv[0]);
00361           else
00362             flag_n++;
00363           break;
00364 
00365         case 'v':
00366           if(flag_v)
00367             fprintf(output,
00368                     "%s: warning: option 'v' has been specified more than once.\n",
00369                     argv[0]);
00370           else
00371             flag_v++;
00372           break;
00373 
00374         case '?':
00375           fprintf(output, "%s: unknown option : %c\n", argv[0], Optopt);
00376           err_flag++;
00377           break;
00378         }
00379     }
00380 
00381   /* help flag */
00382   if(flag_h)
00383     {
00384       fprintf(output, help_cmp, argv[0]);
00385       return -1;
00386     }
00387 
00388   /* check conflicts */
00389   if(flag_i + flag_n > 1)
00390     {
00391       fprintf(output, "%s: conflict between options -i, -n\n", argv[0]);
00392       err_flag++;
00393     }
00394 
00395   /* check arg number */
00396   if(Optind != (argc - 2))
00397     {
00398       /* too much or not enough arguments */
00399       err_flag++;
00400     }
00401   else
00402     {
00403       str1 = argv[Optind];
00404       str2 = argv[Optind + 1];
00405     }
00406 
00407   /* error */
00408   if(err_flag)
00409     {
00410       fprintf(output, help_cmp, argv[0]);
00411       return -1;
00412     }
00413 
00414   if(!flag_i && !flag_n)
00415     {
00416       /* normal comparison */
00417       rc = strcmp(str1, str2);
00418     }
00419   else if(flag_i)
00420     {
00421       /* case insensitive comparison */
00422       rc = strcasecmp(str1, str2);
00423     }
00424   else if(flag_n)
00425     {
00426       int a, b;
00427 
00428       if(str1[0] == '-')
00429         a = my_atoi(str1 + 1);
00430       else
00431         a = my_atoi(str1);
00432 
00433       if(a < 0)
00434         {
00435           fprintf(output, "cmp: invalid integer value %s\n", str1);
00436           return -1;
00437         }
00438 
00439       if(str1[0] == '-')
00440         a = -a;
00441 
00442       if(str2[0] == '-')
00443         b = my_atoi(str2 + 1);
00444       else
00445         b = my_atoi(str2);
00446 
00447       if(b < 0)
00448         {
00449           fprintf(output, "cmp: invalid integer value %s\n", str2);
00450           return -1;
00451         }
00452 
00453       if(str2[0] == '-')
00454         b = -b;
00455 
00456       rc = b - a;
00457 
00458     }
00459 
00460   /* return values */
00461 
00462   if(rc == 0)
00463     {
00464       if(flag_v)
00465         fprintf(output, "arg1 = arg2\n");
00466 
00467       return value_if_equal;
00468     }
00469   else
00470     {
00471       if(flag_v)
00472         fprintf(output, "arg1 <> arg2\n");
00473 
00474       return (!value_if_equal);
00475     }
00476 
00477 }                               /* util_cmp */
00478 
00479 /* diff 2 strings line by line */
00480 
00481 static void diff(FILE * output, char *str1, char *str2)
00482 {
00483 
00484   /* current lines,chars */
00485   char *str_line1;
00486   char *char1;
00487   char *str_line2;
00488   char *char2;
00489 
00490   str_line1 = str1;
00491   str_line2 = str2;
00492 
00493   do
00494     {
00495 
00496       char1 = str_line1;
00497       char2 = str_line2;
00498 
00499       while(*char1 == *char2)
00500         {
00501           if((*char1 == '\0') || (*char1 == '\n'))
00502             break;
00503 
00504           char1++;
00505           char2++;
00506         }
00507 
00508       /* different ? */
00509       if(*char1 != *char2)
00510         {
00511 
00512           /* prints from the beggining of the line to the end */
00513           if(*str_line1)
00514             fprintf(output, "\t<- ");
00515 
00516           while((*str_line1) && (*str_line1 != '\n'))
00517             {
00518               putc(*str_line1, output);
00519               str_line1++;
00520             }
00521 
00522           /* skip the final \n  */
00523           if(*str_line1)
00524             str_line1++;
00525 
00526           if(*str_line2)
00527             fprintf(output, "\n\t-> ");
00528 
00529           while((*str_line2) && (*str_line2 != '\n'))
00530             {
00531               putc(*str_line2, output);
00532               str_line2++;
00533             }
00534           /* skip the final \n  */
00535           if(*str_line2)
00536             str_line2++;
00537 
00538           putc('\n', output);
00539 
00540         }
00541       else if(*char1 == '\n')
00542         {
00543           /* end of line */
00544           str_line1 = char1 + 1;
00545           str_line2 = char2 + 1;
00546         }
00547       else
00548         {
00549           /* end of file */
00550           break;
00551         }
00552 
00553     }
00554   while(1);
00555 
00556   return;
00557 
00558 }
00559 
00560 int util_diff(int argc,         /* IN : number of args in argv */
00561               char **argv,      /* IN : arg list               */
00562               FILE * output     /* IN : output stream          */
00563     )
00564 {
00565 
00566   if(argc != 3)
00567     {
00568       fprintf(output, "Usage: %s <expr1> <expr2>\n", argv[0]);
00569       return -1;
00570     }
00571 
00572   diff(output, argv[1], argv[2]);
00573 
00574   return 0;
00575 
00576 }
00577 
00578 /* counts the number of char and lines in a string.*/
00579 static void wc(FILE * output, char *str)
00580 {
00581 
00582   int nb_char = 0;
00583   int nb_NL = 0;
00584   char *curr = str;
00585 
00586   while(*curr)
00587     {
00588       nb_char++;
00589       if(*curr == '\n')
00590         nb_NL++;
00591       curr++;
00592     }
00593 
00594   fprintf(output, "%d %d\n", nb_char, nb_NL);
00595 
00596   return;
00597 }
00598 
00599 int util_wc(int argc,           /* IN : number of args in argv */
00600             char **argv,        /* IN : arg list               */
00601             FILE * output       /* IN : output stream          */
00602     )
00603 {
00604 
00605   if(argc != 2)
00606     {
00607       fprintf(output, "Usage: %s <expr>\n", argv[0]);
00608       return -1;
00609     }
00610 
00611   wc(output, argv[1]);
00612 
00613   return 0;
00614 
00615 }
00616 
00617 int util_chomp(int argc,        /* IN : number of args in argv */
00618                char **argv,     /* IN : arg list               */
00619                FILE * output    /* IN : output stream          */
00620     )
00621 {
00622 
00623   int len;
00624   char *in;
00625   char *out;
00626 
00627   if(argc != 2)
00628     {
00629       fprintf(output, "Usage: %s <expr>\n", argv[0]);
00630       return -1;
00631     }
00632 
00633   in = argv[1];
00634 
00635   len = strlen(in);
00636 
00637   if(in[len - 1] == '\n')
00638     {
00639 
00640       out = gsh_malloc(len + 1);
00641 
00642       if(out == NULL)
00643         return ENOMEM;
00644 
00645       /* local copy */
00646       strncpy(out, in, len + 1);
00647 
00648       out[len - 1] = '\0';
00649 
00650       fprintf(output, "%s", out);
00651 
00652       gsh_free(out);
00653 
00654     }
00655   else
00656     {
00657       fprintf(output, "%s", in);
00658     }
00659 
00660   return 0;
00661 
00662 }