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 00034 #ifdef HAVE_CONFIG_H 00035 #include "config.h" 00036 #endif 00037 00038 #include <strings.h> 00039 #include <errno.h> 00040 #include <sys/types.h> 00041 #include <sys/stat.h> 00042 #include <sys/time.h> 00043 #include <unistd.h> 00044 #include <time.h> 00045 #include <ctype.h> 00046 #include <string.h> 00047 #include <pwd.h> 00048 #include "fsal.h" 00049 #include "mfsl.h" 00050 #include "log.h" 00051 #include "err_ghost_fs.h" 00052 #include "config_parsing.h" 00053 #include "cmd_tools.h" 00054 #include "commands.h" 00055 #include "Getopt.h" 00056 #icnlude "abstract_mem.h" 00057 00058 static pthread_mutex_t mutex_log = PTHREAD_MUTEX_INITIALIZER; 00059 00060 static int is_loaded = FALSE; /* filsystem initialization status */ 00061 00062 typedef struct cmdmfsl_thr_info__ 00063 { 00064 int is_thread_ok; /* per thread initialization status */ 00065 mfsl_object_t current_dir; /* current directory handle */ 00066 char current_path[FSAL_MAX_PATH_LEN]; /* current path */ 00067 00068 /* thread's context */ 00069 fsal_op_context_t context; 00070 mfsl_context_t mcontext; 00071 00072 /* export context : on for each thread, 00073 * on order to make it possible for them 00074 * to access different filesets. 00075 */ 00076 fsal_export_context_t exp_context; 00077 int opened; /* is file opened ? */ 00078 mfsl_file_t current_fd; /* current file descriptor */ 00079 00080 } cmdmfsl_thr_info_t; 00081 00082 /* pthread key to manage thread specific configuration */ 00083 00084 static pthread_key_t thread_key; 00085 static pthread_once_t once_key = PTHREAD_ONCE_INIT; 00086 00087 /* init pthtread_key for current thread */ 00088 00089 static void init_keys(void) 00090 { 00091 if(pthread_key_create(&thread_key, NULL) == -1) 00092 printf("Error %d creating pthread key for thread %p : %s\n", 00093 errno, (caddr_t) pthread_self(), strerror(errno)); 00094 00095 return; 00096 } /* init_keys */ 00097 00102 cmdmfsl_thr_info_t *GetMFSLCmdContext() 00103 { 00104 00105 cmdmfsl_thr_info_t *p_current_thread_vars; 00106 00107 /* first, we init the keys if this is the first time */ 00108 if(pthread_once(&once_key, init_keys) != 0) 00109 { 00110 printf("Error %d calling pthread_once for thread %p : %s\n", 00111 errno, (caddr_t) pthread_self(), strerror(errno)); 00112 return NULL; 00113 } 00114 00115 p_current_thread_vars = (cmdmfsl_thr_info_t *) pthread_getspecific(thread_key); 00116 00117 /* we allocate the thread context if this is the first time */ 00118 if(p_current_thread_vars == NULL) 00119 { 00120 00121 /* allocates thread structure */ 00122 p_current_thread_vars = 00123 gsh_malloc(sizeof(cmdmfsl_thr_info_t)); 00124 00125 /* panic !!! */ 00126 if(p_current_thread_vars == NULL) 00127 { 00128 printf("%p:commands_FSAL: Not enough memory\n", (caddr_t) pthread_self()); 00129 return NULL; 00130 } 00131 00132 /* Clean thread context */ 00133 00134 memset(p_current_thread_vars, 0, sizeof(cmdmfsl_thr_info_t)); 00135 00136 p_current_thread_vars->is_thread_ok = FALSE; 00137 strcpy(p_current_thread_vars->current_path, ""); 00138 p_current_thread_vars->opened = FALSE; 00139 00140 /* set the specific value */ 00141 pthread_setspecific(thread_key, (void *)p_current_thread_vars); 00142 00143 } 00144 00145 return p_current_thread_vars; 00146 00147 } /* GetMFSLCmdContext */ 00148 00152 int Init_Thread_MFSL(FILE * output, cmdmfsl_thr_info_t * context, int flag_v) 00153 { 00154 00155 uid_t uid; 00156 fsal_status_t st; 00157 mfsl_object_t hdl_dir; 00158 char buff[2 * sizeof(fsal_handle_t) + 1]; 00159 struct passwd *pw_struct; 00160 00161 /* for the moment, create export context for root fileset */ 00162 st = FSAL_BuildExportContext(&context->exp_context, NULL, NULL); 00163 00164 if(FSAL_IS_ERROR(st)) 00165 { 00166 fprintf(output, "Error executing FSAL_BuildExportContext:"); 00167 print_fsal_status(output, st); 00168 fprintf(output, "\n"); 00169 return st.major; 00170 } 00171 00172 /* get user's credentials */ 00173 00174 st = FSAL_InitClientContext(&context->context); 00175 00176 if(FSAL_IS_ERROR(st)) 00177 { 00178 fprintf(output, "Error executing FSAL_InitClientContext:"); 00179 print_fsal_status(output, st); 00180 fprintf(output, "\n"); 00181 return st.major; 00182 } 00183 00184 uid = getuid(); 00185 pw_struct = getpwuid(uid); 00186 00187 if(pw_struct == NULL) 00188 { 00189 fprintf(output, "Unknown uid %u\n", uid); 00190 return errno; 00191 } 00192 00193 st = FSAL_GetClientContext(&context->context, &context->exp_context, 00194 uid, pw_struct->pw_gid, NULL, 0); 00195 00196 if(FSAL_IS_ERROR(st)) 00197 { 00198 fprintf(output, "Error executing FSAL_GetUserCred:"); 00199 print_fsal_status(output, st); 00200 fprintf(output, "\n"); 00201 return st.major; 00202 } 00203 00204 /* get MFSL_Context */ 00205 st = MFSL_GetContext(&context->mcontext, &context->context); 00206 00207 if(FSAL_IS_ERROR(st)) 00208 { 00209 fprintf(output, "Error executing MFSL_GetContext:"); 00210 print_fsal_status(output, st); 00211 fprintf(output, "\n"); 00212 return st.major; 00213 } 00214 00215 /* get root file handle */ 00216 00217 /* lookup */ 00218 00219 st = MFSL_lookup(NULL, NULL, &context->context, &context->mcontext, &hdl_dir, NULL, NULL); 00220 00221 if(FSAL_IS_ERROR(st)) 00222 { 00223 00224 fprintf(output, "Error executing MFSL_lookup:"); 00225 print_fsal_status(output, st); 00226 fprintf(output, "\n"); 00227 return st.major; 00228 00229 } 00230 00231 /* save root handle */ 00232 00233 context->current_dir = hdl_dir; 00234 context->is_thread_ok = TRUE; 00235 00236 strcpy(context->current_path, "/"); 00237 00238 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &context->current_dir.handle); 00239 if(flag_v) 00240 fprintf(output, "Current directory is \"%s\" (@%s)\n", context->current_path, buff); 00241 00242 return 0; 00243 00244 } 00245 00246 void mfsl_layer_SetLogLevel(int log_lvl) 00247 { 00248 /* mutex pour proteger le descriptor de log */ 00249 pthread_mutex_lock(&mutex_log); 00250 00251 SetComponentLogLevel(COMPONENT_MFSL, log_lvl); 00252 00253 pthread_mutex_unlock(&mutex_log); 00254 } 00255 00256 static void getopt_init() 00257 { 00258 Opterr = 0; /* disables Getopt error message */ 00259 /* reinits Getopt processing */ 00260 Optind = 1; 00261 } 00262 00263 int mfsl_init(char *filename, int flag_v, FILE * output) 00264 { 00265 config_file_t config_file; 00266 00267 /* FSAL init parameters */ 00268 mfsl_parameter_t init_param; 00269 fsal_status_t st; 00270 00271 /* thread context */ 00272 cmdmfsl_thr_info_t *context; 00273 00274 /* Initializes the FSAL */ 00275 00276 /* use FSAL error family. */ 00277 00278 AddFamilyError(ERR_MFSL, "MFSL related Errors", tab_errstatus_MFSL); 00279 AddFamilyError(ERR_POSIX, "POSIX Errors", tab_systeme_status); 00280 00281 /* set configuration defaults */ 00282 MFSL_SetDefault_parameter(&init_param); 00283 00284 /* Parse config file */ 00285 00286 config_file = config_ParseFile(filename); 00287 00288 if(!config_file) 00289 { 00290 fprintf(output, "init_fs: Error parsing %s: %s\n", filename, config_GetErrorMsg()); 00291 return -1; 00292 } 00293 00294 /* Load FSAL configuration from file configuration */ 00295 00296 st = MFSL_load_parameter_from_conf(config_file, &init_param); 00297 00298 if(FSAL_IS_ERROR(st)) 00299 { 00300 if(st.major == ERR_FSAL_NOENT) 00301 { 00302 #if defined( _USE_MFSL_ASYNC ) 00303 fprintf(output, "Missing MFSL_Async stanza in config file\n"); 00304 #elif defined( _USE_MFSL_PROXY_RPCSECGSS ) 00305 fprintf(output, "Missing MFSL_Proxy_RrpSeGss stanza in config file\n"); 00306 #else 00307 fprintf(output, "Missing MFSL stanza in config file\n"); 00308 #endif 00309 } 00310 else 00311 { 00312 fprintf(output, "Error executing MFSL_load_FSAL_parameter_from_conf:"); 00313 print_fsal_status(output, st); 00314 fprintf(output, "\n"); 00315 return st.major; 00316 } 00317 } 00318 00319 /* Free config struct */ 00320 config_Free(config_file); 00321 00322 /* Initialization */ 00323 00324 if(flag_v) 00325 fprintf(output, "MFSL initialization...\n"); 00326 00327 st = MFSL_Init(&init_param); 00328 00329 if(FSAL_IS_ERROR(st)) 00330 { 00331 00332 fprintf(output, "Error executing MFSL_Init:"); 00333 print_fsal_status(output, st); 00334 fprintf(output, "\n"); 00335 return st.major; 00336 00337 } 00338 00339 is_loaded = TRUE; 00340 00341 /* initialize current thread */ 00342 00343 context = GetMFSLCmdContext(); 00344 00345 if(context->is_thread_ok != TRUE) 00346 { 00347 int rc; 00348 rc = Init_Thread_MFSL(output, context, flag_v); 00349 if(rc != 0) 00350 return rc; 00351 } 00352 00353 return 0; 00354 } 00355 00357 int fn_mfsl_init(int argc, /* IN : number of args in argv */ 00358 char **argv, /* IN : arg list */ 00359 FILE * output) /* IN : output stream */ 00360 { 00361 int rc; 00362 00363 static char format[] = "hv"; 00364 00365 static char help_init[] = 00366 "usage: init_fs [options] <ganesha_config_file>\n" 00367 "options :\n" "\t-h print this help\n" "\t-v verbose mode\n"; 00368 00369 int option; 00370 int flag_v = 0; 00371 int flag_h = 0; 00372 int err_flag = 0; 00373 char *filename = NULL; 00374 00375 /* analysing options */ 00376 getopt_init(); 00377 while((option = Getopt(argc, argv, format)) != -1) 00378 { 00379 switch (option) 00380 { 00381 case 'v': 00382 if(flag_v) 00383 fprintf(output, 00384 "init_fs: warning: option 'v' has been specified more than once.\n"); 00385 else 00386 flag_v++; 00387 break; 00388 case 'h': 00389 if(flag_h) 00390 fprintf(output, 00391 "init_fs: warning: option 'h' has been specified more than once.\n"); 00392 else 00393 flag_h++; 00394 break; 00395 case '?': 00396 fprintf(output, "init_fs: unknown option : %c\n", Optopt); 00397 err_flag++; 00398 break; 00399 } 00400 } 00401 00402 if(flag_h) 00403 { 00404 fprintf(output, help_init); 00405 return 0; 00406 } 00407 00408 /* verifies mandatory argument */ 00409 00410 if(Optind != (argc - 1)) 00411 { 00412 /* too much or not enough arguments */ 00413 err_flag++; 00414 } 00415 else 00416 { 00417 filename = argv[Optind]; 00418 } 00419 00420 if(err_flag) 00421 { 00422 fprintf(output, help_init); 00423 return -1; 00424 } 00425 00426 rc = mfsl_init(filename, flag_v, output); 00427 00428 return rc; 00429 } 00430 00433 int fn_mfsl_pwd(int argc, /* IN : number of args in argv */ 00434 char **argv, /* IN : arg list */ 00435 FILE * output /* IN : output stream */ 00436 ) 00437 { 00438 00439 cmdmfsl_thr_info_t *context; 00440 00441 /* is the fs initialized ? */ 00442 if(!is_loaded) 00443 { 00444 fprintf(output, "Error: filesystem not initialized\n"); 00445 return -1; 00446 } 00447 00448 /* initialize current thread */ 00449 00450 context = GetMFSLCmdContext(); 00451 00452 if(context->is_thread_ok != TRUE) 00453 { 00454 int rc; 00455 rc = Init_Thread_MFSL(output, context, 0); 00456 if(rc != 0) 00457 return rc; 00458 } 00459 00460 { 00461 char buff[2 * sizeof(fsal_handle_t) + 1]; 00462 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &context->current_dir.handle); 00463 00464 fprintf(output, "Current directory is \"%s\" (@%s)\n", context->current_path, buff); 00465 00466 } 00467 00468 return 0; 00469 00470 } 00471 00472 /* solves a relative or absolute path */ 00473 00474 int msfl_solvepath(char *io_global_path, int size_global_path, /* [IN-OUT] global path */ 00475 char *i_spec_path, /* [IN] user specified path */ 00476 mfsl_object_t i_current_handle, /* [IN] current directory handle */ 00477 mfsl_object_t * new_handle, /* [OUT] target object handle */ 00478 FILE * output) 00479 { 00480 00481 char str_path[FSAL_MAX_PATH_LEN]; 00482 cmdmfsl_thr_info_t *context; 00483 00484 context = GetMFSLCmdContext(); 00485 00486 if(context->is_thread_ok != TRUE) 00487 { 00488 int rc; 00489 rc = Init_Thread_MFSL(output, context, 0); 00490 if(rc != 0) 00491 return rc; 00492 } 00493 00494 /* local copy */ 00495 memset( str_path, 0, FSAL_MAX_PATH_LEN ) ; 00496 strncpy(str_path, i_spec_path, FSAL_MAX_PATH_LEN); 00497 00498 if(str_path[0] == '@') 00499 /* It is a file handle */ 00500 { 00501 int rc; 00502 00503 rc = sscanHandle(new_handle, str_path + 1); 00504 00505 if(rc <= 0) 00506 { 00507 fprintf(output, "Invalid FileHandle: %s\n", str_path); 00508 return -1; 00509 } 00510 00511 if(str_path[rc + 1] != '\0') 00512 { 00513 fprintf(output, "Invalid FileHandle: %s\n", str_path); 00514 return -1; 00515 } 00516 00517 strncpy(io_global_path, str_path, size_global_path); 00518 00519 return 0; 00520 00521 } 00522 else if(str_path[0] == '/') 00523 /* absolute path, proceed a lookupPath */ 00524 { 00525 fsal_path_t path; 00526 fsal_status_t st; 00527 mfsl_object_t tmp_hdl; 00528 00529 if(FSAL_IS_ERROR(st = FSAL_str2path(str_path, FSAL_MAX_PATH_LEN, &path))) 00530 { 00531 fprintf(output, "Error executing FSAL_str2path:"); 00532 print_fsal_status(output, st); 00533 fprintf(output, "\n"); 00534 return st.major; 00535 } 00536 00537 if(FSAL_IS_ERROR(st = MFSL_lookupPath(&path, 00538 &context->context, 00539 &context->mcontext, &tmp_hdl, NULL))) 00540 { 00541 fprintf(output, "Error executing MFSL_lookupPath:"); 00542 print_fsal_status(output, st); 00543 fprintf(output, "\n"); 00544 return st.major; 00545 } 00546 00547 /* cleans path */ 00548 clean_path(str_path, FSAL_MAX_PATH_LEN); 00549 00550 strncpy(io_global_path, str_path, size_global_path); 00551 *new_handle = tmp_hdl; 00552 00553 return 0; 00554 00555 } 00556 else 00557 /* relative path, proceed a step by step lookup */ 00558 { 00559 fsal_name_t name; 00560 fsal_status_t st; 00561 mfsl_object_t old_hdl = i_current_handle; 00562 mfsl_object_t tmp_hdl; 00563 char tmp_path[FSAL_MAX_PATH_LEN]; 00564 char *next_name = str_path; 00565 char *curr = str_path; 00566 int last = 0; 00567 00568 tmp_path[0] = '\0'; /* empty string */ 00569 00570 do 00571 { 00572 00573 /* tokenize to the next '/' */ 00574 while((*curr != '\0') && (*curr != '/')) 00575 curr++; 00576 00577 if(!(*curr)) 00578 last = 1; /* remembers if it was the last dir */ 00579 *curr = '\0'; 00580 00581 /* build the name */ 00582 if(FSAL_IS_ERROR(st = FSAL_str2name(next_name, FSAL_MAX_PATH_LEN, &name))) 00583 { 00584 fprintf(output, "Error executing FSAL_str2name:"); 00585 print_fsal_status(output, st); 00586 fprintf(output, "\n"); 00587 return st.major; 00588 } 00589 00590 /* lookup this name */ 00591 if(FSAL_IS_ERROR(st = MFSL_lookup(&old_hdl, 00592 &name, 00593 &context->context, 00594 &context->mcontext, &tmp_hdl, NULL, NULL))) 00595 { 00596 fprintf(output, "Error executing MFSL_lookup:"); 00597 print_fsal_status(output, st); 00598 fprintf(output, "\n"); 00599 return st.major; 00600 } 00601 00602 /* if handles are the same, we are at fileset root, 00603 * so, don't modify the path. 00604 * Else, we contatenate them. 00605 */ 00606 if(FSAL_handlecmp(&old_hdl.handle, &tmp_hdl.handle, &st) != 0) 00607 { 00608 /* updates current handle */ 00609 old_hdl = tmp_hdl; 00610 00611 /* adds /name at the end of the path */ 00612 strncat(tmp_path, "/", FSAL_MAX_PATH_LEN); 00613 strncat(tmp_path, next_name, FSAL_MAX_PATH_LEN); 00614 } 00615 00616 /* updates cursors */ 00617 if(!last) 00618 { 00619 curr++; 00620 next_name = curr; 00621 /* ignore successive slashes */ 00622 while((*curr != '\0') && (*curr == '/')) 00623 { 00624 curr++; 00625 next_name = curr; 00626 } 00627 if(!(*curr)) 00628 last = 1; /* it is the last dir */ 00629 } 00630 00631 } 00632 while(!last); 00633 00634 /* everything is OK, apply changes */ 00635 00636 strncat(io_global_path, tmp_path, size_global_path); 00637 clean_path(io_global_path, size_global_path); 00638 00639 *new_handle = old_hdl; 00640 00641 return 0; 00642 00643 } 00644 00645 } 00646 00648 int fn_mfsl_cd(int argc, /* IN : number of args in argv */ 00649 char **argv, /* IN : arg list */ 00650 FILE * output /* IN : output stream */ 00651 ) 00652 { 00653 00654 static char help_cd[] = "usage: cd <path>\n"; 00655 00656 char glob_path[FSAL_MAX_PATH_LEN]; 00657 mfsl_object_t new_hdl; 00658 fsal_attrib_list_t attrs; 00659 fsal_status_t st; 00660 int rc; 00661 00662 cmdmfsl_thr_info_t *context; 00663 00664 /* is the fs initialized ? */ 00665 if(!is_loaded) 00666 { 00667 fprintf(output, "Error: filesystem not initialized\n"); 00668 return -1; 00669 } 00670 00671 /* initialize current thread */ 00672 00673 context = GetMFSLCmdContext(); 00674 00675 if(context->is_thread_ok != TRUE) 00676 { 00677 int rc; 00678 rc = Init_Thread_MFSL(output, context, 0); 00679 if(rc != 0) 00680 return rc; 00681 } 00682 00683 /* Exactly one arg expected */ 00684 if(argc != 2) 00685 { 00686 fprintf(output, help_cd); 00687 return -1; 00688 } 00689 00690 /* is it a relative or absolute path. */ 00691 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 00692 00693 if(rc = 00694 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 00695 argv[1], context->current_dir, &new_hdl, output)) 00696 return rc; 00697 00698 /* verify if the object is a directory */ 00699 FSAL_CLEAR_MASK(attrs.asked_attributes); 00700 FSAL_SET_MASK(attrs.asked_attributes, 00701 FSAL_ATTR_TYPE | FSAL_ATTR_MODE | FSAL_ATTR_GROUP | FSAL_ATTR_OWNER); 00702 00703 if(FSAL_IS_ERROR(st = MFSL_getattrs(&new_hdl, 00704 &context->context, &context->mcontext, &attrs, NULL))) 00705 { 00706 fprintf(output, "Error executing MFSL_getattrs:"); 00707 print_fsal_status(output, st); 00708 fprintf(output, "\n"); 00709 return st.major; 00710 } 00711 00712 if(attrs.type != FSAL_TYPE_DIR) 00713 { 00714 fprintf(output, "Error: %s is not a directory\n", glob_path); 00715 return ENOTDIR; 00716 } 00717 00718 if(FSAL_IS_ERROR(st = FSAL_test_access(&context->context, FSAL_X_OK, &attrs))) 00719 { 00720 fprintf(output, "Error: %s: permission denied.\n", glob_path); 00721 return st.major; 00722 } 00723 00724 /* if (FSAL_IS_ERROR(st = FSAL_access(&new_hdl,&contexte,FSAL_X_OK,&attrs))){ 00725 fprintf(output,"Error: %s: permission denied.\n",); 00726 return st.major; 00727 }*/ 00728 00729 /* if so, apply changes */ 00730 strncpy(context->current_path, glob_path, FSAL_MAX_PATH_LEN); 00731 context->current_dir = new_hdl; 00732 00733 { 00734 char buff[2 * sizeof(fsal_handle_t) + 1]; 00735 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &context->current_dir.handle); 00736 00737 fprintf(output, "Current directory is \"%s\" (@%s)\n", context->current_path, buff); 00738 } 00739 00740 return 0; 00741 00742 } 00743 00745 int fn_mfsl_stat(int argc, /* IN : number of args in argv */ 00746 char **argv, /* IN : arg list */ 00747 FILE * output /* IN : output stream */ 00748 ) 00749 { 00750 00751 static char format[] = "hv"; 00752 00753 static char help_stat[] = "usage: stat [-h][-v] <file>\n"; 00754 00755 char glob_path[FSAL_MAX_PATH_LEN]; 00756 mfsl_object_t new_hdl; 00757 fsal_attrib_list_t attrs; 00758 fsal_status_t st; 00759 int rc, option; 00760 int flag_v = 0; 00761 int flag_h = 0; 00762 int err_flag = 0; 00763 char *file = NULL; 00764 00765 cmdmfsl_thr_info_t *context; 00766 00767 /* is the fs initialized ? */ 00768 if(!is_loaded) 00769 { 00770 fprintf(output, "Error: filesystem not initialized\n"); 00771 return -1; 00772 } 00773 00774 /* initialize current thread */ 00775 00776 context = GetMFSLCmdContext(); 00777 00778 if(context->is_thread_ok != TRUE) 00779 { 00780 int rc; 00781 rc = Init_Thread_MFSL(output, context, 0); 00782 if(rc != 0) 00783 return rc; 00784 } 00785 00786 /* analysing options */ 00787 getopt_init(); 00788 while((option = Getopt(argc, argv, format)) != -1) 00789 { 00790 switch (option) 00791 { 00792 case 'v': 00793 if(flag_v) 00794 fprintf(output, 00795 "stat: warning: option 'v' has been specified more than once.\n"); 00796 else 00797 flag_v++; 00798 break; 00799 case 'h': 00800 if(flag_h) 00801 fprintf(output, 00802 "stat: warning: option 'h' has been specified more than once.\n"); 00803 else 00804 flag_h++; 00805 break; 00806 case '?': 00807 fprintf(output, "stat: unknown option : %c\n", Optopt); 00808 err_flag++; 00809 break; 00810 } 00811 } 00812 00813 if(flag_h) 00814 { 00815 fprintf(output, help_stat); 00816 return 0; 00817 } 00818 00819 /* Exactly one arg expected */ 00820 if(Optind != (argc - 1)) 00821 { 00822 err_flag++; 00823 } 00824 else 00825 { 00826 file = argv[Optind]; 00827 } 00828 00829 if(err_flag) 00830 { 00831 fprintf(output, help_stat); 00832 return -1; 00833 } 00834 00835 /* copy current path. */ 00836 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 00837 00838 /* retrieves object handle */ 00839 if(rc = 00840 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 00841 file, context->current_dir, &new_hdl, output)) 00842 return rc; 00843 00844 /* retrieve supported attributes */ 00845 FSAL_CLEAR_MASK(attrs.asked_attributes); 00846 FSAL_SET_MASK(attrs.asked_attributes, FSAL_ATTR_SUPPATTR); 00847 00848 if(FSAL_IS_ERROR(st = MFSL_getattrs(&new_hdl, 00849 &context->context, &context->mcontext, &attrs, NULL))) 00850 { 00851 fprintf(output, "Error executing MFSL_getattrs:"); 00852 print_fsal_status(output, st); 00853 fprintf(output, "\n"); 00854 return st.major; 00855 } 00856 00857 /* print supported attributes if verbose flag is set */ 00858 if(flag_v) 00859 { 00860 fprintf(output, "Supported attributes :\n"); 00861 print_fsal_attrib_mask(attrs.supported_attributes, output); 00862 fprintf(output, "\nAttributes :\n"); 00863 } 00864 00865 /* getting all supported attributes */ 00866 attrs.asked_attributes = attrs.supported_attributes; 00867 00868 if(FSAL_IS_ERROR(st = MFSL_getattrs(&new_hdl, 00869 &context->context, &context->mcontext, &attrs, NULL))) 00870 { 00871 fprintf(output, "Error executing MFSL_getattrs:"); 00872 print_fsal_status(output, st); 00873 fprintf(output, "\n"); 00874 return st.major; 00875 } 00876 00877 /* print file attributes */ 00878 print_fsal_attributes(attrs, output); 00879 00880 return 0; 00881 00882 } 00883 00885 int fn_mfsl_ls(int argc, /* IN : number of args in argv */ 00886 char **argv, /* IN : arg list */ 00887 FILE * output) /* IN : output stream */ 00888 { 00889 00890 static char format[] = "hvdlS"; 00891 00892 static char help_ls[] = 00893 "usage: ls [options] [name|path]\n" 00894 "options :\n" 00895 "\t-h print this help\n" 00896 "\t-v verbose mode\n" 00897 "\t-d print directory info instead of listing its content\n" 00898 "\t-l print standard UNIX attributes\n" "\t-S print all supported attributes\n"; 00899 00900 int option; 00901 int flag_v = 0; 00902 int flag_h = 0; 00903 int flag_d = 0; 00904 int flag_l = 0; 00905 int flag_S = 0; 00906 int err_flag = 0; 00907 char *str_name; 00908 00909 #define READDIR_SIZE FSAL_READDIR_SIZE 00910 00911 fsal_attrib_mask_t mask_needed; 00912 mfsl_object_t obj_hdl; 00913 fsal_dir_t dir; 00914 char glob_path[FSAL_MAX_PATH_LEN]; 00915 fsal_attrib_list_t attrs; 00916 fsal_status_t st; 00917 fsal_cookie_t from, to; 00918 fsal_dirent_t entries[READDIR_SIZE]; 00919 fsal_count_t number; 00920 fsal_boolean_t eod = FALSE; 00921 fsal_path_t symlink_path; 00922 int error = FALSE; 00923 int rc; 00924 00925 cmdmfsl_thr_info_t *context; 00926 00927 /* analysing options */ 00928 getopt_init(); 00929 while((option = Getopt(argc, argv, format)) != -1) 00930 { 00931 00932 switch (option) 00933 { 00934 case 'v': 00935 if(flag_v) 00936 fprintf(output, 00937 "ls: warning: option 'v' has been specified more than once.\n"); 00938 else 00939 flag_v++; 00940 break; 00941 case 'h': 00942 if(flag_h) 00943 fprintf(output, 00944 "ls: warning: option 'h' has been specified more than once.\n"); 00945 else 00946 flag_h++; 00947 break; 00948 case 'd': 00949 if(flag_d) 00950 fprintf(output, 00951 "ls: warning: option 'd' has been specified more than once.\n"); 00952 else 00953 flag_d++; 00954 break; 00955 case 'l': 00956 if(flag_l) 00957 fprintf(output, 00958 "ls: warning: option 'l' has been specified more than once.\n"); 00959 else 00960 flag_l++; 00961 break; 00962 case 'S': 00963 if(flag_S) 00964 fprintf(output, 00965 "ls: warning: option 'S' has been specified more than once.\n"); 00966 else 00967 flag_S++; 00968 break; 00969 case '?': 00970 fprintf(output, "ls: unknown option : %c\n", Optopt); 00971 err_flag++; 00972 break; 00973 } 00974 00975 } 00976 00977 if(flag_l + flag_S > 1) 00978 { 00979 fprintf(output, "ls: conflict between options l,S\n"); 00980 err_flag++; 00981 } 00982 00983 if(flag_h) 00984 { 00985 fprintf(output, help_ls); 00986 return 0; 00987 } 00988 if(err_flag) 00989 { 00990 fprintf(output, help_ls); 00991 return -1; 00992 } 00993 00994 /* is the fs initialized ? */ 00995 if(!is_loaded) 00996 { 00997 fprintf(output, "Error: filesystem not initialized\n"); 00998 return -1; 00999 } 01000 01001 /* initialize current thread */ 01002 01003 context = GetMFSLCmdContext(); 01004 01005 if(context->is_thread_ok != TRUE) 01006 { 01007 int rc; 01008 rc = Init_Thread_MFSL(output, context, 0); 01009 if(rc != 0) 01010 return rc; 01011 } 01012 01013 /* prepare needed attributes mask */ 01014 FSAL_CLEAR_MASK(mask_needed); 01015 FSAL_SET_MASK(mask_needed, FSAL_ATTRS_MANDATORY); 01016 01017 if(flag_l) 01018 FSAL_SET_MASK(mask_needed, FSAL_ATTRS_POSIX); 01019 else if(flag_S) 01020 mask_needed = 0xFFFFFFFFFFFFFFFFLL; 01021 01022 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01023 01024 /* first, retrieve the argument (if any) */ 01025 if(Optind == (argc - 1)) 01026 { 01027 str_name = argv[Optind]; 01028 01029 /* retrieving handle */ 01030 if(rc = 01031 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 01032 str_name, context->current_dir, &obj_hdl, output)) 01033 return rc; 01034 01035 } 01036 else 01037 { 01038 str_name = "."; 01039 obj_hdl = context->current_dir; 01040 } 01041 01042 if(flag_v) 01043 fprintf(output, "proceeding ls on \"%s\"\n", glob_path); 01044 01045 FSAL_CLEAR_MASK(attrs.asked_attributes); 01046 FSAL_SET_MASK(attrs.asked_attributes, FSAL_ATTR_SUPPATTR); 01047 01048 if(FSAL_IS_ERROR(st = MFSL_getattrs(&obj_hdl, 01049 &context->context, &context->mcontext, &attrs, NULL))) 01050 { 01051 fprintf(output, "Error executing MFSL_getattrs:"); 01052 print_fsal_status(output, st); 01053 fprintf(output, "\n"); 01054 return st.major; 01055 } 01056 01057 /* getting all needed attributes */ 01058 attrs.asked_attributes = (attrs.supported_attributes & mask_needed); 01059 01060 if(FSAL_IS_ERROR(st = MFSL_getattrs(&obj_hdl, 01061 &context->context, &context->mcontext, &attrs, NULL))) 01062 { 01063 fprintf(output, "Error executing MFSL_getattrs:"); 01064 print_fsal_status(output, st); 01065 fprintf(output, "\n"); 01066 return st.major; 01067 } 01068 01069 /* 01070 * if the object is a file or a directoy with the -d option specified, 01071 * we only show its info and exit. 01072 */ 01073 if((attrs.type != FSAL_TYPE_DIR) || flag_d) 01074 { 01075 01076 if((attrs.type == FSAL_TYPE_LNK) && (flag_l)) 01077 { 01078 01079 if(FSAL_IS_ERROR 01080 (st = 01081 MFSL_readlink(&obj_hdl, &context->context, &context->mcontext, 01082 &symlink_path, NULL, NULL))) 01083 { 01084 fprintf(output, "Error executing FSAL_readlink:"); 01085 print_fsal_status(output, st); 01086 fprintf(output, "\n"); 01087 return st.major; 01088 } 01089 01090 } 01091 01092 if(flag_l) 01093 print_item_line(output, &attrs, str_name, symlink_path.path); 01094 01095 else if(flag_S) 01096 { 01097 01098 char tracebuff[2 * sizeof(fsal_handle_t) + 1]; 01099 snprintHandle(tracebuff, 2 * sizeof(fsal_handle_t) + 1, &obj_hdl.handle); 01100 fprintf(output, "%s (@%s):\n", str_name, tracebuff); 01101 print_fsal_attributes(attrs, output); 01102 01103 } 01104 else /* only prints the name */ 01105 fprintf(output, "%s\n", str_name); 01106 01107 return 0; 01108 } 01109 01110 /* 01111 * the current object is a directory, we have to list its element 01112 */ 01113 if(FSAL_IS_ERROR(st = MFSL_opendir(&obj_hdl, 01114 &context->context, &context->mcontext, &dir, NULL, NULL))) 01115 { 01116 fprintf(output, "Error executing MFSL_opendir:"); 01117 print_fsal_status(output, st); 01118 fprintf(output, "\n"); 01119 return st.major; 01120 } 01121 01122 FSAL_SET_COOKIE_BEGINNING(from); 01123 01124 while(!error && !eod) 01125 { 01126 fsal_dirent_t *curr; 01127 char item_path[FSAL_MAX_PATH_LEN]; 01128 01129 if(FSAL_IS_ERROR(st = MFSL_readdir(&dir, 01130 from, attrs.supported_attributes & mask_needed, 01131 READDIR_SIZE * sizeof(fsal_dirent_t), 01132 entries, 01133 &to, &number, &eod, &context->mcontext, NULL))) 01134 { 01135 fprintf(output, "Error executing MFSL_readdir:"); 01136 print_fsal_status(output, st); 01137 fprintf(output, "\n"); 01138 error = st.major; 01139 number = 0; 01140 } 01141 01142 if(flag_v) 01143 fprintf(output, "MFSL_readdir returned %u entries\n", (unsigned int)number); 01144 01145 if(number > 0) 01146 { 01147 curr = entries; 01148 do 01149 { 01150 int len; 01151 len = strlen(str_name); 01152 if(!strcmp(str_name, ".")) 01153 strncpy(item_path, curr->name.name, FSAL_MAX_PATH_LEN); 01154 else if(str_name[len - 1] == '/') 01155 snprintf(item_path, FSAL_MAX_PATH_LEN, "%s%s", str_name, curr->name.name); 01156 else 01157 snprintf(item_path, FSAL_MAX_PATH_LEN, "%s/%s", str_name, 01158 curr->name.name); 01159 01160 if((curr->attributes.type == FSAL_TYPE_LNK) && (flag_l)) 01161 { 01162 01163 mfsl_object_t tmp_mfsl; 01164 01165 tmp_mfsl.handle = curr->handle; 01166 01167 if(FSAL_IS_ERROR 01168 (st = 01169 MFSL_readlink(&tmp_mfsl, &context->context, &context->mcontext, 01170 &symlink_path, NULL, NULL))) 01171 { 01172 fprintf(output, "Error executing FSAL_readlink:"); 01173 print_fsal_status(output, st); 01174 fprintf(output, "\n"); 01175 return st.major; 01176 } 01177 01178 } 01179 01180 if(flag_l) 01181 print_item_line(output, &(curr->attributes), item_path, 01182 symlink_path.path); 01183 01184 else if(flag_S) 01185 { 01186 01187 char tracebuff[2 * sizeof(fsal_handle_t) + 1]; 01188 snprintHandle(tracebuff, 2 * sizeof(fsal_handle_t) + 1, &curr->handle); 01189 01190 fprintf(output, "%s (@%s):\n", item_path, tracebuff); 01191 print_fsal_attributes(curr->attributes, output); 01192 01193 } 01194 else /* only prints the name */ 01195 fprintf(output, "%s\n", item_path); 01196 01197 } 01198 while(curr = curr->nextentry); 01199 } 01200 /* preparing next call */ 01201 from = to; 01202 01203 } 01204 01205 FSAL_closedir(&dir); 01206 01207 return error; 01208 01209 } /* fn_mfsl_ls */ 01210 01212 int fn_mfsl_su(int argc, /* IN : number of args in argv */ 01213 char **argv, /* IN : arg list */ 01214 FILE * output /* IN : output stream */ 01215 ) 01216 { 01217 01218 char *str_uid; 01219 fsal_uid_t uid; 01220 fsal_status_t st; 01221 struct passwd *pw_struct; 01222 int i; 01223 01224 # define MAX_GRPS 128 01225 gid_t groups_tab[MAX_GRPS]; 01226 int nb_grp; 01227 01228 static char help_stats[] = "usage: su <uid>\n"; 01229 01230 cmdmfsl_thr_info_t *context; 01231 01232 /* is the fs initialized ? */ 01233 if(!is_loaded) 01234 { 01235 fprintf(output, "Error: filesystem not initialized\n"); 01236 return -1; 01237 } 01238 01239 /* initialize current thread */ 01240 01241 context = GetMFSLCmdContext(); 01242 01243 if(context->is_thread_ok != TRUE) 01244 { 01245 int rc; 01246 rc = Init_Thread_MFSL(output, context, 0); 01247 if(rc != 0) 01248 return rc; 01249 } 01250 01251 /* UID arg expected */ 01252 if(argc != 2) 01253 { 01254 fprintf(output, help_stats); 01255 return -1; 01256 } 01257 else 01258 { 01259 str_uid = argv[1]; 01260 } 01261 01262 if(isdigit(str_uid[0])) 01263 { 01264 if((uid = my_atoi(str_uid)) == (uid_t) - 1) 01265 { 01266 fprintf(output, "Error: invalid uid \"%s\"\n", str_uid); 01267 return -1; 01268 } 01269 pw_struct = getpwuid(uid); 01270 } 01271 else 01272 { 01273 pw_struct = getpwnam(str_uid); 01274 } 01275 01276 if(pw_struct == NULL) 01277 { 01278 fprintf(output, "Unknown user %s\n", str_uid); 01279 return errno; 01280 } 01281 01282 nb_grp = getugroups(MAX_GRPS, groups_tab, pw_struct->pw_name, pw_struct->pw_gid); 01283 01284 fprintf(output, "Changing user to : %s ( uid = %d, gid = %d )\n", 01285 pw_struct->pw_name, pw_struct->pw_uid, pw_struct->pw_gid); 01286 01287 if(nb_grp > 1) 01288 { 01289 fprintf(output, "altgroups = "); 01290 for(i = 1; i < nb_grp; i++) 01291 { 01292 if(i == 1) 01293 fprintf(output, "%d", groups_tab[i]); 01294 else 01295 fprintf(output, ", %d", groups_tab[i]); 01296 } 01297 fprintf(output, "\n"); 01298 } 01299 01300 st = FSAL_GetClientContext(&context->context, &context->exp_context, 01301 pw_struct->pw_uid, pw_struct->pw_gid, groups_tab, nb_grp); 01302 01303 if(FSAL_IS_ERROR(st)) 01304 { 01305 fprintf(output, "Error executing FSAL_GetUserCred:"); 01306 print_fsal_status(output, st); 01307 fprintf(output, "\n"); 01308 return st.major; 01309 } 01310 01311 fprintf(output, "Done.\n"); 01312 01313 return 0; 01314 01315 } 01316 01318 int fn_mfsl_unlink(int argc, /* IN : number of args in argv */ 01319 char **argv, /* IN : arg list */ 01320 FILE * output /* IN : output stream */ 01321 ) 01322 { 01323 01324 static char format[] = "hv"; 01325 01326 static char help_unlink[] = "usage: unlink [-h][-v] <path>\n"; 01327 01328 char glob_path[FSAL_MAX_PATH_LEN]; 01329 mfsl_object_t new_hdl; 01330 fsal_status_t st; 01331 int rc, option; 01332 int flag_v = 0; 01333 int flag_h = 0; 01334 int err_flag = 0; 01335 01336 char tmp_path[FSAL_MAX_PATH_LEN]; 01337 char *path; 01338 char *file; 01339 01340 fsal_name_t objname; 01341 01342 cmdmfsl_thr_info_t *context; 01343 01344 /* is the fs initialized ? */ 01345 if(!is_loaded) 01346 { 01347 fprintf(output, "Error: filesystem not initialized\n"); 01348 return -1; 01349 } 01350 01351 /* initialize current thread */ 01352 01353 context = GetMFSLCmdContext(); 01354 01355 if(context->is_thread_ok != TRUE) 01356 { 01357 int rc; 01358 rc = Init_Thread_MFSL(output, context, 0); 01359 if(rc != 0) 01360 return rc; 01361 } 01362 01363 /* analysing options */ 01364 getopt_init(); 01365 while((option = Getopt(argc, argv, format)) != -1) 01366 { 01367 switch (option) 01368 { 01369 case 'v': 01370 if(flag_v) 01371 fprintf(output, 01372 "unlink: warning: option 'v' has been specified more than once.\n"); 01373 else 01374 flag_v++; 01375 break; 01376 case 'h': 01377 if(flag_h) 01378 fprintf(output, 01379 "unlink: warning: option 'h' has been specified more than once.\n"); 01380 else 01381 flag_h++; 01382 break; 01383 case '?': 01384 fprintf(output, "unlink: unknown option : %c\n", Optopt); 01385 err_flag++; 01386 break; 01387 } 01388 } 01389 01390 if(flag_h) 01391 { 01392 fprintf(output, help_unlink); 01393 return 0; 01394 } 01395 01396 /* Exactly 1 args expected */ 01397 if(Optind != (argc - 1)) 01398 { 01399 err_flag++; 01400 } 01401 else 01402 { 01403 strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN); 01404 split_path(tmp_path, &path, &file); 01405 } 01406 01407 if(err_flag) 01408 { 01409 fprintf(output, help_unlink); 01410 return -1; 01411 } 01412 01413 /* copy current path. */ 01414 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01415 01416 /* retrieves path handle */ 01417 if(rc = 01418 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 01419 path, context->current_dir, &new_hdl, output)) 01420 return rc; 01421 01422 /* create fsal_name_t */ 01423 st = FSAL_str2name(file, 256, &objname); 01424 if(FSAL_IS_ERROR(st)) 01425 { 01426 fprintf(output, "Error executing FSAL_str2name:"); 01427 print_fsal_status(output, st); 01428 fprintf(output, "\n"); 01429 return st.major; 01430 } 01431 01432 if(FSAL_IS_ERROR(st = MFSL_unlink(&new_hdl, &objname, NULL, /* Bad idea, will probably segfault */ 01433 &context->context, &context->mcontext, NULL, NULL))) 01434 { 01435 fprintf(output, "Error executing MFSL_unlink:"); 01436 print_fsal_status(output, st); 01437 fprintf(output, "\n"); 01438 return st.major; 01439 } 01440 01441 if(flag_v) 01442 fprintf(output, "%s/%s successfully unlinked\n", glob_path, file); 01443 01444 return 0; 01445 01446 } 01447 01449 int fn_mfsl_mkdir(int argc, /* IN : number of args in argv */ 01450 char **argv, /* IN : arg list */ 01451 FILE * output /* IN : output stream */ 01452 ) 01453 { 01454 01455 static char format[] = "hv"; 01456 01457 static char help_mkdir[] = 01458 "usage: mkdir [-h][-v] <path> <mode>\n" 01459 " path: path of the directory to be created\n" 01460 " mode: octal mode for the directory is to be created (ex: 755)\n"; 01461 01462 char glob_path[FSAL_MAX_PATH_LEN]; 01463 mfsl_object_t new_hdl, subdir_hdl; 01464 fsal_status_t st; 01465 int rc, option; 01466 int flag_v = 0; 01467 int flag_h = 0; 01468 int err_flag = 0; 01469 int mode; 01470 fsal_accessmode_t fsalmode = 0755; 01471 01472 char tmp_path[FSAL_MAX_PATH_LEN]; 01473 char *path; 01474 char *file; 01475 char *strmode; 01476 01477 fsal_name_t objname; 01478 01479 cmdmfsl_thr_info_t *context; 01480 01481 /* is the fs initialized ? */ 01482 if(!is_loaded) 01483 { 01484 fprintf(output, "Error: filesystem not initialized\n"); 01485 return -1; 01486 } 01487 01488 /* initialize current thread */ 01489 01490 context = GetMFSLCmdContext(); 01491 01492 if(context->is_thread_ok != TRUE) 01493 { 01494 int rc; 01495 rc = Init_Thread_MFSL(output, context, 0); 01496 if(rc != 0) 01497 return rc; 01498 } 01499 01500 /* analysing options */ 01501 getopt_init(); 01502 while((option = Getopt(argc, argv, format)) != -1) 01503 { 01504 switch (option) 01505 { 01506 case 'v': 01507 if(flag_v) 01508 fprintf(output, 01509 "mkdir: warning: option 'v' has been specified more than once.\n"); 01510 else 01511 flag_v++; 01512 break; 01513 case 'h': 01514 if(flag_h) 01515 fprintf(output, 01516 "mkdir: warning: option 'h' has been specified more than once.\n"); 01517 else 01518 flag_h++; 01519 break; 01520 case '?': 01521 fprintf(output, "mkdir: unknown option : %c\n", Optopt); 01522 err_flag++; 01523 break; 01524 } 01525 } 01526 01527 if(flag_h) 01528 { 01529 fprintf(output, help_mkdir); 01530 return 0; 01531 } 01532 01533 /* Exactly 2 args expected */ 01534 if(Optind != (argc - 2)) 01535 { 01536 err_flag++; 01537 } 01538 else 01539 { 01540 01541 strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN); 01542 split_path(tmp_path, &path, &file); 01543 01544 strmode = argv[Optind + 1]; 01545 01546 /* converting mode string to FSAL mode string */ 01547 mode = atomode(strmode); 01548 if(mode < 0) 01549 err_flag++; 01550 else 01551 { 01552 01553 fsalmode = 0; 01554 01555 if(mode & S_ISUID) 01556 fsalmode |= FSAL_MODE_SUID; 01557 if(mode & S_ISGID) 01558 fsalmode |= FSAL_MODE_SGID; 01559 01560 if(mode & S_IRUSR) 01561 fsalmode |= FSAL_MODE_RUSR; 01562 if(mode & S_IWUSR) 01563 fsalmode |= FSAL_MODE_WUSR; 01564 if(mode & S_IXUSR) 01565 fsalmode |= FSAL_MODE_XUSR; 01566 01567 if(mode & S_IRGRP) 01568 fsalmode |= FSAL_MODE_RGRP; 01569 if(mode & S_IWGRP) 01570 fsalmode |= FSAL_MODE_WGRP; 01571 if(mode & S_IXGRP) 01572 fsalmode |= FSAL_MODE_XGRP; 01573 01574 if(mode & S_IROTH) 01575 fsalmode |= FSAL_MODE_ROTH; 01576 if(mode & S_IWOTH) 01577 fsalmode |= FSAL_MODE_WOTH; 01578 if(mode & S_IXOTH) 01579 fsalmode |= FSAL_MODE_XOTH; 01580 01581 } 01582 01583 } 01584 01585 if(err_flag) 01586 { 01587 fprintf(output, help_mkdir); 01588 return -1; 01589 } 01590 01591 /* copy current path. */ 01592 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01593 01594 /* retrieves path handle */ 01595 if(rc = 01596 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 01597 path, context->current_dir, &new_hdl, output)) 01598 return rc; 01599 01600 /* create fsal_name_t */ 01601 st = FSAL_str2name(file, 256, &objname); 01602 if(FSAL_IS_ERROR(st)) 01603 { 01604 fprintf(output, "Error executing FSAL_str2name:"); 01605 print_fsal_status(output, st); 01606 fprintf(output, "\n"); 01607 return st.major; 01608 } 01609 01610 if(FSAL_IS_ERROR(st = MFSL_mkdir(&new_hdl, 01611 &objname, 01612 &context->context, 01613 &context->mcontext, 01614 fsalmode, &subdir_hdl, NULL, NULL, NULL))) 01615 { /* Will probably segfault */ 01616 fprintf(output, "Error executing MFSL_mkdir:"); 01617 print_fsal_status(output, st); 01618 fprintf(output, "\n"); 01619 return st.major; 01620 } 01621 01622 if(flag_v) 01623 { 01624 char buff[2 * sizeof(fsal_handle_t) + 1]; 01625 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &subdir_hdl.handle); 01626 01627 fprintf(output, "%s/%s successfully created (@%s) \n", glob_path, file, buff); 01628 01629 } 01630 01631 return 0; 01632 01633 } 01634 01636 int fn_mfsl_rename(int argc, /* IN : number of args in argv */ 01637 char **argv, /* IN : arg list */ 01638 FILE * output /* IN : output stream */ 01639 ) 01640 { 01641 01642 static char format[] = "hv"; 01643 01644 static char help_rename[] = "usage: rename [-h][-v] <src> <dest>\n"; 01645 01646 char src_glob_path[FSAL_MAX_PATH_LEN]; 01647 char tgt_glob_path[FSAL_MAX_PATH_LEN]; 01648 01649 mfsl_object_t src_path_handle, tgt_path_handle; 01650 fsal_name_t src_name, tgt_name; 01651 01652 fsal_status_t st; 01653 int rc, option; 01654 int flag_v = 0; 01655 int flag_h = 0; 01656 int err_flag = 0; 01657 01658 char tmp_path1[FSAL_MAX_PATH_LEN]; 01659 char tmp_path2[FSAL_MAX_PATH_LEN]; 01660 char *src_path; 01661 char *src_file; 01662 char *tgt_path; 01663 char *tgt_file; 01664 01665 cmdmfsl_thr_info_t *context; 01666 01667 /* is the fs initialized ? */ 01668 if(!is_loaded) 01669 { 01670 fprintf(output, "Error: filesystem not initialized\n"); 01671 return -1; 01672 } 01673 01674 /* initialize current thread */ 01675 01676 context = GetMFSLCmdContext(); 01677 01678 if(context->is_thread_ok != TRUE) 01679 { 01680 int rc; 01681 rc = Init_Thread_MFSL(output, context, 0); 01682 if(rc != 0) 01683 return rc; 01684 } 01685 01686 /* analysing options */ 01687 getopt_init(); 01688 while((option = Getopt(argc, argv, format)) != -1) 01689 { 01690 switch (option) 01691 { 01692 case 'v': 01693 if(flag_v) 01694 fprintf(output, 01695 "rename: warning: option 'v' has been specified more than once.\n"); 01696 else 01697 flag_v++; 01698 break; 01699 case 'h': 01700 if(flag_h) 01701 fprintf(output, 01702 "rename: warning: option 'h' has been specified more than once.\n"); 01703 else 01704 flag_h++; 01705 break; 01706 case '?': 01707 fprintf(output, "rename: unknown option : %c\n", Optopt); 01708 err_flag++; 01709 break; 01710 } 01711 } 01712 01713 if(flag_h) 01714 { 01715 fprintf(output, help_rename); 01716 return 0; 01717 } 01718 01719 /* Exactly 2 args expected */ 01720 if(Optind != (argc - 2)) 01721 { 01722 err_flag++; 01723 } 01724 else 01725 { 01726 01727 strncpy(tmp_path1, argv[Optind], FSAL_MAX_PATH_LEN); 01728 split_path(tmp_path1, &src_path, &src_file); 01729 01730 strncpy(tmp_path2, argv[Optind + 1], FSAL_MAX_PATH_LEN); 01731 split_path(tmp_path2, &tgt_path, &tgt_file); 01732 01733 } 01734 01735 if(err_flag) 01736 { 01737 fprintf(output, help_rename); 01738 return -1; 01739 } 01740 01741 if(flag_v) 01742 fprintf(output, "Renaming %s (dir %s) to %s (dir %s)\n", 01743 src_file, src_path, tgt_file, tgt_path); 01744 01745 /* copy current path. */ 01746 strncpy(src_glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01747 strncpy(tgt_glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01748 01749 /* retrieves paths handles */ 01750 if(rc = 01751 msfl_solvepath(src_glob_path, FSAL_MAX_PATH_LEN, 01752 src_path, context->current_dir, &src_path_handle, output)) 01753 return rc; 01754 01755 if(rc = 01756 msfl_solvepath(tgt_glob_path, FSAL_MAX_PATH_LEN, 01757 tgt_path, context->current_dir, &tgt_path_handle, output)) 01758 return rc; 01759 01760 /* create fsal_name_t */ 01761 01762 st = FSAL_str2name(src_file, 256, &src_name); 01763 01764 if(FSAL_IS_ERROR(st)) 01765 { 01766 01767 fprintf(output, "Error executing FSAL_str2name:"); 01768 print_fsal_status(output, st); 01769 fprintf(output, "\n"); 01770 return st.major; 01771 01772 } 01773 01774 st = FSAL_str2name(tgt_file, 256, &tgt_name); 01775 01776 if(FSAL_IS_ERROR(st)) 01777 { 01778 01779 fprintf(output, "Error executing FSAL_str2name:"); 01780 print_fsal_status(output, st); 01781 fprintf(output, "\n"); 01782 return st.major; 01783 01784 } 01785 01786 /* Rename operation */ 01787 01788 st = MFSL_rename(&src_path_handle, /* IN */ 01789 &src_name, /* IN */ 01790 &tgt_path_handle, /* IN */ 01791 &tgt_name, /* IN */ 01792 &context->context, /* IN */ 01793 &context->mcontext, /* IN */ 01794 NULL, NULL, NULL); 01795 01796 if(FSAL_IS_ERROR(st)) 01797 { 01798 01799 fprintf(output, "Error executing FSAL_rename:"); 01800 print_fsal_status(output, st); 01801 fprintf(output, "\n"); 01802 return st.major; 01803 01804 } 01805 01806 if(flag_v) 01807 fprintf(output, "%s/%s successfully renamed to %s/%s\n", 01808 src_glob_path, src_file, tgt_glob_path, tgt_file); 01809 01810 return 0; 01811 01812 } 01813 01815 int fn_mfsl_ln(int argc, /* IN : number of args in argv */ 01816 char **argv, /* IN : arg list */ 01817 FILE * output /* IN : output stream */ 01818 ) 01819 { 01820 01821 static char format[] = "hv"; 01822 01823 static char help_ln[] = 01824 "ln: create a symbolic link.\n" 01825 "usage: ln [-h][-v] <link_content> <link_path>\n" 01826 " link_content: content of the symbolic link to be created\n" 01827 " link_path: path of the symbolic link to be created\n"; 01828 01829 char glob_path[FSAL_MAX_PATH_LEN]; 01830 mfsl_object_t path_hdl, link_hdl; 01831 fsal_status_t st; 01832 int rc, option; 01833 int flag_v = 0; 01834 int flag_h = 0; 01835 int err_flag = 0; 01836 01837 char *content = NULL; 01838 char tmp_path[FSAL_MAX_PATH_LEN]; 01839 char *path; 01840 char *name; 01841 01842 fsal_name_t objname; 01843 fsal_path_t objcontent; 01844 01845 cmdmfsl_thr_info_t *context; 01846 01847 /* is the fs initialized ? */ 01848 if(!is_loaded) 01849 { 01850 fprintf(output, "Error: filesystem not initialized\n"); 01851 return -1; 01852 } 01853 01854 /* initialize current thread */ 01855 01856 context = GetMFSLCmdContext(); 01857 01858 if(context->is_thread_ok != TRUE) 01859 { 01860 int rc; 01861 rc = Init_Thread_MFSL(output, context, 0); 01862 if(rc != 0) 01863 return rc; 01864 } 01865 01866 /* analysing options */ 01867 getopt_init(); 01868 while((option = Getopt(argc, argv, format)) != -1) 01869 { 01870 switch (option) 01871 { 01872 case 'v': 01873 if(flag_v) 01874 fprintf(output, 01875 "ln: warning: option 'v' has been specified more than once.\n"); 01876 else 01877 flag_v++; 01878 break; 01879 case 'h': 01880 if(flag_h) 01881 fprintf(output, 01882 "ln: warning: option 'h' has been specified more than once.\n"); 01883 else 01884 flag_h++; 01885 break; 01886 case '?': 01887 fprintf(output, "ln: unknown option : %c\n", Optopt); 01888 err_flag++; 01889 break; 01890 } 01891 } 01892 01893 if(flag_h) 01894 { 01895 fprintf(output, help_ln); 01896 return 0; 01897 } 01898 01899 /* 2 args expected */ 01900 01901 if(Optind == (argc - 2)) 01902 { 01903 01904 content = argv[Optind]; 01905 01906 strncpy(tmp_path, argv[Optind + 1], FSAL_MAX_PATH_LEN); 01907 split_path(tmp_path, &path, &name); 01908 01909 } 01910 else 01911 { 01912 err_flag++; 01913 } 01914 01915 if(err_flag) 01916 { 01917 fprintf(output, help_ln); 01918 return -1; 01919 } 01920 01921 /* copy current path. */ 01922 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 01923 01924 /* retrieves path handle */ 01925 if(rc = 01926 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 01927 path, context->current_dir, &path_hdl, output)) 01928 return rc; 01929 01930 /* create fsal_name_t */ 01931 st = FSAL_str2name(name, 256, &objname); 01932 01933 if(FSAL_IS_ERROR(st)) 01934 { 01935 fprintf(output, "Error executing FSAL_str2name:"); 01936 print_fsal_status(output, st); 01937 fprintf(output, "\n"); 01938 return st.major; 01939 } 01940 01941 /* create fsal_path_t */ 01942 st = FSAL_str2path(content, 256, &objcontent); 01943 01944 if(FSAL_IS_ERROR(st)) 01945 { 01946 fprintf(output, "Error executing FSAL_str2path:"); 01947 print_fsal_status(output, st); 01948 fprintf(output, "\n"); 01949 return st.major; 01950 } 01951 01952 st = MFSL_symlink(&path_hdl, /* IN - parent dir handle */ 01953 &objname, /* IN - link name */ 01954 &objcontent, /* IN - link content */ 01955 &context->context, /* IN - user contexte */ 01956 &context->mcontext, /* IN - user contexte */ 01957 0777, /* IN (ignored) */ 01958 &link_hdl, /* OUT - link handle */ 01959 NULL, NULL); /* OUT - link attributes */ 01960 01961 if(FSAL_IS_ERROR(st)) 01962 { 01963 fprintf(output, "Error executing FSAL_symlink:"); 01964 print_fsal_status(output, st); 01965 fprintf(output, "\n"); 01966 return st.major; 01967 } 01968 01969 if(flag_v) 01970 { 01971 char buff[2 * sizeof(fsal_handle_t) + 1]; 01972 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &link_hdl.handle); 01973 01974 fprintf(output, "%s/%s -> %s successfully created (@%s) \n", path, name, content, 01975 buff); 01976 01977 } 01978 01979 return 0; 01980 01981 } 01982 01984 int fn_mfsl_hardlink(int argc, /* IN : number of args in argv */ 01985 char **argv, /* IN : arg list */ 01986 FILE * output /* IN : output stream */ 01987 ) 01988 { 01989 01990 static char format[] = "hv"; 01991 01992 static char help_hardlink[] = 01993 "hardlink: create a hard link.\n" 01994 "usage: hardlink [-h][-v] <target> <new_path>\n" 01995 " target: path of an existing file.\n" 01996 " new_path: path of the hardlink to be created\n"; 01997 01998 char glob_path_target[FSAL_MAX_PATH_LEN]; 01999 char glob_path_link[FSAL_MAX_PATH_LEN]; 02000 02001 mfsl_object_t target_hdl, dir_hdl; 02002 fsal_name_t link_name; 02003 02004 fsal_status_t st; 02005 int rc, option; 02006 int flag_v = 0; 02007 int flag_h = 0; 02008 int err_flag = 0; 02009 02010 char *target = NULL; 02011 02012 char tmp_path[FSAL_MAX_PATH_LEN]; 02013 char *path; 02014 char *name; 02015 02016 cmdmfsl_thr_info_t *context; 02017 02018 /* is the fs initialized ? */ 02019 if(!is_loaded) 02020 { 02021 fprintf(output, "Error: filesystem not initialized\n"); 02022 return -1; 02023 } 02024 02025 /* initialize current thread */ 02026 02027 context = GetMFSLCmdContext(); 02028 02029 if(context->is_thread_ok != TRUE) 02030 { 02031 int rc; 02032 rc = Init_Thread_MFSL(output, context, 0); 02033 if(rc != 0) 02034 return rc; 02035 } 02036 02037 /* analysing options */ 02038 getopt_init(); 02039 while((option = Getopt(argc, argv, format)) != -1) 02040 { 02041 switch (option) 02042 { 02043 case 'v': 02044 if(flag_v) 02045 fprintf(output, 02046 "hardlink: warning: option 'v' has been specified more than once.\n"); 02047 else 02048 flag_v++; 02049 break; 02050 case 'h': 02051 if(flag_h) 02052 fprintf(output, 02053 "hardlink: warning: option 'h' has been specified more than once.\n"); 02054 else 02055 flag_h++; 02056 break; 02057 case '?': 02058 fprintf(output, "hardlink: unknown option : %c\n", Optopt); 02059 err_flag++; 02060 break; 02061 } 02062 } 02063 02064 if(flag_h) 02065 { 02066 fprintf(output, help_hardlink); 02067 return 0; 02068 } 02069 02070 /* 2 args expected */ 02071 02072 if(Optind == (argc - 2)) 02073 { 02074 02075 target = argv[Optind]; 02076 02077 strncpy(tmp_path, argv[Optind + 1], FSAL_MAX_PATH_LEN); 02078 split_path(tmp_path, &path, &name); 02079 02080 } 02081 else 02082 { 02083 err_flag++; 02084 } 02085 02086 if(err_flag) 02087 { 02088 fprintf(output, help_hardlink); 02089 return -1; 02090 } 02091 02092 /* copy current path. */ 02093 strncpy(glob_path_target, context->current_path, FSAL_MAX_PATH_LEN); 02094 strncpy(glob_path_link, context->current_path, FSAL_MAX_PATH_LEN); 02095 02096 /* retrieves path handle for target */ 02097 if(rc = 02098 msfl_solvepath(glob_path_target, FSAL_MAX_PATH_LEN, 02099 target, context->current_dir, &target_hdl, output)) 02100 return rc; 02101 02102 /* retrieves path handle for parent dir */ 02103 if(rc = 02104 msfl_solvepath(glob_path_link, FSAL_MAX_PATH_LEN, 02105 path, context->current_dir, &dir_hdl, output)) 02106 return rc; 02107 02108 /* create fsal_name_t */ 02109 st = FSAL_str2name(name, 256, &link_name); 02110 02111 if(FSAL_IS_ERROR(st)) 02112 { 02113 fprintf(output, "Error executing FSAL_str2name:"); 02114 print_fsal_status(output, st); 02115 fprintf(output, "\n"); 02116 return st.major; 02117 } 02118 02119 st = MFSL_link(&target_hdl, /* IN - target file */ 02120 &dir_hdl, /* IN - parent dir handle */ 02121 &link_name, /* IN - link name */ 02122 &context->context, /* IN - user contexte */ 02123 &context->mcontext, /* IN - user contexte */ 02124 NULL, NULL); /* OUT - new attributes */ 02125 02126 if(FSAL_IS_ERROR(st)) 02127 { 02128 fprintf(output, "Error executing FSAL_link:"); 02129 print_fsal_status(output, st); 02130 fprintf(output, "\n"); 02131 return st.major; 02132 } 02133 02134 if(flag_v) 02135 { 02136 fprintf(output, "%s/%s <=> %s successfully created\n", path, name, 02137 glob_path_target); 02138 02139 } 02140 02141 return 0; 02142 02143 } 02144 02146 int fn_mfsl_create(int argc, /* IN : number of args in argv */ 02147 char **argv, /* IN : arg list */ 02148 FILE * output /* IN : output stream */ 02149 ) 02150 { 02151 02152 static char format[] = "hv"; 02153 02154 static char help_create[] = 02155 "usage: create [-h][-v] <path> <mode>\n" 02156 " path: path of the file to be created\n" 02157 " mode: octal access mode for the file to be created (ex: 644)\n"; 02158 02159 char glob_path_dir[FSAL_MAX_PATH_LEN]; 02160 mfsl_object_t dir_hdl, file_hdl; 02161 02162 fsal_status_t st; 02163 int rc, option; 02164 int flag_v = 0; 02165 int flag_h = 0; 02166 int err_flag = 0; 02167 int mode; 02168 fsal_accessmode_t fsalmode = 0644; 02169 02170 char tmp_path[FSAL_MAX_PATH_LEN]; 02171 char *path; 02172 char *file; 02173 char *strmode; 02174 02175 fsal_name_t objname; 02176 02177 cmdmfsl_thr_info_t *context; 02178 02179 /* is the fs initialized ? */ 02180 if(!is_loaded) 02181 { 02182 fprintf(output, "Error: filesystem not initialized\n"); 02183 return -1; 02184 } 02185 02186 /* initialize current thread */ 02187 02188 context = GetMFSLCmdContext(); 02189 02190 if(context->is_thread_ok != TRUE) 02191 { 02192 int rc; 02193 rc = Init_Thread_MFSL(output, context, 0); 02194 if(rc != 0) 02195 return rc; 02196 } 02197 02198 /* analysing options */ 02199 getopt_init(); 02200 while((option = Getopt(argc, argv, format)) != -1) 02201 { 02202 switch (option) 02203 { 02204 case 'v': 02205 if(flag_v) 02206 fprintf(output, 02207 "create: warning: option 'v' has been specified more than once.\n"); 02208 else 02209 flag_v++; 02210 break; 02211 case 'h': 02212 if(flag_h) 02213 fprintf(output, 02214 "create: warning: option 'h' has been specified more than once.\n"); 02215 else 02216 flag_h++; 02217 break; 02218 case '?': 02219 fprintf(output, "create: unknown option : %c\n", Optopt); 02220 err_flag++; 02221 break; 02222 } 02223 } 02224 02225 if(flag_h) 02226 { 02227 fprintf(output, help_create); 02228 return 0; 02229 } 02230 02231 /* Exactly 2 args expected */ 02232 if(Optind != (argc - 2)) 02233 { 02234 err_flag++; 02235 } 02236 else 02237 { 02238 02239 strncpy(tmp_path, argv[Optind], FSAL_MAX_PATH_LEN); 02240 split_path(tmp_path, &path, &file); 02241 02242 strmode = argv[Optind + 1]; 02243 02244 /* converting mode string to FSAL mode string */ 02245 mode = atomode(strmode); 02246 if(mode < 0) 02247 err_flag++; 02248 else 02249 { 02250 02251 fsalmode = 0; 02252 02253 if(mode & S_ISUID) 02254 fsalmode |= FSAL_MODE_SUID; 02255 if(mode & S_ISGID) 02256 fsalmode |= FSAL_MODE_SGID; 02257 02258 if(mode & S_IRUSR) 02259 fsalmode |= FSAL_MODE_RUSR; 02260 if(mode & S_IWUSR) 02261 fsalmode |= FSAL_MODE_WUSR; 02262 if(mode & S_IXUSR) 02263 fsalmode |= FSAL_MODE_XUSR; 02264 02265 if(mode & S_IRGRP) 02266 fsalmode |= FSAL_MODE_RGRP; 02267 if(mode & S_IWGRP) 02268 fsalmode |= FSAL_MODE_WGRP; 02269 if(mode & S_IXGRP) 02270 fsalmode |= FSAL_MODE_XGRP; 02271 02272 if(mode & S_IROTH) 02273 fsalmode |= FSAL_MODE_ROTH; 02274 if(mode & S_IWOTH) 02275 fsalmode |= FSAL_MODE_WOTH; 02276 if(mode & S_IXOTH) 02277 fsalmode |= FSAL_MODE_XOTH; 02278 02279 } 02280 02281 } 02282 02283 if(err_flag) 02284 { 02285 fprintf(output, help_create); 02286 return -1; 02287 } 02288 02289 /* copy current path. */ 02290 strncpy(glob_path_dir, context->current_path, FSAL_MAX_PATH_LEN); 02291 02292 /* retrieves path handle */ 02293 if(rc = 02294 msfl_solvepath(glob_path_dir, FSAL_MAX_PATH_LEN, 02295 path, context->current_dir, &dir_hdl, output)) 02296 return rc; 02297 02298 /* create fsal_name_t */ 02299 st = FSAL_str2name(file, 256, &objname); 02300 if(FSAL_IS_ERROR(st)) 02301 { 02302 fprintf(output, "Error executing FSAL_str2name:"); 02303 print_fsal_status(output, st); 02304 fprintf(output, "\n"); 02305 return st.major; 02306 } 02307 02308 st = MFSL_create(&dir_hdl, /* IN */ 02309 &objname, /* IN */ 02310 &context->context, /* IN */ 02311 &context->mcontext, /* IN */ 02312 fsalmode, /* IN */ 02313 &file_hdl, /* OUT */ 02314 /*&context->current_fd, *//* OUT */ 02315 NULL /* [ IN/OUT ] */ , 02316 NULL, NULL /* will probably segfault */ 02317 ); 02318 02319 if(FSAL_IS_ERROR(st)) 02320 { 02321 fprintf(output, "Error executing FSAL_create:"); 02322 print_fsal_status(output, st); 02323 fprintf(output, "\n"); 02324 return st.major; 02325 } 02326 02327 if(flag_v) 02328 { 02329 char buff[2 * sizeof(fsal_handle_t) + 1]; 02330 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &file_hdl.handle); 02331 02332 fprintf(output, "%s/%s successfully created (@%s) \n", glob_path_dir, file, buff); 02333 02334 } 02335 02336 return 0; 02337 02338 } 02339 02340 /* setattr 02341 * 02342 * syntax of command line: 02343 * setattr file_path attribute_name attribute_value 02344 * 02345 */ 02346 int fn_mfsl_setattr(int argc, /* IN : number of args in argv */ 02347 char **argv, /* IN : arg list */ 02348 FILE * output /* IN : output stream */ 02349 ) 02350 { 02351 02352 static char format[] = "hv"; 02353 02354 static char help_setattr[] = 02355 "usage: setattr [-h][-v] <path> <attr>=<value>,<attr>=<value>,...\n"; 02356 02357 char glob_path[FSAL_MAX_PATH_LEN]; /* absolute path of the object */ 02358 mfsl_object_t obj_hdl; /* handle of the object */ 02359 fsal_attrib_list_t set_attrs; /* attributes to be setted */ 02360 fsal_status_t st; /* FSAL return status */ 02361 02362 int rc, option; 02363 int flag_v = 0; 02364 int flag_h = 0; 02365 int err_flag = 0; 02366 02367 char *file = NULL; /* the relative path to the object */ 02368 char *attr_list = NULL; /* attribute list */ 02369 02370 cmdmfsl_thr_info_t *context; 02371 02372 /* is the fs initialized ? */ 02373 if(!is_loaded) 02374 { 02375 fprintf(output, "Error: filesystem not initialized\n"); 02376 return -1; 02377 } 02378 02379 /* initialize current thread */ 02380 02381 context = GetMFSLCmdContext(); 02382 02383 if(context->is_thread_ok != TRUE) 02384 { 02385 int rc; 02386 rc = Init_Thread_MFSL(output, context, 0); 02387 if(rc != 0) 02388 return rc; 02389 } 02390 02391 /* analysing options */ 02392 02393 getopt_init(); 02394 while((option = Getopt(argc, argv, format)) != -1) 02395 { 02396 switch (option) 02397 { 02398 02399 case 'v': 02400 if(flag_v) 02401 fprintf(output, 02402 "setattr: warning: option 'v' has been specified more than once.\n"); 02403 else 02404 flag_v++; 02405 break; 02406 02407 case 'h': 02408 if(flag_h) 02409 fprintf(output, 02410 "setattr: warning: option 'h' has been specified more than once.\n"); 02411 else 02412 flag_h++; 02413 break; 02414 02415 case '?': 02416 fprintf(output, "setattr: unknown option : %c\n", Optopt); 02417 err_flag++; 02418 break; 02419 } 02420 } 02421 02422 if(flag_h) 02423 { 02424 02425 shell_attribute_t *curr_attr; 02426 02427 /* print usage */ 02428 fprintf(output, help_setattr); 02429 02430 fprintf(output, "\n<attr> can be one of the following values:\n"); 02431 02432 /* print attribute list */ 02433 02434 for(curr_attr = shell_attr_list; curr_attr->attr_type != ATTR_NONE; curr_attr++) 02435 { 02436 switch (curr_attr->attr_type) 02437 { 02438 case ATTR_32: 02439 fprintf(output, "\t %s \t:\t 32 bits integer\n", curr_attr->attr_name); 02440 break; 02441 case ATTR_64: 02442 fprintf(output, "\t %s \t:\t 64 bits integer\n", curr_attr->attr_name); 02443 break; 02444 case ATTR_OCTAL: 02445 fprintf(output, "\t %s \t:\t octal\n", curr_attr->attr_name); 02446 break; 02447 case ATTR_TIME: 02448 fprintf(output, "\t %s \t:\t time (format: YYYYMMDDhhmmss)\n", 02449 curr_attr->attr_name); 02450 break; 02451 } 02452 } 02453 02454 return 0; 02455 } 02456 02457 /* Exactly 2 args expected (path and attributes) */ 02458 02459 if(Optind != (argc - 2)) 02460 { 02461 err_flag++; 02462 } 02463 else 02464 { 02465 file = argv[Optind]; 02466 attr_list = argv[Optind + 1]; 02467 } 02468 02469 if(err_flag) 02470 { 02471 fprintf(output, help_setattr); 02472 return -1; 02473 } 02474 02475 /* copy current absolute path to a local variable. */ 02476 02477 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02478 02479 /* retrieve handle to the file whose attributes are to be changed */ 02480 02481 rc = msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->current_dir, 02482 &obj_hdl, output); 02483 if(rc) 02484 return rc; 02485 02486 /* Convert the peers (attr_name,attr_val) to an FSAL attribute structure. */ 02487 rc = MkFSALSetAttrStruct(attr_list, &set_attrs); 02488 02489 /* interprets output code */ 02490 switch (rc) 02491 { 02492 case 0: 02493 /* OK */ 02494 break; 02495 02496 case EFAULT: 02497 fprintf(output, "setattr: Internal error.\n"); 02498 return rc; 02499 02500 case ENOENT: 02501 fprintf(output, "setattr: Unknown attribute in list %s\n", attr_list); 02502 return rc; 02503 02504 case EINVAL: 02505 fprintf(output, "setattr: Invalid value for attribute in list %s\n", attr_list); 02506 return rc; 02507 02508 default: 02509 fprintf(output, "setattr: Error %d converting attributes.\n", rc); 02510 return rc; 02511 } 02512 02513 /* if verbose mode is on, we print the attributes to be set */ 02514 if(flag_v) 02515 { 02516 print_fsal_attributes(set_attrs, output); 02517 } 02518 02519 /* executes set attrs */ 02520 02521 st = MFSL_setattrs(&obj_hdl, &context->context, &context->mcontext, &set_attrs, NULL, NULL); 02522 02523 if(FSAL_IS_ERROR(st)) 02524 { 02525 fprintf(output, "Error executing FSAL_setattrs:"); 02526 print_fsal_status(output, st); 02527 fprintf(output, "\n"); 02528 return st.major; 02529 } 02530 02531 return 0; 02532 02533 } 02534 02541 int fn_mfsl_access(int argc, /* IN : number of args in argv */ 02542 char **argv, /* IN : arg list */ 02543 FILE * output /* IN : output stream */ 02544 ) 02545 { 02546 02547 static char format[] = "hvA"; 02548 02549 static char help_access[] = 02550 "usage: access [-h][-v][-A] <rights> <path>\n" 02551 "\n" 02552 " -h : print this help\n" 02553 " -v : verbose mode\n" 02554 " -A : test access from attributes\n" 02555 " ( call to getattr + test_access instead of access )\n" 02556 "\n" 02557 " <rights> : a set of the following characters:\n" 02558 " F: test file existence\n" 02559 " R: test read permission\n" 02560 " W: test write permission\n" 02561 " X: test execute permission\n" 02562 "\n" 02563 "Example: access -A RX my_dir\n" 02564 "test read and exec rights for directory \"my_dir\"\n" 02565 "by doing a getattr and a test_access call.\n\n"; 02566 02567 char glob_path[FSAL_MAX_PATH_LEN]; /* absolute path of the object */ 02568 mfsl_object_t obj_hdl; /* handle of the object */ 02569 fsal_accessflags_t test_perms; /* permissions to be tested */ 02570 fsal_status_t st; /* FSAL return status */ 02571 02572 int rc, option; 02573 unsigned int i; 02574 int flag_v = 0; 02575 int flag_h = 0; 02576 int flag_A = 0; 02577 int err_flag = 0; 02578 02579 char *file = NULL; /* the relative path to the object */ 02580 char *str_perms = NULL; /* string that represents the permissions to be tested */ 02581 02582 cmdmfsl_thr_info_t *context; 02583 02584 /* is the fs initialized ? */ 02585 if(!is_loaded) 02586 { 02587 fprintf(output, "Error: filesystem not initialized\n"); 02588 return -1; 02589 } 02590 02591 /* initialize current thread */ 02592 02593 context = GetMFSLCmdContext(); 02594 02595 if(context->is_thread_ok != TRUE) 02596 { 02597 int rc; 02598 rc = Init_Thread_MFSL(output, context, 0); 02599 if(rc != 0) 02600 return rc; 02601 } 02602 02603 /* analysing options */ 02604 02605 getopt_init(); 02606 while((option = Getopt(argc, argv, format)) != -1) 02607 { 02608 switch (option) 02609 { 02610 02611 case 'v': 02612 if(flag_v) 02613 fprintf(output, 02614 "access: warning: option 'v' has been specified more than once.\n"); 02615 else 02616 flag_v++; 02617 break; 02618 02619 case 'h': 02620 if(flag_h) 02621 fprintf(output, 02622 "access: warning: option 'h' has been specified more than once.\n"); 02623 else 02624 flag_h++; 02625 break; 02626 02627 case 'A': 02628 if(flag_A) 02629 fprintf(output, 02630 "access: warning: option 'A' has been specified more than once.\n"); 02631 else 02632 flag_A++; 02633 break; 02634 02635 case '?': 02636 fprintf(output, "access: unknown option : %c\n", Optopt); 02637 err_flag++; 02638 break; 02639 } 02640 } 02641 02642 if(flag_h) 02643 { 02644 02645 /* print usage */ 02646 fprintf(output, help_access); 02647 return 0; 02648 02649 } 02650 02651 /* Exactly 2 args expected */ 02652 02653 if(Optind != (argc - 2)) 02654 { 02655 err_flag++; 02656 } 02657 else 02658 { 02659 str_perms = argv[Optind]; 02660 file = argv[Optind + 1]; 02661 } 02662 02663 if(err_flag) 02664 { 02665 fprintf(output, help_access); 02666 return -1; 02667 } 02668 02669 /* copy current absolute path to a local variable. */ 02670 02671 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02672 02673 /* retrieve handle to the file whose permissions are to be tested */ 02674 02675 rc = msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, file, context->current_dir, &obj_hdl, 02676 output); 02677 if(rc) 02678 return rc; 02679 02680 /* Convert the permission string to an fsal access test. */ 02681 02682 test_perms = 0; 02683 02684 for(i = 0; i < strlen(str_perms); i++) 02685 { 02686 switch (str_perms[i]) 02687 { 02688 case 'F': 02689 if(flag_v) 02690 fprintf(output, "F_OK flag\n"); 02691 test_perms |= FSAL_F_OK; 02692 break; 02693 02694 case 'R': 02695 if(flag_v) 02696 fprintf(output, "R_OK flag\n"); 02697 test_perms |= FSAL_R_OK; 02698 break; 02699 02700 case 'W': 02701 if(flag_v) 02702 fprintf(output, "W_OK flag\n"); 02703 test_perms |= FSAL_W_OK; 02704 break; 02705 02706 case 'X': 02707 if(flag_v) 02708 fprintf(output, "X_OK flag\n"); 02709 test_perms |= FSAL_X_OK; 02710 break; 02711 02712 default: 02713 fprintf(output, "**** Invalid test: %c ****\n", str_perms[i]); 02714 fprintf(output, help_access); 02715 return -1; 02716 } 02717 } 02718 02719 /* Call to FSAL */ 02720 02721 if(flag_A) 02722 { 02723 fsal_attrib_list_t attributes; 02724 02725 /* 1st method: get attr and test_access */ 02726 02727 FSAL_CLEAR_MASK(attributes.asked_attributes); 02728 FSAL_SET_MASK(attributes.asked_attributes, 02729 FSAL_ATTR_MODE | FSAL_ATTR_OWNER | FSAL_ATTR_GROUP | FSAL_ATTR_ACL); 02730 02731 if(flag_v) 02732 fprintf(output, "Getting file attributes...\n"); 02733 02734 st = MFSL_getattrs(&obj_hdl, &context->context, &context->mcontext, &attributes, NULL); 02735 02736 if(FSAL_IS_ERROR(st)) 02737 { 02738 fprintf(output, "Error executing MFSL_getattrs:"); 02739 print_fsal_status(output, st); 02740 fprintf(output, "\n"); 02741 return st.major; 02742 } 02743 02744 if(flag_v) 02745 { 02746 print_fsal_attributes(attributes, output); 02747 } 02748 02749 if(flag_v) 02750 fprintf(output, "Testing access rights...\n"); 02751 02752 st = FSAL_test_access(&context->context, test_perms, &attributes); 02753 02754 if(FSAL_IS_ERROR(st)) 02755 { 02756 02757 fprintf(output, "Error executing FSAL_test_access:"); 02758 print_fsal_status(output, st); 02759 fprintf(output, "\n"); 02760 return st.major; 02761 02762 } 02763 else 02764 { 02765 02766 fprintf(output, "access: Access granted.\n"); 02767 return 0; 02768 02769 } 02770 02771 } 02772 else 02773 { 02774 /* 2nd method: simply calling access */ 02775 02776 if(flag_v) 02777 fprintf(output, "Calling access\n"); 02778 02779 st = MFSL_access(&obj_hdl, &context->context, &context->mcontext, test_perms, NULL, NULL); 02780 02781 if(FSAL_IS_ERROR(st)) 02782 { 02783 02784 fprintf(output, "Error executing FSAL_access:"); 02785 print_fsal_status(output, st); 02786 fprintf(output, "\n"); 02787 return st.major; 02788 02789 } 02790 else 02791 { 02792 02793 fprintf(output, "access: Access granted.\n"); 02794 return 0; 02795 } 02796 02797 } 02798 02799 } 02800 02802 int fn_mfsl_truncate(int argc, /* IN : number of args in argv */ 02803 char **argv, /* IN : arg list */ 02804 FILE * output /* IN : output stream */ 02805 ) 02806 { 02807 02808 static char format[] = "hv"; 02809 02810 static char help_truncate[] = "usage: truncate [-h][-v] <file> <size>\n"; 02811 02812 char glob_path[FSAL_MAX_PATH_LEN]; 02813 mfsl_object_t filehdl; 02814 02815 fsal_status_t st; 02816 fsal_size_t trunc_size; 02817 02818 int rc, option; 02819 int flag_v = 0; 02820 int flag_h = 0; 02821 int err_flag = 0; 02822 02823 char *file = NULL; 02824 char *str_size = NULL; 02825 02826 cmdmfsl_thr_info_t *context; 02827 02828 /* is the fs initialized ? */ 02829 if(!is_loaded) 02830 { 02831 fprintf(output, "Error: filesystem not initialized\n"); 02832 return -1; 02833 } 02834 02835 /* initialize current thread */ 02836 02837 context = GetMFSLCmdContext(); 02838 02839 if(context->is_thread_ok != TRUE) 02840 { 02841 int rc; 02842 rc = Init_Thread_MFSL(output, context, 0); 02843 if(rc != 0) 02844 return rc; 02845 } 02846 02847 /* analysing options */ 02848 getopt_init(); 02849 while((option = Getopt(argc, argv, format)) != -1) 02850 { 02851 switch (option) 02852 { 02853 case 'v': 02854 if(flag_v) 02855 fprintf(output, 02856 "truncate: warning: option 'v' has been specified more than once.\n"); 02857 else 02858 flag_v++; 02859 break; 02860 case 'h': 02861 if(flag_h) 02862 fprintf(output, 02863 "truncate: warning: option 'h' has been specified more than once.\n"); 02864 else 02865 flag_h++; 02866 break; 02867 case '?': 02868 fprintf(output, "truncate: unknown option : %c\n", Optopt); 02869 err_flag++; 02870 break; 02871 } 02872 } 02873 02874 if(flag_h) 02875 { 02876 fprintf(output, help_truncate); 02877 return 0; 02878 } 02879 02880 /* Exactly two arg expected */ 02881 if(Optind != (argc - 2)) 02882 { 02883 err_flag++; 02884 } 02885 else 02886 { 02887 file = argv[Optind]; 02888 str_size = argv[Optind + 1]; 02889 02890 rc = ato64(str_size, &trunc_size); 02891 if(rc == -1) 02892 { 02893 fprintf(output, "truncate: error: invalid trunc size \"%s\"\n", str_size); 02894 err_flag++; 02895 } 02896 02897 } 02898 02899 if(err_flag) 02900 { 02901 fprintf(output, help_truncate); 02902 return -1; 02903 } 02904 02905 /* copy current path. */ 02906 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 02907 02908 /* retrieves object handle */ 02909 if(rc = 02910 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 02911 file, context->current_dir, &filehdl, output)) 02912 return rc; 02913 02914 if(flag_v) 02915 fprintf(output, "Truncating \"%s\" to %llu bytes.\n", glob_path, trunc_size); 02916 02917 st = MFSL_truncate(&filehdl, &context->context, &context->mcontext, trunc_size, NULL, /* Will fail with FSAL_PROXY */ 02918 NULL, NULL); 02919 02920 if(FSAL_IS_ERROR(st)) 02921 { 02922 fprintf(output, "Error executing FSAL_truncate:"); 02923 print_fsal_status(output, st); 02924 fprintf(output, "\n"); 02925 return st.major; 02926 } 02927 02928 if(flag_v) 02929 fprintf(output, "Truncate operation completed sucessfully.\n"); 02930 02931 return 0; 02932 02933 } 02934 02939 int fn_mfsl_open(int argc, /* IN : number of args in argv */ 02940 char **argv, /* IN : arg list */ 02941 FILE * output /* IN : output stream */ 02942 ) 02943 { 02944 02945 static char format[] = "hv"; 02946 02947 static char help_open[] = 02948 "usage: open [-h][-v] <path> [<oflags>]\n" 02949 " where <oflags> is a set of the following values:\n" 02950 " 'r': read, 'w': write, 'a': append, 't': truncate.\n"; 02951 02952 char glob_path[FSAL_MAX_PATH_LEN]; 02953 mfsl_object_t filehdl; 02954 02955 fsal_status_t st; 02956 02957 int rc, option; 02958 int flag_v = 0; 02959 int flag_h = 0; 02960 int err_flag = 0; 02961 02962 fsal_openflags_t o_flags; 02963 02964 int flag_r = 0; 02965 int flag_w = 0; 02966 int flag_a = 0; 02967 int flag_t = 0; 02968 02969 char *file = NULL; 02970 char *opt_str; 02971 02972 cmdmfsl_thr_info_t *context; 02973 02974 /* is the fs initialized ? */ 02975 if(!is_loaded) 02976 { 02977 fprintf(output, "Error: filesystem not initialized\n"); 02978 return -1; 02979 } 02980 02981 /* initialize current thread */ 02982 02983 context = GetMFSLCmdContext(); 02984 02985 if(context->is_thread_ok != TRUE) 02986 { 02987 int rc; 02988 rc = Init_Thread_MFSL(output, context, 0); 02989 if(rc != 0) 02990 return rc; 02991 } 02992 02993 /* is a file already opened ? */ 02994 if(context->opened) 02995 { 02996 fprintf(output, "Error: a file is already opened. Use 'close' command first.\n"); 02997 return -1; 02998 } 02999 03000 /* analysing options */ 03001 03002 getopt_init(); 03003 while((option = Getopt(argc, argv, format)) != -1) 03004 { 03005 switch (option) 03006 { 03007 case 'v': 03008 if(flag_v) 03009 fprintf(output, 03010 "open: warning: option 'v' has been specified more than once.\n"); 03011 else 03012 flag_v++; 03013 break; 03014 case 'h': 03015 if(flag_h) 03016 fprintf(output, 03017 "open: warning: option 'h' has been specified more than once.\n"); 03018 else 03019 flag_h++; 03020 break; 03021 case '?': 03022 fprintf(output, "open: unknown option : %c\n", Optopt); 03023 err_flag++; 03024 break; 03025 } 03026 } 03027 03028 if(flag_h) 03029 { 03030 fprintf(output, help_open); 03031 return 0; 03032 } 03033 03034 /* one or two args expected */ 03035 if(Optind > (argc - 1)) 03036 err_flag++; 03037 else 03038 { 03039 file = argv[Optind]; 03040 03041 Optind++; 03042 03043 /* optional flags */ 03044 while(Optind < argc) 03045 { 03046 /* test flags */ 03047 opt_str = argv[Optind]; 03048 03049 while(*opt_str) 03050 { 03051 switch (*opt_str) 03052 { 03053 case 'r': 03054 case 'R': 03055 flag_r++; 03056 break; 03057 03058 case 'w': 03059 case 'W': 03060 flag_w++; 03061 break; 03062 03063 case 'a': 03064 case 'A': 03065 flag_a++; 03066 break; 03067 03068 case 't': 03069 case 'T': 03070 flag_t++; 03071 break; 03072 03073 default: 03074 fprintf(output, "open: unknown open flag : '%c'\n", *opt_str); 03075 err_flag++; 03076 } 03077 opt_str++; 03078 } 03079 03080 Optind++; 03081 } 03082 03083 } 03084 03085 if(err_flag) 03086 { 03087 fprintf(output, help_open); 03088 return -1; 03089 } 03090 03091 /* copy current path. */ 03092 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 03093 03094 /* retrieves object handle */ 03095 if(rc = 03096 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 03097 file, context->current_dir, &filehdl, output)) 03098 return rc; 03099 03100 /* make open flags */ 03101 03102 o_flags = 0; 03103 03104 if(flag_r && flag_w) 03105 o_flags |= FSAL_O_RDWR; 03106 else if(flag_r) 03107 o_flags |= FSAL_O_RDONLY; 03108 else if(flag_w) 03109 o_flags |= FSAL_O_WRONLY; 03110 03111 if(flag_a) 03112 o_flags |= FSAL_O_APPEND; 03113 if(flag_t) 03114 o_flags |= FSAL_O_TRUNC; 03115 03116 if(flag_v) 03117 fprintf(output, "Open operation on %s with flags %#X.\n", glob_path, o_flags); 03118 03119 st = MFSL_open(&filehdl, 03120 &context->context, 03121 &context->mcontext, o_flags, &context->current_fd, NULL, NULL); 03122 03123 if(FSAL_IS_ERROR(st)) 03124 { 03125 fprintf(output, "Error executing FSAL_open:"); 03126 print_fsal_status(output, st); 03127 fprintf(output, "\n"); 03128 return st.major; 03129 } 03130 03131 /* note that a file is opened. */ 03132 context->opened = TRUE; 03133 03134 if(flag_v) 03135 fprintf(output, "Open operation completed sucessfully : fd = %d.\n", 03136 FSAL_FILENO(&(context->current_fd.fsal_file))); 03137 03138 return 0; 03139 03140 } 03141 03145 int fn_mfsl_read(int argc, /* IN : number of args in argv */ 03146 char **argv, /* IN : arg list */ 03147 FILE * output /* IN : output stream */ 03148 ) 03149 { 03150 03151 static char format[] = "hvAXB:s:"; 03152 03153 static char help_read[] = 03154 "Usage:\n" 03155 " read [-h][-v][-A][-X] [-B <block_size> ] [ -s <seek_type>,<offset> ] { <total_bytes> | all }\n" 03156 "Options:\n" 03157 " -h: print this help\n" 03158 " -v: verbose mode\n" 03159 " -A: display read data in ascii\n" 03160 " -X: display read data in hexa\n" 03161 " -B <blocksize>: block size used for reading, in bytes (default 1k).\n" 03162 " -s <seek_type>,<offset>: specify the position of the first byte to be read.\n" 03163 " <seek_type> can take the values SET, CUR or END.\n" 03164 " <offset> is a signed integer.\n" 03165 " <total_bytes>: indicates the total number of bytes to be read\n" 03166 " ('all' indicates that data are read until the end of the file).\n" 03167 "Example:\n" 03168 " For reading the last 2kB of the opened file, using 1k block size:\n" 03169 " read -B 1024 -s END,-2048 all \n"; 03170 03171 fsal_status_t st; 03172 03173 int rc, option; 03174 03175 int flag_v = 0; 03176 int flag_h = 0; 03177 int flag_A = 0; 03178 int flag_X = 0; 03179 int flag_B = 0; 03180 int flag_s = 0; 03181 03182 int err_flag = 0; 03183 03184 char *str_block_size = NULL; 03185 03186 char str_seek_buff[256]; 03187 03188 char *str_seek_type = NULL; 03189 char *str_seek_offset = NULL; 03190 char *str_total_bytes = NULL; 03191 03192 fsal_size_t block_size = 1024; /* default: 1ko */ 03193 fsal_size_t total_bytes = 0; /* 0 == read all */ 03194 fsal_seek_t seek_desc = { FSAL_SEEK_CUR, 0 }; /* default: read current position */ 03195 03196 fsal_seek_t *p_seek_desc = NULL; 03197 03198 /* fsal arguments */ 03199 03200 fsal_boolean_t is_eof = 0; 03201 fsal_size_t total_nb_read = 0; 03202 fsal_size_t once_nb_read = 0; 03203 fsal_size_t nb_block_read = 0; 03204 03205 char *p_read_buff; 03206 03207 struct timeval timer_start; 03208 struct timeval timer_stop; 03209 struct timeval timer_diff; 03210 03211 cmdmfsl_thr_info_t *context; 03212 03213 /* is the fs initialized ? */ 03214 if(!is_loaded) 03215 { 03216 fprintf(output, "Error: filesystem not initialized\n"); 03217 return -1; 03218 } 03219 03220 /* initialize current thread */ 03221 03222 context = GetMFSLCmdContext(); 03223 03224 if(context->is_thread_ok != TRUE) 03225 { 03226 int rc; 03227 rc = Init_Thread_MFSL(output, context, 0); 03228 if(rc != 0) 03229 return rc; 03230 } 03231 03232 /* is a file opened ? */ 03233 if(!context->opened) 03234 { 03235 fprintf(output, "Error: no opened file. Use 'open' command first.\n"); 03236 return -1; 03237 } 03238 03239 /* option analysis. */ 03240 03241 getopt_init(); 03242 while((option = Getopt(argc, argv, format)) != -1) 03243 { 03244 switch (option) 03245 { 03246 03247 case 'v': 03248 if(flag_v) 03249 fprintf(output, 03250 "read: warning: option 'v' has been specified more than once.\n"); 03251 else 03252 flag_v++; 03253 break; 03254 03255 case 'h': 03256 if(flag_h) 03257 fprintf(output, 03258 "read: warning: option 'h' has been specified more than once.\n"); 03259 else 03260 flag_h++; 03261 break; 03262 03263 case 'A': 03264 if(flag_A) 03265 fprintf(output, 03266 "read: warning: option 'A' has been specified more than once.\n"); 03267 else if(flag_X) 03268 { 03269 fprintf(output, "read: option 'A' conflicts with option 'X'.\n"); 03270 err_flag++; 03271 } 03272 else 03273 flag_A++; 03274 break; 03275 03276 case 'X': 03277 if(flag_X) 03278 fprintf(output, 03279 "read: warning: option 'X' has been specified more than once.\n"); 03280 else if(flag_A) 03281 { 03282 fprintf(output, "read: option 'X' conflicts with option 'A'.\n"); 03283 err_flag++; 03284 } 03285 else 03286 flag_X++; 03287 break; 03288 03289 case 'B': 03290 if(flag_B) 03291 fprintf(output, 03292 "read: warning: option 'B' has been specified more than once.\n"); 03293 else 03294 { 03295 flag_B++; 03296 str_block_size = Optarg; 03297 } 03298 break; 03299 03300 case 's': 03301 if(flag_s) 03302 fprintf(output, 03303 "read: warning: option 's' has been specified more than once.\n"); 03304 else 03305 { 03306 flag_s++; 03307 strncpy(str_seek_buff, Optarg, 256); 03308 str_seek_type = str_seek_buff; 03309 } 03310 break; 03311 03312 case '?': 03313 fprintf(output, "read: unknown option : %c\n", Optopt); 03314 err_flag++; 03315 break; 03316 } 03317 } 03318 03319 if(flag_h) 03320 { 03321 fprintf(output, help_read); 03322 return 0; 03323 } 03324 03325 /* Exactly one arg expected */ 03326 03327 if(Optind != (argc - 1)) 03328 err_flag++; 03329 else 03330 str_total_bytes = argv[Optind]; 03331 03332 if(err_flag) 03333 { 03334 fprintf(output, help_read); 03335 return -1; 03336 } 03337 03338 /* check argument types */ 03339 03340 if(flag_B) 03341 { 03342 /* Try to convert the str_block_size to fsal_size_t */ 03343 03344 rc = ato64(str_block_size, &block_size); 03345 03346 if(rc == -1) 03347 { 03348 fprintf(output, "read: error: invalid block size \"%s\"\n", str_block_size); 03349 err_flag++; 03350 } 03351 03352 } 03353 03354 if(flag_s) 03355 { 03356 /* Try to parse the argument */ 03357 03358 str_seek_offset = strchr(str_seek_type, ','); 03359 03360 if(str_seek_offset == NULL) 03361 { 03362 fprintf(output, 03363 "read: error: invalid seek specifier \"%s\". <seek_type>,<offset> expected.\n", 03364 str_seek_type); 03365 err_flag++; 03366 } 03367 03368 if(!err_flag) 03369 { 03370 int sign = 1; 03371 03372 *str_seek_offset = '\0'; 03373 str_seek_offset++; /* the first char after the "," */ 03374 03375 /* Check seek type */ 03376 03377 if(!strncmp(str_seek_type, "CUR", 256)) 03378 seek_desc.whence = FSAL_SEEK_CUR; 03379 else if(!strncmp(str_seek_type, "SET", 256)) 03380 seek_desc.whence = FSAL_SEEK_SET; 03381 else if(!strncmp(str_seek_type, "END", 256)) 03382 seek_desc.whence = FSAL_SEEK_END; 03383 else 03384 { 03385 fprintf(output, 03386 "read: error: invalid seek type \"%s\". CUR, SET or END expected.\n", 03387 str_seek_type); 03388 err_flag++; 03389 } 03390 03391 /* Try to convert str_seek_offset to fsal_off_t */ 03392 03393 switch (str_seek_offset[0]) 03394 { 03395 case '+': 03396 sign = 1; 03397 str_seek_offset++; 03398 break; 03399 03400 case '-': 03401 sign = -1; 03402 str_seek_offset++; 03403 break; 03404 } 03405 03406 rc = ato64(str_seek_offset, (unsigned long long *)&seek_desc.offset); 03407 03408 if(rc == -1) 03409 { 03410 fprintf(output, "read: error: invalid offset \"%s\".\n", str_seek_offset); 03411 err_flag++; 03412 } 03413 else if(sign < 0) 03414 seek_desc.offset = -seek_desc.offset; 03415 03416 } 03417 03418 p_seek_desc = &seek_desc; 03419 03420 } 03421 else 03422 { 03423 p_seek_desc = NULL; /* default seeking */ 03424 } 03425 03426 if(!strcasecmp(str_total_bytes, "all")) 03427 { 03428 total_bytes = 0; 03429 } 03430 else 03431 { 03432 rc = ato64(str_total_bytes, &total_bytes); 03433 03434 if(rc == -1) 03435 { 03436 fprintf(output, 03437 "read: error: invalid read size \"%s\". \"all\" or <nb_bytes> expected.\n", 03438 str_total_bytes); 03439 err_flag++; 03440 } 03441 } 03442 03443 if(err_flag) 03444 { 03445 fprintf(output, help_read); 03446 return -1; 03447 } 03448 03449 if(flag_v) 03450 { 03451 03452 /* print a sum-up of read parameters */ 03453 fprintf(output, 03454 "Read options: Block size: %llu Bytes, Seek: %s%+lld, Read limit: %llu Bytes\n", 03455 block_size, 03456 (p_seek_desc 03457 ? (seek_desc.whence == FSAL_SEEK_SET ? "SET" : seek_desc.whence == 03458 FSAL_SEEK_CUR ? "CUR" : "END") : "DEFAULT"), 03459 (p_seek_desc ? seek_desc.offset : 0LL), total_bytes); 03460 } 03461 03462 /* Now all arguments have been parsed, let's act ! */ 03463 03464 /* alloc a buffer */ 03465 p_read_buff = gsh_malloc(block_size); 03466 03467 if(p_read_buff == NULL) 03468 { 03469 fprintf(output, 03470 "read: error: Not enough memory to allocate read buffer (%llu Bytes).\n", 03471 block_size); 03472 return ENOMEM; 03473 } 03474 03475 gettimeofday(&timer_start, NULL) ; 03476 03477 /* while EOF is not reached, and read<asked (when total_bytes!=0) */ 03478 while(!is_eof && !((total_bytes != 0) && (total_nb_read >= total_bytes))) 03479 { 03480 03481 st = MFSL_read(&context->current_fd, 03482 p_seek_desc, 03483 block_size, 03484 (caddr_t) p_read_buff, &once_nb_read, &is_eof, &context->mcontext, NULL); 03485 03486 if(FSAL_IS_ERROR(st)) 03487 { 03488 fprintf(output, "Error executing FSAL_read:"); 03489 print_fsal_status(output, st); 03490 fprintf(output, "\n"); 03491 03492 /* exit only if it is not retryable */ 03493 if(fsal_is_retryable(st)) 03494 { 03495 sleep(1); 03496 continue; 03497 } 03498 else 03499 { 03500 gsh_free(p_read_buff); 03501 return st.major; 03502 } 03503 } 03504 03505 /* print what was read. */ 03506 if(flag_A) 03507 { 03508 fsal_size_t index; 03509 for(index = 0; index < once_nb_read; index++) 03510 fprintf(output, "%c.", p_read_buff[index]); 03511 } 03512 else if(flag_X) 03513 { 03514 fsal_size_t index; 03515 for(index = 0; index < once_nb_read; index++) 03516 fprintf(output, "%.2X ", p_read_buff[index]); 03517 } 03518 else 03519 fprintf(output, "."); 03520 03521 /* update stats */ 03522 03523 if(once_nb_read > 0) 03524 nb_block_read++; 03525 03526 total_nb_read += once_nb_read; 03527 03528 /* flush */ 03529 if(nb_block_read % 10) 03530 fflush(output); 03531 03532 /* what ever seek type was, we continue reading from current position */ 03533 p_seek_desc = NULL; 03534 03535 } 03536 03537 gettimeofday(&timer_stop, NULL); 03538 03539 /* newline after read blocks */ 03540 fprintf(output, "\n"); 03541 03542 if(flag_v) 03543 { 03544 double bandwidth; 03545 03546 /* print stats */ 03547 fprintf(output, "Nb blocks read: %llu\n", nb_block_read); 03548 fprintf(output, "Total: %llu Bytes\n", total_nb_read); 03549 03550 fprintf(output, "Time enlapsed: "); 03551 timer_diff = time_diff(timer_start, timer_stop); 03552 print_timeval(output, timer_diff); 03553 03554 bandwidth = 03555 total_nb_read / (1024 * 1024 * 03556 (timer_diff.tv_sec + 0.000001 * timer_diff.tv_usec)); 03557 03558 fprintf(output, "Bandwidth: %f MB/s\n", bandwidth); 03559 03560 } 03561 gsh_free(p_read_buff); 03562 03563 return 0; 03564 } 03565 03595 int fn_mfsl_write(int argc, /* IN : number of args in argv */ 03596 char **argv, /* IN : arg list */ 03597 FILE * output /* IN : output stream */ 03598 ) 03599 { 03600 03601 static char format[] = "hvs:N:A:X:"; 03602 03603 static char help_write[] = 03604 "Usage:\n" 03605 " write [-h][-v] [ -s <seek_type>,<offset> ] [-N <nb_times>] -A <ascii_string>\n" 03606 " write [-h][-v] [ -s <seek_type>,<offset> ] [-N <nb_times>] -X <hexa_data>\n" 03607 "Where:\n" 03608 " <seek_type> can be: SET, CUR, END\n" 03609 " <offset> is a signed number of bytes.\n" 03610 " <nb_times> is the number of times we write the expression into the file.\n" 03611 "\n" 03612 " <ascii_string> is a string to be written to file.\n" 03613 " Note that the null terminating character of is also written\n" 03614 " to file.\n" 03615 "or\n" 03616 " <hexa_data> is a data represented in hexadecimal format,\n" 03617 " that is to be written to file.\n" 03618 "\n" 03619 "Examples:\n" 03620 "\n" 03621 " For writting 10 times the null terminated string \"hello world\"\n" 03622 " at the end of the file:\n" 03623 " write -s END,0 -N 10 -A \"hello world\"\n" 03624 "\n" 03625 " For overwritting the beginning of the file with\n" 03626 " the pattern 0xA1267AEF31254ADE repeated twice:\n" 03627 " write -s SET,0 -N 2 -X \"A1267AEF31254ADE\"\n"; 03628 03629 fsal_status_t st; 03630 03631 int rc, option; 03632 03633 int flag_v = 0; 03634 int flag_h = 0; 03635 int flag_N = 0; 03636 int flag_s = 0; 03637 int flag_A = 0; 03638 int flag_X = 0; 03639 03640 int err_flag = 0; 03641 03642 char *str_times = NULL; 03643 char str_seek_buff[256]; 03644 char *str_seek_type = NULL; 03645 char *str_seek_offset = NULL; 03646 03647 char *str_hexa = NULL; 03648 char *str_ascii = NULL; 03649 03650 size_t datasize = 0; 03651 char *databuff = NULL; 03652 03653 unsigned long long nb_times = 1; /* default = 1 */ 03654 03655 fsal_size_t block_size; /* the length of the data block to be written */ 03656 03657 fsal_u64_t nb_block_written = 0; 03658 fsal_size_t size_written = 0; 03659 fsal_size_t size_written_once = 0; 03660 03661 fsal_seek_t seek_desc = { FSAL_SEEK_CUR, 0 }; /* default: write to current position */ 03662 03663 fsal_seek_t *p_seek_desc = NULL; 03664 03665 struct timeval timer_start; 03666 struct timeval timer_stop; 03667 struct timeval timer_diff; 03668 03669 cmdmfsl_thr_info_t *context; 03670 03671 /* is the fs initialized ? */ 03672 if(!is_loaded) 03673 { 03674 fprintf(output, "Error: filesystem not initialized\n"); 03675 return -1; 03676 } 03677 03678 /* initialize current thread */ 03679 03680 context = GetMFSLCmdContext(); 03681 03682 if(context->is_thread_ok != TRUE) 03683 { 03684 int rc; 03685 rc = Init_Thread_MFSL(output, context, 0); 03686 if(rc != 0) 03687 return rc; 03688 } 03689 03690 /* is a file opened ? */ 03691 if(!context->opened) 03692 { 03693 fprintf(output, "Error: no opened file. Use 'open' command first.\n"); 03694 return -1; 03695 } 03696 03697 /* option analysis. */ 03698 03699 getopt_init(); 03700 while((option = Getopt(argc, argv, format)) != -1) 03701 { 03702 switch (option) 03703 { 03704 03705 case 'v': 03706 if(flag_v) 03707 fprintf(output, 03708 "write: warning: option 'v' has been specified more than once.\n"); 03709 else 03710 flag_v++; 03711 break; 03712 03713 case 'h': 03714 if(flag_h) 03715 fprintf(output, 03716 "write: warning: option 'h' has been specified more than once.\n"); 03717 else 03718 flag_h++; 03719 break; 03720 03721 case 'N': 03722 if(flag_N) 03723 fprintf(output, 03724 "write: warning: option 'N' has been specified more than once.\n"); 03725 else 03726 { 03727 flag_N++; 03728 str_times = Optarg; 03729 } 03730 break; 03731 03732 case 's': 03733 if(flag_s) 03734 fprintf(output, 03735 "write: warning: option 's' has been specified more than once.\n"); 03736 else 03737 { 03738 flag_s++; 03739 strncpy(str_seek_buff, Optarg, 256); 03740 str_seek_type = str_seek_buff; 03741 } 03742 break; 03743 03744 case 'A': 03745 if(flag_A) 03746 fprintf(output, 03747 "write: warning: option 'A' has been specified more than once.\n"); 03748 else if(flag_X) 03749 { 03750 fprintf(output, "write: option 'A' conflicts with option 'X'.\n"); 03751 err_flag++; 03752 } 03753 else 03754 { 03755 flag_A++; 03756 str_ascii = Optarg; 03757 } 03758 break; 03759 03760 case 'X': 03761 if(flag_X) 03762 fprintf(output, 03763 "write: warning: option 'X' has been specified more than once.\n"); 03764 else if(flag_A) 03765 { 03766 fprintf(output, "write: option 'X' conflicts with option 'A'.\n"); 03767 err_flag++; 03768 } 03769 else 03770 { 03771 flag_X++; 03772 str_hexa = Optarg; 03773 } 03774 break; 03775 03776 case '?': 03777 fprintf(output, "write: unknown option : %c\n", Optopt); 03778 err_flag++; 03779 break; 03780 } 03781 } 03782 03783 if(flag_h) 03784 { 03785 fprintf(output, help_write); 03786 return 0; 03787 } 03788 03789 /* No extra arg expected */ 03790 03791 if(Optind != argc) 03792 err_flag++; 03793 03794 if(!flag_A && !flag_X) 03795 { 03796 fprintf(output, "write: error: -A or -X option is mandatory.\n"); 03797 err_flag++; 03798 } 03799 03800 if(err_flag) 03801 { 03802 fprintf(output, help_write); 03803 return -1; 03804 } 03805 03806 /* check argument types */ 03807 03808 if(flag_N) 03809 { 03810 /* Try to convert the str_times to nb_times */ 03811 03812 rc = ato64(str_times, &nb_times); 03813 03814 if(rc == -1) 03815 { 03816 fprintf(output, "write: error: invalid number \"%s\"\n", str_times); 03817 return EINVAL; 03818 } 03819 03820 } 03821 03822 if(flag_s) 03823 { 03824 int sign = 1; 03825 03826 /* Try to parse the argument */ 03827 03828 str_seek_offset = strchr(str_seek_type, ','); 03829 03830 if(str_seek_offset == NULL) 03831 { 03832 fprintf(output, 03833 "write: error: invalid seek specifier \"%s\". <seek_type>,<offset> expected.\n", 03834 str_seek_type); 03835 return EINVAL; 03836 } 03837 03838 *str_seek_offset = '\0'; 03839 str_seek_offset++; /* the first char after the "," */ 03840 03841 /* Check seek type */ 03842 03843 if(!strncmp(str_seek_type, "CUR", 256)) 03844 seek_desc.whence = FSAL_SEEK_CUR; 03845 else if(!strncmp(str_seek_type, "SET", 256)) 03846 seek_desc.whence = FSAL_SEEK_SET; 03847 else if(!strncmp(str_seek_type, "END", 256)) 03848 seek_desc.whence = FSAL_SEEK_END; 03849 else 03850 { 03851 fprintf(output, 03852 "write: error: invalid seek type \"%s\". CUR, SET or END expected.\n", 03853 str_seek_type); 03854 return EINVAL; 03855 } 03856 03857 /* Try to convert str_seek_offset to fsal_off_t */ 03858 03859 switch (str_seek_offset[0]) 03860 { 03861 case '+': 03862 sign = 1; 03863 str_seek_offset++; 03864 break; 03865 03866 case '-': 03867 sign = -1; 03868 str_seek_offset++; 03869 break; 03870 } 03871 03872 rc = ato64(str_seek_offset, (unsigned long long *)&seek_desc.offset); 03873 03874 if(rc == -1) 03875 { 03876 fprintf(output, "write: error: invalid offset \"%s\".\n", str_seek_offset); 03877 return EINVAL; 03878 } 03879 else if(sign < 0) 03880 seek_desc.offset = -seek_desc.offset; 03881 03882 p_seek_desc = &seek_desc; 03883 03884 } 03885 else 03886 { 03887 p_seek_desc = NULL; /* default seeking */ 03888 } 03889 03890 if(flag_A) 03891 { 03892 datasize = strlen(str_ascii) + 1; /* Include null termination char. */ 03893 databuff = str_ascii; 03894 } 03895 03896 if(flag_X) 03897 { 03898 size_t length = strlen(str_hexa); 03899 03900 datasize = (length >> 1); 03901 03902 if(length % 2) 03903 { 03904 03905 /* if it is not odd: error */ 03906 fprintf(output, 03907 "write: error: in \"%s\", data length is not a multiple of 8 bits.\n", 03908 str_hexa); 03909 03910 return EINVAL; 03911 } 03912 03913 databuff = gsh_malloc(datasize + 1); 03914 03915 if(databuff == NULL) 03916 { 03917 fprintf(output, "write: error: Not enough memory to allocate %llu Bytes.\n", 03918 (unsigned long long)datasize); 03919 return ENOMEM; 03920 } 03921 03922 memset(databuff, 0, datasize + 1); 03923 03924 /* try to convert the string to hexa */ 03925 rc = sscanmem(databuff, datasize, str_hexa); 03926 03927 if(rc != (int)(2 * datasize)) 03928 { 03929 /* if it is not odd: error */ 03930 fprintf(output, "write: error: \"%s\" in not a valid hexa format.\n", str_hexa); 03931 03932 gsh_free(str_hexa); 03933 03934 return EINVAL; 03935 } 03936 03937 } 03938 03939 if(flag_v) 03940 { 03941 /* print a sum-up of write parameters */ 03942 fprintf(output, "Write options: Data length: %llu x %llu Bytes, Seek: %s%+lld\n", 03943 (unsigned long long)nb_times, 03944 (unsigned long long)datasize, 03945 (p_seek_desc ? (seek_desc.whence == FSAL_SEEK_SET ? "SET" : 03946 seek_desc.whence == FSAL_SEEK_CUR ? "CUR" : 03947 "END") : "DEFAULT"), 03948 (p_seek_desc ? seek_desc.offset : 0LL)); 03949 } 03950 03951 /* variables initialisation */ 03952 03953 block_size = (fsal_size_t) datasize; 03954 nb_block_written = 0; 03955 size_written = 0; 03956 size_written_once = 0; 03957 03958 gettimeofday(&timer_start, NULL); 03959 03960 /* write loop */ 03961 03962 while(nb_block_written < nb_times) 03963 { 03964 03965 st = MFSL_write(&context->current_fd, 03966 p_seek_desc, 03967 block_size, 03968 (caddr_t) databuff, &size_written_once, &context->mcontext, NULL ); 03969 03970 if(FSAL_IS_ERROR(st)) 03971 { 03972 fprintf(output, "Error executing FSAL_write:"); 03973 print_fsal_status(output, st); 03974 fprintf(output, "\n"); 03975 03976 /* exit only if it is not retryable */ 03977 if(fsal_is_retryable(st)) 03978 { 03979 sleep(1); 03980 continue; 03981 } 03982 else 03983 { 03984 if(flag_X) 03985 gsh_free(databuff); 03986 return st.major; 03987 } 03988 } 03989 03990 fprintf(output, "."); 03991 03992 /* update stats */ 03993 03994 if(size_written_once > 0) 03995 nb_block_written++; 03996 03997 size_written += size_written_once; 03998 03999 /* flush */ 04000 if(nb_block_written % 10) 04001 fflush(output); 04002 04003 /* what ever seek type was, we continue writting to the current position */ 04004 p_seek_desc = NULL; 04005 04006 } 04007 04008 gettimeofday(&timer_stop, NULL); 04009 04010 /* newline after written blocks */ 04011 fprintf(output, "\n"); 04012 04013 if(flag_v) 04014 { 04015 double bandwidth; 04016 04017 /* print stats */ 04018 fprintf(output, "Nb blocks written: %llu\n", nb_block_written); 04019 fprintf(output, "Total volume: %llu Bytes\n", size_written); 04020 04021 fprintf(output, "Time enlapsed: "); 04022 timer_diff = time_diff(timer_start, timer_stop); 04023 print_timeval(output, timer_diff); 04024 04025 bandwidth = 04026 size_written / (1024 * 1024 * 04027 (timer_diff.tv_sec + 0.000001 * timer_diff.tv_usec)); 04028 04029 fprintf(output, "Bandwidth: %f MB/s\n", bandwidth); 04030 04031 } 04032 04033 if(flag_X) 04034 gsh_free(databuff); 04035 04036 return 0; 04037 04038 } 04039 04044 int fn_mfsl_close(int argc, /* IN : number of args in argv */ 04045 char **argv, /* IN : arg list */ 04046 FILE * output /* IN : output stream */ 04047 ) 04048 { 04049 04050 static char help_close[] = "usage: close\n"; 04051 04052 fsal_status_t st; 04053 04054 cmdmfsl_thr_info_t *context; 04055 04056 /* is the fs initialized ? */ 04057 if(!is_loaded) 04058 { 04059 fprintf(output, "Error: filesystem not initialized\n"); 04060 return -1; 04061 } 04062 04063 /* initialize current thread */ 04064 04065 context = GetMFSLCmdContext(); 04066 04067 if(context->is_thread_ok != TRUE) 04068 { 04069 int rc; 04070 rc = Init_Thread_MFSL(output, context, 0); 04071 if(rc != 0) 04072 return rc; 04073 } 04074 04075 /* is a file already opened ? */ 04076 if(!context->opened) 04077 { 04078 fprintf(output, "Error: this is no file currently opened.\n"); 04079 return -1; 04080 } 04081 04082 if(argc != 1) 04083 { 04084 fprintf(output, help_close); 04085 return -1; 04086 } 04087 04088 st = MFSL_close(&context->current_fd, &context->mcontext, NULL); 04089 04090 if(FSAL_IS_ERROR(st)) 04091 { 04092 fprintf(output, "Error executing FSAL_close:"); 04093 print_fsal_status(output, st); 04094 fprintf(output, "\n"); 04095 return st.major; 04096 } 04097 04098 /* note that a file is closed. */ 04099 context->opened = FALSE; 04100 04101 return 0; 04102 04103 } 04104 04109 int fn_mfsl_cat(int argc, /* IN : number of args in argv */ 04110 char **argv, /* IN : arg list */ 04111 FILE * output /* IN : output stream */ 04112 ) 04113 { 04114 04115 static char format[] = "hf"; 04116 04117 static char help_cat[] = 04118 "usage: cat [-h][-f] <path>\n" 04119 " -h: print this help\n" 04120 " -f: by default, cat doesn't print more that 1MB.\n" 04121 " this option force it to print the whole file.\n"; 04122 04123 char glob_path[FSAL_MAX_PATH_LEN]; 04124 mfsl_object_t filehdl; 04125 04126 fsal_status_t st; 04127 04128 int rc, option; 04129 int flag_h = 0; 04130 int flag_f = 0; 04131 int err_flag = 0; 04132 04133 fsal_openflags_t o_flags; 04134 mfsl_file_t cat_fd; 04135 04136 #define MAX_CAT_SIZE (1024*1024) 04137 fsal_size_t nb_read = 0; 04138 fsal_size_t buffsize = 1024; 04139 char readbuff[1024]; 04140 int is_eof = 0; 04141 04142 char *file = NULL; 04143 04144 cmdmfsl_thr_info_t *context; 04145 04146 /* is the fs initialized ? */ 04147 if(!is_loaded) 04148 { 04149 fprintf(output, "Error: filesystem not initialized\n"); 04150 return -1; 04151 } 04152 04153 /* initialize current thread */ 04154 04155 context = GetMFSLCmdContext(); 04156 04157 if(context->is_thread_ok != TRUE) 04158 { 04159 int rc; 04160 rc = Init_Thread_MFSL(output, context, 0); 04161 if(rc != 0) 04162 return rc; 04163 } 04164 04165 /* analysing options */ 04166 04167 getopt_init(); 04168 while((option = Getopt(argc, argv, format)) != -1) 04169 { 04170 switch (option) 04171 { 04172 case 'f': 04173 if(flag_f) 04174 fprintf(output, 04175 "cat: warning: option 'f' has been specified more than once.\n"); 04176 else 04177 flag_f++; 04178 break; 04179 case 'h': 04180 if(flag_h) 04181 fprintf(output, 04182 "cat: warning: option 'h' has been specified more than once.\n"); 04183 else 04184 flag_h++; 04185 break; 04186 case '?': 04187 fprintf(output, "cat: unknown option : %c\n", Optopt); 04188 err_flag++; 04189 break; 04190 } 04191 } 04192 04193 if(flag_h) 04194 { 04195 fprintf(output, help_cat); 04196 return 0; 04197 } 04198 04199 /* one arg expected */ 04200 if(Optind != (argc - 1)) 04201 err_flag++; 04202 else 04203 file = argv[Optind]; 04204 04205 if(err_flag) 04206 { 04207 fprintf(output, help_cat); 04208 return -1; 04209 } 04210 04211 /* copy current path. */ 04212 strncpy(glob_path, context->current_path, FSAL_MAX_PATH_LEN); 04213 04214 /* retrieves object handle */ 04215 if(rc = 04216 msfl_solvepath(glob_path, FSAL_MAX_PATH_LEN, 04217 file, context->current_dir, &filehdl, output)) 04218 return rc; 04219 04220 /* make open flags */ 04221 04222 o_flags = FSAL_O_RDONLY; 04223 04224 st = MFSL_open(&filehdl, &context->context, &context->mcontext, o_flags, &cat_fd, NULL, NULL); 04225 04226 if(FSAL_IS_ERROR(st)) 04227 { 04228 fprintf(output, "Error executing FSAL_open:"); 04229 print_fsal_status(output, st); 04230 fprintf(output, "\n"); 04231 return st.major; 04232 } 04233 04234 /* read operations */ 04235 04236 while(!is_eof && (flag_f || (nb_read < MAX_CAT_SIZE))) 04237 { 04238 fsal_size_t nb_read_once; 04239 04240 st = MFSL_read(&cat_fd, NULL, buffsize, (caddr_t) readbuff, 04241 &nb_read_once, &is_eof, &context->mcontext, NULL); 04242 04243 if(FSAL_IS_ERROR(st)) 04244 { 04245 fprintf(output, "Error executing FSAL_read:"); 04246 print_fsal_status(output, st); 04247 fprintf(output, "\n"); 04248 04249 /* exit only if it is not retryable */ 04250 if(fsal_is_retryable(st)) 04251 { 04252 sleep(1); 04253 continue; 04254 } 04255 else 04256 return st.major; 04257 } 04258 04259 fwrite((caddr_t) readbuff, (size_t) nb_read_once, 1, output); 04260 04261 /* update stats */ 04262 nb_read += nb_read_once; 04263 04264 } 04265 04266 MFSL_close(&cat_fd, &context->mcontext, NULL); 04267 04268 if(!is_eof) 04269 { 04270 fprintf(output, 04271 "\n----------------- File is larger than 1MB (use -f option to display all) -----------------\n"); 04272 return EPERM; 04273 } 04274 04275 return 0; 04276 04277 } 04278 04280 int fn_mfsl_handlecmp(int argc, /* IN : number of args in argv */ 04281 char **argv, /* IN : arg list */ 04282 FILE * output /* IN : output stream */ 04283 ) 04284 { 04285 static char help_handlecmp[] = "usage: handlecmp <obj1> <obj2>\n"; 04286 04287 char glob_path1[FSAL_MAX_PATH_LEN]; 04288 char glob_path2[FSAL_MAX_PATH_LEN]; 04289 char buff[2 * sizeof(fsal_handle_t) + 1]; 04290 04291 mfsl_object_t hdl1, hdl2; 04292 fsal_status_t st; 04293 int rc; 04294 04295 cmdmfsl_thr_info_t *context; 04296 04297 /* is the fs initialized ? */ 04298 if(!is_loaded) 04299 { 04300 fprintf(output, "Error: filesystem not initialized\n"); 04301 return -1; 04302 } 04303 04304 /* initialize current thread */ 04305 04306 context = GetMFSLCmdContext(); 04307 04308 if(context->is_thread_ok != TRUE) 04309 { 04310 int rc; 04311 rc = Init_Thread_MFSL(output, context, 0); 04312 if(rc != 0) 04313 return rc; 04314 } 04315 04316 /* Exactly 2 args expected */ 04317 if(argc != 3) 04318 { 04319 fprintf(output, help_handlecmp); 04320 return -1; 04321 } 04322 04323 strncpy(glob_path1, context->current_path, FSAL_MAX_PATH_LEN); 04324 strncpy(glob_path2, context->current_path, FSAL_MAX_PATH_LEN); 04325 04326 if(rc = 04327 msfl_solvepath(glob_path1, FSAL_MAX_PATH_LEN, 04328 argv[1], context->current_dir, &hdl1, output)) 04329 return rc; 04330 04331 if(rc = 04332 msfl_solvepath(glob_path2, FSAL_MAX_PATH_LEN, 04333 argv[2], context->current_dir, &hdl2, output)) 04334 return rc; 04335 04336 /* it should return : 04337 * - 0 if handle are the same 04338 * - A non null value else. 04339 */ 04340 rc = FSAL_handlecmp(&hdl1.handle, &hdl2.handle, &st); 04341 04342 if(FSAL_IS_ERROR(st)) 04343 { 04344 fprintf(output, "Error executing FSAL_handlecmp:"); 04345 print_fsal_status(output, st); 04346 fprintf(output, "\n"); 04347 return st.major; 04348 } 04349 04350 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &hdl1.handle); 04351 fprintf(output, "%s: handle = @%s\n", argv[1], buff); 04352 04353 snprintHandle(buff, 2 * sizeof(fsal_handle_t) + 1, &hdl2.handle); 04354 fprintf(output, "%s: handle = @%s\n", argv[2], buff); 04355 04356 if(rc == 0) 04357 { 04358 fprintf(output, "Handles are identical.\n"); 04359 return rc; 04360 } 04361 else 04362 { 04363 fprintf(output, "Handles are different.\n"); 04364 return rc; 04365 } 04366 04367 return 0; 04368 }