nfs-ganesha 1.4
|
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 }