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 00217 #ifdef HAVE_CONFIG_H 00218 #include "config.h" 00219 #endif 00220 00221 #include <strings.h> 00222 #include <errno.h> 00223 #include <sys/types.h> 00224 #include <sys/stat.h> 00225 #include <sys/time.h> 00226 #include <unistd.h> 00227 #include <time.h> 00228 #include <ctype.h> 00229 #include <string.h> 00230 #include <pwd.h> 00231 #include "fsal.h" 00232 #include "log.h" 00233 #include "err_ghost_fs.h" 00234 #include "config_parsing.h" 00235 #include "cmd_tools.h" 00236 #include "commands.h" 00237 #include "Getopt.h" 00238 #include "abstract_mem.h" 00239 00240 int nfs_get_fsalpathlib_conf(char *configPath, char *PathLib); 00241 00242 /* global FS configuration variables */ 00243 00244 #ifdef OLD_LOGGING 00245 static desc_log_stream_t voie; 00246 static log_t log_desc = LOG_INITIALIZER; 00247 #endif 00248 00249 static int is_loaded = FALSE; /* filsystem initialization status */ 00250 00251 /* thread specific configuration variables */ 00252 00253 typedef struct cmdfsal_thr_info__ 00254 { 00255 int is_thread_ok; /* per thread initialization status */ 00256 fsal_handle_t current_dir; /* current directory handle */ 00257 char current_path[FSAL_MAX_PATH_LEN]; /* current path */ 00258 00259 /* thread's context */ 00260 fsal_op_context_t context; 00261 00262 /* export context : on for each thread, 00263 * on order to make it possible for them 00264 * to access different filesets. 00265 */ 00266 fsal_export_context_t exp_context; 00267 int opened; /* is file opened ? */ 00268 fsal_file_t current_fd; /* current file descriptor */ 00269 00270 } cmdfsal_thr_info_t; 00271 00272 /* pthread key to manage thread specific configuration */ 00273 00274 static pthread_key_t thread_key; 00275 static pthread_once_t once_key = PTHREAD_ONCE_INIT; 00276 00277 /* init pthtread_key for current thread */ 00278 00279 static void init_keys(void) 00280 { 00281 if(pthread_key_create(&thread_key, NULL) == -1) 00282 printf("Error %d creating pthread key for thread %p : %s\n", 00283 errno, (caddr_t) pthread_self(), strerror(errno)); 00284 00285 return; 00286 } /* init_keys */ 00287 00292 cmdfsal_thr_info_t *GetFSALCmdContext() 00293 { 00294 00295 cmdfsal_thr_info_t *p_current_thread_vars; 00296 00297 /* first, we init the keys if this is the first time */ 00298 if(pthread_once(&once_key, init_keys) != 0) 00299 { 00300 printf("Error %d calling pthread_once for thread %p : %s\n", 00301 errno, (caddr_t) pthread_self(), strerror(errno)); 00302 return NULL; 00303 } 00304 00305 p_current_thread_vars = (cmdfsal_thr_info_t *) pthread_getspecific(thread_key); 00306 00307 /* we allocate the thread context if this is the first time */ 00308 if(p_current_thread_vars == NULL) 00309 { 00310 00311 /* allocates thread structure */ 00312 p_current_thread_vars = gsh_malloc(sizeof(cmdfsal_thr_info_t)); 00313 00314 /* panic !!! */ 00315 if(p_current_thread_vars == NULL) 00316 { 00317 printf("%p:commands_FSAL: Not enough memory\n", (caddr_t) pthread_self()); 00318 return NULL; 00319 } 00320 00321 /* Clean thread context */ 00322 00323 memset(p_current_thread_vars, 0, sizeof(cmdfsal_thr_info_t)); 00324 00325 p_current_thread_vars->is_thread_ok = FALSE; 00326 strcpy(p_current_thread_vars->current_path, ""); 00327 p_current_thread_vars->opened = FALSE; 00328 00329 /* set the specific value */ 00330 pthread_setspecific(thread_key, (void *)p_current_thread_vars); 00331 00332 } 00333 00334 return p_current_thread_vars; 00335 00336 } /* GetFSALCmdContext */ 00337 00341 int Init_Thread_Context(FILE * output, cmdfsal_thr_info_t * context, int flag_v) 00342 { 00343 00344 uid_t uid; 00345 char fsal_status_buf[256]; 00346 fsal_status_t st; 00347 fsal_handle_t hdl_dir; 00348 char buff[2 * sizeof(fsal_handle_t) + 1]; 00349 struct passwd *pw_struct; 00350 00351 /* for the moment, create export context for root fileset */ 00352 #if defined( _USE_XFS ) 00353 fsal_path_t local_path_fsal; 00354 st = FSAL_str2path("/xfs", strlen("/xfs"), &local_path_fsal); 00355 st = FSAL_BuildExportContext(&context->exp_context, &local_path_fsal, NULL); 00356 #elif defined( _USE_VFS ) 00357 fsal_path_t local_path_fsal; 00358 st = FSAL_str2path("/tmp", strlen("/tmp"), &local_path_fsal); 00359 st = FSAL_BuildExportContext(&context->exp_context, &local_path_fsal, NULL); 00360 #elif defined( _USE_LUSTRE ) 00361 fsal_path_t local_path_fsal; 00362 st = FSAL_str2path("/mnt/lustre", strlen("/mnt/lustre"), &local_path_fsal); 00363 st = FSAL_BuildExportContext(&context->exp_context, &local_path_fsal, NULL); 00364 #else 00365 st = FSAL_BuildExportContext(&context->exp_context, NULL, NULL); 00366 #endif 00367 00368 if(FSAL_IS_ERROR(st)) 00369 { 00370 fsal_status_to_string(fsal_status_buf, st); 00371 fprintf(output, "Error executing FSAL_BuildExportContext: %s\n", fsal_status_buf); 00372 return st.major; 00373 } 00374 00375 /* get user's credentials */ 00376 00377 st = FSAL_InitClientContext(&context->context); 00378 00379 if(FSAL_IS_ERROR(st)) 00380 { 00381 fsal_status_to_string(fsal_status_buf, st); 00382 fprintf(output, "Error executing FSAL_InitClientContext: %s\n", fsal_status_buf); 00383 return st.major; 00384 } 00385 00386 uid = getuid(); 00387 pw_struct = getpwuid(uid); 00388 00389 if(pw_struct == NULL) 00390 { 00391 fprintf(output, "Unknown uid %u\n", uid); 00392 return errno; 00393 } 00394 00395 st = FSAL_GetClientContext(&context->context, &context->exp_context, 00396 uid, pw_struct->pw_gid, NULL, 0); 00397 00398 if(FSAL_IS_ERROR(st)) 00399 { 00400 fsal_status_to_string(fsal_status_buf, st); 00401 fprintf(output, "Error executing FSAL_GetUserCred: %s\n", fsal_status_buf); 00402 return st.major; 00403 } 00404 00405 /* get root file handle */ 00406 00407 /* lookup */ 00408 00409 st = FSAL_lookup(NULL, NULL, &context->context, &hdl_dir, NULL); 00410 00411 if(FSAL_IS_ERROR(st)) 00412 { 00413 fsal_status_to_string(fsal_status_buf, st); 00414 fprintf(output, "Error executing FSAL_lookup: %s\n", fsal_status_buf); 00415 return st.major; 00416 } 00417 00418 /* save root handle */ 00419 00420 context->current_dir = hdl_dir; 00421 context->is_thread_ok = TRUE; 00422 00423 strcpy(context->current_path, "/"); 00424 00425 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &context->current_dir); 00426 if(flag_v) 00427 fprintf(output, "Current directory is \"%s\" (@%s)\n", context->current_path, buff); 00428 00429 return 0; 00430 00431 } 00432 00433 void fsal_layer_SetLogLevel(int log_lvl) 00434 { 00435 #ifdef OLD_LOGGING 00436 log_stream_t *curr; 00437 00438 /* mutex pour proteger le descriptor de log */ 00439 pthread_mutex_lock(&mutex_log); 00440 00441 /* first time */ 00442 if(log_level == -1) 00443 { 00444 log_level = log_lvl; 00445 voie.fd = fileno(stderr); 00446 AddLogStreamJd(&log_desc, V_FD, voie, log_level, SUP); 00447 } 00448 else 00449 { 00450 log_level = log_lvl; 00451 /* changing log level */ 00452 curr = log_desc.liste_voies; 00453 while(curr) 00454 { 00455 curr->niveau = log_level; 00456 curr = curr->suivante; 00457 } 00458 } 00459 00460 pthread_mutex_unlock(&mutex_log); 00461 #endif 00462 } 00463 00464 static void getopt_init() 00465 { 00466 Opterr = 0; /* disables Getopt error message */ 00467 /* reinits Getopt processing */ 00468 Optind = 1; 00469 } 00470 00471 int fsal_init(char *filename, int flag_v, FILE * output) 00472 { 00473 config_file_t config_file; 00474 00475 /* FSAL init parameters */ 00476 fsal_parameter_t init_param; 00477 fsal_status_t st; 00478 00479 /* thread context */ 00480 cmdfsal_thr_info_t *context; 00481 00482 /* Initializes the FSAL */ 00483 char fsal_path_lib[MAXPATHLEN]; 00484 00485 /* TODO - This code is now broken by the new fsal api which is still 00486 * in flux. Commented some stale stuff out to build at this point. 00487 * come back to this when api settles down enough. 00488 */ 00489 00490 /* Load the FSAL library (if needed) */ 00491 if(!FSAL_LoadLibrary(fsal_path_lib)) 00492 { 00493 fprintf(stderr, "NFS MAIN: Could not load FSAL dynamic library %s\n", 00494 fsal_path_lib); 00495 exit(1); 00496 } 00497 00498 /* Get the FSAL functions */ 00499 FSAL_LoadFunctions(); 00500 00501 /* Get the FSAL consts */ 00502 FSAL_LoadConsts(); 00503 00504 /* use FSAL error family. */ 00505 00506 AddFamilyError(ERR_FSAL, "FSAL related Errors", tab_errstatus_FSAL); 00507 AddFamilyError(ERR_POSIX, "POSIX Errors", tab_systeme_status); 00508 00509 /* set configuration defaults */ 00510 00511 FSAL_SetDefault_FSAL_parameter(&init_param); 00512 FSAL_SetDefault_FS_common_parameter(&init_param); 00513 FSAL_SetDefault_FS_specific_parameter(&init_param); 00514 00515 /* Parse config file */ 00516 00517 config_file = config_ParseFile(filename); 00518 00519 if(!config_file) 00520 { 00521 fprintf(output, "init_fs: Error parsing %s: %s\n", filename, config_GetErrorMsg()); 00522 return -1; 00523 } 00524 00525 /* Load FSAL configuration from file configuration */ 00526 00527 st = FSAL_load_FSAL_parameter_from_conf(config_file, &init_param); 00528 00529 if(FSAL_IS_ERROR(st)) 00530 { 00531 if(st.major == ERR_FSAL_NOENT) 00532 { 00533 fprintf(output, "Missing FSAL stanza in config file\n"); 00534 } 00535 else 00536 { 00537 fprintf(output, "Error executing FSAL_load_FSAL_parameter_from_conf:"); 00538 print_fsal_status(output, st); 00539 fprintf(output, "\n"); 00540 return st.major; 00541 } 00542 } 00543 00544 st = FSAL_load_FS_common_parameter_from_conf(config_file, &init_param); 00545 00546 if(FSAL_IS_ERROR(st)) 00547 { 00548 if(st.major == ERR_FSAL_NOENT) 00549 { 00550 fprintf(output, "Missing FS common stanza in config file\n"); 00551 } 00552 else 00553 { 00554 fprintf(output, "Error executing FSAL_load_FS_common_parameter_from_conf:"); 00555 print_fsal_status(output, st); 00556 fprintf(output, "\n"); 00557 return st.major; 00558 } 00559 } 00560 00561 st = FSAL_load_FS_specific_parameter_from_conf(config_file, &init_param); 00562 00563 if(FSAL_IS_ERROR(st)) 00564 { 00565 if(st.major == ERR_FSAL_NOENT) 00566 { 00567 fprintf(output, "Missing FS specific stanza in config file\n"); 00568 } 00569 else 00570 { 00571 fprintf(output, "Error executing FSAL_load_FS_specific_parameter_from_conf:"); 00572 print_fsal_status(output, st); 00573 fprintf(output, "\n"); 00574 return st.major; 00575 } 00576 } 00577 00578 /* Free config struct */ 00579 config_Free(config_file); 00580 00581 #ifdef OLD_LOGGING 00582 /* overide log descriptor for FSAL */ 00583 init_param.fsal_info.log_outputs = log_desc; 00584 #endif 00585 00586 /* Initialization */ 00587 00588 if(flag_v) 00589 fprintf(output, "Filesystem initialization...\n"); 00590 00591 st = FSAL_Init(&init_param); 00592 00593 if(FSAL_IS_ERROR(st)) 00594 { 00595 00596 fprintf(output, "Error executing FSAL_Init:"); 00597 print_fsal_status(output, st); 00598 fprintf(output, "\n"); 00599 return st.major; 00600 00601 } 00602 00603 is_loaded = TRUE; 00604 00605 /* initialize current thread */ 00606 00607 context = GetFSALCmdContext(); 00608 00609 if(context->is_thread_ok != TRUE) 00610 { 00611 int rc; 00612 rc = Init_Thread_Context(output, context, flag_v); 00613 if(rc != 0) 00614 return rc; 00615 } 00616 00617 return 0; 00618 } 00619 00621 int fn_fsal_init_fs(int argc, /* IN : number of args in argv */ 00622 char **argv, /* IN : arg list */ 00623 FILE * output) /* IN : output stream */ 00624 { 00625 int rc; 00626 00627 char format[] = "hv"; 00628 00629 const char help_init[] = 00630 "usage: init_fs [options] <ganesha_config_file>\n" 00631 "options :\n" "\t-h print this help\n" "\t-v verbose mode\n"; 00632 00633 int option; 00634 int flag_v = 0; 00635 int flag_h = 0; 00636 int err_flag = 0; 00637 char *filename = NULL; 00638 00639 /* analysing options */ 00640 getopt_init(); 00641 while((option = Getopt(argc, argv, format)) != -1) 00642 { 00643 switch (option) 00644 { 00645 case 'v': 00646 if(flag_v) 00647 fprintf(output, 00648 "init_fs: warning: option 'v' has been specified more than once.\n"); 00649 else 00650 flag_v++; 00651 break; 00652 case 'h': 00653 if(flag_h) 00654 fprintf(output, 00655 "init_fs: warning: option 'h' has been specified more than once.\n"); 00656 else 00657 flag_h++; 00658 break; 00659 case '?': 00660 fprintf(output, "init_fs: unknown option : %c\n", Optopt); 00661 err_flag++; 00662 break; 00663 } 00664 } 00665 00666 if(flag_h) 00667 { 00668 fprintf(output, help_init); 00669 return 0; 00670 } 00671 00672 /* verifies mandatory argument */ 00673 00674 if(Optind != (argc - 1)) 00675 { 00676 /* too much or not enough arguments */ 00677 err_flag++; 00678 } 00679 else 00680 { 00681 filename = argv[Optind]; 00682 } 00683 00684 if(err_flag) 00685 { 00686 fprintf(output, help_init); 00687 return -1; 00688 } 00689 00690 rc = fsal_init(filename, flag_v, output); 00691 00692 return rc; 00693 } 00694 00697 int fn_fsal_pwd(int argc, /* IN : number of args in argv */ 00698 char **argv, /* IN : arg list */ 00699 FILE * output /* IN : output stream */ 00700 ) 00701 { 00702 00703 cmdfsal_thr_info_t *context; 00704 00705 /* is the fs initialized ? */ 00706 if(!is_loaded) 00707 { 00708 fprintf(output, "Error: filesystem not initialized\n"); 00709 return -1; 00710 } 00711 00712 /* initialize current thread */ 00713 00714 context = GetFSALCmdContext(); 00715 00716 if(context->is_thread_ok != TRUE) 00717 { 00718 int rc; 00719 rc = Init_Thread_Context(output, context, 0); 00720 if(rc != 0) 00721 return rc; 00722 } 00723 00724 { 00725 char buff[2 * sizeof(fsal_handle_t) + 1]; 00726 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &context->current_dir); 00727 00728 fprintf(output, "Current directory is \"%s\" (@%s)\n", context->current_path, buff); 00729 00730 } 00731 00732 return 0; 00733 00734 } 00735 00736 /* solves a relative or absolute path */ 00737 00738 int solvepath(char *io_global_path, int size_global_path, /* [IN-OUT] global path */ 00739 char *i_spec_path, /* [IN] user specified path */ 00740 fsal_handle_t i_current_handle, /* [IN] current directory handle */ 00741 fsal_handle_t * new_handle, /* [OUT] target object handle */ 00742 FILE * output) 00743 { 00744 00745 char str_path[FSAL_MAX_PATH_LEN]; 00746 cmdfsal_thr_info_t *context; 00747 00748 context = GetFSALCmdContext(); 00749 00750 if(context->is_thread_ok != TRUE) 00751 { 00752 int rc; 00753 rc = Init_Thread_Context(output, context, 0); 00754 if(rc != 0) 00755 return rc; 00756 } 00757 00758 /* local copy */ 00759 memset( str_path, 0, FSAL_MAX_PATH_LEN ) ; 00760 strncpy(str_path, i_spec_path, FSAL_MAX_PATH_LEN); 00761 00762 if(str_path[0] == '@') 00763 /* It is a file handle */ 00764 { 00765 int rc; 00766 00767 rc = sscanHandle(new_handle, str_path + 1); 00768 00769 if(rc <= 0) 00770 { 00771 fprintf(output, "Invalid FileHandle: %s\n", str_path); 00772 return -1; 00773 } 00774 00775 if(str_path[rc + 1] != '\0') 00776 { 00777 fprintf(output, "Invalid FileHandle: %s\n", str_path); 00778 return -1; 00779 } 00780 00781 strncpy(io_global_path, str_path, size_global_path); 00782 00783 return 0; 00784 00785 } 00786 else if(str_path[0] == '/') 00787 /* absolute path, proceed a lookupPath */ 00788 { 00789 fsal_path_t path; 00790 fsal_status_t st; 00791 fsal_handle_t tmp_hdl; 00792 00793 if(FSAL_IS_ERROR(st = FSAL_str2path(str_path, FSAL_MAX_PATH_LEN, &path))) 00794 { 00795 fprintf(output, "Error executing FSAL_str2path:"); 00796 print_fsal_status(output, st); 00797 fprintf(output, "\n"); 00798 return st.major; 00799 } 00800 00801 if(FSAL_IS_ERROR(st = FSAL_lookupPath(&path, &context->context, &tmp_hdl, NULL))) 00802 { 00803 fprintf(output, "Error executing FSAL_lookupPath:"); 00804 print_fsal_status(output, st); 00805 fprintf(output, "\n"); 00806 return st.major; 00807 } 00808 00809 /* cleans path */ 00810 clean_path(str_path, FSAL_MAX_PATH_LEN); 00811 00812 strncpy(io_global_path, str_path, size_global_path); 00813 *new_handle = tmp_hdl; 00814 00815 return 0; 00816 00817 } 00818 else 00819 /* relative path, proceed a step by step lookup */ 00820 { 00821 fsal_name_t name; 00822 fsal_status_t st; 00823 fsal_handle_t old_hdl = i_current_handle; 00824 fsal_handle_t tmp_hdl; 00825 char tmp_path[FSAL_MAX_PATH_LEN]; 00826 char *next_name = str_path; 00827 char *curr = str_path; 00828 int last = 0; 00829 00830 tmp_path[0] = '\0'; /* empty string */ 00831 00832 do 00833 { 00834 00835 /* tokenize to the next '/' */ 00836 while((*curr != '\0') && (*curr != '/')) 00837 curr++; 00838 00839 if(!(*curr)) 00840 last = 1; /* remembers if it was the last dir */ 00841 *curr = '\0'; 00842 00843 /* build the name */ 00844 if(FSAL_IS_ERROR(st = FSAL_str2name(next_name, FSAL_MAX_PATH_LEN, &name))) 00845 { 00846 fprintf(output, "Error executing FSAL_str2name:"); 00847 print_fsal_status(output, st); 00848 fprintf(output, "\n"); 00849 return st.major; 00850 } 00851 00852 /* lookup this name */ 00853 if(FSAL_IS_ERROR 00854 (st = FSAL_lookup(&old_hdl, &name, &context->context, &tmp_hdl, NULL))) 00855 { 00856 fprintf(output, "Error executing FSAL_lookup:"); 00857 print_fsal_status(output, st); 00858 fprintf(output, "\n"); 00859 return st.major; 00860 } 00861 00862 /* if handles are the same, we are at fileset root, 00863 * so, don't modify the path. 00864 * Else, we contatenate them. 00865 */ 00866 if(FSAL_handlecmp(&old_hdl, &tmp_hdl, &st) != 0) 00867 { 00868 /* updates current handle */ 00869 old_hdl = tmp_hdl; 00870 00871 /* adds /name at the end of the path */ 00872 strncat(tmp_path, "/", FSAL_MAX_PATH_LEN); 00873 strncat(tmp_path, next_name, FSAL_MAX_PATH_LEN - strlen(tmp_path)); 00874 } 00875 00876 /* updates cursors */ 00877 if(!last) 00878 { 00879 curr++; 00880 next_name = curr; 00881 /* ignore successive slashes */ 00882 while((*curr != '\0') && (*curr == '/')) 00883 { 00884 curr++; 00885 next_name = curr; 00886 } 00887 if(!(*curr)) 00888 last = 1; /* it is the last dir */ 00889 } 00890 00891 } 00892 while(!last); 00893 00894 /* everything is OK, apply changes */ 00895 00896 strncat(io_global_path, tmp_path, size_global_path); 00897 clean_path(io_global_path, size_global_path); 00898 00899 *new_handle = old_hdl; 00900 00901 return 0; 00902 00903 } 00904 00905 } 00906 00908 int fn_fsal_cd(int argc, /* IN : number of args in argv */ 00909 char **argv, /* IN : arg list */ 00910 FILE * output /* IN : output stream */ 00911 ) 00912 { 00913 00914 static char help_cd[] = "usage: cd <path>\n"; 00915 00916 char glob_path[FSAL_MAX_PATH_LEN]; 00917 fsal_handle_t new_hdl; 00918 fsal_attrib_list_t attrs; 00919 fsal_status_t st; 00920 int rc; 00921 00922 cmdfsal_thr_info_t *context; 00923 00924 /* is the fs initialized ? */ 00925 if(!is_loaded) 00926 { 00927 fprintf(output, "Error: filesystem not initialized\n"); 00928 return -1; 00929 } 00930 00931 /* initialize current thread */ 00932 00933 context = GetFSALCmdContext(); 00934 00935 if(context->is_thread_ok != TRUE) 00936 { 00937 int rc; 00938 rc = Init_Thread_Context(output, context, 0); 00939 if(rc != 0) 00940 return rc; 00941 } 00942 00943 /* Exactly one arg expected */ 00944 if(argc != 2) 00945 { 00946 fprintf(output, help_cd, NULL); 00947 return -1; 00948 } 00949 00950 /* is it a relative or absolute path. */ 00951 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 00952 00953 if((rc = 00954 solvepath(glob_path, FSAL_MAX_PATH_LEN, 00955 argv[1], context->current_dir, &new_hdl, output))) 00956 return rc; 00957 00958 /* verify if the object is a directory */ 00959 FSAL_CLEAR_MASK(attrs.asked_attributes); 00960 FSAL_SET_MASK(attrs.asked_attributes, 00961 FSAL_ATTR_TYPE | FSAL_ATTR_MODE | FSAL_ATTR_GROUP | FSAL_ATTR_OWNER); 00962 00963 if(FSAL_IS_ERROR(st = FSAL_getattrs(&new_hdl, &context->context, &attrs))) 00964 { 00965 fprintf(output, "Error executing FSAL_getattrs:"); 00966 print_fsal_status(output, st); 00967 fprintf(output, "\n"); 00968 return st.major; 00969 } 00970 00971 if(attrs.type != FSAL_TYPE_DIR) 00972 { 00973 fprintf(output, "Error: %s is not a directory\n", glob_path); 00974 return ENOTDIR; 00975 } 00976 00977 if(FSAL_IS_ERROR(st = FSAL_test_access(&context->context, FSAL_X_OK, &attrs))) 00978 { 00979 fprintf(output, "Error: %s: permission denied.\n", glob_path); 00980 return st.major; 00981 } 00982 00983 /* if (FSAL_IS_ERROR(st = FSAL_access(&new_hdl,&contexte,FSAL_X_OK,&attrs))){ 00984 fprintf(output,"Error: %s: permission denied.\n",); 00985 return st.major; 00986 }*/ 00987 00988 /* if so, apply changes */ 00989 strncpy(context->current_path, glob_path, FSAL_MAX_PATH_LEN); 00990 context->current_dir = new_hdl; 00991 00992 { 00993 char buff[2 * sizeof(fsal_handle_t) + 1]; 00994 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &context->current_dir); 00995 00996 fprintf(output, "Current directory is \"%s\" (@%s)\n", context->current_path, buff); 00997 } 00998 00999 return 0; 01000 01001 } 01002 01004 int fn_fsal_stat(int argc, /* IN : number of args in argv */ 01005 char **argv, /* IN : arg list */ 01006 FILE * output /* IN : output stream */ 01007 ) 01008 { 01009 01010 char format[] = "hv"; 01011 01012 const char help_stat[] = "usage: stat [-h][-v] <file>\n"; 01013 01014 char glob_path[FSAL_MAX_PATH_LEN]; 01015 fsal_handle_t new_hdl; 01016 fsal_attrib_list_t attrs; 01017 fsal_status_t st; 01018 int rc, option; 01019 int flag_v = 0; 01020 int flag_h = 0; 01021 int err_flag = 0; 01022 char *file = NULL; 01023 01024 cmdfsal_thr_info_t *context; 01025 01026 /* is the fs initialized ? */ 01027 if(!is_loaded) 01028 { 01029 fprintf(output, "Error: filesystem not initialized\n"); 01030 return -1; 01031 } 01032 01033 /* initialize current thread */ 01034 01035 context = GetFSALCmdContext(); 01036 01037 if(context->is_thread_ok != TRUE) 01038 { 01039 int rc; 01040 rc = Init_Thread_Context(output, context, 0); 01041 if(rc != 0) 01042 return rc; 01043 } 01044 01045 /* analysing options */ 01046 getopt_init(); 01047 while((option = Getopt(argc, argv, format)) != -1) 01048 { 01049 switch (option) 01050 { 01051 case 'v': 01052 if(flag_v) 01053 fprintf(output, 01054 "stat: warning: option 'v' has been specified more than once.\n"); 01055 else 01056 flag_v++; 01057 break; 01058 case 'h': 01059 if(flag_h) 01060 fprintf(output, 01061 "stat: warning: option 'h' has been specified more than once.\n"); 01062 else 01063 flag_h++; 01064 break; 01065 case '?': 01066 fprintf(output, "stat: unknown option : %c\n", Optopt); 01067 err_flag++; 01068 break; 01069 } 01070 } 01071 01072 if(flag_h) 01073 { 01074 fprintf(output, help_stat); 01075 return 0; 01076 } 01077 01078 /* Exactly one arg expected */ 01079 if(Optind != (argc - 1)) 01080 { 01081 err_flag++; 01082 } 01083 else 01084 { 01085 file = argv[Optind]; 01086 } 01087 01088 if(err_flag) 01089 { 01090 fprintf(output, help_stat); 01091 return -1; 01092 } 01093 01094 /* copy current path. */ 01095 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01096 01097 /* retrieves object handle */ 01098 if((rc = 01099 solvepath(glob_path, FSAL_MAX_PATH_LEN, 01100 file, context->current_dir, &new_hdl, output))) 01101 return rc; 01102 01103 /* retrieve supported attributes */ 01104 FSAL_CLEAR_MASK(attrs.asked_attributes); 01105 FSAL_SET_MASK(attrs.asked_attributes, FSAL_ATTR_SUPPATTR); 01106 01107 if(FSAL_IS_ERROR(st = FSAL_getattrs(&new_hdl, &context->context, &attrs))) 01108 { 01109 fprintf(output, "Error executing FSAL_getattrs:"); 01110 print_fsal_status(output, st); 01111 fprintf(output, "\n"); 01112 return st.major; 01113 } 01114 01115 /* print supported attributes if verbose flag is set */ 01116 if(flag_v) 01117 { 01118 fprintf(output, "Supported attributes :\n"); 01119 print_fsal_attrib_mask(attrs.supported_attributes, output); 01120 fprintf(output, "\nAttributes :\n"); 01121 } 01122 01123 /* getting all supported attributes */ 01124 attrs.asked_attributes = attrs.supported_attributes; 01125 01126 if(FSAL_IS_ERROR(st = FSAL_getattrs(&new_hdl, &context->context, &attrs))) 01127 { 01128 fprintf(output, "Error executing FSAL_getattrs:"); 01129 print_fsal_status(output, st); 01130 fprintf(output, "\n"); 01131 return st.major; 01132 } 01133 01134 /* print file attributes */ 01135 print_fsal_attributes(attrs, output); 01136 01137 return 0; 01138 01139 } 01140 01142 int fn_fsal_lsxattrs(int argc, /* IN : number of args in argv */ 01143 char **argv, /* IN : arg list */ 01144 FILE * output /* IN : output stream */ 01145 ) 01146 { 01147 char fsal_status_buf[256]; 01148 01149 char format[] = "hv"; 01150 01151 const char help_lsxattr[] = "usage: lsxattrs [-h][-v] <path>\n"; 01152 01153 char glob_path[FSAL_MAX_PATH_LEN]; 01154 fsal_handle_t new_hdl; 01155 fsal_status_t st; 01156 int rc, option; 01157 int flag_v = 0; 01158 int flag_h = 0; 01159 int err_flag = 0; 01160 char *file = NULL; 01161 01162 unsigned int cookie; 01163 fsal_xattrent_t xattr_array[256]; 01164 unsigned int nb_returned; 01165 int eol; 01166 01167 cmdfsal_thr_info_t *context; 01168 01169 /* is the fs initialized ? */ 01170 if(!is_loaded) 01171 { 01172 fprintf(output, "Error: filesystem not initialized\n"); 01173 return -1; 01174 } 01175 01176 /* initialize current thread */ 01177 01178 context = GetFSALCmdContext(); 01179 01180 if(context->is_thread_ok != TRUE) 01181 { 01182 int rc; 01183 rc = Init_Thread_Context(output, context, 0); 01184 if(rc != 0) 01185 return rc; 01186 } 01187 01188 /* analysing options */ 01189 getopt_init(); 01190 while((option = Getopt(argc, argv, format)) != -1) 01191 { 01192 switch (option) 01193 { 01194 case 'v': 01195 if(flag_v) 01196 fprintf(output, 01197 "lsxattrs: warning: option 'v' has been specified more than once.\n"); 01198 else 01199 flag_v++; 01200 break; 01201 case 'h': 01202 if(flag_h) 01203 fprintf(output, 01204 "lsxattrs: warning: option 'h' has been specified more than once.\n"); 01205 else 01206 flag_h++; 01207 break; 01208 case '?': 01209 fprintf(output, "lsxattrs: unknown option : %c\n", Optopt); 01210 err_flag++; 01211 break; 01212 } 01213 } 01214 01215 if(flag_h) 01216 { 01217 fprintf(output, help_lsxattr); 01218 return 0; 01219 } 01220 01221 /* Exactly one arg expected */ 01222 if(Optind != (argc - 1)) 01223 { 01224 err_flag++; 01225 } 01226 else 01227 { 01228 file = argv[Optind]; 01229 } 01230 01231 if(err_flag) 01232 { 01233 fprintf(output, help_lsxattr); 01234 return -1; 01235 } 01236 01237 /* copy current path. */ 01238 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01239 01240 /* retrieves object handle */ 01241 if((rc = 01242 solvepath(glob_path, FSAL_MAX_PATH_LEN, 01243 file, context->current_dir, &new_hdl, output))) 01244 return rc; 01245 01246 /* list extended attributes */ 01247 01248 cookie = XATTRS_READLIST_FROM_BEGINNING; 01249 eol = FALSE; 01250 01251 while(!eol) 01252 { 01253 unsigned int index; 01254 01255 st = FSAL_ListXAttrs(&new_hdl, cookie, &context->context, 01256 xattr_array, 256, &nb_returned, &eol); 01257 01258 if(FSAL_IS_ERROR(st)) 01259 { 01260 fsal_status_to_string(fsal_status_buf, st); 01261 fprintf(output, "Error executing FSAL_ListXAttrs: %s\n", fsal_status_buf); 01262 return st.major; 01263 } 01264 01265 /* list attributes */ 01266 01267 for(index = 0; index < nb_returned; index++) 01268 { 01269 if(flag_v) 01270 /* print all attribute's info */ 01271 fprintf(output, "%u: %s\n", xattr_array[index].xattr_id, 01272 xattr_array[index].xattr_name.name); 01273 else 01274 /* print only attribute's name */ 01275 fprintf(output, "%s\n", xattr_array[index].xattr_name.name); 01276 01277 cookie = xattr_array[index].xattr_cookie; 01278 } 01279 01280 } 01281 01282 return 0; 01283 01284 } 01285 01287 int fn_fsal_getxattr(int argc, /* IN : number of args in argv */ 01288 char **argv, /* IN : arg list */ 01289 FILE * output /* IN : output stream */ 01290 ) 01291 { 01292 char format[] = "hvaxn"; 01293 01294 const char help_getxattr[] = 01295 "usage: getxattr [-hv] [-a|-n|-x] <path> <attr_name>\n" 01296 "options :\n" 01297 "\t-h print this help\n" 01298 "\t-v verbose mode\n" 01299 "\t-a display attribute value as ascii\n" 01300 "\t-n display attribute value as numeric\n" 01301 "\t-x display attribute value as hexa\n"; 01302 01303 char glob_path[FSAL_MAX_PATH_LEN]; 01304 fsal_handle_t new_hdl; 01305 fsal_status_t st; 01306 int rc, option; 01307 int flag_v = 0; 01308 int flag_h = 0; 01309 int flag_x = 0; 01310 int flag_n = 0; 01311 int flag_a = 0; 01312 int err_flag = 0; 01313 char *file = NULL; 01314 char *attrname = NULL; 01315 01316 fsal_name_t attrnamefsal; 01317 char buffer[4096]; 01318 size_t returned; 01319 unsigned int index; 01320 01321 cmdfsal_thr_info_t *context; 01322 01323 /* is the fs initialized ? */ 01324 if(!is_loaded) 01325 { 01326 fprintf(output, "Error: filesystem not initialized\n"); 01327 return -1; 01328 } 01329 01330 /* initialize current thread */ 01331 01332 context = GetFSALCmdContext(); 01333 01334 if(context->is_thread_ok != TRUE) 01335 { 01336 int rc; 01337 rc = Init_Thread_Context(output, context, 0); 01338 if(rc != 0) 01339 return rc; 01340 } 01341 01342 /* analysing options */ 01343 getopt_init(); 01344 while((option = Getopt(argc, argv, format)) != -1) 01345 { 01346 switch (option) 01347 { 01348 case 'v': 01349 if(flag_v) 01350 fprintf(output, 01351 "getxattr: warning: option 'v' has been specified more than once.\n"); 01352 else 01353 flag_v++; 01354 break; 01355 case 'a': 01356 if(flag_a) 01357 fprintf(output, 01358 "getxattr: warning: option 'a' has been specified more than once.\n"); 01359 else 01360 flag_a++; 01361 break; 01362 case 'x': 01363 if(flag_x) 01364 fprintf(output, 01365 "getxattr: warning: option 'x' has been specified more than once.\n"); 01366 else 01367 flag_x++; 01368 break; 01369 case 'n': 01370 if(flag_n) 01371 fprintf(output, 01372 "getxattr: warning: option 'n' has been specified more than once.\n"); 01373 else 01374 flag_n++; 01375 break; 01376 case 'h': 01377 if(flag_h) 01378 fprintf(output, 01379 "getxattr: warning: option 'h' has been specified more than once.\n"); 01380 else 01381 flag_h++; 01382 break; 01383 case '?': 01384 fprintf(output, "getxattr: unknown option : %c\n", Optopt); 01385 err_flag++; 01386 break; 01387 } 01388 } 01389 01390 if(flag_h) 01391 { 01392 fprintf(output, help_getxattr); 01393 return 0; 01394 } 01395 01396 if(flag_x + flag_n + flag_a > 1) 01397 { 01398 fprintf(output, "getxattr: options -x, -a and -n are not compatible\n"); 01399 fprintf(output, help_getxattr); 01400 return -1; 01401 } 01402 01403 /* Exactly 2 args expected */ 01404 if(Optind != (argc - 2)) 01405 { 01406 err_flag++; 01407 } 01408 else 01409 { 01410 file = argv[Optind]; 01411 attrname = argv[Optind + 1]; 01412 } 01413 01414 if(err_flag) 01415 { 01416 fprintf(output, help_getxattr); 01417 return -1; 01418 } 01419 01420 /* copy current path. */ 01421 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01422 01423 /* retrieves object handle */ 01424 if((rc = 01425 solvepath(glob_path, FSAL_MAX_PATH_LEN, 01426 file, context->current_dir, &new_hdl, output))) 01427 return rc; 01428 01429 /* create fsal_name_t */ 01430 FSAL_str2name(attrname, 256, &attrnamefsal); 01431 01432 memset(buffer, 0, sizeof(buffer)); 01433 01434 /* get extended attribute */ 01435 01436 st = FSAL_GetXAttrValueByName(&new_hdl, &attrnamefsal, &context->context, 01437 buffer, 4096, &returned); 01438 01439 if(FSAL_IS_ERROR(st)) 01440 { 01441 fprintf(output, "Error executing FSAL_GetXAttrValueByName:"); 01442 print_fsal_status(output, st); 01443 fprintf(output, "\n"); 01444 return st.major; 01445 } 01446 01447 if(returned == 0) 01448 { 01449 fprintf(output, "(empty)\n"); 01450 return 0; 01451 } 01452 01453 /* display returned value */ 01454 01455 /* when no flags are given, try to determinate what it is */ 01456 01457 if(!flag_a && !flag_n && !flag_x) 01458 { 01459 /* is it ascii ? */ 01460 if(strlen(buffer) == returned - 1 || strlen(buffer) == returned) 01461 { 01462 unsigned int i; 01463 char *str = buffer; 01464 int is_ascii = TRUE; 01465 01466 for(i = 0; i < strlen(str); i++) 01467 { 01468 if(!isprint(str[i]) && !isspace(str[i])) 01469 { 01470 is_ascii = FALSE; 01471 break; 01472 } 01473 } 01474 if(is_ascii) 01475 flag_a = 1; 01476 } 01477 01478 /* is it numeric */ 01479 if(!flag_a) 01480 { 01481 if(returned == 1 || returned == 2 || returned == 4 || returned == 8) 01482 flag_n = 1; 01483 else 01484 flag_x = 1; 01485 } 01486 } 01487 01488 if(flag_a) 01489 { 01490 if(strlen(buffer) > 0 && buffer[strlen(buffer) - 1] != '\n') 01491 fprintf(output, "%s\n", buffer); 01492 else 01493 fprintf(output, "%s", buffer); 01494 } 01495 else if(flag_n) 01496 { 01497 if(returned == 1) 01498 fprintf(output, "%hhu\n", buffer[0]); 01499 else if(returned == 2) 01500 fprintf(output, "%hu\n", *(buffer)); 01501 else if(returned == 4) 01502 fprintf(output, "%u\n", *(buffer)); 01503 else if(returned == 8) 01504 fprintf(output, "%llu\n", (long long unsigned int)*(buffer)); 01505 else 01506 { 01507 for(index = 0; index < returned; index += 8) 01508 { 01509 unsigned long long *p64 = (unsigned long long *)(buffer + index); 01510 if(index == 0) 01511 fprintf(output, "%llu", *p64); 01512 else 01513 fprintf(output, ".%llu", *p64); 01514 } 01515 fprintf(output, "\n"); 01516 01517 } 01518 01519 } 01520 else if(flag_x) /* hexa */ 01521 { 01522 fprintf(output, "0X"); 01523 for(index = 0; index < returned; index++) 01524 { 01525 unsigned char val = buffer[index]; 01526 fprintf(output, "%hhX", val); 01527 } 01528 fprintf(output, "\n"); 01529 01530 } 01531 01532 return 0; 01533 01534 } 01535 01537 int fn_fsal_ls(int argc, /* IN : number of args in argv */ 01538 char **argv, /* IN : arg list */ 01539 FILE * output) /* IN : output stream */ 01540 { 01541 01542 char format[] = "hvdlS"; 01543 01544 const char help_ls[] = 01545 "usage: ls [options] [name|path]\n" 01546 "options :\n" 01547 "\t-h print this help\n" 01548 "\t-v verbose mode\n" 01549 "\t-d print directory info instead of listing its content\n" 01550 "\t-l print standard UNIX attributes\n" "\t-S print all supported attributes\n"; 01551 01552 int option; 01553 int flag_v = 0; 01554 int flag_h = 0; 01555 int flag_d = 0; 01556 int flag_l = 0; 01557 int flag_S = 0; 01558 int err_flag = 0; 01559 char *str_name; 01560 01561 //#define READDIR_SIZE FSAL_READDIR_SIZE 01562 #define READDIR_SIZE 10 01563 01564 fsal_attrib_mask_t mask_needed; 01565 fsal_handle_t obj_hdl; 01566 fsal_dir_t dir; 01567 char glob_path[FSAL_MAX_PATH_LEN]; 01568 fsal_attrib_list_t attrs; 01569 fsal_status_t st; 01570 fsal_cookie_t from, to; 01571 fsal_dirent_t entries[READDIR_SIZE]; 01572 fsal_count_t number; 01573 fsal_boolean_t eod = FALSE; 01574 fsal_path_t symlink_path; 01575 int error = FALSE; 01576 int rc; 01577 01578 cmdfsal_thr_info_t *context; 01579 01580 /* analysing options */ 01581 getopt_init(); 01582 while((option = Getopt(argc, argv, format)) != -1) 01583 { 01584 01585 switch (option) 01586 { 01587 case 'v': 01588 if(flag_v) 01589 fprintf(output, 01590 "ls: warning: option 'v' has been specified more than once.\n"); 01591 else 01592 flag_v++; 01593 break; 01594 case 'h': 01595 if(flag_h) 01596 fprintf(output, 01597 "ls: warning: option 'h' has been specified more than once.\n"); 01598 else 01599 flag_h++; 01600 break; 01601 case 'd': 01602 if(flag_d) 01603 fprintf(output, 01604 "ls: warning: option 'd' has been specified more than once.\n"); 01605 else 01606 flag_d++; 01607 break; 01608 case 'l': 01609 if(flag_l) 01610 fprintf(output, 01611 "ls: warning: option 'l' has been specified more than once.\n"); 01612 else 01613 flag_l++; 01614 break; 01615 case 'S': 01616 if(flag_S) 01617 fprintf(output, 01618 "ls: warning: option 'S' has been specified more than once.\n"); 01619 else 01620 flag_S++; 01621 break; 01622 case '?': 01623 fprintf(output, "ls: unknown option : %c\n", Optopt); 01624 err_flag++; 01625 break; 01626 } 01627 01628 } 01629 01630 if(flag_l + flag_S > 1) 01631 { 01632 fprintf(output, "ls: conflict between options l,S\n"); 01633 err_flag++; 01634 } 01635 01636 if(flag_h) 01637 { 01638 fprintf(output, help_ls); 01639 return 0; 01640 } 01641 if(err_flag) 01642 { 01643 fprintf(output, help_ls); 01644 return -1; 01645 } 01646 01647 /* is the fs initialized ? */ 01648 if(!is_loaded) 01649 { 01650 fprintf(output, "Error: filesystem not initialized\n"); 01651 return -1; 01652 } 01653 01654 /* initialize current thread */ 01655 01656 context = GetFSALCmdContext(); 01657 01658 if(context->is_thread_ok != TRUE) 01659 { 01660 int rc; 01661 rc = Init_Thread_Context(output, context, 0); 01662 if(rc != 0) 01663 return rc; 01664 } 01665 01666 /* prepare needed attributes mask */ 01667 FSAL_CLEAR_MASK(mask_needed); 01668 FSAL_SET_MASK(mask_needed, FSAL_ATTRS_MANDATORY); 01669 01670 if(flag_l) 01671 FSAL_SET_MASK(mask_needed, FSAL_ATTRS_POSIX); 01672 else if(flag_S) 01673 mask_needed = 0xFFFFFFFFFFFFFFFFLL; 01674 01675 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01676 01677 /* first, retrieve the argument (if any) */ 01678 if(Optind == (argc - 1)) 01679 { 01680 str_name = argv[Optind]; 01681 01682 /* retrieving handle */ 01683 if((rc = 01684 solvepath(glob_path, FSAL_MAX_PATH_LEN, 01685 str_name, context->current_dir, &obj_hdl, output))) 01686 return rc; 01687 01688 } 01689 else 01690 { 01691 str_name = "."; 01692 obj_hdl = context->current_dir; 01693 } 01694 01695 if(flag_v) 01696 fprintf(output, "proceeding ls on \"%s\"\n", glob_path); 01697 01698 FSAL_CLEAR_MASK(attrs.asked_attributes); 01699 FSAL_SET_MASK(attrs.asked_attributes, FSAL_ATTR_SUPPATTR); 01700 01701 if(FSAL_IS_ERROR(st = FSAL_getattrs(&obj_hdl, &context->context, &attrs))) 01702 { 01703 fprintf(output, "Error executing FSAL_getattrs:"); 01704 print_fsal_status(output, st); 01705 fprintf(output, "\n"); 01706 return st.major; 01707 } 01708 01709 /* getting all needed attributes */ 01710 attrs.asked_attributes = (attrs.supported_attributes & mask_needed); 01711 01712 if(FSAL_IS_ERROR(st = FSAL_getattrs(&obj_hdl, &context->context, &attrs))) 01713 { 01714 fprintf(output, "Error executing FSAL_getattrs:"); 01715 print_fsal_status(output, st); 01716 fprintf(output, "\n"); 01717 return st.major; 01718 } 01719 01720 /* 01721 * if the object is a file or a directoy with the -d option specified, 01722 * we only show its info and exit. 01723 */ 01724 if((attrs.type != FSAL_TYPE_DIR) || flag_d) 01725 { 01726 01727 if((attrs.type == FSAL_TYPE_LNK) && (flag_l)) 01728 { 01729 01730 if(FSAL_IS_ERROR 01731 (st = FSAL_readlink(&obj_hdl, &context->context, &symlink_path, NULL))) 01732 { 01733 fprintf(output, "Error executing FSAL_readlink:"); 01734 print_fsal_status(output, st); 01735 fprintf(output, "\n"); 01736 return st.major; 01737 } 01738 01739 } 01740 01741 if(flag_l) 01742 print_item_line(output, &attrs, str_name, symlink_path.path); 01743 01744 else if(flag_S) 01745 { 01746 01747 char tracebuff[2 * sizeof(fsal_handle_t) + 1]; 01748 snprintHandle(tracebuff, 2 * sizeof(fsal_handle_t) + 1, &obj_hdl); 01749 fprintf(output, "%s (@%s):\n", str_name, tracebuff); 01750 print_fsal_attributes(attrs, output); 01751 01752 } 01753 else /* only prints the name */ 01754 fprintf(output, "%s\n", str_name); 01755 01756 return 0; 01757 } 01758 01759 /* 01760 * the current object is a directory, we have to list its element 01761 */ 01762 if(FSAL_IS_ERROR(st = FSAL_opendir(&obj_hdl, &context->context, &dir, NULL))) 01763 { 01764 fprintf(output, "Error executing FSAL_opendir:"); 01765 print_fsal_status(output, st); 01766 fprintf(output, "\n"); 01767 return st.major; 01768 } 01769 01770 FSAL_SET_COOKIE_BEGINNING(from); 01771 01772 while(!error && !eod) 01773 { 01774 fsal_dirent_t *curr; 01775 char item_path[FSAL_MAX_PATH_LEN]; 01776 01777 if(FSAL_IS_ERROR 01778 (st = 01779 FSAL_readdir(&dir, from, attrs.supported_attributes & mask_needed, 01780 READDIR_SIZE * sizeof(fsal_dirent_t), entries, &to, &number, 01781 &eod))) 01782 { 01783 fprintf(output, "Error executing FSAL_readdir:"); 01784 print_fsal_status(output, st); 01785 fprintf(output, "\n"); 01786 error = st.major; 01787 number = 0; 01788 } 01789 01790 if(flag_v) 01791 fprintf(output, "FSAL_readdir returned %u entries\n", (unsigned int)number); 01792 01793 if(number > 0) 01794 { 01795 curr = entries; 01796 do 01797 { 01798 int len; 01799 len = strlen(str_name); 01800 if(!strcmp(str_name, ".")) 01801 strncpy(item_path, curr->name.name, FSAL_MAX_PATH_LEN); 01802 else if(str_name[len - 1] == '/') 01803 snprintf(item_path, FSAL_MAX_PATH_LEN, "%s%s", str_name, curr->name.name); 01804 else 01805 snprintf(item_path, FSAL_MAX_PATH_LEN, "%s/%s", str_name, 01806 curr->name.name); 01807 01808 if((curr->attributes.type == FSAL_TYPE_LNK) && (flag_l)) 01809 { 01810 01811 if(FSAL_IS_ERROR 01812 (st = 01813 FSAL_readlink(&curr->handle, &context->context, &symlink_path, 01814 NULL))) 01815 { 01816 fprintf(output, "Error executing FSAL_readlink:"); 01817 print_fsal_status(output, st); 01818 fprintf(output, "\n"); 01819 return st.major; 01820 } 01821 01822 } 01823 01824 if(flag_l) 01825 print_item_line(output, &(curr->attributes), item_path, 01826 symlink_path.path); 01827 01828 else if(flag_S) 01829 { 01830 01831 char tracebuff[2 * sizeof(fsal_handle_t) + 1]; 01832 snprintHandle(tracebuff, 2 * sizeof(fsal_handle_t) + 1, &curr->handle); 01833 01834 fprintf(output, "%s (@%s):\n", item_path, tracebuff); 01835 print_fsal_attributes(curr->attributes, output); 01836 01837 } 01838 else /* only prints the name */ 01839 fprintf(output, "%s\n", item_path); 01840 01841 } 01842 while((curr = curr->nextentry)); 01843 } 01844 /* preparing next call */ 01845 from = to; 01846 01847 } 01848 01849 FSAL_closedir(&dir); 01850 01851 return error; 01852 01853 } /* fn_fsal_ls */ 01854 01856 int fn_fsal_callstat(int argc, /* IN : number of args in argv */ 01857 char **argv, /* IN : arg list */ 01858 FILE * output /* IN : output stream */ 01859 ) 01860 { 01861 01862 fsal_statistics_t call_stat; 01863 int i; 01864 01865 const char help_stats[] = "usage: stats\n"; 01866 01867 /* is the fs initialized ? */ 01868 if(!is_loaded) 01869 { 01870 fprintf(output, "Error: filesystem not initialized\n"); 01871 return -1; 01872 } 01873 01874 /* No args expected */ 01875 if(argc != 1) 01876 { 01877 fprintf(output, help_stats); 01878 return -1; 01879 } 01880 01881 /* retrieving current thread stats */ 01882 FSAL_get_stats(&call_stat, FALSE); 01883 01884 /* displaying stats */ 01885 /* header: */ 01886 fprintf(output, 01887 "Function | Nb_Calls | Success | Retryable | Unrecoverable\n"); 01888 /* content */ 01889 for(i = 0; i < FSAL_NB_FUNC; i++) 01890 fprintf(output, "%-20s | %11u | %11u | %11u | %11u\n", 01891 fsal_function_names[i], 01892 call_stat.func_stats.nb_call[i], 01893 call_stat.func_stats.nb_success[i], 01894 call_stat.func_stats.nb_err_retryable[i], 01895 call_stat.func_stats.nb_err_unrecover[i]); 01896 01897 return 0; 01898 } 01899 01901 int fn_fsal_su(int argc, /* IN : number of args in argv */ 01902 char **argv, /* IN : arg list */ 01903 FILE * output /* IN : output stream */ 01904 ) 01905 { 01906 01907 char *str_uid; 01908 fsal_uid_t uid; 01909 fsal_status_t st; 01910 struct passwd *pw_struct; 01911 int i; 01912 01913 # define MAX_GRPS 128 01914 gid_t groups_tab[MAX_GRPS]; 01915 int nb_grp; 01916 01917 const char help_stats[] = "usage: su <uid>\n"; 01918 01919 cmdfsal_thr_info_t *context; 01920 01921 /* is the fs initialized ? */ 01922 if(!is_loaded) 01923 { 01924 fprintf(output, "Error: filesystem not initialized\n"); 01925 return -1; 01926 } 01927 01928 /* initialize current thread */ 01929 01930 context = GetFSALCmdContext(); 01931 01932 if(context->is_thread_ok != TRUE) 01933 { 01934 int rc; 01935 rc = Init_Thread_Context(output, context, 0); 01936 if(rc != 0) 01937 return rc; 01938 } 01939 01940 /* UID arg expected */ 01941 if(argc != 2) 01942 { 01943 fprintf(output, help_stats); 01944 return -1; 01945 } 01946 else 01947 { 01948 str_uid = argv[1]; 01949 } 01950 01951 if(isdigit(str_uid[0])) 01952 { 01953 if((uid = my_atoi(str_uid)) == (uid_t) - 1) 01954 { 01955 fprintf(output, "Error: invalid uid \"%s\"\n", str_uid); 01956 return -1; 01957 } 01958 pw_struct = getpwuid(uid); 01959 } 01960 else 01961 { 01962 pw_struct = getpwnam(str_uid); 01963 } 01964 01965 if(pw_struct == NULL) 01966 { 01967 fprintf(output, "Unknown user %s\n", str_uid); 01968 return errno; 01969 } 01970 01971 nb_grp = getugroups(MAX_GRPS, groups_tab, pw_struct->pw_name, pw_struct->pw_gid); 01972 01973 fprintf(output, "Changing user to : %s ( uid = %d, gid = %d )\n", 01974 pw_struct->pw_name, pw_struct->pw_uid, pw_struct->pw_gid); 01975 01976 if(nb_grp > 1) 01977 { 01978 fprintf(output, "altgroups = "); 01979 for(i = 1; i < nb_grp; i++) 01980 { 01981 if(i == 1) 01982 fprintf(output, "%d", groups_tab[i]); 01983 else 01984 fprintf(output, ", %d", groups_tab[i]); 01985 } 01986 fprintf(output, "\n"); 01987 } 01988 01989 st = FSAL_GetClientContext(&context->context, &context->exp_context, 01990 pw_struct->pw_uid, pw_struct->pw_gid, groups_tab, nb_grp); 01991 01992 if(FSAL_IS_ERROR(st)) 01993 { 01994 fprintf(output, "Error executing FSAL_GetUserCred:"); 01995 print_fsal_status(output, st); 01996 fprintf(output, "\n"); 01997 return st.major; 01998 } 01999 02000 fprintf(output, "Done.\n"); 02001 02002 return 0; 02003 02004 } 02005 02007 int fn_fsal_unlink(int argc, /* IN : number of args in argv */ 02008 char **argv, /* IN : arg list */ 02009 FILE * output /* IN : output stream */ 02010 ) 02011 { 02012 02013 char format[] = "hv"; 02014 02015 const char help_unlink[] = "usage: unlink [-h][-v] <path>\n"; 02016 02017 char glob_path[FSAL_MAX_PATH_LEN]; 02018 fsal_handle_t new_hdl; 02019 fsal_status_t st; 02020 int rc, option; 02021 int flag_v = 0; 02022 int flag_h = 0; 02023 int err_flag = 0; 02024 02025 char tmp_path[FSAL_MAX_PATH_LEN]; 02026 char *path; 02027 char *file; 02028 02029 fsal_name_t objname; 02030 02031 cmdfsal_thr_info_t *context; 02032 02033 /* is the fs initialized ? */ 02034 if(!is_loaded) 02035 { 02036 fprintf(output, "Error: filesystem not initialized\n"); 02037 return -1; 02038 } 02039 02040 /* initialize current thread */ 02041 02042 context = GetFSALCmdContext(); 02043 02044 if(context->is_thread_ok != TRUE) 02045 { 02046 int rc; 02047 rc = Init_Thread_Context(output, context, 0); 02048 if(rc != 0) 02049 return rc; 02050 } 02051 02052 /* analysing options */ 02053 getopt_init(); 02054 while((option = Getopt(argc, argv, format)) != -1) 02055 { 02056 switch (option) 02057 { 02058 case 'v': 02059 if(flag_v) 02060 fprintf(output, 02061 "unlink: warning: option 'v' has been specified more than once.\n"); 02062 else 02063 flag_v++; 02064 break; 02065 case 'h': 02066 if(flag_h) 02067 fprintf(output, 02068 "unlink: warning: option 'h' has been specified more than once.\n"); 02069 else 02070 flag_h++; 02071 break; 02072 case '?': 02073 fprintf(output, "unlink: unknown option : %c\n", Optopt); 02074 err_flag++; 02075 break; 02076 } 02077 } 02078 02079 if(flag_h) 02080 { 02081 fprintf(output, help_unlink); 02082 return 0; 02083 } 02084 02085 /* Exactly 1 args expected */ 02086 if(Optind != (argc - 1)) 02087 { 02088 err_flag++; 02089 } 02090 else 02091 { 02092 strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN); 02093 split_path(tmp_path, &path, &file); 02094 } 02095 02096 if(err_flag) 02097 { 02098 fprintf(output, help_unlink); 02099 return -1; 02100 } 02101 02102 /* copy current path. */ 02103 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02104 02105 /* retrieves path handle */ 02106 if((rc = 02107 solvepath(glob_path, FSAL_MAX_PATH_LEN, 02108 path, context->current_dir, &new_hdl, output))) 02109 return rc; 02110 02111 /* create fsal_name_t */ 02112 st = FSAL_str2name(file, 256, &objname); 02113 if(FSAL_IS_ERROR(st)) 02114 { 02115 fprintf(output, "Error executing FSAL_str2name:"); 02116 print_fsal_status(output, st); 02117 fprintf(output, "\n"); 02118 return st.major; 02119 } 02120 02121 if(FSAL_IS_ERROR(st = FSAL_unlink(&new_hdl, &objname, &context->context, NULL))) 02122 { 02123 fprintf(output, "Error executing FSAL_unlink:"); 02124 print_fsal_status(output, st); 02125 fprintf(output, "\n"); 02126 return st.major; 02127 } 02128 02129 if(flag_v) 02130 fprintf(output, "%s/%s successfully unlinked\n", glob_path, file); 02131 02132 return 0; 02133 02134 } 02135 02137 int fn_fsal_mkdir(int argc, /* IN : number of args in argv */ 02138 char **argv, /* IN : arg list */ 02139 FILE * output /* IN : output stream */ 02140 ) 02141 { 02142 02143 char format[] = "hv"; 02144 02145 const char help_mkdir[] = 02146 "usage: mkdir [-h][-v] <path> <mode>\n" 02147 " path: path of the directory to be created\n" 02148 " mode: octal mode for the directory is to be created (ex: 755)\n"; 02149 02150 char glob_path[FSAL_MAX_PATH_LEN]; 02151 fsal_handle_t new_hdl, subdir_hdl; 02152 fsal_status_t st; 02153 int rc, option; 02154 int flag_v = 0; 02155 int flag_h = 0; 02156 int err_flag = 0; 02157 int mode; 02158 fsal_accessmode_t fsalmode = 0755; 02159 02160 char tmp_path[FSAL_MAX_PATH_LEN]; 02161 char *path; 02162 char *file; 02163 char *strmode; 02164 02165 fsal_name_t objname; 02166 02167 cmdfsal_thr_info_t *context; 02168 02169 /* is the fs initialized ? */ 02170 if(!is_loaded) 02171 { 02172 fprintf(output, "Error: filesystem not initialized\n"); 02173 return -1; 02174 } 02175 02176 /* initialize current thread */ 02177 02178 context = GetFSALCmdContext(); 02179 02180 if(context->is_thread_ok != TRUE) 02181 { 02182 int rc; 02183 rc = Init_Thread_Context(output, context, 0); 02184 if(rc != 0) 02185 return rc; 02186 } 02187 02188 /* analysing options */ 02189 getopt_init(); 02190 while((option = Getopt(argc, argv, format)) != -1) 02191 { 02192 switch (option) 02193 { 02194 case 'v': 02195 if(flag_v) 02196 fprintf(output, 02197 "mkdir: warning: option 'v' has been specified more than once.\n"); 02198 else 02199 flag_v++; 02200 break; 02201 case 'h': 02202 if(flag_h) 02203 fprintf(output, 02204 "mkdir: warning: option 'h' has been specified more than once.\n"); 02205 else 02206 flag_h++; 02207 break; 02208 case '?': 02209 fprintf(output, "mkdir: unknown option : %c\n", Optopt); 02210 err_flag++; 02211 break; 02212 } 02213 } 02214 02215 if(flag_h) 02216 { 02217 fprintf(output, help_mkdir); 02218 return 0; 02219 } 02220 02221 /* Exactly 2 args expected */ 02222 if(Optind != (argc - 2)) 02223 { 02224 err_flag++; 02225 } 02226 else 02227 { 02228 02229 strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN); 02230 split_path(tmp_path, &path, &file); 02231 02232 strmode = argv[Optind + 1]; 02233 02234 /* converting mode string to FSAL mode string */ 02235 mode = atomode(strmode); 02236 if(mode < 0) 02237 err_flag++; 02238 else 02239 { 02240 02241 fsalmode = 0; 02242 02243 if(mode & S_ISUID) 02244 fsalmode |= FSAL_MODE_SUID; 02245 if(mode & S_ISGID) 02246 fsalmode |= FSAL_MODE_SGID; 02247 02248 if(mode & S_IRUSR) 02249 fsalmode |= FSAL_MODE_RUSR; 02250 if(mode & S_IWUSR) 02251 fsalmode |= FSAL_MODE_WUSR; 02252 if(mode & S_IXUSR) 02253 fsalmode |= FSAL_MODE_XUSR; 02254 02255 if(mode & S_IRGRP) 02256 fsalmode |= FSAL_MODE_RGRP; 02257 if(mode & S_IWGRP) 02258 fsalmode |= FSAL_MODE_WGRP; 02259 if(mode & S_IXGRP) 02260 fsalmode |= FSAL_MODE_XGRP; 02261 02262 if(mode & S_IROTH) 02263 fsalmode |= FSAL_MODE_ROTH; 02264 if(mode & S_IWOTH) 02265 fsalmode |= FSAL_MODE_WOTH; 02266 if(mode & S_IXOTH) 02267 fsalmode |= FSAL_MODE_XOTH; 02268 02269 } 02270 02271 } 02272 02273 if(err_flag) 02274 { 02275 fprintf(output, help_mkdir); 02276 return -1; 02277 } 02278 02279 /* copy current path. */ 02280 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02281 02282 /* retrieves path handle */ 02283 if((rc = 02284 solvepath(glob_path, FSAL_MAX_PATH_LEN, 02285 path, context->current_dir, &new_hdl, output))) 02286 return rc; 02287 02288 /* create fsal_name_t */ 02289 st = FSAL_str2name(file, 256, &objname); 02290 if(FSAL_IS_ERROR(st)) 02291 { 02292 fprintf(output, "Error executing FSAL_str2name:"); 02293 print_fsal_status(output, st); 02294 fprintf(output, "\n"); 02295 return st.major; 02296 } 02297 02298 if(FSAL_IS_ERROR(st = FSAL_mkdir(&new_hdl, &objname, &context->context, 02299 fsalmode, &subdir_hdl, NULL))) 02300 { 02301 fprintf(output, "Error executing FSAL_mkdir:"); 02302 print_fsal_status(output, st); 02303 fprintf(output, "\n"); 02304 return st.major; 02305 } 02306 02307 if(flag_v) 02308 { 02309 char buff[2 * sizeof(fsal_handle_t) + 1]; 02310 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &subdir_hdl); 02311 02312 fprintf(output, "%s/%s successfully created (@%s) \n", glob_path, file, buff); 02313 02314 } 02315 02316 return 0; 02317 02318 } 02319 02321 int fn_fsal_rename(int argc, /* IN : number of args in argv */ 02322 char **argv, /* IN : arg list */ 02323 FILE * output /* IN : output stream */ 02324 ) 02325 { 02326 02327 char format[] = "hv"; 02328 02329 const char help_rename[] = "usage: rename [-h][-v] <src> <dest>\n"; 02330 02331 char src_glob_path[FSAL_MAX_PATH_LEN]; 02332 char tgt_glob_path[FSAL_MAX_PATH_LEN]; 02333 02334 fsal_handle_t src_path_handle, tgt_path_handle; 02335 fsal_name_t src_name, tgt_name; 02336 02337 fsal_status_t st; 02338 int rc, option; 02339 int flag_v = 0; 02340 int flag_h = 0; 02341 int err_flag = 0; 02342 02343 char tmp_path1[FSAL_MAX_PATH_LEN]; 02344 char tmp_path2[FSAL_MAX_PATH_LEN]; 02345 char *src_path; 02346 char *src_file; 02347 char *tgt_path; 02348 char *tgt_file; 02349 02350 cmdfsal_thr_info_t *context; 02351 02352 /* is the fs initialized ? */ 02353 if(!is_loaded) 02354 { 02355 fprintf(output, "Error: filesystem not initialized\n"); 02356 return -1; 02357 } 02358 02359 /* initialize current thread */ 02360 02361 context = GetFSALCmdContext(); 02362 02363 if(context->is_thread_ok != TRUE) 02364 { 02365 int rc; 02366 rc = Init_Thread_Context(output, context, 0); 02367 if(rc != 0) 02368 return rc; 02369 } 02370 02371 /* analysing options */ 02372 getopt_init(); 02373 while((option = Getopt(argc, argv, format)) != -1) 02374 { 02375 switch (option) 02376 { 02377 case 'v': 02378 if(flag_v) 02379 fprintf(output, 02380 "rename: warning: option 'v' has been specified more than once.\n"); 02381 else 02382 flag_v++; 02383 break; 02384 case 'h': 02385 if(flag_h) 02386 fprintf(output, 02387 "rename: warning: option 'h' has been specified more than once.\n"); 02388 else 02389 flag_h++; 02390 break; 02391 case '?': 02392 fprintf(output, "rename: unknown option : %c\n", Optopt); 02393 err_flag++; 02394 break; 02395 } 02396 } 02397 02398 if(flag_h) 02399 { 02400 fprintf(output, help_rename); 02401 return 0; 02402 } 02403 02404 /* Exactly 2 args expected */ 02405 if(Optind != (argc - 2)) 02406 { 02407 err_flag++; 02408 } 02409 else 02410 { 02411 02412 strncpy(tmp_path1, argv[Optind], FSAL_MAX_PATH_LEN); 02413 split_path(tmp_path1, &src_path, &src_file); 02414 02415 strncpy(tmp_path2, argv[Optind + 1], FSAL_MAX_PATH_LEN); 02416 split_path(tmp_path2, &tgt_path, &tgt_file); 02417 02418 } 02419 02420 if(err_flag) 02421 { 02422 fprintf(output, help_rename); 02423 return -1; 02424 } 02425 02426 if(flag_v) 02427 fprintf(output, "Renaming %s (dir %s) to %s (dir %s)\n", 02428 src_file, src_path, tgt_file, tgt_path); 02429 02430 /* copy current path. */ 02431 strncpy(src_glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02432 strncpy(tgt_glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02433 02434 /* retrieves paths handles */ 02435 if((rc = 02436 solvepath(src_glob_path, FSAL_MAX_PATH_LEN, 02437 src_path, context->current_dir, &src_path_handle, output))) 02438 return rc; 02439 02440 if((rc = 02441 solvepath(tgt_glob_path, FSAL_MAX_PATH_LEN, 02442 tgt_path, context->current_dir, &tgt_path_handle, output))) 02443 return rc; 02444 02445 /* create fsal_name_t */ 02446 02447 st = FSAL_str2name(src_file, 256, &src_name); 02448 02449 if(FSAL_IS_ERROR(st)) 02450 { 02451 02452 fprintf(output, "Error executing FSAL_str2name:"); 02453 print_fsal_status(output, st); 02454 fprintf(output, "\n"); 02455 return st.major; 02456 02457 } 02458 02459 st = FSAL_str2name(tgt_file, 256, &tgt_name); 02460 02461 if(FSAL_IS_ERROR(st)) 02462 { 02463 02464 fprintf(output, "Error executing FSAL_str2name:"); 02465 print_fsal_status(output, st); 02466 fprintf(output, "\n"); 02467 return st.major; 02468 02469 } 02470 02471 /* Rename operation */ 02472 02473 st = FSAL_rename(&src_path_handle, /* IN */ 02474 &src_name, /* IN */ 02475 &tgt_path_handle, /* IN */ 02476 &tgt_name, /* IN */ 02477 &context->context, /* IN */ 02478 NULL, NULL); 02479 02480 if(FSAL_IS_ERROR(st)) 02481 { 02482 02483 fprintf(output, "Error executing FSAL_rename:"); 02484 print_fsal_status(output, st); 02485 fprintf(output, "\n"); 02486 return st.major; 02487 02488 } 02489 02490 if(flag_v) 02491 fprintf(output, "%s/%s successfully renamed to %s/%s\n", 02492 src_glob_path, src_file, tgt_glob_path, tgt_file); 02493 02494 return 0; 02495 02496 } 02497 02499 int fn_fsal_ln(int argc, /* IN : number of args in argv */ 02500 char **argv, /* IN : arg list */ 02501 FILE * output /* IN : output stream */ 02502 ) 02503 { 02504 02505 char format[] = "hv"; 02506 02507 const char help_ln[] = 02508 "ln: create a symbolic link.\n" 02509 "usage: ln [-h][-v] <link_content> <link_path>\n" 02510 " link_content: content of the symbolic link to be created\n" 02511 " link_path: path of the symbolic link to be created\n"; 02512 02513 char glob_path[FSAL_MAX_PATH_LEN]; 02514 fsal_handle_t path_hdl, link_hdl; 02515 fsal_status_t st; 02516 int rc, option; 02517 int flag_v = 0; 02518 int flag_h = 0; 02519 int err_flag = 0; 02520 02521 char *content = NULL; 02522 char tmp_path[FSAL_MAX_PATH_LEN]; 02523 char *path; 02524 char *name; 02525 02526 fsal_name_t objname; 02527 fsal_path_t objcontent; 02528 02529 cmdfsal_thr_info_t *context; 02530 02531 /* is the fs initialized ? */ 02532 if(!is_loaded) 02533 { 02534 fprintf(output, "Error: filesystem not initialized\n"); 02535 return -1; 02536 } 02537 02538 /* initialize current thread */ 02539 02540 context = GetFSALCmdContext(); 02541 02542 if(context->is_thread_ok != TRUE) 02543 { 02544 int rc; 02545 rc = Init_Thread_Context(output, context, 0); 02546 if(rc != 0) 02547 return rc; 02548 } 02549 02550 /* analysing options */ 02551 getopt_init(); 02552 while((option = Getopt(argc, argv, format)) != -1) 02553 { 02554 switch (option) 02555 { 02556 case 'v': 02557 if(flag_v) 02558 fprintf(output, 02559 "ln: warning: option 'v' has been specified more than once.\n"); 02560 else 02561 flag_v++; 02562 break; 02563 case 'h': 02564 if(flag_h) 02565 fprintf(output, 02566 "ln: warning: option 'h' has been specified more than once.\n"); 02567 else 02568 flag_h++; 02569 break; 02570 case '?': 02571 fprintf(output, "ln: unknown option : %c\n", Optopt); 02572 err_flag++; 02573 break; 02574 } 02575 } 02576 02577 if(flag_h) 02578 { 02579 fprintf(output, help_ln); 02580 return 0; 02581 } 02582 02583 /* 2 args expected */ 02584 02585 if(Optind == (argc - 2)) 02586 { 02587 02588 content = argv[Optind]; 02589 02590 strncpy(tmp_path, argv[Optind + 1], FSAL_MAX_PATH_LEN); 02591 split_path(tmp_path, &path, &name); 02592 02593 } 02594 else 02595 { 02596 err_flag++; 02597 } 02598 02599 if(err_flag) 02600 { 02601 fprintf(output, help_ln); 02602 return -1; 02603 } 02604 02605 /* copy current path. */ 02606 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02607 02608 /* retrieves path handle */ 02609 if((rc = 02610 solvepath(glob_path, FSAL_MAX_PATH_LEN, 02611 path, context->current_dir, &path_hdl, output))) 02612 return rc; 02613 02614 /* create fsal_name_t */ 02615 st = FSAL_str2name(name, 256, &objname); 02616 02617 if(FSAL_IS_ERROR(st)) 02618 { 02619 fprintf(output, "Error executing FSAL_str2name:"); 02620 print_fsal_status(output, st); 02621 fprintf(output, "\n"); 02622 return st.major; 02623 } 02624 02625 /* create fsal_path_t */ 02626 st = FSAL_str2path(content, 256, &objcontent); 02627 02628 if(FSAL_IS_ERROR(st)) 02629 { 02630 fprintf(output, "Error executing FSAL_str2path:"); 02631 print_fsal_status(output, st); 02632 fprintf(output, "\n"); 02633 return st.major; 02634 } 02635 02636 st = FSAL_symlink(&path_hdl, /* IN - parent dir handle */ 02637 &objname, /* IN - link name */ 02638 &objcontent, /* IN - link content */ 02639 &context->context, /* IN - user contexte */ 02640 0777, /* IN (ignored) */ 02641 &link_hdl, /* OUT - link handle */ 02642 NULL); /* OUT - link attributes */ 02643 02644 if(FSAL_IS_ERROR(st)) 02645 { 02646 fprintf(output, "Error executing FSAL_symlink:"); 02647 print_fsal_status(output, st); 02648 fprintf(output, "\n"); 02649 return st.major; 02650 } 02651 02652 if(flag_v) 02653 { 02654 char buff[2 * sizeof(fsal_handle_t) + 1]; 02655 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &link_hdl); 02656 02657 fprintf(output, "%s/%s -> %s successfully created (@%s) \n", path, name, content, 02658 buff); 02659 02660 } 02661 02662 return 0; 02663 02664 } 02665 02667 int fn_fsal_hardlink(int argc, /* IN : number of args in argv */ 02668 char **argv, /* IN : arg list */ 02669 FILE * output /* IN : output stream */ 02670 ) 02671 { 02672 02673 char format[] = "hv"; 02674 02675 const char help_hardlink[] = 02676 "hardlink: create a hard link.\n" 02677 "usage: hardlink [-h][-v] <target> <new_path>\n" 02678 " target: path of an existing file.\n" 02679 " new_path: path of the hardlink to be created\n"; 02680 02681 char glob_path_target[FSAL_MAX_PATH_LEN]; 02682 char glob_path_link[FSAL_MAX_PATH_LEN]; 02683 02684 fsal_handle_t target_hdl, dir_hdl; 02685 fsal_name_t link_name; 02686 02687 fsal_status_t st; 02688 int rc, option; 02689 int flag_v = 0; 02690 int flag_h = 0; 02691 int err_flag = 0; 02692 02693 char *target = NULL; 02694 02695 char tmp_path[FSAL_MAX_PATH_LEN]; 02696 char *path; 02697 char *name; 02698 02699 cmdfsal_thr_info_t *context; 02700 02701 /* is the fs initialized ? */ 02702 if(!is_loaded) 02703 { 02704 fprintf(output, "Error: filesystem not initialized\n"); 02705 return -1; 02706 } 02707 02708 /* initialize current thread */ 02709 02710 context = GetFSALCmdContext(); 02711 02712 if(context->is_thread_ok != TRUE) 02713 { 02714 int rc; 02715 rc = Init_Thread_Context(output, context, 0); 02716 if(rc != 0) 02717 return rc; 02718 } 02719 02720 /* analysing options */ 02721 getopt_init(); 02722 while((option = Getopt(argc, argv, format)) != -1) 02723 { 02724 switch (option) 02725 { 02726 case 'v': 02727 if(flag_v) 02728 fprintf(output, 02729 "hardlink: warning: option 'v' has been specified more than once.\n"); 02730 else 02731 flag_v++; 02732 break; 02733 case 'h': 02734 if(flag_h) 02735 fprintf(output, 02736 "hardlink: warning: option 'h' has been specified more than once.\n"); 02737 else 02738 flag_h++; 02739 break; 02740 case '?': 02741 fprintf(output, "hardlink: unknown option : %c\n", Optopt); 02742 err_flag++; 02743 break; 02744 } 02745 } 02746 02747 if(flag_h) 02748 { 02749 fprintf(output, help_hardlink); 02750 return 0; 02751 } 02752 02753 /* 2 args expected */ 02754 02755 if(Optind == (argc - 2)) 02756 { 02757 02758 target = argv[Optind]; 02759 02760 strncpy(tmp_path, argv[Optind + 1], FSAL_MAX_PATH_LEN); 02761 split_path(tmp_path, &path, &name); 02762 02763 } 02764 else 02765 { 02766 err_flag++; 02767 } 02768 02769 if(err_flag) 02770 { 02771 fprintf(output, help_hardlink); 02772 return -1; 02773 } 02774 02775 /* copy current path. */ 02776 strncpy(glob_path_target, context->current_path, FSAL_MAX_PATH_LEN); 02777 strncpy(glob_path_link, context->current_path, FSAL_MAX_PATH_LEN); 02778 02779 /* retrieves path handle for target */ 02780 if((rc = 02781 solvepath(glob_path_target, FSAL_MAX_PATH_LEN, 02782 target, context->current_dir, &target_hdl, output))) 02783 return rc; 02784 02785 /* retrieves path handle for parent dir */ 02786 if((rc = 02787 solvepath(glob_path_link, FSAL_MAX_PATH_LEN, 02788 path, context->current_dir, &dir_hdl, output))) 02789 return rc; 02790 02791 /* create fsal_name_t */ 02792 st = FSAL_str2name(name, 256, &link_name); 02793 02794 if(FSAL_IS_ERROR(st)) 02795 { 02796 fprintf(output, "Error executing FSAL_str2name:"); 02797 print_fsal_status(output, st); 02798 fprintf(output, "\n"); 02799 return st.major; 02800 } 02801 02802 st = FSAL_link(&target_hdl, /* IN - target file */ 02803 &dir_hdl, /* IN - parent dir handle */ 02804 &link_name, /* IN - link name */ 02805 &context->context, /* IN - user contexte */ 02806 NULL); /* OUT - new attributes */ 02807 02808 if(FSAL_IS_ERROR(st)) 02809 { 02810 fprintf(output, "Error executing FSAL_link:"); 02811 print_fsal_status(output, st); 02812 fprintf(output, "\n"); 02813 return st.major; 02814 } 02815 02816 if(flag_v) 02817 { 02818 fprintf(output, "%s/%s <=> %s successfully created\n", path, name, 02819 glob_path_target); 02820 02821 } 02822 02823 return 0; 02824 02825 } 02826 02828 int fn_fsal_create(int argc, /* IN : number of args in argv */ 02829 char **argv, /* IN : arg list */ 02830 FILE * output /* IN : output stream */ 02831 ) 02832 { 02833 02834 char format[] = "hv"; 02835 02836 const char help_create[] = 02837 "usage: create [-h][-v] <path> <mode>\n" 02838 " path: path of the file to be created\n" 02839 " mode: octal access mode for the file to be created (ex: 644)\n"; 02840 02841 char glob_path_dir[FSAL_MAX_PATH_LEN]; 02842 fsal_handle_t dir_hdl, file_hdl; 02843 02844 fsal_status_t st; 02845 int rc, option; 02846 int flag_v = 0; 02847 int flag_h = 0; 02848 int err_flag = 0; 02849 int mode; 02850 fsal_accessmode_t fsalmode = 0644; 02851 02852 char tmp_path[FSAL_MAX_PATH_LEN]; 02853 char *path; 02854 char *file; 02855 char *strmode; 02856 02857 fsal_name_t objname; 02858 02859 cmdfsal_thr_info_t *context; 02860 02861 /* is the fs initialized ? */ 02862 if(!is_loaded) 02863 { 02864 fprintf(output, "Error: filesystem not initialized\n"); 02865 return -1; 02866 } 02867 02868 /* initialize current thread */ 02869 02870 context = GetFSALCmdContext(); 02871 02872 if(context->is_thread_ok != TRUE) 02873 { 02874 int rc; 02875 rc = Init_Thread_Context(output, context, 0); 02876 if(rc != 0) 02877 return rc; 02878 } 02879 02880 /* analysing options */ 02881 getopt_init(); 02882 while((option = Getopt(argc, argv, format)) != -1) 02883 { 02884 switch (option) 02885 { 02886 case 'v': 02887 if(flag_v) 02888 fprintf(output, 02889 "create: warning: option 'v' has been specified more than once.\n"); 02890 else 02891 flag_v++; 02892 break; 02893 case 'h': 02894 if(flag_h) 02895 fprintf(output, 02896 "create: warning: option 'h' has been specified more than once.\n"); 02897 else 02898 flag_h++; 02899 break; 02900 case '?': 02901 fprintf(output, "create: unknown option : %c\n", Optopt); 02902 err_flag++; 02903 break; 02904 } 02905 } 02906 02907 if(flag_h) 02908 { 02909 fprintf(output, help_create); 02910 return 0; 02911 } 02912 02913 /* Exactly 2 args expected */ 02914 if(Optind != (argc - 2)) 02915 { 02916 err_flag++; 02917 } 02918 else 02919 { 02920 02921 strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN); 02922 split_path(tmp_path, &path, &file); 02923 02924 strmode = argv[Optind + 1]; 02925 02926 /* converting mode string to FSAL mode string */ 02927 mode = atomode(strmode); 02928 if(mode < 0) 02929 err_flag++; 02930 else 02931 { 02932 02933 fsalmode = 0; 02934 02935 if(mode & S_ISUID) 02936 fsalmode |= FSAL_MODE_SUID; 02937 if(mode & S_ISGID) 02938 fsalmode |= FSAL_MODE_SGID; 02939 02940 if(mode & S_IRUSR) 02941 fsalmode |= FSAL_MODE_RUSR; 02942 if(mode & S_IWUSR) 02943 fsalmode |= FSAL_MODE_WUSR; 02944 if(mode & S_IXUSR) 02945 fsalmode |= FSAL_MODE_XUSR; 02946 02947 if(mode & S_IRGRP) 02948 fsalmode |= FSAL_MODE_RGRP; 02949 if(mode & S_IWGRP) 02950 fsalmode |= FSAL_MODE_WGRP; 02951 if(mode & S_IXGRP) 02952 fsalmode |= FSAL_MODE_XGRP; 02953 02954 if(mode & S_IROTH) 02955 fsalmode |= FSAL_MODE_ROTH; 02956 if(mode & S_IWOTH) 02957 fsalmode |= FSAL_MODE_WOTH; 02958 if(mode & S_IXOTH) 02959 fsalmode |= FSAL_MODE_XOTH; 02960 02961 } 02962 02963 } 02964 02965 if(err_flag) 02966 { 02967 fprintf(output, help_create); 02968 return -1; 02969 } 02970 02971 /* copy current path. */ 02972 strncpy(glob_path_dir, context->current_path, FSAL_MAX_PATH_LEN); 02973 02974 /* retrieves path handle */ 02975 if((rc = 02976 solvepath(glob_path_dir, FSAL_MAX_PATH_LEN, 02977 path, context->current_dir, &dir_hdl, output))) 02978 return rc; 02979 02980 /* create fsal_name_t */ 02981 st = FSAL_str2name(file, 256, &objname); 02982 if(FSAL_IS_ERROR(st)) 02983 { 02984 fprintf(output, "Error executing FSAL_str2name:"); 02985 print_fsal_status(output, st); 02986 fprintf(output, "\n"); 02987 return st.major; 02988 } 02989 02990 st = FSAL_create(&dir_hdl, /* IN */ 02991 &objname, /* IN */ 02992 &context->context, /* IN */ 02993 fsalmode, /* IN */ 02994 &file_hdl, /* OUT */ 02995 /*&context->current_fd, *//* OUT */ 02996 NULL /* [ IN/OUT ] */ 02997 ); 02998 02999 if(FSAL_IS_ERROR(st)) 03000 { 03001 fprintf(output, "Error executing FSAL_create:"); 03002 print_fsal_status(output, st); 03003 fprintf(output, "\n"); 03004 return st.major; 03005 } 03006 03007 if(flag_v) 03008 { 03009 char buff[2 * sizeof(fsal_handle_t) + 1]; 03010 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &file_hdl); 03011 03012 fprintf(output, "%s/%s successfully created (@%s) \n", glob_path_dir, file, buff); 03013 03014 } 03015 03016 return 0; 03017 03018 } 03019 03020 /* setattr 03021 * 03022 * syntax of command line: 03023 * setattr file_path attribute_name attribute_value 03024 * 03025 */ 03026 int fn_fsal_setattr(int argc, /* IN : number of args in argv */ 03027 char **argv, /* IN : arg list */ 03028 FILE * output /* IN : output stream */ 03029 ) 03030 { 03031 03032 char format[] = "hv"; 03033 03034 const char help_setattr[] = 03035 "usage: setattr [-h][-v] <path> <attr>=<value>,<attr>=<value>,...\n"; 03036 03037 char glob_path[FSAL_MAX_PATH_LEN]; /* absolute path of the object */ 03038 fsal_handle_t obj_hdl; /* handle of the object */ 03039 fsal_attrib_list_t set_attrs; /* attributes to be setted */ 03040 fsal_status_t st; /* FSAL return status */ 03041 03042 int rc, option; 03043 int flag_v = 0; 03044 int flag_h = 0; 03045 int err_flag = 0; 03046 03047 char *file = NULL; /* the relative path to the object */ 03048 char *attr_list = NULL; /* attribute list */ 03049 03050 cmdfsal_thr_info_t *context; 03051 03052 /* is the fs initialized ? */ 03053 if(!is_loaded) 03054 { 03055 fprintf(output, "Error: filesystem not initialized\n"); 03056 return -1; 03057 } 03058 03059 /* initialize current thread */ 03060 03061 context = GetFSALCmdContext(); 03062 03063 if(context->is_thread_ok != TRUE) 03064 { 03065 int rc; 03066 rc = Init_Thread_Context(output, context, 0); 03067 if(rc != 0) 03068 return rc; 03069 } 03070 03071 /* analysing options */ 03072 03073 getopt_init(); 03074 while((option = Getopt(argc, argv, format)) != -1) 03075 { 03076 switch (option) 03077 { 03078 03079 case 'v': 03080 if(flag_v) 03081 fprintf(output, 03082 "setattr: warning: option 'v' has been specified more than once.\n"); 03083 else 03084 flag_v++; 03085 break; 03086 03087 case 'h': 03088 if(flag_h) 03089 fprintf(output, 03090 "setattr: warning: option 'h' has been specified more than once.\n"); 03091 else 03092 flag_h++; 03093 break; 03094 03095 case '?': 03096 fprintf(output, "setattr: unknown option : %c\n", Optopt); 03097 err_flag++; 03098 break; 03099 } 03100 } 03101 03102 if(flag_h) 03103 { 03104 03105 shell_attribute_t *curr_attr; 03106 03107 /* print usage */ 03108 fprintf(output, help_setattr); 03109 03110 fprintf(output, "\n<attr> can be one of the following values:\n"); 03111 03112 /* print attribute list */ 03113 03114 for(curr_attr = shell_attr_list; curr_attr->attr_type != ATTR_NONE; curr_attr++) 03115 { 03116 switch (curr_attr->attr_type) 03117 { 03118 case ATTR_32: 03119 fprintf(output, "\t %s \t:\t 32 bits integer\n", curr_attr->attr_name); 03120 break; 03121 case ATTR_64: 03122 fprintf(output, "\t %s \t:\t 64 bits integer\n", curr_attr->attr_name); 03123 break; 03124 case ATTR_OCTAL: 03125 fprintf(output, "\t %s \t:\t octal\n", curr_attr->attr_name); 03126 break; 03127 case ATTR_TIME: 03128 fprintf(output, "\t %s \t:\t time (format: YYYYMMDDhhmmss)\n", 03129 curr_attr->attr_name); 03130 break; 03131 default: 03132 break; 03133 } 03134 } 03135 03136 return 0; 03137 } 03138 03139 /* Exactly 2 args expected (path and attributes) */ 03140 03141 if(Optind != (argc - 2)) 03142 { 03143 err_flag++; 03144 } 03145 else 03146 { 03147 file = argv[Optind]; 03148 attr_list = argv[Optind + 1]; 03149 } 03150 03151 if(err_flag) 03152 { 03153 fprintf(output, help_setattr); 03154 return -1; 03155 } 03156 03157 /* copy current absolute path to a local variable. */ 03158 03159 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 03160 03161 /* retrieve handle to the file whose attributes are to be changed */ 03162 03163 rc = solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->current_dir, 03164 &obj_hdl, output); 03165 if(rc) 03166 return rc; 03167 03168 /* Convert the peers (attr_name,attr_val) to an FSAL attribute structure. */ 03169 rc = MkFSALSetAttrStruct(attr_list, &set_attrs); 03170 03171 /* interprets output code */ 03172 switch (rc) 03173 { 03174 case 0: 03175 /* OK */ 03176 break; 03177 03178 case EFAULT: 03179 fprintf(output, "setattr: Internal error.\n"); 03180 return rc; 03181 03182 case ENOENT: 03183 fprintf(output, "setattr: Unknown attribute in list %s\n", attr_list); 03184 return rc; 03185 03186 case EINVAL: 03187 fprintf(output, "setattr: Invalid value for attribute in list %s\n", attr_list); 03188 return rc; 03189 03190 default: 03191 fprintf(output, "setattr: Error %d converting attributes.\n", rc); 03192 return rc; 03193 } 03194 03195 /* if verbose mode is on, we print the attributes to be set */ 03196 if(flag_v) 03197 { 03198 print_fsal_attributes(set_attrs, output); 03199 } 03200 03201 /* executes set attrs */ 03202 03203 st = FSAL_setattrs(&obj_hdl, &context->context, &set_attrs, NULL); 03204 03205 if(FSAL_IS_ERROR(st)) 03206 { 03207 fprintf(output, "Error executing FSAL_setattrs:"); 03208 print_fsal_status(output, st); 03209 fprintf(output, "\n"); 03210 return st.major; 03211 } 03212 03213 return 0; 03214 03215 } 03216 03223 int fn_fsal_access(int argc, /* IN : number of args in argv */ 03224 char **argv, /* IN : arg list */ 03225 FILE * output /* IN : output stream */ 03226 ) 03227 { 03228 03229 char format[] = "hvA"; 03230 03231 const char help_access[] = 03232 "usage: access [-h][-v][-A] <rights> <path>\n" 03233 "\n" 03234 " -h : print this help\n" 03235 " -v : verbose mode\n" 03236 " -A : test access from attributes\n" 03237 " ( call to getattr + test_access instead of access )\n" 03238 "\n" 03239 " <rights> : a set of the following characters:\n" 03240 " F: test file existence\n" 03241 " R: test read permission\n" 03242 " W: test write permission\n" 03243 " X: test execute permission\n" 03244 "\n" 03245 "Example: access -A RX my_dir\n" 03246 "test read and exec rights for directory \"my_dir\"\n" 03247 "by doing a getattr and a test_access call.\n\n"; 03248 03249 char glob_path[FSAL_MAX_PATH_LEN]; /* absolute path of the object */ 03250 fsal_handle_t obj_hdl; /* handle of the object */ 03251 fsal_accessflags_t test_perms; /* permissions to be tested */ 03252 fsal_status_t st; /* FSAL return status */ 03253 03254 int rc, option; 03255 unsigned int i; 03256 int flag_v = 0; 03257 int flag_h = 0; 03258 int flag_A = 0; 03259 int err_flag = 0; 03260 03261 char *file = NULL; /* the relative path to the object */ 03262 char *str_perms = NULL; /* string that represents the permissions to be tested */ 03263 03264 cmdfsal_thr_info_t *context; 03265 03266 /* is the fs initialized ? */ 03267 if(!is_loaded) 03268 { 03269 fprintf(output, "Error: filesystem not initialized\n"); 03270 return -1; 03271 } 03272 03273 /* initialize current thread */ 03274 03275 context = GetFSALCmdContext(); 03276 03277 if(context->is_thread_ok != TRUE) 03278 { 03279 int rc; 03280 rc = Init_Thread_Context(output, context, 0); 03281 if(rc != 0) 03282 return rc; 03283 } 03284 03285 /* analysing options */ 03286 03287 getopt_init(); 03288 while((option = Getopt(argc, argv, format)) != -1) 03289 { 03290 switch (option) 03291 { 03292 03293 case 'v': 03294 if(flag_v) 03295 fprintf(output, 03296 "access: warning: option 'v' has been specified more than once.\n"); 03297 else 03298 flag_v++; 03299 break; 03300 03301 case 'h': 03302 if(flag_h) 03303 fprintf(output, 03304 "access: warning: option 'h' has been specified more than once.\n"); 03305 else 03306 flag_h++; 03307 break; 03308 03309 case 'A': 03310 if(flag_A) 03311 fprintf(output, 03312 "access: warning: option 'A' has been specified more than once.\n"); 03313 else 03314 flag_A++; 03315 break; 03316 03317 case '?': 03318 fprintf(output, "access: unknown option : %c\n", Optopt); 03319 err_flag++; 03320 break; 03321 } 03322 } 03323 03324 if(flag_h) 03325 { 03326 03327 /* print usage */ 03328 fprintf(output, help_access); 03329 return 0; 03330 03331 } 03332 03333 /* Exactly 2 args expected */ 03334 03335 if(Optind != (argc - 2)) 03336 { 03337 err_flag++; 03338 } 03339 else 03340 { 03341 str_perms = argv[Optind]; 03342 file = argv[Optind + 1]; 03343 } 03344 03345 if(err_flag) 03346 { 03347 fprintf(output, help_access); 03348 return -1; 03349 } 03350 03351 /* copy current absolute path to a local variable. */ 03352 03353 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 03354 03355 /* retrieve handle to the file whose permissions are to be tested */ 03356 03357 rc = solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->current_dir, &obj_hdl, 03358 output); 03359 if(rc) 03360 return rc; 03361 03362 /* Convert the permission string to an fsal access test. */ 03363 03364 test_perms = 0; 03365 03366 for(i = 0; i < strlen(str_perms); i++) 03367 { 03368 switch (str_perms[i]) 03369 { 03370 case 'F': 03371 if(flag_v) 03372 fprintf(output, "F_OK flag\n"); 03373 test_perms |= FSAL_F_OK; 03374 break; 03375 03376 case 'R': 03377 if(flag_v) 03378 fprintf(output, "R_OK flag\n"); 03379 test_perms |= FSAL_R_OK; 03380 break; 03381 03382 case 'W': 03383 if(flag_v) 03384 fprintf(output, "W_OK flag\n"); 03385 test_perms |= FSAL_W_OK; 03386 break; 03387 03388 case 'X': 03389 if(flag_v) 03390 fprintf(output, "X_OK flag\n"); 03391 test_perms |= FSAL_X_OK; 03392 break; 03393 03394 default: 03395 fprintf(output, "**** Invalid test: %c ****\n", str_perms[i]); 03396 fprintf(output, help_access); 03397 return -1; 03398 } 03399 } 03400 03401 /* Call to FSAL */ 03402 03403 if(flag_A) 03404 { 03405 fsal_attrib_list_t attributes; 03406 03407 /* 1st method: get attr and test_access */ 03408 03409 FSAL_CLEAR_MASK(attributes.asked_attributes); 03410 FSAL_SET_MASK(attributes.asked_attributes, 03411 FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP | FSAL_ATTR_ACL); 03412 03413 if(flag_v) 03414 fprintf(output, "Getting file attributes...\n"); 03415 03416 st = FSAL_getattrs(&obj_hdl, &context->context, &attributes); 03417 03418 if(FSAL_IS_ERROR(st)) 03419 { 03420 fprintf(output, "Error executing FSAL_getattrs:"); 03421 print_fsal_status(output, st); 03422 fprintf(output, "\n"); 03423 return st.major; 03424 } 03425 03426 if(flag_v) 03427 { 03428 print_fsal_attributes(attributes, output); 03429 } 03430 03431 if(flag_v) 03432 fprintf(output, "Testing access rights...\n"); 03433 03434 st = FSAL_test_access(&context->context, test_perms, &attributes); 03435 03436 if(FSAL_IS_ERROR(st)) 03437 { 03438 03439 fprintf(output, "Error executing FSAL_test_access:"); 03440 print_fsal_status(output, st); 03441 fprintf(output, "\n"); 03442 return st.major; 03443 03444 } 03445 else 03446 { 03447 03448 fprintf(output, "access: Access granted.\n"); 03449 return 0; 03450 03451 } 03452 03453 } 03454 else 03455 { 03456 /* 2nd method: simply calling access */ 03457 03458 if(flag_v) 03459 fprintf(output, "Calling access\n"); 03460 03461 st = FSAL_access(&obj_hdl, &context->context, test_perms, NULL); 03462 03463 if(FSAL_IS_ERROR(st)) 03464 { 03465 03466 fprintf(output, "Error executing FSAL_access:"); 03467 print_fsal_status(output, st); 03468 fprintf(output, "\n"); 03469 return st.major; 03470 03471 } 03472 else 03473 { 03474 03475 fprintf(output, "access: Access granted.\n"); 03476 return 0; 03477 } 03478 03479 } 03480 03481 } 03482 03484 int fn_fsal_truncate(int argc, /* IN : number of args in argv */ 03485 char **argv, /* IN : arg list */ 03486 FILE * output /* IN : output stream */ 03487 ) 03488 { 03489 03490 char format[] = "hv"; 03491 03492 const char help_truncate[] = "usage: truncate [-h][-v] <file> <size>\n"; 03493 03494 char glob_path[FSAL_MAX_PATH_LEN]; 03495 fsal_handle_t filehdl; 03496 03497 fsal_status_t st; 03498 fsal_size_t trunc_size; 03499 03500 int rc, option; 03501 int flag_v = 0; 03502 int flag_h = 0; 03503 int err_flag = 0; 03504 03505 char *file = NULL; 03506 char *str_size = NULL; 03507 03508 cmdfsal_thr_info_t *context; 03509 03510 /* is the fs initialized ? */ 03511 if(!is_loaded) 03512 { 03513 fprintf(output, "Error: filesystem not initialized\n"); 03514 return -1; 03515 } 03516 03517 /* initialize current thread */ 03518 03519 context = GetFSALCmdContext(); 03520 03521 if(context->is_thread_ok != TRUE) 03522 { 03523 int rc; 03524 rc = Init_Thread_Context(output, context, 0); 03525 if(rc != 0) 03526 return rc; 03527 } 03528 03529 /* analysing options */ 03530 getopt_init(); 03531 while((option = Getopt(argc, argv, format)) != -1) 03532 { 03533 switch (option) 03534 { 03535 case 'v': 03536 if(flag_v) 03537 fprintf(output, 03538 "truncate: warning: option 'v' has been specified more than once.\n"); 03539 else 03540 flag_v++; 03541 break; 03542 case 'h': 03543 if(flag_h) 03544 fprintf(output, 03545 "truncate: warning: option 'h' has been specified more than once.\n"); 03546 else 03547 flag_h++; 03548 break; 03549 case '?': 03550 fprintf(output, "truncate: unknown option : %c\n", Optopt); 03551 err_flag++; 03552 break; 03553 } 03554 } 03555 03556 if(flag_h) 03557 { 03558 fprintf(output, help_truncate); 03559 return 0; 03560 } 03561 03562 /* Exactly two arg expected */ 03563 if(Optind != (argc - 2)) 03564 { 03565 err_flag++; 03566 } 03567 else 03568 { 03569 file = argv[Optind]; 03570 str_size = argv[Optind + 1]; 03571 03572 rc = ato64(str_size, &trunc_size); 03573 if(rc == -1) 03574 { 03575 fprintf(output, "truncate: error: invalid trunc size \"%s\"\n", str_size); 03576 err_flag++; 03577 } 03578 03579 } 03580 03581 if(err_flag) 03582 { 03583 fprintf(output, help_truncate); 03584 return -1; 03585 } 03586 03587 /* copy current path. */ 03588 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 03589 03590 /* retrieves object handle */ 03591 if((rc = 03592 solvepath(glob_path, FSAL_MAX_PATH_LEN, 03593 file, context->current_dir, &filehdl, output))) 03594 return rc; 03595 03596 if(flag_v) 03597 fprintf(output, "Truncating \"%s\" to %llu bytes.\n", glob_path, trunc_size); 03598 03599 st = FSAL_truncate(&filehdl, &context->context, trunc_size, NULL, /* Will fail with FSAL_PROXY */ 03600 NULL); 03601 03602 if(FSAL_IS_ERROR(st)) 03603 { 03604 fprintf(output, "Error executing FSAL_truncate:"); 03605 print_fsal_status(output, st); 03606 fprintf(output, "\n"); 03607 return st.major; 03608 } 03609 03610 if(flag_v) 03611 fprintf(output, "Truncate operation completed sucessfully.\n"); 03612 03613 return 0; 03614 03615 } 03616 03621 int fn_fsal_open_byname(int argc, /* IN : number of args in argv */ 03622 char **argv, /* IN : arg list */ 03623 FILE * output /* IN : output stream */ 03624 ) 03625 { 03626 03627 char format[] = "hv"; 03628 03629 const char help_open[] = 03630 "usage: open_byname [-h][-v] <path> [<oflags>]\n" 03631 " where <oflags> is a set of the following values:\n" 03632 " 'r': read, 'w': write, 'a': append, 't': truncate.\n"; 03633 03634 char glob_path[FSAL_MAX_PATH_LEN]; 03635 fsal_name_t filename; 03636 03637 fsal_status_t st; 03638 03639 int option; 03640 int flag_v = 0; 03641 int flag_h = 0; 03642 int err_flag = 0; 03643 03644 fsal_openflags_t o_flags; 03645 03646 int flag_r = 0; 03647 int flag_w = 0; 03648 int flag_a = 0; 03649 int flag_t = 0; 03650 03651 char *file = NULL; 03652 char *opt_str; 03653 03654 cmdfsal_thr_info_t *context; 03655 03656 /* is the fs initialized ? */ 03657 if(!is_loaded) 03658 { 03659 fprintf(output, "Error: filesystem not initialized\n"); 03660 return -1; 03661 } 03662 03663 /* initialize current thread */ 03664 03665 context = GetFSALCmdContext(); 03666 03667 if(context->is_thread_ok != TRUE) 03668 { 03669 int rc; 03670 rc = Init_Thread_Context(output, context, 0); 03671 if(rc != 0) 03672 return rc; 03673 } 03674 03675 /* is a file already opened ? */ 03676 if(context->opened) 03677 { 03678 fprintf(output, "Error: a file is already opened. Use 'close' command first.\n"); 03679 return -1; 03680 } 03681 03682 /* analysing options */ 03683 03684 getopt_init(); 03685 while((option = Getopt(argc, argv, format)) != -1) 03686 { 03687 switch (option) 03688 { 03689 case 'v': 03690 if(flag_v) 03691 fprintf(output, 03692 "open: warning: option 'v' has been specified more than once.\n"); 03693 else 03694 flag_v++; 03695 break; 03696 case 'h': 03697 if(flag_h) 03698 fprintf(output, 03699 "open: warning: option 'h' has been specified more than once.\n"); 03700 else 03701 flag_h++; 03702 break; 03703 case '?': 03704 fprintf(output, "open: unknown option : %c\n", Optopt); 03705 err_flag++; 03706 break; 03707 } 03708 } 03709 03710 if(flag_h) 03711 { 03712 fprintf(output, help_open); 03713 return 0; 03714 } 03715 03716 /* one or two args expected */ 03717 if(Optind > (argc - 1)) 03718 err_flag++; 03719 else 03720 { 03721 file = argv[Optind]; 03722 03723 Optind++; 03724 03725 /* optional flags */ 03726 while(Optind < argc) 03727 { 03728 /* test flags */ 03729 opt_str = argv[Optind]; 03730 03731 while(*opt_str) 03732 { 03733 switch (*opt_str) 03734 { 03735 case 'r': 03736 case 'R': 03737 flag_r++; 03738 break; 03739 03740 case 'w': 03741 case 'W': 03742 flag_w++; 03743 break; 03744 03745 case 'a': 03746 case 'A': 03747 flag_a++; 03748 break; 03749 03750 case 't': 03751 case 'T': 03752 flag_t++; 03753 break; 03754 03755 default: 03756 fprintf(output, "open_byname: unknown open flag : '%c'\n", *opt_str); 03757 err_flag++; 03758 } 03759 opt_str++; 03760 } 03761 03762 Optind++; 03763 } 03764 03765 } 03766 03767 if(err_flag) 03768 { 03769 fprintf(output, help_open); 03770 return -1; 03771 } 03772 03773 /* Convert filename to fsal_name_t */ 03774 if(FSAL_IS_ERROR(st = FSAL_str2name(file, FSAL_MAX_PATH_LEN, &filename))) 03775 { 03776 fprintf(output, "Error executing FSAL_str2name:"); 03777 print_fsal_status(output, st); 03778 fprintf(output, "\n"); 03779 return st.major; 03780 } 03781 03782 /* make open flags */ 03783 03784 o_flags = 0; 03785 03786 if(flag_r && flag_w) 03787 o_flags |= FSAL_O_RDWR; 03788 else if(flag_r) 03789 o_flags |= FSAL_O_RDONLY; 03790 else if(flag_w) 03791 o_flags |= FSAL_O_WRONLY; 03792 03793 if(flag_a) 03794 o_flags |= FSAL_O_APPEND; 03795 if(flag_t) 03796 o_flags |= FSAL_O_TRUNC; 03797 03798 if(flag_v) 03799 fprintf(output, "Open operation on %s with flags %#X.\n", glob_path, o_flags); 03800 03801 st = FSAL_open_by_name(&(context->current_dir), &filename, &context->context, o_flags, 03802 &context->current_fd, NULL); 03803 03804 if(FSAL_IS_ERROR(st)) 03805 { 03806 fprintf(output, "Error executing FSAL_open:"); 03807 print_fsal_status(output, st); 03808 fprintf(output, "\n"); 03809 return st.major; 03810 } 03811 03812 /* note that a file is opened. */ 03813 context->opened = TRUE; 03814 03815 if(flag_v) 03816 fprintf(output, "Open operation completed sucessfully : fd = %d.\n", 03817 FSAL_FILENO(&(context->current_fd))); 03818 03819 return 0; 03820 03821 } 03822 03827 int fn_fsal_open(int argc, /* IN : number of args in argv */ 03828 char **argv, /* IN : arg list */ 03829 FILE * output /* IN : output stream */ 03830 ) 03831 { 03832 03833 char format[] = "hv"; 03834 03835 const char help_open[] = 03836 "usage: open [-h][-v] <path> [<oflags>]\n" 03837 " where <oflags> is a set of the following values:\n" 03838 " 'r': read, 'w': write, 'a': append, 't': truncate.\n"; 03839 03840 char glob_path[FSAL_MAX_PATH_LEN]; 03841 fsal_handle_t filehdl; 03842 03843 fsal_status_t st; 03844 03845 int rc, option; 03846 int flag_v = 0; 03847 int flag_h = 0; 03848 int err_flag = 0; 03849 03850 fsal_openflags_t o_flags; 03851 03852 int flag_r = 0; 03853 int flag_w = 0; 03854 int flag_a = 0; 03855 int flag_t = 0; 03856 03857 char *file = NULL; 03858 char *opt_str; 03859 03860 cmdfsal_thr_info_t *context; 03861 03862 /* is the fs initialized ? */ 03863 if(!is_loaded) 03864 { 03865 fprintf(output, "Error: filesystem not initialized\n"); 03866 return -1; 03867 } 03868 03869 /* initialize current thread */ 03870 03871 context = GetFSALCmdContext(); 03872 03873 if(context->is_thread_ok != TRUE) 03874 { 03875 int rc; 03876 rc = Init_Thread_Context(output, context, 0); 03877 if(rc != 0) 03878 return rc; 03879 } 03880 03881 /* is a file already opened ? */ 03882 if(context->opened) 03883 { 03884 fprintf(output, "Error: a file is already opened. Use 'close' command first.\n"); 03885 return -1; 03886 } 03887 03888 /* analysing options */ 03889 03890 getopt_init(); 03891 while((option = Getopt(argc, argv, format)) != -1) 03892 { 03893 switch (option) 03894 { 03895 case 'v': 03896 if(flag_v) 03897 fprintf(output, 03898 "open: warning: option 'v' has been specified more than once.\n"); 03899 else 03900 flag_v++; 03901 break; 03902 case 'h': 03903 if(flag_h) 03904 fprintf(output, 03905 "open: warning: option 'h' has been specified more than once.\n"); 03906 else 03907 flag_h++; 03908 break; 03909 case '?': 03910 fprintf(output, "open: unknown option : %c\n", Optopt); 03911 err_flag++; 03912 break; 03913 } 03914 } 03915 03916 if(flag_h) 03917 { 03918 fprintf(output, help_open); 03919 return 0; 03920 } 03921 03922 /* one or two args expected */ 03923 if(Optind > (argc - 1)) 03924 err_flag++; 03925 else 03926 { 03927 file = argv[Optind]; 03928 03929 Optind++; 03930 03931 /* optional flags */ 03932 while(Optind < argc) 03933 { 03934 /* test flags */ 03935 opt_str = argv[Optind]; 03936 03937 while(*opt_str) 03938 { 03939 switch (*opt_str) 03940 { 03941 case 'r': 03942 case 'R': 03943 flag_r++; 03944 break; 03945 03946 case 'w': 03947 case 'W': 03948 flag_w++; 03949 break; 03950 03951 case 'a': 03952 case 'A': 03953 flag_a++; 03954 break; 03955 03956 case 't': 03957 case 'T': 03958 flag_t++; 03959 break; 03960 03961 default: 03962 fprintf(output, "open: unknown open flag : '%c'\n", *opt_str); 03963 err_flag++; 03964 } 03965 opt_str++; 03966 } 03967 03968 Optind++; 03969 } 03970 03971 } 03972 03973 if(err_flag) 03974 { 03975 fprintf(output, help_open); 03976 return -1; 03977 } 03978 03979 /* copy current path. */ 03980 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 03981 03982 /* retrieves object handle */ 03983 if((rc = 03984 solvepath(glob_path, FSAL_MAX_PATH_LEN, 03985 file, context->current_dir, &filehdl, output))) 03986 return rc; 03987 03988 /* make open flags */ 03989 03990 o_flags = 0; 03991 03992 if(flag_r && flag_w) 03993 o_flags |= FSAL_O_RDWR; 03994 else if(flag_r) 03995 o_flags |= FSAL_O_RDONLY; 03996 else if(flag_w) 03997 o_flags |= FSAL_O_WRONLY; 03998 03999 if(flag_a) 04000 o_flags |= FSAL_O_APPEND; 04001 if(flag_t) 04002 o_flags |= FSAL_O_TRUNC; 04003 04004 if(flag_v) 04005 fprintf(output, "Open operation on %s with flags %#X.\n", glob_path, o_flags); 04006 04007 st = FSAL_open(&filehdl, &context->context, o_flags, &context->current_fd, NULL); 04008 04009 if(FSAL_IS_ERROR(st)) 04010 { 04011 fprintf(output, "Error executing FSAL_open:"); 04012 print_fsal_status(output, st); 04013 fprintf(output, "\n"); 04014 return st.major; 04015 } 04016 04017 /* note that a file is opened. */ 04018 context->opened = TRUE; 04019 04020 if(flag_v) 04021 fprintf(output, "Open operation completed sucessfully : fd = %d.\n", 04022 FSAL_FILENO(&(context->current_fd))); 04023 04024 return 0; 04025 04026 } 04027 04032 int fn_fsal_open_byfileid(int argc, /* IN : number of args in argv */ 04033 char **argv, /* IN : arg list */ 04034 FILE * output /* IN : output stream */ 04035 ) 04036 { 04037 04038 char format[] = "hv"; 04039 04040 const char help_open_byfileid[] = 04041 "usage: open_byfileid [-h][-v] <path> <fileid> [<oflags>]\n" 04042 " where <oflags> is a set of the following values:\n" 04043 " 'r': read, 'w': write, 'a': append, 't': truncate.\n"; 04044 04045 char glob_path[FSAL_MAX_PATH_LEN]; 04046 fsal_handle_t filehdl; 04047 04048 fsal_status_t st; 04049 04050 int rc, option; 04051 int flag_v = 0; 04052 int flag_h = 0; 04053 int err_flag = 0; 04054 04055 fsal_openflags_t o_flags; 04056 04057 int flag_r = 0; 04058 int flag_w = 0; 04059 int flag_a = 0; 04060 int flag_t = 0; 04061 04062 char *file = NULL; 04063 char *strfileid = NULL; 04064 fsal_u64_t fileid = 0LL; 04065 char *opt_str; 04066 04067 cmdfsal_thr_info_t *context; 04068 04069 /* is the fs initialized ? */ 04070 if(!is_loaded) 04071 { 04072 fprintf(output, "Error: filesystem not initialized\n"); 04073 return -1; 04074 } 04075 04076 /* initialize current thread */ 04077 04078 context = GetFSALCmdContext(); 04079 04080 if(context->is_thread_ok != TRUE) 04081 { 04082 int rc; 04083 rc = Init_Thread_Context(output, context, 0); 04084 if(rc != 0) 04085 return rc; 04086 } 04087 04088 /* is a file already opened ? */ 04089 if(context->opened) 04090 { 04091 fprintf(output, "Error: a file is already opened. Use 'close' command first.\n"); 04092 return -1; 04093 } 04094 04095 /* analysing options */ 04096 04097 getopt_init(); 04098 while((option = Getopt(argc, argv, format)) != -1) 04099 { 04100 switch (option) 04101 { 04102 case 'v': 04103 if(flag_v) 04104 fprintf(output, 04105 "open: warning: option 'v' has been specified more than once.\n"); 04106 else 04107 flag_v++; 04108 break; 04109 case 'h': 04110 if(flag_h) 04111 fprintf(output, 04112 "open: warning: option 'h' has been specified more than once.\n"); 04113 else 04114 flag_h++; 04115 break; 04116 case '?': 04117 fprintf(output, "open: unknown option : %c\n", Optopt); 04118 err_flag++; 04119 break; 04120 } 04121 } 04122 04123 if(flag_h) 04124 { 04125 fprintf(output, help_open_byfileid); 04126 return 0; 04127 } 04128 04129 /* two or three args expected */ 04130 if(Optind > (argc - 2)) 04131 err_flag++; 04132 else 04133 { 04134 file = argv[Optind]; 04135 strfileid = argv[Optind + 1]; 04136 sscanf(strfileid, "%llu", &fileid); 04137 04138 Optind += 2; 04139 04140 /* optional flags */ 04141 while(Optind < argc) 04142 { 04143 /* test flags */ 04144 opt_str = argv[Optind]; 04145 04146 while(*opt_str) 04147 { 04148 switch (*opt_str) 04149 { 04150 case 'r': 04151 case 'R': 04152 flag_r++; 04153 break; 04154 04155 case 'w': 04156 case 'W': 04157 flag_w++; 04158 break; 04159 04160 case 'a': 04161 case 'A': 04162 flag_a++; 04163 break; 04164 04165 case 't': 04166 case 'T': 04167 flag_t++; 04168 break; 04169 04170 default: 04171 fprintf(output, "open: unknown open flag : '%c'\n", *opt_str); 04172 err_flag++; 04173 } 04174 opt_str++; 04175 } 04176 04177 Optind++; 04178 } 04179 04180 } 04181 04182 if(err_flag) 04183 { 04184 fprintf(output, help_open_byfileid); 04185 return -1; 04186 } 04187 04188 /* copy current path. */ 04189 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 04190 04191 /* retrieves object handle */ 04192 if((rc = 04193 solvepath(glob_path, FSAL_MAX_PATH_LEN, 04194 file, context->current_dir, &filehdl, output))) 04195 return rc; 04196 04197 /* make open flags */ 04198 04199 o_flags = 0; 04200 04201 if(flag_r && flag_w) 04202 o_flags |= FSAL_O_RDWR; 04203 else if(flag_r) 04204 o_flags |= FSAL_O_RDONLY; 04205 else if(flag_w) 04206 o_flags |= FSAL_O_WRONLY; 04207 04208 if(flag_a) 04209 o_flags |= FSAL_O_APPEND; 04210 if(flag_t) 04211 o_flags |= FSAL_O_TRUNC; 04212 04213 if(flag_v) 04214 fprintf(output, "Open operation on %s with flags %#X.\n", glob_path, o_flags); 04215 04216 st = FSAL_open_by_fileid(&filehdl, fileid, &context->context, o_flags, 04217 &context->current_fd, NULL); 04218 04219 if(FSAL_IS_ERROR(st)) 04220 { 04221 fprintf(output, "Error executing FSAL_open:"); 04222 print_fsal_status(output, st); 04223 fprintf(output, "\n"); 04224 return st.major; 04225 } 04226 04227 /* note that a file is opened. */ 04228 context->opened = TRUE; 04229 04230 if(flag_v) 04231 fprintf(output, "Open operation completed sucessfully : fd = %d.\n", 04232 FSAL_FILENO(&(context->current_fd))); 04233 04234 return 0; 04235 04236 } 04237 04241 int fn_fsal_read(int argc, /* IN : number of args in argv */ 04242 char **argv, /* IN : arg list */ 04243 FILE * output /* IN : output stream */ 04244 ) 04245 { 04246 04247 char format[] = "hvAXB:s:"; 04248 04249 const char help_read[] = 04250 "Usage:\n" 04251 " read [-h][-v][-A][-X] [-B <block_size> ] [ -s <seek_type>,<offset> ] { <total_bytes> | all }\n" 04252 "Options:\n" 04253 " -h: print this help\n" 04254 " -v: verbose mode\n" 04255 " -A: display read data in ascii\n" 04256 " -X: display read data in hexa\n" 04257 " -B <blocksize>: block size used for reading, in bytes (default 1k).\n" 04258 " -s <seek_type>,<offset>: specify the position of the first byte to be read.\n" 04259 " <seek_type> can take the values SET, CUR or END.\n" 04260 " <offset> is a signed integer.\n" 04261 " <total_bytes>: indicates the total number of bytes to be read\n" 04262 " ('all' indicates that data are read until the end of the file).\n" 04263 "Example:\n" 04264 " For reading the last 2kB of the opened file, using 1k block size:\n" 04265 " read -B 1024 -s END,-2048 all \n"; 04266 04267 fsal_status_t st; 04268 04269 int rc, option; 04270 04271 int flag_v = 0; 04272 int flag_h = 0; 04273 int flag_A = 0; 04274 int flag_X = 0; 04275 int flag_B = 0; 04276 int flag_s = 0; 04277 04278 int err_flag = 0; 04279 04280 char *str_block_size = NULL; 04281 04282 char str_seek_buff[256]; 04283 04284 char *str_seek_type = NULL; 04285 char *str_seek_offset = NULL; 04286 char *str_total_bytes = NULL; 04287 04288 fsal_size_t block_size = 1024; /* default: 1ko */ 04289 fsal_size_t total_bytes = 0; /* 0 == read all */ 04290 fsal_seek_t seek_desc = { FSAL_SEEK_CUR, 0 }; /* default: read current position */ 04291 04292 fsal_seek_t *p_seek_desc = NULL; 04293 04294 /* fsal arguments */ 04295 04296 fsal_boolean_t is_eof = 0; 04297 fsal_size_t total_nb_read = 0; 04298 fsal_size_t once_nb_read = 0; 04299 fsal_size_t nb_block_read = 0; 04300 04301 char *p_read_buff; 04302 04303 struct timeval timer_start; 04304 struct timeval timer_stop; 04305 struct timeval timer_diff; 04306 04307 cmdfsal_thr_info_t *context; 04308 04309 /* is the fs initialized ? */ 04310 if(!is_loaded) 04311 { 04312 fprintf(output, "Error: filesystem not initialized\n"); 04313 return -1; 04314 } 04315 04316 /* initialize current thread */ 04317 04318 context = GetFSALCmdContext(); 04319 04320 if(context->is_thread_ok != TRUE) 04321 { 04322 int rc; 04323 rc = Init_Thread_Context(output, context, 0); 04324 if(rc != 0) 04325 return rc; 04326 } 04327 04328 /* is a file opened ? */ 04329 if(!context->opened) 04330 { 04331 fprintf(output, "Error: no opened file. Use 'open' command first.\n"); 04332 return -1; 04333 } 04334 04335 /* option analysis. */ 04336 04337 getopt_init(); 04338 while((option = Getopt(argc, argv, format)) != -1) 04339 { 04340 switch (option) 04341 { 04342 04343 case 'v': 04344 if(flag_v) 04345 fprintf(output, 04346 "read: warning: option 'v' has been specified more than once.\n"); 04347 else 04348 flag_v++; 04349 break; 04350 04351 case 'h': 04352 if(flag_h) 04353 fprintf(output, 04354 "read: warning: option 'h' has been specified more than once.\n"); 04355 else 04356 flag_h++; 04357 break; 04358 04359 case 'A': 04360 if(flag_A) 04361 fprintf(output, 04362 "read: warning: option 'A' has been specified more than once.\n"); 04363 else if(flag_X) 04364 { 04365 fprintf(output, "read: option 'A' conflicts with option 'X'.\n"); 04366 err_flag++; 04367 } 04368 else 04369 flag_A++; 04370 break; 04371 04372 case 'X': 04373 if(flag_X) 04374 fprintf(output, 04375 "read: warning: option 'X' has been specified more than once.\n"); 04376 else if(flag_A) 04377 { 04378 fprintf(output, "read: option 'X' conflicts with option 'A'.\n"); 04379 err_flag++; 04380 } 04381 else 04382 flag_X++; 04383 break; 04384 04385 case 'B': 04386 if(flag_B) 04387 fprintf(output, 04388 "read: warning: option 'B' has been specified more than once.\n"); 04389 else 04390 { 04391 flag_B++; 04392 str_block_size = Optarg; 04393 } 04394 break; 04395 04396 case 's': 04397 if(flag_s) 04398 fprintf(output, 04399 "read: warning: option 's' has been specified more than once.\n"); 04400 else 04401 { 04402 flag_s++; 04403 strncpy(str_seek_buff, Optarg, 256); 04404 str_seek_type = str_seek_buff; 04405 } 04406 break; 04407 04408 case '?': 04409 fprintf(output, "read: unknown option : %c\n", Optopt); 04410 err_flag++; 04411 break; 04412 } 04413 } 04414 04415 if(flag_h) 04416 { 04417 fprintf(output, help_read); 04418 return 0; 04419 } 04420 04421 /* Exactly one arg expected */ 04422 04423 if(Optind != (argc - 1)) 04424 err_flag++; 04425 else 04426 str_total_bytes = argv[Optind]; 04427 04428 if(err_flag) 04429 { 04430 fprintf(output, help_read); 04431 return -1; 04432 } 04433 04434 /* check argument types */ 04435 04436 if(flag_B) 04437 { 04438 /* Try to convert the str_block_size to fsal_size_t */ 04439 04440 rc = ato64(str_block_size, &block_size); 04441 04442 if(rc == -1) 04443 { 04444 fprintf(output, "read: error: invalid block size \"%s\"\n", str_block_size); 04445 err_flag++; 04446 } 04447 04448 } 04449 04450 if(flag_s) 04451 { 04452 /* Try to parse the argument */ 04453 04454 str_seek_offset = strchr(str_seek_type, ','); 04455 04456 if(str_seek_offset == NULL) 04457 { 04458 fprintf(output, 04459 "read: error: invalid seek specifier \"%s\". <seek_type>,<offset> expected.\n", 04460 str_seek_type); 04461 err_flag++; 04462 } 04463 04464 if(!err_flag) 04465 { 04466 int sign = 1; 04467 04468 *str_seek_offset = '\0'; 04469 str_seek_offset++; /* the first char after the "," */ 04470 04471 /* Check seek type */ 04472 04473 if(!strncmp(str_seek_type, "CUR", 256)) 04474 seek_desc.whence = FSAL_SEEK_CUR; 04475 else if(!strncmp(str_seek_type, "SET", 256)) 04476 seek_desc.whence = FSAL_SEEK_SET; 04477 else if(!strncmp(str_seek_type, "END", 256)) 04478 seek_desc.whence = FSAL_SEEK_END; 04479 else 04480 { 04481 fprintf(output, 04482 "read: error: invalid seek type \"%s\". CUR, SET or END expected.\n", 04483 str_seek_type); 04484 err_flag++; 04485 } 04486 04487 /* Try to convert str_seek_offset to fsal_off_t */ 04488 04489 switch (str_seek_offset[0]) 04490 { 04491 case '+': 04492 sign = 1; 04493 str_seek_offset++; 04494 break; 04495 04496 case '-': 04497 sign = -1; 04498 str_seek_offset++; 04499 break; 04500 } 04501 04502 rc = ato64(str_seek_offset, (unsigned long long *)&seek_desc.offset); 04503 04504 if(rc == -1) 04505 { 04506 fprintf(output, "read: error: invalid offset \"%s\".\n", str_seek_offset); 04507 err_flag++; 04508 } 04509 else if(sign < 0) 04510 seek_desc.offset = -seek_desc.offset; 04511 04512 } 04513 04514 p_seek_desc = &seek_desc; 04515 04516 } 04517 else 04518 { 04519 p_seek_desc = NULL; /* default seeking */ 04520 } 04521 04522 if(!strcasecmp(str_total_bytes, "all")) 04523 { 04524 total_bytes = 0; 04525 } 04526 else 04527 { 04528 rc = ato64(str_total_bytes, &total_bytes); 04529 04530 if(rc == -1) 04531 { 04532 fprintf(output, 04533 "read: error: invalid read size \"%s\". \"all\" or <nb_bytes> expected.\n", 04534 str_total_bytes); 04535 err_flag++; 04536 } 04537 } 04538 04539 if(err_flag) 04540 { 04541 fprintf(output, help_read); 04542 return -1; 04543 } 04544 04545 if(flag_v) 04546 { 04547 04548 /* print a sum-up of read parameters */ 04549 fprintf(output, 04550 "Read options: Block size: %llu Bytes, Seek: %s%+lld, Read limit: %llu Bytes\n", 04551 block_size, 04552 (p_seek_desc 04553 ? (seek_desc.whence == FSAL_SEEK_SET ? "SET" : seek_desc.whence == 04554 FSAL_SEEK_CUR ? "CUR" : "END") : "DEFAULT"), 04555 (long long)(p_seek_desc ? seek_desc.offset : 0LL), total_bytes); 04556 } 04557 04558 /* Now all arguments have been parsed, let's act ! */ 04559 04560 /* alloc a buffer */ 04561 p_read_buff = gsh_malloc(block_size); 04562 04563 if(p_read_buff == NULL) 04564 { 04565 fprintf(output, 04566 "read: error: Not enough memory to allocate read buffer (%llu Bytes).\n", 04567 block_size); 04568 return ENOMEM; 04569 } 04570 04571 gettimeofday(&timer_start, NULL); 04572 04573 /* while EOF is not reached, and read<asked (when total_bytes!=0) */ 04574 while(!is_eof && !((total_bytes != 0) && (total_nb_read >= total_bytes))) 04575 { 04576 04577 st = FSAL_read(&context->current_fd, p_seek_desc, 04578 block_size, (caddr_t) p_read_buff, &once_nb_read, &is_eof); 04579 04580 if(FSAL_IS_ERROR(st)) 04581 { 04582 fprintf(output, "Error executing FSAL_read:"); 04583 print_fsal_status(output, st); 04584 fprintf(output, "\n"); 04585 04586 /* exit only if it is not retryable */ 04587 if(fsal_is_retryable(st)) 04588 { 04589 sleep(1); 04590 continue; 04591 } 04592 else 04593 { 04594 gsh_free(p_read_buff); 04595 return st.major; 04596 } 04597 } 04598 04599 /* print what was read. */ 04600 if(flag_A) 04601 { 04602 fsal_size_t index; 04603 for(index = 0; index < once_nb_read; index++) 04604 fprintf(output, "%c.", p_read_buff[index]); 04605 } 04606 else if(flag_X) 04607 { 04608 fsal_size_t index; 04609 for(index = 0; index < once_nb_read; index++) 04610 fprintf(output, "%.2X ", p_read_buff[index]); 04611 } 04612 else 04613 fprintf(output, "."); 04614 04615 /* update stats */ 04616 04617 if(once_nb_read > 0) 04618 nb_block_read++; 04619 04620 total_nb_read += once_nb_read; 04621 04622 /* flush */ 04623 if(nb_block_read % 10) 04624 fflush(output); 04625 04626 /* what ever seek type was, we continue reading from current position */ 04627 p_seek_desc = NULL; 04628 04629 } 04630 04631 gettimeofday(&timer_stop, NULL); 04632 04633 /* newline after read blocks */ 04634 fprintf(output, "\n"); 04635 04636 if(flag_v) 04637 { 04638 double bandwidth; 04639 04640 /* print stats */ 04641 fprintf(output, "Nb blocks read: %llu\n", nb_block_read); 04642 fprintf(output, "Total: %llu Bytes\n", total_nb_read); 04643 04644 fprintf(output, "Time enlapsed: "); 04645 timer_diff = time_diff(timer_start, timer_stop); 04646 print_timeval(output, timer_diff); 04647 04648 bandwidth = 04649 total_nb_read / (1024 * 1024 * 04650 (timer_diff.tv_sec + 0.000001 * timer_diff.tv_usec)); 04651 04652 fprintf(output, "Bandwidth: %f MB/s\n", bandwidth); 04653 04654 } 04655 gsh_free(p_read_buff); 04656 04657 return 0; 04658 } 04659 04689 int fn_fsal_write(int argc, /* IN : number of args in argv */ 04690 char **argv, /* IN : arg list */ 04691 FILE * output /* IN : output stream */ 04692 ) 04693 { 04694 04695 char format[] = "hvs:N:A:X:"; 04696 04697 const char help_write[] = 04698 "Usage:\n" 04699 " write [-h][-v] [ -s <seek_type>,<offset> ] [-N <nb_times>] -A <ascii_string>\n" 04700 " write [-h][-v] [ -s <seek_type>,<offset> ] [-N <nb_times>] -X <hexa_data>\n" 04701 "Where:\n" 04702 " <seek_type> can be: SET, CUR, END\n" 04703 " <offset> is a signed number of bytes.\n" 04704 " <nb_times> is the number of times we write the expression into the file.\n" 04705 "\n" 04706 " <ascii_string> is a string to be written to file.\n" 04707 " Note that the null terminating character of is also written\n" 04708 " to file.\n" 04709 "or\n" 04710 " <hexa_data> is a data represented in hexadecimal format,\n" 04711 " that is to be written to file.\n" 04712 "\n" 04713 "Examples:\n" 04714 "\n" 04715 " For writting 10 times the null terminated string \"hello world\"\n" 04716 " at the end of the file:\n" 04717 " write -s END,0 -N 10 -A \"hello world\"\n" 04718 "\n" 04719 " For overwritting the beginning of the file with\n" 04720 " the pattern 0xA1267AEF31254ADE repeated twice:\n" 04721 " write -s SET,0 -N 2 -X \"A1267AEF31254ADE\"\n"; 04722 04723 fsal_status_t st; 04724 04725 int rc, option; 04726 04727 int flag_v = 0; 04728 int flag_h = 0; 04729 int flag_N = 0; 04730 int flag_s = 0; 04731 int flag_A = 0; 04732 int flag_X = 0; 04733 04734 int err_flag = 0; 04735 04736 char *str_times = NULL; 04737 char str_seek_buff[256]; 04738 char *str_seek_type = NULL; 04739 char *str_seek_offset = NULL; 04740 04741 char *str_hexa = NULL; 04742 char *str_ascii = NULL; 04743 04744 size_t datasize = 0; 04745 char *databuff = NULL; 04746 04747 unsigned long long nb_times = 1; /* default = 1 */ 04748 04749 fsal_size_t block_size; /* the length of the data block to be written */ 04750 04751 fsal_u64_t nb_block_written = 0; 04752 fsal_size_t size_written = 0; 04753 fsal_size_t size_written_once = 0; 04754 04755 fsal_seek_t seek_desc = { FSAL_SEEK_CUR, 0 }; /* default: write to current position */ 04756 04757 fsal_seek_t *p_seek_desc = NULL; 04758 04759 struct timeval timer_start; 04760 struct timeval timer_stop; 04761 struct timeval timer_diff; 04762 04763 cmdfsal_thr_info_t *context; 04764 04765 /* is the fs initialized ? */ 04766 if(!is_loaded) 04767 { 04768 fprintf(output, "Error: filesystem not initialized\n"); 04769 return -1; 04770 } 04771 04772 /* initialize current thread */ 04773 04774 context = GetFSALCmdContext(); 04775 04776 if(context->is_thread_ok != TRUE) 04777 { 04778 int rc; 04779 rc = Init_Thread_Context(output, context, 0); 04780 if(rc != 0) 04781 return rc; 04782 } 04783 04784 /* is a file opened ? */ 04785 if(!context->opened) 04786 { 04787 fprintf(output, "Error: no opened file. Use 'open' command first.\n"); 04788 return -1; 04789 } 04790 04791 /* option analysis. */ 04792 04793 getopt_init(); 04794 while((option = Getopt(argc, argv, format)) != -1) 04795 { 04796 switch (option) 04797 { 04798 04799 case 'v': 04800 if(flag_v) 04801 fprintf(output, 04802 "write: warning: option 'v' has been specified more than once.\n"); 04803 else 04804 flag_v++; 04805 break; 04806 04807 case 'h': 04808 if(flag_h) 04809 fprintf(output, 04810 "write: warning: option 'h' has been specified more than once.\n"); 04811 else 04812 flag_h++; 04813 break; 04814 04815 case 'N': 04816 if(flag_N) 04817 fprintf(output, 04818 "write: warning: option 'N' has been specified more than once.\n"); 04819 else 04820 { 04821 flag_N++; 04822 str_times = Optarg; 04823 } 04824 break; 04825 04826 case 's': 04827 if(flag_s) 04828 fprintf(output, 04829 "write: warning: option 's' has been specified more than once.\n"); 04830 else 04831 { 04832 flag_s++; 04833 strncpy(str_seek_buff, Optarg, 256); 04834 str_seek_type = str_seek_buff; 04835 } 04836 break; 04837 04838 case 'A': 04839 if(flag_A) 04840 fprintf(output, 04841 "write: warning: option 'A' has been specified more than once.\n"); 04842 else if(flag_X) 04843 { 04844 fprintf(output, "write: option 'A' conflicts with option 'X'.\n"); 04845 err_flag++; 04846 } 04847 else 04848 { 04849 flag_A++; 04850 str_ascii = Optarg; 04851 } 04852 break; 04853 04854 case 'X': 04855 if(flag_X) 04856 fprintf(output, 04857 "write: warning: option 'X' has been specified more than once.\n"); 04858 else if(flag_A) 04859 { 04860 fprintf(output, "write: option 'X' conflicts with option 'A'.\n"); 04861 err_flag++; 04862 } 04863 else 04864 { 04865 flag_X++; 04866 str_hexa = Optarg; 04867 } 04868 break; 04869 04870 case '?': 04871 fprintf(output, "write: unknown option : %c\n", Optopt); 04872 err_flag++; 04873 break; 04874 } 04875 } 04876 04877 if(flag_h) 04878 { 04879 fprintf(output, help_write); 04880 return 0; 04881 } 04882 04883 /* No extra arg expected */ 04884 04885 if(Optind != argc) 04886 err_flag++; 04887 04888 if(!flag_A && !flag_X) 04889 { 04890 fprintf(output, "write: error: -A or -X option is mandatory.\n"); 04891 err_flag++; 04892 } 04893 04894 if(err_flag) 04895 { 04896 fprintf(output, help_write); 04897 return -1; 04898 } 04899 04900 /* check argument types */ 04901 04902 if(flag_N) 04903 { 04904 /* Try to convert the str_times to nb_times */ 04905 04906 rc = ato64(str_times, &nb_times); 04907 04908 if(rc == -1) 04909 { 04910 fprintf(output, "write: error: invalid number \"%s\"\n", str_times); 04911 return EINVAL; 04912 } 04913 04914 } 04915 04916 if(flag_s) 04917 { 04918 int sign = 1; 04919 04920 /* Try to parse the argument */ 04921 04922 str_seek_offset = strchr(str_seek_type, ','); 04923 04924 if(str_seek_offset == NULL) 04925 { 04926 fprintf(output, 04927 "write: error: invalid seek specifier \"%s\". <seek_type>,<offset> expected.\n", 04928 str_seek_type); 04929 return EINVAL; 04930 } 04931 04932 *str_seek_offset = '\0'; 04933 str_seek_offset++; /* the first char after the "," */ 04934 04935 /* Check seek type */ 04936 04937 if(!strncmp(str_seek_type, "CUR", 256)) 04938 seek_desc.whence = FSAL_SEEK_CUR; 04939 else if(!strncmp(str_seek_type, "SET", 256)) 04940 seek_desc.whence = FSAL_SEEK_SET; 04941 else if(!strncmp(str_seek_type, "END", 256)) 04942 seek_desc.whence = FSAL_SEEK_END; 04943 else 04944 { 04945 fprintf(output, 04946 "write: error: invalid seek type \"%s\". CUR, SET or END expected.\n", 04947 str_seek_type); 04948 return EINVAL; 04949 } 04950 04951 /* Try to convert str_seek_offset to fsal_off_t */ 04952 04953 switch (str_seek_offset[0]) 04954 { 04955 case '+': 04956 sign = 1; 04957 str_seek_offset++; 04958 break; 04959 04960 case '-': 04961 sign = -1; 04962 str_seek_offset++; 04963 break; 04964 } 04965 04966 rc = ato64(str_seek_offset, (unsigned long long *)&seek_desc.offset); 04967 04968 if(rc == -1) 04969 { 04970 fprintf(output, "write: error: invalid offset \"%s\".\n", str_seek_offset); 04971 return EINVAL; 04972 } 04973 else if(sign < 0) 04974 seek_desc.offset = -seek_desc.offset; 04975 04976 p_seek_desc = &seek_desc; 04977 04978 } 04979 else 04980 { 04981 p_seek_desc = NULL; /* default seeking */ 04982 } 04983 04984 if(flag_A) 04985 { 04986 datasize = strlen(str_ascii) + 1; /* Include null termination char. */ 04987 databuff = str_ascii; 04988 } 04989 04990 if(flag_X) 04991 { 04992 size_t length = strlen(str_hexa); 04993 04994 datasize = (length >> 1); 04995 04996 if(length % 2) 04997 { 04998 04999 /* if it is not odd: error */ 05000 fprintf(output, 05001 "write: error: in \"%s\", data length is not a multiple of 8 bits.\n", 05002 str_hexa); 05003 05004 return EINVAL; 05005 } 05006 05007 databuff = gsh_calloc(1, datasize + 1); 05008 05009 if(databuff == NULL) 05010 { 05011 fprintf(output, "write: error: Not enough memory to allocate %zu Bytes.\n", 05012 datasize); 05013 return ENOMEM; 05014 } 05015 05016 /* try to convert the string to hexa */ 05017 rc = sscanmem(databuff, datasize, str_hexa); 05018 05019 if(rc != (int)(2 * datasize)) 05020 { 05021 /* if it is not odd: error */ 05022 fprintf(output, "write: error: \"%s\" in not a valid hexa format.\n", str_hexa); 05023 05024 gsh_free(str_hexa); 05025 05026 return EINVAL; 05027 } 05028 05029 } 05030 05031 if(flag_v) 05032 { 05033 /* print a sum-up of write parameters */ 05034 fprintf(output, "Write options: Data length: %llu x %llu Bytes, Seek: %s%+lld\n", 05035 (unsigned long long)nb_times, 05036 (unsigned long long)datasize, 05037 (p_seek_desc ? (seek_desc.whence == FSAL_SEEK_SET ? "SET" : 05038 seek_desc.whence == FSAL_SEEK_CUR ? "CUR" : 05039 "END") : "DEFAULT"), 05040 (p_seek_desc ? seek_desc.offset : 0LL)); 05041 } 05042 05043 /* variables initialisation */ 05044 05045 block_size = (fsal_size_t) datasize; 05046 nb_block_written = 0; 05047 size_written = 0; 05048 size_written_once = 0; 05049 05050 gettimeofday(&timer_start, NULL); 05051 05052 /* write loop */ 05053 05054 while(nb_block_written < nb_times) 05055 { 05056 05057 st = FSAL_write(&context->current_fd, &context->context, p_seek_desc, 05058 block_size, (caddr_t) databuff, &size_written_once); 05059 05060 if(FSAL_IS_ERROR(st)) 05061 { 05062 fprintf(output, "Error executing FSAL_write:"); 05063 print_fsal_status(output, st); 05064 fprintf(output, "\n"); 05065 05066 /* exit only if it is not retryable */ 05067 if(fsal_is_retryable(st)) 05068 { 05069 sleep(1); 05070 continue; 05071 } 05072 else 05073 { 05074 if(flag_X) 05075 gsh_free(databuff); 05076 return st.major; 05077 } 05078 } 05079 05080 fprintf(output, "."); 05081 05082 /* update stats */ 05083 05084 if(size_written_once > 0) 05085 nb_block_written++; 05086 05087 size_written += size_written_once; 05088 05089 /* flush */ 05090 if(nb_block_written % 10) 05091 fflush(output); 05092 05093 /* what ever seek type was, we continue writting to the current position */ 05094 p_seek_desc = NULL; 05095 05096 } 05097 05098 gettimeofday(&timer_stop, NULL); 05099 05100 /* newline after written blocks */ 05101 fprintf(output, "\n"); 05102 05103 if(flag_v) 05104 { 05105 double bandwidth; 05106 05107 /* print stats */ 05108 fprintf(output, "Nb blocks written: %llu\n", nb_block_written); 05109 fprintf(output, "Total volume: %llu Bytes\n", size_written); 05110 05111 fprintf(output, "Time enlapsed: "); 05112 timer_diff = time_diff(timer_start, timer_stop); 05113 print_timeval(output, timer_diff); 05114 05115 bandwidth = 05116 size_written / (1024 * 1024 * 05117 (timer_diff.tv_sec + 0.000001 * timer_diff.tv_usec)); 05118 05119 fprintf(output, "Bandwidth: %f MB/s\n", bandwidth); 05120 05121 } 05122 05123 if(flag_X) 05124 gsh_free(databuff); 05125 05126 return 0; 05127 05128 } 05129 05134 int fn_fsal_close(int argc, /* IN : number of args in argv */ 05135 char **argv, /* IN : arg list */ 05136 FILE * output /* IN : output stream */ 05137 ) 05138 { 05139 05140 const char help_close[] = "usage: close\n"; 05141 05142 fsal_status_t st; 05143 05144 cmdfsal_thr_info_t *context; 05145 05146 /* is the fs initialized ? */ 05147 if(!is_loaded) 05148 { 05149 fprintf(output, "Error: filesystem not initialized\n"); 05150 return -1; 05151 } 05152 05153 /* initialize current thread */ 05154 05155 context = GetFSALCmdContext(); 05156 05157 if(context->is_thread_ok != TRUE) 05158 { 05159 int rc; 05160 rc = Init_Thread_Context(output, context, 0); 05161 if(rc != 0) 05162 return rc; 05163 } 05164 05165 /* is a file already opened ? */ 05166 if(!context->opened) 05167 { 05168 fprintf(output, "Error: this is no file currently opened.\n"); 05169 return -1; 05170 } 05171 05172 if(argc != 1) 05173 { 05174 fprintf(output, help_close); 05175 return -1; 05176 } 05177 05178 st = FSAL_close(&context->current_fd); 05179 05180 if(FSAL_IS_ERROR(st)) 05181 { 05182 fprintf(output, "Error executing FSAL_close:"); 05183 print_fsal_status(output, st); 05184 fprintf(output, "\n"); 05185 return st.major; 05186 } 05187 05188 /* note that a file is closed. */ 05189 context->opened = FALSE; 05190 05191 return 0; 05192 05193 } 05194 05199 int fn_fsal_close_byfileid(int argc, /* IN : number of args in argv */ 05200 char **argv, /* IN : arg list */ 05201 FILE * output /* IN : output stream */ 05202 ) 05203 { 05204 05205 const char help_close[] = "usage: close_byfileid <fileid>\n"; 05206 05207 fsal_status_t st; 05208 05209 cmdfsal_thr_info_t *context; 05210 05211 /* is the fs initialized ? */ 05212 if(!is_loaded) 05213 { 05214 fprintf(output, "Error: filesystem not initialized\n"); 05215 return -1; 05216 } 05217 05218 /* initialize current thread */ 05219 05220 context = GetFSALCmdContext(); 05221 05222 if(context->is_thread_ok != TRUE) 05223 { 05224 int rc; 05225 rc = Init_Thread_Context(output, context, 0); 05226 if(rc != 0) 05227 return rc; 05228 } 05229 05230 /* is a file already opened ? */ 05231 if(!context->opened) 05232 { 05233 fprintf(output, "Error: this is no file currently opened.\n"); 05234 return -1; 05235 } 05236 05237 if(argc != 1) 05238 { 05239 fprintf(output, help_close); 05240 return -1; 05241 } 05242 05243 st = FSAL_close(&context->current_fd); 05244 05245 if(FSAL_IS_ERROR(st)) 05246 { 05247 fprintf(output, "Error executing FSAL_close:"); 05248 print_fsal_status(output, st); 05249 fprintf(output, "\n"); 05250 return st.major; 05251 } 05252 05253 /* note that a file is closed. */ 05254 context->opened = FALSE; 05255 05256 return 0; 05257 05258 } 05259 05264 int fn_fsal_cat(int argc, /* IN : number of args in argv */ 05265 char **argv, /* IN : arg list */ 05266 FILE * output /* IN : output stream */ 05267 ) 05268 { 05269 05270 char format[] = "hf"; 05271 05272 const char help_cat[] = 05273 "usage: cat [-h][-f] <path>\n" 05274 " -h: print this help\n" 05275 " -f: by default, cat doesn't print more that 1MB.\n" 05276 " this option force it to print the whole file.\n"; 05277 05278 char glob_path[FSAL_MAX_PATH_LEN]; 05279 fsal_handle_t filehdl; 05280 05281 fsal_status_t st; 05282 05283 int rc, option; 05284 int flag_h = 0; 05285 int flag_f = 0; 05286 int err_flag = 0; 05287 05288 fsal_openflags_t o_flags; 05289 fsal_file_t cat_fd; 05290 05291 #define MAX_CAT_SIZE (1024*1024) 05292 fsal_size_t nb_read = 0; 05293 fsal_size_t buffsize = 1024; 05294 char readbuff[1024]; 05295 int is_eof = 0; 05296 05297 char *file = NULL; 05298 05299 cmdfsal_thr_info_t *context; 05300 05301 /* is the fs initialized ? */ 05302 if(!is_loaded) 05303 { 05304 fprintf(output, "Error: filesystem not initialized\n"); 05305 return -1; 05306 } 05307 05308 /* initialize current thread */ 05309 05310 context = GetFSALCmdContext(); 05311 05312 if(context->is_thread_ok != TRUE) 05313 { 05314 int rc; 05315 rc = Init_Thread_Context(output, context, 0); 05316 if(rc != 0) 05317 return rc; 05318 } 05319 05320 /* analysing options */ 05321 05322 getopt_init(); 05323 while((option = Getopt(argc, argv, format)) != -1) 05324 { 05325 switch (option) 05326 { 05327 case 'f': 05328 if(flag_f) 05329 fprintf(output, 05330 "cat: warning: option 'f' has been specified more than once.\n"); 05331 else 05332 flag_f++; 05333 break; 05334 case 'h': 05335 if(flag_h) 05336 fprintf(output, 05337 "cat: warning: option 'h' has been specified more than once.\n"); 05338 else 05339 flag_h++; 05340 break; 05341 case '?': 05342 fprintf(output, "cat: unknown option : %c\n", Optopt); 05343 err_flag++; 05344 break; 05345 } 05346 } 05347 05348 if(flag_h) 05349 { 05350 fprintf(output, help_cat); 05351 return 0; 05352 } 05353 05354 /* one arg expected */ 05355 if(Optind != (argc - 1)) 05356 err_flag++; 05357 else 05358 file = argv[Optind]; 05359 05360 if(err_flag) 05361 { 05362 fprintf(output, help_cat); 05363 return -1; 05364 } 05365 05366 /* copy current path. */ 05367 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 05368 05369 /* retrieves object handle */ 05370 if((rc = 05371 solvepath(glob_path, FSAL_MAX_PATH_LEN, 05372 file, context->current_dir, &filehdl, output))) 05373 return rc; 05374 05375 /* make open flags */ 05376 05377 o_flags = FSAL_O_RDONLY; 05378 05379 st = FSAL_open(&filehdl, &context->context, o_flags, &cat_fd, NULL); 05380 05381 if(FSAL_IS_ERROR(st)) 05382 { 05383 fprintf(output, "Error executing FSAL_open:"); 05384 print_fsal_status(output, st); 05385 fprintf(output, "\n"); 05386 return st.major; 05387 } 05388 05389 /* read operations */ 05390 05391 while(!is_eof && (flag_f || (nb_read < MAX_CAT_SIZE))) 05392 { 05393 fsal_size_t nb_read_once; 05394 05395 st = FSAL_read(&cat_fd, NULL, buffsize, (caddr_t) readbuff, &nb_read_once, &is_eof); 05396 05397 if(FSAL_IS_ERROR(st)) 05398 { 05399 fprintf(output, "Error executing FSAL_read:"); 05400 print_fsal_status(output, st); 05401 fprintf(output, "\n"); 05402 05403 /* exit only if it is not retryable */ 05404 if(fsal_is_retryable(st)) 05405 { 05406 sleep(1); 05407 continue; 05408 } 05409 else 05410 return st.major; 05411 } 05412 05413 if (fwrite((caddr_t) readbuff, (size_t) nb_read_once, 1, output)); 05414 05415 /* update stats */ 05416 nb_read += nb_read_once; 05417 05418 } 05419 05420 FSAL_close(&cat_fd); 05421 05422 if(!is_eof) 05423 { 05424 fprintf(output, 05425 "\n----------------- File is larger than 1MB (use -f option to display all) -----------------\n"); 05426 return EPERM; 05427 } 05428 05429 return 0; 05430 05431 } 05432 05437 int fn_fsal_rcp(int argc, /* IN : number of args in argv */ 05438 char **argv, /* IN : arg list */ 05439 FILE * output /* IN : output stream */ 05440 ) 05441 { 05442 05443 char format[] = "hvrw"; 05444 05445 const char help_rcp[] = 05446 "usage: rcp [-h][-v] -r|-w <fsal_path> <local_path>\n" 05447 " -h : print this help\n" 05448 " -v : verbose mode\n" 05449 "copy direction:\n" 05450 " -r : FSAL -> local filesystem\n" " -w : local filesystem -> FSAL\n"; 05451 05452 char glob_path[FSAL_MAX_PATH_LEN]; 05453 fsal_handle_t filehdl; 05454 05455 fsal_status_t st; 05456 05457 int rc, option; 05458 int flag_h = 0; 05459 int flag_v = 0; 05460 int flag_r = 0; 05461 int flag_w = 0; 05462 05463 int err_flag = 0; 05464 05465 char *local_file = NULL; 05466 char *fsal_file = NULL; 05467 05468 fsal_path_t local_path_fsal; 05469 fsal_rcpflag_t rcp_opt; 05470 05471 cmdfsal_thr_info_t *context; 05472 05473 /* is the fs initialized ? */ 05474 if(!is_loaded) 05475 { 05476 fprintf(output, "Error: filesystem not initialized\n"); 05477 return -1; 05478 } 05479 05480 /* initialize current thread */ 05481 05482 context = GetFSALCmdContext(); 05483 05484 if(context->is_thread_ok != TRUE) 05485 { 05486 int rc; 05487 rc = Init_Thread_Context(output, context, 0); 05488 if(rc != 0) 05489 return rc; 05490 } 05491 05492 /* analysing options */ 05493 05494 getopt_init(); 05495 while((option = Getopt(argc, argv, format)) != -1) 05496 { 05497 switch (option) 05498 { 05499 case 'r': 05500 if(flag_w) 05501 { 05502 fprintf(output, "rcp: error: option 'r' conflicts with option 'w'.\n"); 05503 err_flag++; 05504 } 05505 else if(flag_r) 05506 fprintf(output, 05507 "rcp: warning: option 'r' has been specified more than once.\n"); 05508 else 05509 flag_r++; 05510 break; 05511 case 'w': 05512 if(flag_r) 05513 { 05514 fprintf(output, "rcp: error: option 'w' conflicts with option 'r'.\n"); 05515 err_flag++; 05516 } 05517 else if(flag_w) 05518 fprintf(output, 05519 "rcp: warning: option 'w' has been specified more than once.\n"); 05520 else 05521 flag_w++; 05522 break; 05523 case 'h': 05524 if(flag_h) 05525 fprintf(output, 05526 "rcp: warning: option 'h' has been specified more than once.\n"); 05527 else 05528 flag_h++; 05529 break; 05530 case 'v': 05531 if(flag_v) 05532 fprintf(output, 05533 "rcp: warning: option 'v' has been specified more than once.\n"); 05534 else 05535 flag_v++; 05536 break; 05537 case '?': 05538 fprintf(output, "rcp: unknown option : %c\n", Optopt); 05539 err_flag++; 05540 break; 05541 } 05542 } 05543 05544 if(flag_h) 05545 { 05546 fprintf(output, help_rcp); 05547 return 0; 05548 } 05549 05550 /* two args expected */ 05551 if(Optind != (argc - 2)) 05552 err_flag++; 05553 else 05554 { 05555 fsal_file = argv[Optind]; 05556 local_file = argv[Optind + 1]; 05557 } 05558 05559 if(err_flag) 05560 { 05561 fprintf(output, help_rcp); 05562 return -1; 05563 } 05564 05565 /* copy current path. */ 05566 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 05567 05568 /* retrieves object handle */ 05569 05570 if((rc = 05571 solvepath(glob_path, FSAL_MAX_PATH_LEN, 05572 fsal_file, context->current_dir, &filehdl, output))) 05573 return rc; 05574 05575 /* build fsal path strcuture for local file */ 05576 05577 st = FSAL_str2path(local_file, strlen(local_file) + 1, &local_path_fsal); 05578 05579 if(FSAL_IS_ERROR(st)) 05580 { 05581 05582 fprintf(output, "Error executing FSAL_str2path:"); 05583 print_fsal_status(output, st); 05584 fprintf(output, "\n"); 05585 return st.major; 05586 05587 } 05588 05589 /* make rcp flags */ 05590 05591 if(flag_r) 05592 rcp_opt = FSAL_RCP_FS_TO_LOCAL | FSAL_RCP_LOCAL_CREAT; 05593 else 05594 rcp_opt = FSAL_RCP_LOCAL_TO_FS; 05595 05596 if(flag_v) 05597 { 05598 fprintf(output, "rcp: calling FSAL_rcp with options: "); 05599 05600 if(rcp_opt & FSAL_RCP_FS_TO_LOCAL) 05601 fprintf(output, "FSAL_RCP_FS_TO_LOCAL "); 05602 05603 if(rcp_opt & FSAL_RCP_LOCAL_TO_FS) 05604 fprintf(output, "FSAL_RCP_LOCAL_TO_FS "); 05605 05606 if(rcp_opt & FSAL_RCP_LOCAL_EXCL) 05607 fprintf(output, "FSAL_RCP_LOCAL_EXCL "); 05608 05609 if(rcp_opt & FSAL_RCP_LOCAL_CREAT) 05610 fprintf(output, "FSAL_RCP_LOCAL_CREAT "); 05611 05612 fprintf(output, "\n"); 05613 } 05614 05615 /* rcp operation */ 05616 05617 st = FSAL_rcp(&filehdl, &context->context, &local_path_fsal, rcp_opt); 05618 05619 if(FSAL_IS_ERROR(st)) 05620 { 05621 fprintf(output, "Error executing FSAL_rcp:"); 05622 print_fsal_status(output, st); 05623 fprintf(output, "\n"); 05624 return st.major; 05625 } 05626 05627 if(flag_v) 05628 { 05629 if(flag_r) 05630 fprintf(output, "rcp operation successfully completed : %s -> %s\n", glob_path, 05631 local_file); 05632 else 05633 fprintf(output, "rcp operation successfully completed : %s -> %s\n", local_file, 05634 glob_path); 05635 } 05636 05637 return 0; 05638 05639 } 05640 05642 int fn_fsal_cross(int argc, /* IN : number of args in argv */ 05643 char **argv, /* IN : arg list */ 05644 FILE * output /* IN : output stream */ 05645 ) 05646 { 05647 05648 const char help_cross[] = "usage: cross <junction_path>\n"; 05649 05650 char glob_path[FSAL_MAX_PATH_LEN]; 05651 fsal_handle_t junction_hdl, root_hdl; 05652 fsal_attrib_list_t attrs; 05653 fsal_status_t st; 05654 int rc; 05655 05656 cmdfsal_thr_info_t *context; 05657 05658 /* is the fs initialized ? */ 05659 if(!is_loaded) 05660 { 05661 fprintf(output, "Error: filesystem not initialized\n"); 05662 return -1; 05663 } 05664 05665 /* initialize current thread */ 05666 05667 context = GetFSALCmdContext(); 05668 05669 if(context->is_thread_ok != TRUE) 05670 { 05671 int rc; 05672 rc = Init_Thread_Context(output, context, 0); 05673 if(rc != 0) 05674 return rc; 05675 } 05676 05677 /* Exactly one arg expected */ 05678 if(argc != 2) 05679 { 05680 fprintf(output, help_cross); 05681 return -1; 05682 } 05683 05684 /* is it a relative or absolute path. */ 05685 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 05686 05687 if((rc = 05688 solvepath(glob_path, FSAL_MAX_PATH_LEN, 05689 argv[1], context->current_dir, &junction_hdl, output))) 05690 return rc; 05691 05692 /* solves the junction */ 05693 FSAL_CLEAR_MASK(attrs.asked_attributes); 05694 FSAL_SET_MASK(attrs.asked_attributes, 05695 FSAL_ATTR_TYPE | FSAL_ATTR_MODE | FSAL_ATTR_GROUP | FSAL_ATTR_OWNER); 05696 05697 st = FSAL_lookupJunction(&junction_hdl, &context->context, &root_hdl, NULL); 05698 05699 if(FSAL_IS_ERROR(st)) 05700 { 05701 char buff[2 * sizeof(fsal_handle_t) + 1]; 05702 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &junction_hdl); 05703 05704 fprintf(output, "Error executing FSAL_lookupJunction(@%s):", buff); 05705 print_fsal_status(output, st); 05706 fprintf(output, "\n"); 05707 return st.major; 05708 } 05709 05710 /* Apply changes */ 05711 strncat(glob_path, ">", FSAL_MAX_PATH_LEN); 05712 strncpy(context->current_path, glob_path, FSAL_MAX_PATH_LEN); 05713 context->current_dir = root_hdl; 05714 05715 { 05716 char buff[2 * sizeof(fsal_handle_t) + 1]; 05717 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &context->current_dir); 05718 05719 fprintf(output, "Current directory is \"%s\" (@%s)\n", context->current_path, buff); 05720 } 05721 05722 return 0; 05723 05724 } 05725 05727 int fn_fsal_handle(int argc, /* IN : number of args in argv */ 05728 char **argv, /* IN : arg list */ 05729 FILE * output /* IN : output stream */ 05730 ) 05731 { 05732 05733 const char help_handle[] = "usage: handle digest {2|3|4} <handle|path>\n" 05734 " handle expand {2|3|4} <handle>\n"; 05735 cmdfsal_thr_info_t *context; 05736 char glob_path[FSAL_MAX_PATH_LEN]; 05737 char buff[1024]; 05738 char buff2[1024]; 05739 fsal_handle_t filehdl; 05740 struct fsal_handle_desc fh_desc; 05741 fsal_status_t st; 05742 int rc; 05743 fsal_digesttype_t dt ; /* digest type */ 05744 size_t ds ; /* digest size */ 05745 05746 05747 /* is the fs initialized ? */ 05748 if(!is_loaded) 05749 { 05750 fprintf(output, "Error: filesystem not initialized\n"); 05751 return -1; 05752 } 05753 05754 /* initialize current thread */ 05755 05756 context = GetFSALCmdContext(); 05757 05758 if(context->is_thread_ok != TRUE) 05759 { 05760 int rc; 05761 rc = Init_Thread_Context(output, context, 0); 05762 if(rc != 0) 05763 return rc; 05764 } 05765 05766 /* Exactly 3 args expected */ 05767 if(argc != 4) 05768 { 05769 fprintf(output, help_handle); 05770 return -1; 05771 } 05772 05773 switch( atoi(argv[2]) ) 05774 { 05775 case 2: 05776 dt = FSAL_DIGEST_NFSV2; 05777 ds = FSAL_DIGEST_SIZE_HDLV2; 05778 break; 05779 case 3: 05780 dt = FSAL_DIGEST_NFSV3; 05781 ds = FSAL_DIGEST_SIZE_HDLV3; 05782 break; 05783 case 4: 05784 dt = FSAL_DIGEST_NFSV4; 05785 ds = FSAL_DIGEST_SIZE_HDLV4; 05786 break; 05787 default: 05788 fprintf(output, "Unsupported NFS version: '%s' (2, 3 or 4 expected)\n", argv[2]); 05789 fprintf(output, help_handle); 05790 return EINVAL; 05791 } 05792 05793 /* digest operation */ 05794 if ( !strcmp(argv[1], "digest") ) 05795 { 05796 /* retrieves object handle */ 05797 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 05798 if((rc = solvepath(glob_path, FSAL_MAX_PATH_LEN, 05799 argv[3], context->current_dir, &filehdl, output))) 05800 return rc; 05801 05802 fh_desc.start = buff; 05803 fh_desc.len = sizeof(buff); 05804 st = FSAL_DigestHandle(&context->exp_context, dt, &filehdl, &fh_desc); 05805 if(FSAL_IS_ERROR(st)) 05806 { 05807 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &filehdl); 05808 fprintf(output, "Error executing FSAL_DigestHandle(@%s):", buff); 05809 print_fsal_status(output, st); 05810 fprintf(output, "\n"); 05811 return st.major; 05812 } 05813 /* display the result */ 05814 snprintmem(buff2, 1024, buff, ds); 05815 fprintf(output, "%s\n", buff2); 05816 } 05817 /* expand operation */ 05818 else if ( !strcmp(argv[1], "expand") ) 05819 { 05820 memset(buff, 0, 1024); 05821 size_t length = strlen(argv[3]); 05822 size_t datasize = (length >> 1); 05823 05824 if(length % 2) 05825 { 05826 /* if it is not odd: error */ 05827 fprintf(output, 05828 "handle expand: error: in \"%s\", data length is not a multiple of 8 bits.\n", 05829 argv[3]); 05830 return EINVAL; 05831 } 05832 05833 /* try to read hexa from the string */ 05834 rc = sscanmem(buff, datasize, argv[3]); 05835 05836 if (rc < 0) 05837 { 05838 fprintf(output, "Error %d reading digest from command line (%s)", 05839 -rc, argv[3]); 05840 return rc; 05841 } 05842 else if (rc != 2*ds) 05843 { 05844 fprintf(output, "Unexpected data size for digest type NFSv%s: 2x%zu expected, %u read\n", 05845 argv[2], ds, rc); 05846 return EINVAL; 05847 } 05848 05849 fh_desc.start = buff; 05850 fh_desc.len = length; 05851 /* Expand the handle */ 05852 st = FSAL_ExpandHandle(&context->exp_context, dt, &fh_desc); 05853 if(FSAL_IS_ERROR(st)) 05854 { 05855 fprintf(output, "Error executing FSAL_ExpandHandle(%s):", argv[3]); 05856 print_fsal_status(output, st); 05857 fprintf(output, "\n"); 05858 return st.major; 05859 } 05860 05861 snprintHandle(buff2, 2 * fh_desc.len + 1, fh_desc.start); 05862 fprintf(output, "@%s\n", buff2); 05863 } 05864 else 05865 { 05866 fprintf(output, help_handle); 05867 return -1; 05868 } 05869 return 0; 05870 } 05871 05872 05873 05875 int fn_fsal_handlecmp(int argc, /* IN : number of args in argv */ 05876 char **argv, /* IN : arg list */ 05877 FILE * output /* IN : output stream */ 05878 ) 05879 { 05880 const char help_handlecmp[] = "usage: handlecmp <obj1> <obj2>\n"; 05881 05882 char glob_path1[FSAL_MAX_PATH_LEN]; 05883 char glob_path2[FSAL_MAX_PATH_LEN]; 05884 char buff[2 * sizeof(fsal_handle_t) + 1]; 05885 05886 fsal_handle_t hdl1, hdl2; 05887 fsal_status_t st; 05888 int rc; 05889 05890 cmdfsal_thr_info_t *context; 05891 05892 /* is the fs initialized ? */ 05893 if(!is_loaded) 05894 { 05895 fprintf(output, "Error: filesystem not initialized\n"); 05896 return -1; 05897 } 05898 05899 /* initialize current thread */ 05900 05901 context = GetFSALCmdContext(); 05902 05903 if(context->is_thread_ok != TRUE) 05904 { 05905 int rc; 05906 rc = Init_Thread_Context(output, context, 0); 05907 if(rc != 0) 05908 return rc; 05909 } 05910 05911 /* Exactly 2 args expected */ 05912 if(argc != 3) 05913 { 05914 fprintf(output, help_handlecmp); 05915 return -1; 05916 } 05917 05918 strncpy(glob_path1, context->current_path, FSAL_MAX_PATH_LEN); 05919 strncpy(glob_path2, context->current_path, FSAL_MAX_PATH_LEN); 05920 05921 if((rc = 05922 solvepath(glob_path1, FSAL_MAX_PATH_LEN, 05923 argv[1], context->current_dir, &hdl1, output))) 05924 return rc; 05925 05926 if((rc = 05927 solvepath(glob_path2, FSAL_MAX_PATH_LEN, 05928 argv[2], context->current_dir, &hdl2, output))) 05929 return rc; 05930 05931 /* it should return : 05932 * - 0 if handle are the same 05933 * - A non null value else. 05934 */ 05935 rc = FSAL_handlecmp(&hdl1, &hdl2, &st); 05936 05937 if(FSAL_IS_ERROR(st)) 05938 { 05939 fprintf(output, "Error executing FSAL_handlecmp:"); 05940 print_fsal_status(output, st); 05941 fprintf(output, "\n"); 05942 return st.major; 05943 } 05944 05945 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &hdl1); 05946 fprintf(output, "%s: handle = @%s\n", argv[1], buff); 05947 05948 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &hdl2); 05949 fprintf(output, "%s: handle = @%s\n", argv[2], buff); 05950 05951 if(rc == 0) 05952 { 05953 fprintf(output, "Handles are identical.\n"); 05954 return rc; 05955 } 05956 else 05957 { 05958 fprintf(output, "Handles are different.\n"); 05959 return rc; 05960 } 05961 05962 return 0; 05963 }