nfs-ganesha 1.4
|
00001 /* 00002 * vim:expandtab:shiftwidth=8:tabstop=8: 00003 * 00004 * Copyright CEA/DAM/DIF (2008) 00005 00006 * contributeur : Philippe DENIEL philippe.deniel@cea.fr 00007 * Thomas LEIBOVICI thomas.leibovici@cea.fr 00008 * 00009 * 00010 * This program is free software; you can redistribute it and/or 00011 * modify it under the terms of the GNU Lesser General Public 00012 * License as published by the Free Software Foundation; either 00013 * version 3 of the License, or (at your option) any later version. 00014 * 00015 * This program is distributed in the hope that it will be useful, 00016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00018 * Lesser General Public License for more details. 00019 * 00020 * You should have received a copy of the GNU Lesser General Public 00021 * License along with this library; if not, write to the Free Software 00022 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00023 * 00024 * --------------------------------------- 00025 */ 00026 00137 #ifdef HAVE_CONFIG_H 00138 #include "config.h" 00139 #endif 00140 00141 #ifdef _SOLARIS 00142 #include "solaris_port.h" 00143 #endif 00144 00145 #include "ganesha_rpc.h" 00146 #include "fsal.h" 00147 #include "cache_inode.h" 00148 #include "commands.h" 00149 #include "abstract_mem.h" 00150 #include "Getopt.h" 00151 #include "cmd_nfstools.h" 00152 #include "cmd_tools.h" 00153 #include "nfs_file_handle.h" 00154 #include "nfs_core.h" 00155 #include <ctype.h> 00156 #include <unistd.h> 00157 #include <pwd.h> 00158 #include <string.h> 00159 #include "cmd_tools.h" 00160 00161 writeverf3 NFS3_write_verifier; 00162 00163 /* Function used for debugging */ 00164 #ifdef _DEBUG_NFS_SHELL 00165 void print_nfs_res(nfs_res_t * p_res) 00166 { 00167 int index; 00168 for(index = 0; index < sizeof(nfs_res_t); index++) 00169 { 00170 if((index + 1) % 32 == 0) 00171 printf("%02X\n", ((char *)p_res)[index]); 00172 else 00173 printf("%02X.", ((char *)p_res)[index]); 00174 } 00175 printf("\n"); 00176 } 00177 #endif 00178 00179 /* --------------- INTERNAL FH3 REPRESENTATION ---------------- */ 00180 /* used for keeping handle value after 00181 * freeing nfs res. 00182 */ 00183 typedef struct shell_fh3__ 00184 { 00185 u_int data_len; 00186 char data_val[NFS3_FHSIZE]; 00187 } shell_fh3_t; 00188 00189 static void set_shell_fh3(shell_fh3_t * p_int_fh3, nfs_fh3 * p_nfshdl) 00190 { 00191 p_int_fh3->data_len = p_nfshdl->data.data_len; 00192 memcpy(p_int_fh3->data_val, p_nfshdl->data.data_val, p_nfshdl->data.data_len); 00193 } 00194 00195 static void set_nfs_fh3(nfs_fh3 * p_nfshdl, shell_fh3_t * p_int_fh3) 00196 { 00197 p_nfshdl->data.data_len = p_int_fh3->data_len; 00198 p_nfshdl->data.data_val = p_int_fh3->data_val; 00199 } 00200 00201 /* ------------------------- END ------------------------------ */ 00202 00203 /* The cache hash table (defined in "commands_Cache_inode.c") */ 00204 extern hash_table_t *fh_to_cache_entry_ht; 00205 00206 extern cache_inode_client_parameter_t cache_client_param; 00207 extern cache_content_client_parameter_t datacache_client_param; 00208 00209 /* NFS layer initialization status*/ 00210 static int is_nfs_layer_initialized = FALSE; 00211 00212 /* Global variable: export list */ 00213 exportlist_t exportlist[128]; 00214 exportlist_t *pexportlist = exportlist; 00215 00216 /* Global variable: local host name */ 00217 static char localmachine[256]; 00218 00219 /* thread specific variables */ 00220 00221 typedef struct cmdnfs_thr_info__ 00222 { 00223 00224 int is_thread_init; 00225 00226 /* export context : on for each thread, 00227 * on order to make it possible for them 00228 * to access different filesets. 00229 */ 00230 fsal_export_context_t exp_context; 00231 00233 fsal_op_context_t context; 00234 00235 /* AuthUnix_params for this thread */ 00236 struct authunix_parms authunix_struct; 00237 00239 cache_content_client_t dc_client; 00240 00241 /* info for advanced commands (pwd, ls, cd, ...) */ 00242 int is_mounted_path; 00243 00244 shell_fh3_t mounted_path_hdl; 00245 char mounted_path[NFS2_MAXPATHLEN]; 00246 00247 shell_fh3_t current_path_hdl; 00248 char current_path[NFS2_MAXPATHLEN]; 00249 00250 } cmdnfs_thr_info_t; 00251 00252 /* pthread key to manage thread specific configuration */ 00253 00254 static pthread_key_t thread_key; 00255 static pthread_once_t once_key = PTHREAD_ONCE_INIT; 00256 00257 /* init pthtread_key for current thread */ 00258 00259 static void init_keys(void) 00260 { 00261 time_t ServerBootTime = time(NULL); 00262 00263 if(pthread_key_create(&thread_key, NULL) == -1) 00264 printf("Error %d creating pthread key for thread %p : %s\n", 00265 errno, (caddr_t) pthread_self(), strerror(errno)); 00266 00267 memset(NFS3_write_verifier, 0, sizeof(writeverf3)); 00268 memcpy(NFS3_write_verifier, &ServerBootTime, sizeof(time_t)); 00269 00270 return; 00271 } /* init_keys */ 00272 00273 cmdnfs_thr_info_t *GetNFSClient() 00274 { 00275 cmdnfs_thr_info_t *p_thr_info; 00276 00277 /* first, we init the keys if this is the first time */ 00278 if(pthread_once(&once_key, init_keys) != 0) 00279 { 00280 printf("Error %d calling pthread_once for thread %p : %s\n", 00281 errno, (caddr_t) pthread_self(), strerror(errno)); 00282 return NULL; 00283 } 00284 00285 p_thr_info = (cmdnfs_thr_info_t *) pthread_getspecific(thread_key); 00286 00287 /* we allocate the thread context if this is the first time */ 00288 if(p_thr_info == NULL) 00289 { 00290 00291 /* allocates thread structure */ 00292 p_thr_info = gsh_malloc(sizeof(cmdnfs_thr_info_t)); 00293 00294 /* panic !!! */ 00295 if(p_thr_info == NULL) 00296 { 00297 printf("%p:commands_NFS: Not enough memory\n", (caddr_t) pthread_self()); 00298 return NULL; 00299 } 00300 00301 /* Clean thread context */ 00302 00303 memset(p_thr_info, 0, sizeof(cmdnfs_thr_info_t)); 00304 00305 p_thr_info->is_thread_init = FALSE; 00306 p_thr_info->is_mounted_path = FALSE; 00307 00308 /* set the specific value */ 00309 pthread_setspecific(thread_key, (void *)p_thr_info); 00310 00311 } 00312 00313 return p_thr_info; 00314 00315 } /* GetNFSClient */ 00316 00317 int InitNFSClient(cmdnfs_thr_info_t * p_thr_info) 00318 { 00319 uid_t uid; 00320 fsal_status_t st; 00321 struct passwd *pw_struct; 00322 00323 if(p_thr_info == NULL) 00324 return -1; 00325 00326 if(p_thr_info->is_thread_init == TRUE) 00327 return 0; 00328 00329 /* for the moment, create export context for root fileset */ 00330 st = FSAL_BuildExportContext(&p_thr_info->exp_context, NULL, NULL); 00331 00332 if(FSAL_IS_ERROR(st)) 00333 { 00334 printf 00335 ("%p:commands_NFS: Error %d initializing credentials for thread (FSAL_InitThreadCred)\n", 00336 (caddr_t) pthread_self(), st.major); 00337 return st.major; 00338 } 00339 00340 /* initialize FSAL credential for this thread */ 00341 00342 st = FSAL_InitClientContext(&p_thr_info->context); 00343 00344 if(FSAL_IS_ERROR(st)) 00345 { 00346 printf 00347 ("%p:commands_NFS: Error %d initializing credentials for thread (FSAL_InitThreadCred)\n", 00348 (caddr_t) pthread_self(), st.major); 00349 return st.major; 00350 } 00351 00352 uid = getuid(); 00353 pw_struct = getpwuid(uid); 00354 00355 if(pw_struct == NULL) 00356 { 00357 printf("commands_NFS: Unknown user %u\n", uid); 00358 return errno; 00359 } 00360 00361 st = FSAL_GetClientContext(&p_thr_info->context, &p_thr_info->exp_context, 00362 uid, pw_struct->pw_gid, NULL, 0); 00363 00364 if(FSAL_IS_ERROR(st)) 00365 { 00366 printf("%p:commands_NFS: Error %d getting contexte for uid %d (FSAL_GetUserCred)\n", 00367 (caddr_t) pthread_self(), st.major, uid); 00368 return st.major; 00369 } 00370 00371 p_thr_info->authunix_struct.aup_machname = localmachine; 00372 p_thr_info->authunix_struct.aup_uid = uid; 00373 p_thr_info->authunix_struct.aup_gid = getgid(); 00374 p_thr_info->authunix_struct.aup_len = 0; 00376 /* Init the cache content client */ 00377 if(cache_content_client_init(&p_thr_info->dc_client, datacache_client_param, "") != 0) 00378 return 1; 00379 00380 p_thr_info->is_thread_init = TRUE; 00381 00382 return 0; 00383 00384 } /* InitNFSClient */ 00385 00386 void nfs_layer_SetLogLevel(int log_lvl) 00387 { 00388 00389 /* Nothing to do. */ 00390 return; 00391 00392 } 00393 00394 static void getopt_init() 00395 { 00396 /* disables getopt error message */ 00397 Opterr = 0; 00398 /* reinits getopt processing */ 00399 Optind = 1; 00400 } 00401 00402 int nfs_init(char *filename, int flag_v, FILE * output) 00403 { 00404 config_file_t config_file; 00405 int rc; 00406 00407 nfs_param.cache_layers_param.cache_content_client_param.nb_prealloc_entry = 100; 00408 nfs_param.cache_layers_param.cache_content_client_param.flush_force_fsal = 1; 00409 nfs_param.cache_layers_param.cache_content_client_param.max_fd = 20; 00410 nfs_param.cache_layers_param.cache_content_client_param.use_fd_cache = 0; 00411 nfs_param.cache_layers_param.cache_content_client_param.retention = 60; 00412 strcpy(nfs_param.cache_layers_param.cache_content_client_param.cache_dir, 00413 "/tmp/ganesha.datacache"); 00414 00415 /* Parse config file */ 00416 00417 config_file = config_ParseFile(filename); 00418 00419 if(!config_file) 00420 { 00421 fprintf(output, "nfs_init: Error parsing %s: %s\n", filename, config_GetErrorMsg()); 00422 return -1; 00423 } 00424 00425 if((rc = 00426 cache_content_read_conf_client_parameter(config_file, 00427 &nfs_param.cache_layers_param. 00428 cache_content_client_param)) != 00429 CACHE_CONTENT_SUCCESS) 00430 { 00431 fprintf(output, "nfs_init: Error %d reading cache content parameters.\n", -rc); 00432 return -1; 00433 } 00434 00435 /* Read export list from file */ 00436 00437 rc = ReadExports(config_file, &pexportlist); 00438 00439 if(rc < 0) 00440 { 00441 fprintf(output, "nfs_init: Error %d while parsing exports file.\n", -rc); 00442 return -1; 00443 } 00444 00445 /* initalize export entries */ 00446 if((rc = nfs_export_create_root_entry(pexportlist)) != TRUE) 00447 { 00448 fprintf(output, "nfs_init: Error %d initializing root entries, exiting...", -rc); 00449 return -1; 00450 } 00451 00452 /* geting the hostname */ 00453 rc = gethostname(localmachine, sizeof(localmachine)); 00454 if(rc != 0) 00455 { 00456 fprintf(output, "nfs_init: Error %d while getting hostname.\n", rc); 00457 return -1; 00458 } 00459 00462 is_nfs_layer_initialized = TRUE; 00463 00464 if(flag_v) 00465 fprintf(output, "\tNFS layer successfully initialized.\n"); 00466 00467 return 0; 00468 } 00469 00471 int fn_nfs_init(int argc, /* IN : number of args in argv */ 00472 char **argv, /* IN : arg list */ 00473 FILE * output /* IN : output stream */ 00474 ) 00475 { 00476 int flag_v = 0; 00477 int flag_h = 0; 00478 int err_flag = 0; 00479 int option; 00480 char *filename = NULL; 00481 int rc; 00482 00483 char format[] = "hv"; 00484 00485 const char help_nfs_init[] = 00486 /* "usage: nfs_init [options] <ganesha_config_file>\n"*/ 00487 "usage: nfs_init [options] <ganesha_config_file>\n" 00488 "options :\n" "\t-h print this help\n" "\t-v verbose mode\n"; 00489 00490 if(is_nfs_layer_initialized != FALSE) 00491 { 00492 fprintf(output, "\tNFS layer is already initialized.\n"); 00493 return 0; 00494 } 00495 00496 /* analysing options */ 00497 getopt_init(); 00498 while((option = Getopt(argc, argv, format)) != -1) 00499 { 00500 switch (option) 00501 { 00502 case 'v': 00503 if(flag_v) 00504 fprintf(output, 00505 "nfs_init: warning: option 'v' has been specified more than once.\n"); 00506 else 00507 flag_v++; 00508 break; 00509 00510 case 'h': 00511 if(flag_h) 00512 fprintf(output, 00513 "nfs_init: warning: option 'h' has been specified more than once.\n"); 00514 else 00515 flag_h++; 00516 break; 00517 00518 case '?': 00519 fprintf(output, "nfs_init: unknown option : %c\n", Optopt); 00520 err_flag++; 00521 break; 00522 } /* switch */ 00523 } /* while */ 00524 00525 if(flag_h) 00526 { 00527 fprintf(output, help_nfs_init); 00528 return 0; 00529 } 00530 00531 /* verifies mandatory argument */ 00532 if(Optind != (argc - 1)) 00533 { 00534 /* too much or not enough arguments */ 00535 err_flag++; 00536 } 00537 else 00538 filename = argv[Optind]; 00539 00540 if(err_flag) 00541 { 00542 fprintf(output, help_nfs_init); 00543 return -1; 00544 } 00545 00546 rc = nfs_init(filename, flag_v, output); 00547 00548 return rc; 00549 00550 } /* fn_nfs_init */ 00551 00553 int fn_MNT1_command(int argc, /* IN : number of args in argv */ 00554 char **argv, /* IN : arg list */ 00555 FILE * output /* IN : output stream */ 00556 ) 00557 { 00558 00559 cmdnfs_funcdesc_t *funcdesc = mnt1_funcdesc; 00560 00561 nfs_arg_t nfs_arg; 00562 nfs_res_t nfs_res; 00563 struct svc_req req; 00564 int rc; 00565 cmdnfs_thr_info_t *p_thr_info = NULL; 00566 00567 if(is_nfs_layer_initialized != TRUE) 00568 { 00569 fprintf(output, "\tNFS layer not initialized.\n"); 00570 return -1; 00571 } 00572 00573 p_thr_info = GetNFSClient(); 00574 00575 if(p_thr_info->is_thread_init != TRUE) 00576 { 00577 if((rc = InitNFSClient(p_thr_info))) 00578 { 00579 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 00580 return -1; 00581 } 00582 } 00583 00584 while(funcdesc->func_name != NULL) 00585 { 00586 if(!strcmp(funcdesc->func_name, argv[0])) 00587 { 00588 00589 /* encoding args */ 00590 00591 if(funcdesc->func_encode(CMDNFS_ENCODE, 00592 argc - 1, argv + 1, 00593 0, NULL, (caddr_t) & nfs_arg) == FALSE) 00594 { 00595 fprintf(output, "%s: bad arguments.\n", argv[0]); 00596 fprintf(output, "Usage: %s\n", funcdesc->func_help); 00597 return -1; 00598 } 00599 00600 /* preparing request identifier */ 00601 req.rq_prog = MOUNTPROG; 00602 req.rq_vers = MOUNT_V1; 00603 00604 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 00605 00606 /* nfs call */ 00607 00608 rc = funcdesc->func_call(&nfs_arg, 00609 pexportlist, 00610 &(p_thr_info->context), 00611 &(p_thr_info->client), &req, &nfs_res); 00612 00613 /* freeing args */ 00614 00615 funcdesc->func_encode(CMDNFS_FREE, 0, NULL, 0, NULL, (caddr_t) & nfs_arg); 00616 00617 /* decoding output */ 00618 00619 #ifdef _DEBUG_NFS_SHELL 00620 printf("MNTv1: RETURNED STRUCTURE:\n"); 00621 print_nfs_res(&nfs_res); 00622 #endif 00623 00624 funcdesc->func_decode(CMDNFS_DECODE, 0, NULL, 0, output, (caddr_t) & nfs_res); 00625 00626 funcdesc->func_free(&nfs_res); 00627 00628 /* returning status */ 00629 return rc; 00630 00631 } 00632 00633 /* pointer to the next cmdnfs_funcdesc_t */ 00634 funcdesc++; 00635 } 00636 00637 fprintf(output, "%s: command not found in MNT1 protocol.\n", argv[0]); 00638 return -1; 00639 00640 } /* fn_MNT1_command */ 00641 00643 int fn_MNT3_command(int argc, /* IN : number of args in argv */ 00644 char **argv, /* IN : arg list */ 00645 FILE * output /* IN : output stream */ 00646 ) 00647 { 00648 00649 cmdnfs_funcdesc_t *funcdesc = mnt3_funcdesc; 00650 00651 nfs_arg_t nfs_arg; 00652 nfs_res_t nfs_res; 00653 struct svc_req req; 00654 int rc; 00655 cmdnfs_thr_info_t *p_thr_info = NULL; 00656 00657 if(is_nfs_layer_initialized != TRUE) 00658 { 00659 fprintf(output, "\tNFS layer not initialized.\n"); 00660 return -1; 00661 } 00662 00663 p_thr_info = GetNFSClient(); 00664 00665 if(p_thr_info->is_thread_init != TRUE) 00666 { 00667 if((rc = InitNFSClient(p_thr_info))) 00668 { 00669 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 00670 return -1; 00671 } 00672 } 00673 00674 while(funcdesc->func_name != NULL) 00675 { 00676 if(!strcmp(funcdesc->func_name, argv[0])) 00677 { 00678 00679 /* encoding args */ 00680 00681 if(funcdesc->func_encode(CMDNFS_ENCODE, 00682 argc - 1, argv + 1, 00683 0, NULL, (caddr_t) & nfs_arg) == FALSE) 00684 { 00685 fprintf(output, "%s: bad arguments.\n", argv[0]); 00686 fprintf(output, "Usage: %s\n", funcdesc->func_help); 00687 return -1; 00688 } 00689 00690 /* preparing request identifier */ 00691 req.rq_prog = MOUNTPROG; 00692 req.rq_vers = MOUNT_V3; 00693 00694 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 00695 00696 /* nfs call */ 00697 00698 rc = funcdesc->func_call(&nfs_arg, 00699 pexportlist, 00700 &(p_thr_info->context), 00701 &(p_thr_info->client), &req, &nfs_res); 00702 00703 /* freeing args */ 00704 00705 funcdesc->func_encode(CMDNFS_FREE, 0, NULL, 0, NULL, (caddr_t) & nfs_arg); 00706 00707 /* decoding output */ 00708 #ifdef _DEBUG_NFS_SHELL 00709 printf("MNTv3: RETURNED STRUCTURE:\n"); 00710 print_nfs_res(&nfs_res); 00711 #endif 00712 00713 funcdesc->func_decode(CMDNFS_DECODE, 0, NULL, 0, output, (caddr_t) & nfs_res); 00714 00715 funcdesc->func_free(&nfs_res); 00716 00717 /* returning status */ 00718 return rc; 00719 00720 } 00721 00722 /* pointer to the next cmdnfs_funcdesc_t */ 00723 funcdesc++; 00724 } 00725 00726 fprintf(output, "%s: command not found in MNT3 protocol.\n", argv[0]); 00727 return -1; 00728 00729 } 00730 00732 int fn_NFS2_command(int argc, /* IN : number of args in argv */ 00733 char **argv, /* IN : arg list */ 00734 FILE * output /* IN : output stream */ 00735 ) 00736 { 00737 00738 cmdnfs_funcdesc_t *funcdesc = nfs2_funcdesc; 00739 00740 nfs_arg_t nfs_arg; 00741 nfs_res_t nfs_res; 00742 struct svc_req req; 00743 int rc; 00744 cmdnfs_thr_info_t *p_thr_info = NULL; 00745 00746 short exportid; 00747 exportlist_t *pexport; 00748 00749 if(is_nfs_layer_initialized != TRUE) 00750 { 00751 fprintf(output, "\tNFS layer not initialized.\n"); 00752 return -1; 00753 } 00754 00755 p_thr_info = GetNFSClient(); 00756 00757 if(p_thr_info->is_thread_init != TRUE) 00758 { 00759 if((rc = InitNFSClient(p_thr_info))) 00760 { 00761 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 00762 return -1; 00763 } 00764 } 00765 00766 while(funcdesc->func_name != NULL) 00767 { 00768 if(!strcmp(funcdesc->func_name, argv[0])) 00769 { 00770 00771 /* encoding args */ 00772 00773 if(funcdesc->func_encode(CMDNFS_ENCODE, 00774 argc - 1, argv + 1, 00775 0, NULL, (caddr_t) & nfs_arg) == FALSE) 00776 { 00777 fprintf(output, "%s: bad arguments.\n", argv[0]); 00778 fprintf(output, "Usage: %s\n", funcdesc->func_help); 00779 return -1; 00780 } 00781 00782 /* preparing request identifier */ 00783 00784 req.rq_prog = NFS_PROGRAM; 00785 req.rq_vers = NFS_V2; 00786 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 00787 00788 /* the only function that doesn't take a filehandle */ 00789 if(funcdesc->func_call != nfs_Null) 00790 { 00791 exportid = nfs2_FhandleToExportId((fhandle2 *) & nfs_arg); 00792 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 00793 { 00794 /* invalid handle */ 00795 fprintf(output, "\t%s: Bad arguments: Invalid file handle.\n", argv[0]); 00796 return -1; 00797 } 00798 } 00799 else 00800 pexport = NULL; 00801 00802 /* nfs call */ 00803 00804 rc = funcdesc->func_call(&nfs_arg, 00805 pexport, 00806 &(p_thr_info->context), 00807 &(p_thr_info->client), &req, &nfs_res); 00808 00809 /* freeing args */ 00810 00811 funcdesc->func_encode(CMDNFS_FREE, 0, NULL, 0, NULL, (caddr_t) & nfs_arg); 00812 00813 #ifdef _DEBUG_NFS_SHELL 00814 printf("NFSv2: RETURNED STRUCTURE:\n"); 00815 print_nfs_res(&nfs_res); 00816 #endif 00817 00818 /* decoding output */ 00819 00820 funcdesc->func_decode(CMDNFS_DECODE, 0, NULL, 0, output, (caddr_t) & nfs_res); 00821 00822 funcdesc->func_free(&nfs_res); 00823 00824 /* returning status */ 00825 return rc; 00826 00827 } 00828 00829 /* pointer to the next cmdnfs_funcdesc_t */ 00830 funcdesc++; 00831 } 00832 00833 fprintf(output, "%s: command not found in NFS2 protocol.\n", argv[0]); 00834 return -1; 00835 00836 } 00837 00839 int fn_NFS3_command(int argc, /* IN : number of args in argv */ 00840 char **argv, /* IN : arg list */ 00841 FILE * output /* IN : output stream */ 00842 ) 00843 { 00844 00845 cmdnfs_funcdesc_t *funcdesc = nfs3_funcdesc; 00846 00847 nfs_arg_t nfs_arg; 00848 nfs_res_t nfs_res; 00849 struct svc_req req; 00850 int rc; 00851 cmdnfs_thr_info_t *p_thr_info = NULL; 00852 00853 short exportid; 00854 exportlist_t *pexport; 00855 00856 if(is_nfs_layer_initialized != TRUE) 00857 { 00858 fprintf(output, "\tNFS layer not initialized.\n"); 00859 return -1; 00860 } 00861 00862 p_thr_info = GetNFSClient(); 00863 00864 if(p_thr_info->is_thread_init != TRUE) 00865 { 00866 if((rc = InitNFSClient(p_thr_info))) 00867 { 00868 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 00869 return -1; 00870 } 00871 } 00872 00873 while(funcdesc->func_name != NULL) 00874 { 00875 if(!strcmp(funcdesc->func_name, argv[0])) 00876 { 00877 00878 /* encoding args */ 00879 00880 if(funcdesc->func_encode(CMDNFS_ENCODE, 00881 argc - 1, argv + 1, 00882 0, NULL, (caddr_t) & nfs_arg) == FALSE) 00883 { 00884 fprintf(output, "%s: bad arguments.\n", argv[0]); 00885 fprintf(output, "Usage: %s\n", funcdesc->func_help); 00886 return -1; 00887 } 00888 00889 /* preparing request identifier */ 00890 00891 req.rq_prog = NFS_PROGRAM; 00892 req.rq_vers = NFS_V3; 00893 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 00894 00895 /* the only function that doesn't take a filehandle */ 00896 if(funcdesc->func_call != nfs_Null) 00897 { 00898 exportid = nfs3_FhandleToExportId((nfs_fh3 *) & nfs_arg); 00899 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 00900 { 00901 /* invalid handle */ 00902 fprintf(output, "\t%s: Bad arguments: Invalid file handle.\n", argv[0]); 00903 return -1; 00904 } 00905 } 00906 else 00907 pexport = NULL; 00908 00909 /* nfs call */ 00910 00911 rc = funcdesc->func_call(&nfs_arg, 00912 pexport, 00913 &(p_thr_info->context), 00914 &(p_thr_info->client), &req, &nfs_res); 00915 00916 /* freeing args */ 00917 00918 funcdesc->func_encode(CMDNFS_FREE, 0, NULL, 0, NULL, (caddr_t) & nfs_arg); 00919 00920 #ifdef _DEBUG_NFS_SHELL 00921 printf("NFSv3: RETURNED STRUCTURE:\n"); 00922 print_nfs_res(&nfs_res); 00923 #endif 00924 00925 /* decoding output */ 00926 00927 funcdesc->func_decode(CMDNFS_DECODE, 0, NULL, 0, output, (caddr_t) & nfs_res); 00928 00929 funcdesc->func_free(&nfs_res); 00930 00931 /* returning status */ 00932 return rc; 00933 00934 } 00935 00936 /* pointer to the next cmdnfs_funcdesc_t */ 00937 funcdesc++; 00938 } 00939 00940 fprintf(output, "%s: command not found in NFS3 protocol.\n", argv[0]); 00941 return -1; 00942 00943 } /* fn_NFS3_command */ 00944 00945 /*------------------------------------------------------------ 00946 * Wrapping of NFS calls (used by high level commands) 00947 *-----------------------------------------------------------*/ 00948 00949 /* solves a relative or aboslute path */ 00950 static int nfs_solvepath(cmdnfs_thr_info_t * p_thr_info, char *io_global_path, /* global path */ 00951 int size_global_path, /* max size for global path */ 00952 char *i_spec_path, /* specified path */ 00953 shell_fh3_t * p_current_hdl, /* current directory handle */ 00954 shell_fh3_t * pnew_hdl, /* pointer to solved handle */ 00955 FILE * output) 00956 { 00957 char str_path[NFS2_MAXPATHLEN]; 00958 char *pstr_path = str_path; 00959 00960 char tmp_path[NFS2_MAXPATHLEN]; 00961 char *next_name; 00962 char *curr; 00963 int last = 0; 00964 int rc; 00965 00966 shell_fh3_t hdl_lookup; 00967 nfs_fh3 hdl_param; 00968 00969 diropargs3 dirop_arg; 00970 LOOKUP3res lookup_res; 00971 struct svc_req req; 00972 short exportid; 00973 exportlist_t *pexport; 00974 00975 strncpy(str_path, i_spec_path, NFS2_MAXPATHLEN); 00976 curr = str_path; 00977 next_name = str_path; 00978 00979 if(str_path[0] == '@') 00980 { 00981 00982 rc = cmdnfs_fhandle3(CMDNFS_ENCODE, 1, &pstr_path, 0, NULL, (caddr_t) & hdl_param); 00983 00984 if(rc != TRUE) 00985 { 00986 fprintf(output, "Invalid FileHandle: %s\n", str_path); 00987 return -1; 00988 } 00989 00990 strncpy(io_global_path, str_path, size_global_path); 00991 00992 set_shell_fh3(pnew_hdl, &hdl_param); 00993 00994 cmdnfs_fhandle3(CMDNFS_FREE, 0, NULL, 0, NULL, (caddr_t) & hdl_param); 00995 00996 return 0; 00997 00998 } 00999 else if(str_path[0] == '/') 01000 { 01001 /* absolute path, starting from "/", with a relative path */ 01002 curr++; 01003 next_name++; 01004 hdl_lookup = p_thr_info->mounted_path_hdl; 01005 strncpy(tmp_path, "/", NFS2_MAXPATHLEN); 01006 01007 /* the the directory is /, return */ 01008 if(str_path[1] == '\0') 01009 { 01010 strncpy(io_global_path, tmp_path, size_global_path); 01011 *pnew_hdl = hdl_lookup; 01012 return 0; 01013 } 01014 01015 } 01016 else 01017 { 01018 hdl_lookup = *p_current_hdl; 01019 strncpy(tmp_path, io_global_path, NFS2_MAXPATHLEN); 01020 } 01021 01022 /* Now, the path is a relative path, proceed a step by step lookup */ 01023 do 01024 { 01025 /* tokenize to the next '/' */ 01026 while((curr[0] != '\0') && (curr[0] != '/')) 01027 curr++; 01028 01029 if(!curr[0]) 01030 last = 1; /* remembers if it was the last dir */ 01031 01032 curr[0] = '\0'; 01033 01034 /* build the arguments */ 01035 01036 set_nfs_fh3(&dirop_arg.dir, &hdl_lookup); 01037 dirop_arg.name = next_name; 01038 01039 /* preparing request identifier */ 01040 01041 req.rq_prog = NFS_PROGRAM; 01042 req.rq_vers = NFS_V3; 01043 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01044 01045 exportid = nfs3_FhandleToExportId(&dirop_arg.dir); 01046 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01047 { 01048 /* invalid handle */ 01049 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01050 return -1; 01051 } 01052 01053 /* lookup this name */ 01054 01055 rc = nfs_Lookup((nfs_arg_t *) & dirop_arg, 01056 pexport, 01057 &(p_thr_info->context), 01058 &(p_thr_info->client), &req, (nfs_res_t *) & lookup_res); 01059 01060 if(rc != 0) 01061 { 01062 fprintf(output, "Error %d in nfs_Lookup.\n", rc); 01063 return rc; 01064 } 01065 01066 rc = lookup_res.status; 01067 if(rc != NFS3_OK) 01068 { 01069 nfs3_Lookup_Free((nfs_res_t *) & lookup_res); 01070 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01071 return rc; 01072 } 01073 01074 /* updates current handle */ 01075 set_shell_fh3(&hdl_lookup, &lookup_res.LOOKUP3res_u.resok.object); 01076 01077 nfs3_Lookup_Free((nfs_res_t *) & lookup_res); 01078 01079 /* adds /name at the end of the path */ 01080 strncat(tmp_path, "/", FSAL_MAX_PATH_LEN); 01081 strncat(tmp_path, next_name, FSAL_MAX_PATH_LEN - strlen(tmp_path)); 01082 01083 /* updates cursors */ 01084 if(!last) 01085 { 01086 curr++; 01087 next_name = curr; 01088 /* ignore successive slashes */ 01089 while((curr[0] != '\0') && (curr[0] == '/')) 01090 { 01091 curr++; 01092 next_name = curr; 01093 } 01094 if(!curr[0]) 01095 last = 1; /* it is the last dir */ 01096 } 01097 01098 } 01099 while(!last); 01100 01101 /* everything is OK, apply changes */ 01102 clean_path(tmp_path, size_global_path); 01103 strncpy(io_global_path, tmp_path, size_global_path); 01104 01105 *pnew_hdl = hdl_lookup; 01106 return 0; 01107 01108 } /* nfs_solvepath */ 01109 01110 static int nfs_getattr(cmdnfs_thr_info_t * p_thr_info, shell_fh3_t * p_hdl, 01111 fattr3 * attrs, FILE * output) 01112 { 01113 GETATTR3res res; 01114 struct svc_req req; 01115 unsigned short exportid; 01116 exportlist_t *pexport; 01117 int rc; 01118 01119 nfs_fh3 nfshdl; 01120 01121 /* preparing request identifier */ 01122 01123 req.rq_prog = NFS_PROGRAM; 01124 req.rq_vers = NFS_V3; 01125 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01126 01127 set_nfs_fh3(&nfshdl, p_hdl); 01128 01129 exportid = nfs3_FhandleToExportId(&nfshdl); 01130 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01131 { 01132 /* invalid handle */ 01133 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01134 return -1; 01135 } 01136 01137 rc = nfs_Getattr((nfs_arg_t *) & nfshdl, 01138 pexport, 01139 &(p_thr_info->context), 01140 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01141 01142 if(rc != 0) 01143 { 01144 fprintf(output, "Error %d in nfs_Getattr.\n", rc); 01145 return rc; 01146 } 01147 01148 rc = res.status; 01149 if(rc != NFS3_OK) 01150 { 01151 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01152 01153 nfs_Getattr_Free((nfs_res_t *) & res); 01154 return rc; 01155 } 01156 01157 /* updates current handle */ 01158 *attrs = res.GETATTR3res_u.resok.obj_attributes; 01159 01160 nfs_Getattr_Free((nfs_res_t *) & res); 01161 01162 return 0; 01163 01164 } 01165 01166 static int nfs_access(cmdnfs_thr_info_t * p_thr_info, shell_fh3_t * p_hdl, nfs3_uint32 * access_mask, /* IN/OUT */ 01167 FILE * output) 01168 { 01169 ACCESS3args arg; 01170 ACCESS3res res; 01171 struct svc_req req; 01172 unsigned short exportid; 01173 exportlist_t *pexport; 01174 int rc; 01175 01176 /* preparing args */ 01177 set_nfs_fh3(&arg.object, p_hdl); 01178 arg.access = *access_mask; 01179 01180 /* preparing request identifier */ 01181 01182 req.rq_prog = NFS_PROGRAM; 01183 req.rq_vers = NFS_V3; 01184 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01185 01186 exportid = nfs3_FhandleToExportId(&arg.object); 01187 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01188 { 01189 /* invalid handle */ 01190 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01191 return -1; 01192 } 01193 01194 rc = nfs3_Access((nfs_arg_t *) & arg, 01195 pexport, 01196 &(p_thr_info->context), 01197 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01198 01199 if(rc != 0) 01200 { 01201 fprintf(output, "Error %d in nfs_Access.\n", rc); 01202 return rc; 01203 } 01204 01205 rc = res.status; 01206 if(rc != NFS3_OK) 01207 { 01208 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01209 nfs3_Access_Free((nfs_res_t *) & res); 01210 return rc; 01211 } 01212 01213 /* updates access mask */ 01214 *access_mask = res.ACCESS3res_u.resok.access; 01215 01216 nfs3_Access_Free((nfs_res_t *) & res); 01217 01218 return 0; 01219 01220 } 01221 01222 static int nfs_readlink(cmdnfs_thr_info_t * p_thr_info, shell_fh3_t * p_hdl, 01223 char *linkcontent, FILE * output) 01224 { 01225 READLINK3res res; 01226 struct svc_req req; 01227 unsigned short exportid; 01228 exportlist_t *pexport; 01229 int rc; 01230 01231 nfs_fh3 nfshdl; 01232 01233 set_nfs_fh3(&nfshdl, p_hdl); 01234 01235 /* preparing request identifier */ 01236 01237 req.rq_prog = NFS_PROGRAM; 01238 req.rq_vers = NFS_V3; 01239 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01240 01241 exportid = nfs3_FhandleToExportId(&nfshdl); 01242 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01243 { 01244 /* invalid handle */ 01245 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01246 return -1; 01247 } 01248 01249 rc = nfs_Readlink((nfs_arg_t *) & nfshdl, 01250 pexport, 01251 &(p_thr_info->context), 01252 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01253 01254 if(rc != 0) 01255 { 01256 fprintf(output, "Error %d in nfs_Readlink.\n", rc); 01257 return rc; 01258 } 01259 01260 rc = res.status; 01261 if(rc != NFS3_OK) 01262 { 01263 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01264 nfs3_Readlink_Free((nfs_res_t *) & res); 01265 return rc; 01266 } 01267 01268 /* copy link content */ 01269 strcpy(linkcontent, res.READLINK3res_u.resok.data); 01270 01271 nfs3_Readlink_Free((nfs_res_t *) & res); 01272 01273 return 0; 01274 01275 } /* nfs_readlink */ 01276 01277 static int nfs_readdirplus(cmdnfs_thr_info_t * p_thr_info, shell_fh3_t * p_dir_hdl, cookie3 cookie, cookieverf3 * p_cookieverf, /* IN/OUT */ 01278 dirlistplus3 * dirlist, 01279 nfs_res_t ** to_be_freed, FILE * output) 01280 { 01281 READDIRPLUS3args arg; 01282 READDIRPLUS3res *p_res; 01283 struct svc_req req; 01284 unsigned short exportid; 01285 exportlist_t *pexport; 01286 int rc; 01287 01288 *to_be_freed = NULL; 01289 01290 /* args */ 01291 set_nfs_fh3(&arg.dir, p_dir_hdl); 01292 arg.cookie = cookie; 01293 memcpy(&arg.cookieverf, p_cookieverf, sizeof(cookieverf3)); 01294 arg.dircount = 1024; 01295 arg.maxcount = 4096; 01296 01297 /* preparing request identifier */ 01298 01299 req.rq_prog = NFS_PROGRAM; 01300 req.rq_vers = NFS_V3; 01301 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01302 01303 exportid = nfs3_FhandleToExportId(&arg.dir); 01304 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01305 { 01306 /* invalid handle */ 01307 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01308 return -1; 01309 } 01310 01311 p_res = gsh_malloc(sizeof(READDIRPLUS3res)); 01312 01313 rc = nfs3_Readdirplus((nfs_arg_t *) & arg, 01314 pexport, 01315 &(p_thr_info->context), 01316 &(p_thr_info->client), &req, (nfs_res_t *) p_res); 01317 01318 if(rc != 0) 01319 { 01320 gsh_free(p_res); 01321 fprintf(output, "Error %d in nfs3_Readdirplus.\n", rc); 01322 return rc; 01323 } 01324 01325 rc = p_res->status; 01326 if(rc != NFS3_OK) 01327 { 01328 nfs3_Readdirplus_Free((nfs_res_t *) p_res); 01329 gsh_free(p_res); 01330 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01331 return rc; 01332 } 01333 01334 memcpy(p_cookieverf, p_res->READDIRPLUS3res_u.resok.cookieverf, sizeof(cookieverf3)); 01335 01336 *dirlist = p_res->READDIRPLUS3res_u.resok.reply; 01337 *to_be_freed = (nfs_res_t *) p_res; 01338 01339 return 0; 01340 01341 } /* nfs_readdirplus */ 01342 01343 void nfs_readdirplus_free(nfs_res_t * to_free) 01344 { 01345 if(to_free == NULL) 01346 return; 01347 01348 nfs3_Readdirplus_Free((nfs_res_t *) to_free); 01349 gsh_free(to_free); 01350 } 01351 01352 static int nfs_create(cmdnfs_thr_info_t * p_thr_info, 01353 shell_fh3_t * p_dir_hdl, char *obj_name, 01354 mode_t posix_mode, shell_fh3_t * p_obj_hdl, FILE * output) 01355 { 01356 CREATE3args arg; 01357 CREATE3res res; 01358 struct svc_req req; 01359 unsigned short exportid; 01360 exportlist_t *pexport; 01361 int rc; 01362 01363 /* preparing arguments */ 01364 01365 set_nfs_fh3(&arg.where.dir, p_dir_hdl); 01366 arg.where.name = obj_name; 01367 arg.how.mode = GUARDED; 01368 01369 /* preparing request identifier */ 01370 01371 req.rq_prog = NFS_PROGRAM; 01372 req.rq_vers = NFS_V3; 01373 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01374 01375 exportid = nfs3_FhandleToExportId(&arg.where.dir); 01376 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01377 { 01378 /* invalid handle */ 01379 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01380 return -1; 01381 } 01382 01383 /* empty sattr3 list */ 01384 if(cmdnfs_sattr3(CMDNFS_ENCODE, 0, NULL, 0, NULL, 01385 (caddr_t) & (arg.how.createhow3_u.obj_attributes)) == FALSE) 01386 { 01387 /* invalid handle */ 01388 fprintf(output, "\tError encoding nfs arguments.\n"); 01389 return -1; 01390 } 01391 01392 /* only setting mode */ 01393 arg.how.createhow3_u.obj_attributes.mode.set_it = TRUE; 01394 arg.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = posix_mode; 01395 01396 rc = nfs_Create((nfs_arg_t *) & arg, 01397 pexport, 01398 &(p_thr_info->context), 01399 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01400 01401 if(rc != 0) 01402 { 01403 fprintf(output, "Error %d in nfs_Create.\n", rc); 01404 return rc; 01405 } 01406 01407 rc = res.status; 01408 if(rc != NFS3_OK) 01409 { 01410 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01411 nfs_Create_Free((nfs_res_t *) & res); 01412 return rc; 01413 } 01414 01415 /* object handle */ 01416 if(res.CREATE3res_u.resok.obj.handle_follows) 01417 set_shell_fh3(p_obj_hdl, &res.CREATE3res_u.resok.obj.post_op_fh3_u.handle); 01418 else 01419 fprintf(output, "Warning: nfs_Create did not return file handle.\n"); 01420 01421 nfs_Create_Free((nfs_res_t *) & res); 01422 01423 return 0; 01424 01425 } 01426 01427 static int nfs_mkdir(cmdnfs_thr_info_t * p_thr_info, 01428 shell_fh3_t * p_dir_hdl, char *obj_name, 01429 mode_t posix_mode, shell_fh3_t * p_obj_hdl, FILE * output) 01430 { 01431 MKDIR3args arg; 01432 MKDIR3res res; 01433 struct svc_req req; 01434 unsigned short exportid; 01435 exportlist_t *pexport; 01436 int rc; 01437 01438 /* preparing request identifier */ 01439 01440 req.rq_prog = NFS_PROGRAM; 01441 req.rq_vers = NFS_V3; 01442 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01443 01444 /* preparing arguments */ 01445 01446 set_nfs_fh3(&arg.where.dir, p_dir_hdl); 01447 arg.where.name = obj_name; 01448 01449 exportid = nfs3_FhandleToExportId(&arg.where.dir); 01450 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01451 { 01452 /* invalid handle */ 01453 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01454 return -1; 01455 } 01456 01457 /* empty sattr3 list */ 01458 if(cmdnfs_sattr3(CMDNFS_ENCODE, 0, NULL, 0, NULL, 01459 (caddr_t) & (arg.attributes)) == FALSE) 01460 { 01461 /* invalid handle */ 01462 fprintf(output, "\tError encoding nfs arguments.\n"); 01463 return -1; 01464 } 01465 01466 /* only setting mode */ 01467 arg.attributes.mode.set_it = TRUE; 01468 arg.attributes.mode.set_mode3_u.mode = posix_mode; 01469 01470 rc = nfs_Mkdir((nfs_arg_t *) & arg, 01471 pexport, 01472 &(p_thr_info->context), 01473 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01474 01475 if(rc != 0) 01476 { 01477 fprintf(output, "Error %d in nfs_Mkdir.\n", rc); 01478 return rc; 01479 } 01480 01481 rc = res.status; 01482 if(rc != NFS3_OK) 01483 { 01484 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01485 nfs_Mkdir_Free((nfs_res_t *) & res); 01486 return rc; 01487 } 01488 01489 /* object handle */ 01490 if(res.MKDIR3res_u.resok.obj.handle_follows) 01491 set_shell_fh3(p_obj_hdl, &res.MKDIR3res_u.resok.obj.post_op_fh3_u.handle); 01492 else 01493 fprintf(output, "Warning: nfs_Mkdir did not return file handle.\n"); 01494 01495 nfs_Mkdir_Free((nfs_res_t *) & res); 01496 01497 return 0; 01498 01499 } /*nfs_mkdir */ 01500 01501 static int nfs_rmdir(cmdnfs_thr_info_t * p_thr_info, 01502 shell_fh3_t * p_dir_hdl, char *obj_name, FILE * output) 01503 { 01504 diropargs3 arg; 01505 RMDIR3res res; 01506 struct svc_req req; 01507 unsigned short exportid; 01508 exportlist_t *pexport; 01509 int rc; 01510 01511 /* preparing request identifier */ 01512 01513 req.rq_prog = NFS_PROGRAM; 01514 req.rq_vers = NFS_V3; 01515 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01516 01517 /* preparing arguments */ 01518 01519 set_nfs_fh3(&arg.dir, p_dir_hdl); 01520 arg.name = obj_name; 01521 01522 /* extract expoort id */ 01523 exportid = nfs3_FhandleToExportId(&arg.dir); 01524 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01525 { 01526 /* invalid handle */ 01527 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01528 return -1; 01529 } 01530 01531 rc = nfs_Rmdir((nfs_arg_t *) & arg, 01532 pexport, 01533 &(p_thr_info->context), 01534 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01535 01536 if(rc != 0) 01537 { 01538 fprintf(output, "Error %d in nfs_Rmdir.\n", rc); 01539 return rc; 01540 } 01541 01542 rc = res.status; 01543 if(rc != NFS3_OK) 01544 { 01545 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01546 nfs_Rmdir_Free((nfs_res_t *) & res); 01547 return rc; 01548 } 01549 01550 nfs_Rmdir_Free((nfs_res_t *) & res); 01551 return 0; 01552 01553 } /* nfs_rmdir */ 01554 01555 static int nfs_remove(cmdnfs_thr_info_t * p_thr_info, 01556 shell_fh3_t * p_dir_hdl, char *obj_name, FILE * output) 01557 { 01558 diropargs3 arg; 01559 REMOVE3res res; 01560 struct svc_req req; 01561 unsigned short exportid; 01562 exportlist_t *pexport; 01563 int rc; 01564 01565 /* preparing request identifier */ 01566 01567 req.rq_prog = NFS_PROGRAM; 01568 req.rq_vers = NFS_V3; 01569 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01570 01571 /* preparing arguments */ 01572 01573 set_nfs_fh3(&arg.dir, p_dir_hdl); 01574 arg.name = obj_name; 01575 01576 /* extract export id */ 01577 01578 exportid = nfs3_FhandleToExportId(&arg.dir); 01579 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01580 { 01581 /* invalid handle */ 01582 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01583 return -1; 01584 } 01585 01586 rc = nfs_Remove((nfs_arg_t *) & arg, 01587 pexport, 01588 &(p_thr_info->context), 01589 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01590 01591 if(rc != 0) 01592 { 01593 fprintf(output, "Error %d in nfs_Remove.\n", rc); 01594 return rc; 01595 } 01596 01597 rc = res.status; 01598 if(rc != NFS3_OK) 01599 { 01600 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01601 nfs_Remove_Free((nfs_res_t *) & res); 01602 return rc; 01603 } 01604 01605 nfs_Remove_Free((nfs_res_t *) & res); 01606 return 0; 01607 01608 } /* nfs_remove */ 01609 01610 static int nfs_setattr(cmdnfs_thr_info_t * p_thr_info, 01611 shell_fh3_t * p_obj_hdl, sattr3 * p_attributes, FILE * output) 01612 { 01613 SETATTR3args arg; 01614 SETATTR3res res; 01615 struct svc_req req; 01616 unsigned short exportid; 01617 exportlist_t *pexport; 01618 int rc; 01619 01620 /* preparing request identifier */ 01621 01622 req.rq_prog = NFS_PROGRAM; 01623 req.rq_vers = NFS_V3; 01624 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01625 01626 /* preparing arguments */ 01627 01628 set_nfs_fh3(&arg.object, p_obj_hdl); 01629 arg.new_attributes = *p_attributes; 01630 arg.guard.check = FALSE; 01631 01632 /* extract export id */ 01633 exportid = nfs3_FhandleToExportId(&arg.object); 01634 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01635 { 01636 /* invalid handle */ 01637 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01638 return -1; 01639 } 01640 01641 rc = nfs_Setattr((nfs_arg_t *) & arg, 01642 pexport, 01643 &(p_thr_info->context), 01644 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01645 01646 if(rc != 0) 01647 { 01648 fprintf(output, "Error %d in nfs_Setattr.\n", rc); 01649 return rc; 01650 } 01651 01652 rc = res.status; 01653 if(rc != NFS3_OK) 01654 { 01655 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01656 nfs_Setattr_Free((nfs_res_t *) & res); 01657 return rc; 01658 } 01659 01660 nfs_Setattr_Free((nfs_res_t *) & res); 01661 return 0; 01662 01663 } /*nfs_setattr */ 01664 01665 static int nfs_rename(cmdnfs_thr_info_t * p_thr_info, 01666 shell_fh3_t * p_src_dir_hdl, char *src_name, 01667 shell_fh3_t * p_tgt_dir_hdl, char *tgt_name, FILE * output) 01668 { 01669 RENAME3args arg; 01670 RENAME3res res; 01671 struct svc_req req; 01672 unsigned short exportid; 01673 exportlist_t *pexport; 01674 int rc; 01675 01676 /* preparing request identifier */ 01677 01678 req.rq_prog = NFS_PROGRAM; 01679 req.rq_vers = NFS_V3; 01680 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01681 01682 /* preparing arguments */ 01683 01684 set_nfs_fh3(&arg.from.dir, p_src_dir_hdl); 01685 arg.from.name = src_name; 01686 set_nfs_fh3(&arg.to.dir, p_tgt_dir_hdl); 01687 arg.to.name = tgt_name; 01688 01689 /* extract export id */ 01690 exportid = nfs3_FhandleToExportId(&arg.from.dir); 01691 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01692 { 01693 /* invalid handle */ 01694 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01695 return -1; 01696 } 01697 01698 rc = nfs_Rename((nfs_arg_t *) & arg, 01699 pexport, 01700 &(p_thr_info->context), 01701 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01702 01703 if(rc != 0) 01704 { 01705 fprintf(output, "Error %d in nfs_Rename.\n", rc); 01706 return rc; 01707 } 01708 01709 rc = res.status; 01710 if(rc != NFS3_OK) 01711 { 01712 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01713 nfs_Rename_Free((nfs_res_t *) & res); 01714 return rc; 01715 } 01716 01717 nfs_Rename_Free((nfs_res_t *) & res); 01718 return 0; 01719 01720 } /*nfs_rename */ 01721 01722 static int nfs_link(cmdnfs_thr_info_t * p_thr_info, 01723 shell_fh3_t * p_file_hdl, 01724 shell_fh3_t * p_tgt_dir_hdl, char *tgt_name, FILE * output) 01725 { 01726 LINK3args arg; 01727 LINK3res res; 01728 struct svc_req req; 01729 unsigned short exportid; 01730 exportlist_t *pexport; 01731 int rc; 01732 01733 /* preparing request identifier */ 01734 01735 req.rq_prog = NFS_PROGRAM; 01736 req.rq_vers = NFS_V3; 01737 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01738 01739 /* preparing arguments */ 01740 01741 set_nfs_fh3(&arg.file, p_file_hdl); 01742 set_nfs_fh3(&arg.link.dir, p_tgt_dir_hdl); 01743 arg.link.name = tgt_name; 01744 01745 /* extract export id */ 01746 exportid = nfs3_FhandleToExportId(&arg.file); 01747 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01748 { 01749 /* invalid handle */ 01750 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01751 return -1; 01752 } 01753 01754 rc = nfs_Link((nfs_arg_t *) & arg, 01755 pexport, 01756 &(p_thr_info->context), 01757 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01758 01759 if(rc != 0) 01760 { 01761 fprintf(output, "Error %d in nfs_Link.\n", rc); 01762 return rc; 01763 } 01764 01765 rc = res.status; 01766 if(rc != NFS3_OK) 01767 { 01768 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01769 nfs_Link_Free((nfs_res_t *) & res); 01770 return rc; 01771 } 01772 01773 nfs_Link_Free((nfs_res_t *) & res); 01774 return 0; 01775 01776 } /*nfs_link */ 01777 01778 static int nfs_symlink(cmdnfs_thr_info_t * p_thr_info, 01779 shell_fh3_t path_hdl, char *link_name, 01780 char *link_content, sattr3 * p_setattr, 01781 shell_fh3_t * p_link_hdl, FILE * output) 01782 { 01783 SYMLINK3args arg; 01784 SYMLINK3res res; 01785 struct svc_req req; 01786 unsigned short exportid; 01787 exportlist_t *pexport; 01788 int rc; 01789 01790 /* preparing request identifier */ 01791 01792 req.rq_prog = NFS_PROGRAM; 01793 req.rq_vers = NFS_V3; 01794 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01795 01796 /* preparing arguments */ 01797 01798 set_nfs_fh3(&arg.where.dir, &path_hdl); 01799 arg.where.name = link_name; 01800 arg.symlink.symlink_attributes = *p_setattr; 01801 arg.symlink.symlink_data = link_content; 01802 01803 exportid = nfs3_FhandleToExportId(&arg.where.dir); 01804 if((pexport = nfs_Get_export_by_id(pexportlist, exportid)) == NULL) 01805 { 01806 /* invalid handle */ 01807 fprintf(output, "\tBad arguments: Invalid file handle.\n"); 01808 return -1; 01809 } 01810 01811 rc = nfs_Symlink((nfs_arg_t *) & arg, 01812 pexport, 01813 &(p_thr_info->context), 01814 &(p_thr_info->client), &req, (nfs_res_t *) & res); 01815 01816 if(rc != 0) 01817 { 01818 fprintf(output, "Error %d in nfs_Symlink.\n", rc); 01819 return rc; 01820 } 01821 01822 rc = res.status; 01823 if(rc != NFS3_OK) 01824 { 01825 fprintf(output, "Error %d in NFSv3 protocol: %s\n", rc, nfsstat3_to_str(rc)); 01826 /* free nfs call resources */ 01827 nfs_Symlink_Free((nfs_res_t *) & res); 01828 return rc; 01829 } 01830 01831 /* returned handle */ 01832 if(res.SYMLINK3res_u.resok.obj.handle_follows) 01833 { 01834 set_shell_fh3(p_link_hdl, &res.SYMLINK3res_u.resok.obj.post_op_fh3_u.handle); 01835 } 01836 else 01837 { 01838 fprintf(output, "Warning: nfs_Symlink did not return file handle.\n"); 01839 } 01840 01841 /* free nfs call resources */ 01842 nfs_Symlink_Free((nfs_res_t *) & res); 01843 01844 return 0; 01845 01846 } /*nfs_symlink */ 01847 01848 /*------------------------------------------------------------ 01849 * High level, shell-like commands 01850 *-----------------------------------------------------------*/ 01851 01853 int fn_nfs_mount(int argc, /* IN : number of args in argv */ 01854 char **argv, /* IN : arg list */ 01855 FILE * output) /* IN : output stream */ 01856 { 01857 nfs_arg_t nfs_arg; 01858 nfs_res_t nfs_res; 01859 struct svc_req req; 01860 int rc; 01861 char buff[2 * NFS3_FHSIZE + 1]; 01862 mountres3 *p_mountres = (mountres3 *) & nfs_res; 01863 01864 cmdnfs_thr_info_t *p_thr_info = NULL; 01865 01866 if(is_nfs_layer_initialized != TRUE) 01867 { 01868 fprintf(output, "\tNFS layer not initialized.\n"); 01869 return -1; 01870 } 01871 01872 p_thr_info = GetNFSClient(); 01873 01874 /* We only need to init thread in mount command. */ 01875 if(p_thr_info->is_thread_init != TRUE) 01876 { 01877 if((rc = InitNFSClient(p_thr_info))) 01878 { 01879 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 01880 return -1; 01881 } 01882 } 01883 01884 /* check if a path has already been mounted */ 01885 01886 if(p_thr_info->is_mounted_path != FALSE) 01887 { 01888 fprintf(output, "%s: a path is already mounted. Use \"umount\" command first.\n", 01889 argv[0]); 01890 return -1; 01891 } 01892 01893 if(cmdnfs_dirpath(CMDNFS_ENCODE, 01894 argc - 1, argv + 1, 0, NULL, (caddr_t) & nfs_arg) == FALSE) 01895 { 01896 fprintf(output, "%s: bad arguments.\n", argv[0]); 01897 fprintf(output, "Usage: mount <path>.\n"); 01898 return -1; 01899 } 01900 01901 /* preparing request identifier */ 01902 req.rq_prog = MOUNTPROG; 01903 req.rq_vers = MOUNT_V3; 01904 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 01905 01906 /* nfs call */ 01907 01908 rc = mnt_Mnt(&nfs_arg, 01909 pexportlist, 01910 &(p_thr_info->context), &(p_thr_info->client), &req, &nfs_res); 01911 01912 /* freeing args */ 01913 01914 cmdnfs_dirpath(CMDNFS_FREE, 0, NULL, 0, NULL, (caddr_t) & nfs_arg); 01915 01916 if(rc != 0) 01917 { 01918 fprintf(output, "%s: Error %d in mnt_Mnt.\n", argv[0], rc); 01919 return rc; 01920 } 01921 01922 rc = p_mountres->fhs_status; 01923 if(rc != MNT3_OK) 01924 { 01925 mnt3_Mnt_Free(&nfs_res); 01926 fprintf(output, "%s: Error %d in MNT3 protocol.\n", argv[0], rc); 01927 return rc; 01928 } 01929 01930 set_shell_fh3(&p_thr_info->mounted_path_hdl, 01931 (nfs_fh3 *) & p_mountres->mountres3_u.mountinfo.fhandle); 01932 01933 mnt3_Mnt_Free(&nfs_res); 01934 01935 strcpy(p_thr_info->mounted_path, argv[1]); 01936 01937 p_thr_info->current_path_hdl = p_thr_info->mounted_path_hdl; 01938 strcpy(p_thr_info->current_path, "/"); 01939 01940 p_thr_info->is_mounted_path = TRUE; 01941 01942 fprintf(output, "Current directory is \"%s\" \n", p_thr_info->current_path); 01943 snprintmem(buff, 2 * NFS3_FHSIZE + 1, 01944 (caddr_t) p_thr_info->current_path_hdl.data_val, 01945 p_thr_info->current_path_hdl.data_len); 01946 fprintf(output, "Current File handle is \"@%s\" \n", buff); 01947 01948 return 0; 01949 } 01950 01952 int fn_nfs_umount(int argc, /* IN : number of args in argv */ 01953 char **argv, /* IN : arg list */ 01954 FILE * output) /* IN : output stream */ 01955 { 01956 nfs_arg_t nfs_arg; 01957 nfs_res_t nfs_res; 01958 struct svc_req req; 01959 int rc; 01960 01961 cmdnfs_thr_info_t *p_thr_info = NULL; 01962 01963 if(is_nfs_layer_initialized != TRUE) 01964 { 01965 fprintf(output, "\tNFS layer not initialized.\n"); 01966 return -1; 01967 } 01968 01969 p_thr_info = GetNFSClient(); 01970 01971 /* We only need to init thread in mount command. */ 01972 if(p_thr_info->is_thread_init != TRUE) 01973 { 01974 if((rc = InitNFSClient(p_thr_info))) 01975 { 01976 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 01977 return -1; 01978 } 01979 } 01980 01981 /* check if a path has already been mounted */ 01982 01983 if(p_thr_info->is_mounted_path != TRUE) 01984 { 01985 fprintf(output, "%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 01986 return -1; 01987 } 01988 01989 if(cmdnfs_dirpath(CMDNFS_ENCODE, 01990 argc - 1, argv + 1, 0, NULL, (caddr_t) & nfs_arg) == FALSE) 01991 { 01992 fprintf(output, "%s: bad arguments.\n", argv[0]); 01993 fprintf(output, "Usage: umount <path>.\n"); 01994 return -1; 01995 } 01996 01997 if(strncmp(argv[1], p_thr_info->mounted_path, NFS2_MAXPATHLEN)) 01998 { 01999 fprintf(output, "%s: this path is not mounted.\n", argv[0]); 02000 fprintf(output, "Current monted path : %s.\n", p_thr_info->mounted_path); 02001 return -1; 02002 } 02003 02004 /* preparing request identifier */ 02005 req.rq_prog = MOUNTPROG; 02006 req.rq_vers = MOUNT_V3; 02007 req.rq_clntcred = (caddr_t) & p_thr_info->authunix_struct; 02008 02009 /* nfs call */ 02010 02011 rc = mnt_Umnt(&nfs_arg, 02012 pexportlist, 02013 &(p_thr_info->context), &(p_thr_info->client), &req, &nfs_res); 02014 02015 /* freeing args */ 02016 02017 cmdnfs_dirpath(CMDNFS_FREE, 0, NULL, 0, NULL, (caddr_t) & nfs_arg); 02018 02019 if(rc != 0) 02020 { 02021 fprintf(output, "%s: Error %d in mnt_Umnt.\n", argv[0], rc); 02022 return rc; 02023 } 02024 02025 mnt_Umnt_Free(&nfs_res); 02026 02027 p_thr_info->is_mounted_path = FALSE; 02028 02029 return 0; 02030 } 02031 02033 int fn_nfs_pwd(int argc, /* IN : number of args in argv */ 02034 char **argv, /* IN : arg list */ 02035 FILE * output) /* IN : output stream */ 02036 { 02037 char buff[2 * NFS3_FHSIZE + 1]; 02038 cmdnfs_thr_info_t *p_thr_info = NULL; 02039 02040 if(is_nfs_layer_initialized != TRUE) 02041 { 02042 fprintf(output, "\tNFS layer not initialized.\n"); 02043 return -1; 02044 } 02045 02046 p_thr_info = GetNFSClient(); 02047 02048 /* check if a path has been mounted */ 02049 02050 if(p_thr_info->is_mounted_path != TRUE) 02051 { 02052 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 02053 return -1; 02054 } 02055 02056 fprintf(output, "Current directory is \"%s\" \n", p_thr_info->current_path); 02057 snprintmem(buff, 2 * NFS3_FHSIZE + 1, 02058 (caddr_t) p_thr_info->current_path_hdl.data_val, 02059 p_thr_info->current_path_hdl.data_len); 02060 fprintf(output, "Current File handle is \"@%s\" \n", buff); 02061 02062 return 0; 02063 } 02064 02066 int fn_nfs_ls(int argc, /* IN : number of args in argv */ 02067 char **argv, /* IN : arg list */ 02068 FILE * output) /* IN : output stream */ 02069 { 02070 #define NFS_READDIR_SIZE 10 02071 02072 char linkdata[NFS2_MAXPATHLEN]; 02073 char item_path[NFS2_MAXPATHLEN]; 02074 char *str_name = "."; 02075 shell_fh3_t handle_tmp; 02076 fattr3 attrs; 02077 cookie3 begin_cookie; 02078 bool_t eod_met; 02079 cookieverf3 cookieverf; 02080 dirlistplus3 dirlist; 02081 entryplus3 *p_entry; 02082 02083 fattr3 *p_attrs; 02084 shell_fh3_t hdl; 02085 shell_fh3_t *p_hdl = NULL; 02086 02087 nfs_res_t *to_free = NULL; 02088 02089 int rc = 0; 02090 char glob_path[NFS2_MAXPATHLEN]; 02091 02092 static char format[] = "hvdlSHz"; 02093 const char help_ls[] = "usage: ls [options] [name|path]\n" 02094 "options :\n" 02095 "\t-h print this help\n" 02096 "\t-v verbose mode\n" 02097 "\t-d print directory info instead of listing its content\n" 02098 "\t-l print standard UNIX attributes\n" 02099 "\t-S print all supported attributes\n" 02100 "\t-H print the NFS handle\n" "\t-z silent mode (print nothing)\n"; 02101 02102 int option; 02103 int flag_v = 0; 02104 int flag_h = 0; 02105 int flag_d = 0; 02106 int flag_l = 0; 02107 int flag_S = 0; 02108 int flag_H = 0; 02109 int flag_z = 0; 02110 int err_flag = 0; 02111 02112 cmdnfs_thr_info_t *p_thr_info = NULL; 02113 02114 if(is_nfs_layer_initialized != TRUE) 02115 { 02116 fprintf(output, "\tNFS layer not initialized.\n"); 02117 return -1; 02118 } 02119 02120 p_thr_info = GetNFSClient(); 02121 02122 /* check if a path has been mounted */ 02123 02124 if(p_thr_info->is_mounted_path != TRUE) 02125 { 02126 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 02127 return -1; 02128 } 02129 02130 /* analysing options */ 02131 getopt_init(); 02132 02133 while((option = Getopt(argc, argv, format)) != -1) 02134 { 02135 switch (option) 02136 { 02137 case 'v': 02138 if(flag_v) 02139 fprintf(output, 02140 "ls: warning: option 'v' has been specified more than once.\n"); 02141 else 02142 flag_v++; 02143 break; 02144 02145 case 'h': 02146 if(flag_h) 02147 fprintf(output, 02148 "ls: warning: option 'h' has been specified more than once.\n"); 02149 else 02150 flag_h++; 02151 break; 02152 02153 case 'd': 02154 if(flag_d) 02155 fprintf(output, 02156 "ls: warning: option 'd' has been specified more than once.\n"); 02157 else 02158 flag_d++; 02159 break; 02160 02161 case 'l': 02162 if(flag_l) 02163 fprintf(output, 02164 "ls: warning: option 'l' has been specified more than once.\n"); 02165 else 02166 flag_l++; 02167 break; 02168 02169 case 'S': 02170 if(flag_S) 02171 fprintf(output, 02172 "ls: warning: option 'S' has been specified more than once.\n"); 02173 else 02174 flag_S++; 02175 break; 02176 02177 case 'z': 02178 if(flag_z) 02179 fprintf(output, 02180 "ls: warning: option 'z' has been specified more than once.\n"); 02181 else 02182 flag_z++; 02183 break; 02184 02185 case 'H': 02186 if(flag_H) 02187 fprintf(output, 02188 "ls: warning: option 'H' has been specified more than once.\n"); 02189 else 02190 flag_H++; 02191 break; 02192 02193 case '?': 02194 fprintf(output, "ls: unknown option : %c\n", Optopt); 02195 err_flag++; 02196 break; 02197 } 02198 } /* while */ 02199 02200 if(flag_l + flag_S + flag_H > 1) 02201 { 02202 fprintf(output, "ls: conflict between options l,S,H\n"); 02203 err_flag++; 02204 } 02205 02206 if(flag_z + flag_v > 1) 02207 { 02208 fprintf(output, "ls: can't use -z and -v at the same time\n"); 02209 err_flag++; 02210 } 02211 02212 if(flag_h) 02213 { 02214 fprintf(output, help_ls); 02215 return 0; 02216 } 02217 02218 if(err_flag) 02219 { 02220 fprintf(output, help_ls); 02221 return -1; 02222 } 02223 02224 /* copy current global path */ 02225 strncpy(glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 02226 02227 /* first, retrieve the argument (if any) */ 02228 if(Optind == argc - 1) 02229 { 02230 str_name = argv[Optind]; 02231 02232 /* retrieving handle */ 02233 if((rc = nfs_solvepath(p_thr_info, 02234 glob_path, 02235 NFS2_MAXPATHLEN, 02236 str_name, &p_thr_info->current_path_hdl, &handle_tmp, output))) 02237 return rc; 02238 } 02239 else 02240 { 02241 str_name = "."; 02242 handle_tmp = p_thr_info->current_path_hdl; 02243 } 02244 02245 if(flag_v) 02246 fprintf(output, "proceeding ls (using NFS protocol) on \"%s\"\n", glob_path); 02247 02248 if((rc = nfs_getattr(p_thr_info, &handle_tmp, &attrs, output))) 02249 return rc; 02250 02251 /* 02252 * if the object is a file or a directoy with the -d option specified, 02253 * we only show its info and exit. 02254 */ 02255 if((attrs.type != NF3DIR) || flag_d) 02256 { 02257 if((attrs.type == NF3LNK) && flag_l) 02258 { 02259 if((rc = nfs_readlink(p_thr_info, &handle_tmp, linkdata, output))) 02260 return rc; 02261 } 02262 02263 if(flag_l) 02264 { 02265 if(!flag_z) 02266 print_nfsitem_line(output, &attrs, str_name, linkdata); 02267 } 02268 else if(flag_S) 02269 { 02270 if(!flag_z) 02271 { 02272 fprintf(output, "%s :\n", str_name); 02273 print_nfs_attributes(&attrs, output); 02274 } 02275 } 02276 else if(flag_H) 02277 { 02278 if(!flag_z) 02279 { 02280 char buff[2 * NFS3_FHSIZE + 1]; 02281 02282 snprintmem(buff, 2 * NFS3_FHSIZE + 1, (caddr_t) handle_tmp.data_val, 02283 handle_tmp.data_len); 02284 fprintf(output, "%s (@%s)\n", str_name, buff); 02285 } 02286 } 02287 else /* only prints the name */ 02288 { 02289 if(!flag_z) 02290 fprintf(output, "%s\n", str_name); 02291 } 02292 02293 return 0; 02294 } 02295 02296 /* If this point is reached, then the current element is a directory */ 02297 02298 begin_cookie = 0LL; 02299 eod_met = FALSE; 02300 memset(&cookieverf, 0, sizeof(cookieverf3)); 02301 02302 while(!eod_met) 02303 { 02304 02305 if(flag_v) 02306 fprintf(output, "-->nfs3_Readdirplus( path=%s, cookie=%llu )\n", 02307 glob_path, begin_cookie); 02308 02309 if((rc = nfs_readdirplus(p_thr_info, &handle_tmp, begin_cookie, &cookieverf, /* IN/OUT */ 02310 &dirlist, &to_free, output))) 02311 return rc; 02312 02313 p_entry = dirlist.entries; 02314 02315 while(p_entry) 02316 { 02317 if(!strcmp(str_name, ".")) 02318 strncpy(item_path, p_entry->name, NFS2_MAXPATHLEN); 02319 else if(str_name[strlen(str_name) - 1] == '/') 02320 snprintf(item_path, NFS2_MAXPATHLEN, "%s%s", str_name, p_entry->name); 02321 else 02322 snprintf(item_path, NFS2_MAXPATHLEN, "%s/%s", str_name, p_entry->name); 02323 02324 /* interpreting post-op attributes */ 02325 02326 if(p_entry->name_attributes.attributes_follow) 02327 p_attrs = &p_entry->name_attributes.post_op_attr_u.attributes; 02328 else 02329 p_attrs = NULL; 02330 02331 /* interpreting post-op handle */ 02332 02333 if(p_entry->name_handle.handle_follows) 02334 { 02335 set_shell_fh3(&hdl, &p_entry->name_handle.post_op_fh3_u.handle); 02336 p_hdl = &hdl; 02337 } 02338 else 02339 p_hdl = NULL; 02340 02341 if((p_attrs != NULL) && (p_hdl != NULL) && (p_attrs->type == NF3LNK)) 02342 { 02343 if((rc = nfs_readlink(p_thr_info, p_hdl, linkdata, output))) 02344 return rc; 02345 } 02346 02347 if((p_attrs != NULL) && flag_l) 02348 { 02349 print_nfsitem_line(output, p_attrs, item_path, linkdata); 02350 } 02351 else if((p_attrs != NULL) && flag_S) 02352 { 02353 fprintf(output, "%s :\n", item_path); 02354 if(!flag_z) 02355 print_nfs_attributes(p_attrs, output); 02356 } 02357 else if((p_hdl != NULL) && flag_H) 02358 { 02359 if(!flag_z) 02360 { 02361 char buff[2 * NFS3_FHSIZE + 1]; 02362 02363 snprintmem(buff, 2 * NFS3_FHSIZE + 1, (caddr_t) p_hdl->data_val, 02364 p_hdl->data_len); 02365 fprintf(output, "%s (@%s)\n", item_path, buff); 02366 } 02367 } 02368 else 02369 { 02370 if(!flag_z) 02371 fprintf(output, "%s\n", item_path); 02372 } 02373 02374 begin_cookie = p_entry->cookie; 02375 p_entry = p_entry->nextentry; 02376 } 02377 02378 /* Ready for next iteration */ 02379 eod_met = dirlist.eof; 02380 02381 } 02382 02383 nfs_readdirplus_free(to_free); 02384 02385 return 0; 02386 } /* fn_nfs_ls */ 02387 02389 int fn_nfs_cd(int argc, /* IN : number of args in argv */ 02390 char **argv, /* IN : arg list */ 02391 FILE * output /* IN : output stream */ 02392 ) 02393 { 02394 02395 const char help_cd[] = "usage: cd <path>\n"; 02396 02397 char glob_path[NFS2_MAXPATHLEN]; 02398 shell_fh3_t new_hdl; 02399 int rc; 02400 fattr3 attrs; 02401 nfs3_uint32 mask; 02402 02403 cmdnfs_thr_info_t *p_thr_info = NULL; 02404 02405 if(is_nfs_layer_initialized != TRUE) 02406 { 02407 fprintf(output, "\tNFS layer not initialized.\n"); 02408 return -1; 02409 } 02410 02411 p_thr_info = GetNFSClient(); 02412 02413 /* check if a path has been mounted */ 02414 02415 if(p_thr_info->is_mounted_path != TRUE) 02416 { 02417 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 02418 return -1; 02419 } 02420 02421 /* Exactly one arg expected */ 02422 if(argc != 2) 02423 { 02424 fprintf(output, help_cd); 02425 return -1; 02426 } 02427 02428 strncpy(glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 02429 02430 if((rc = 02431 nfs_solvepath(p_thr_info, glob_path, NFS2_MAXPATHLEN, 02432 argv[1], &p_thr_info->current_path_hdl, &new_hdl, output))) 02433 return rc; 02434 02435 /* verify if the object is a directory */ 02436 02437 if((rc = nfs_getattr(p_thr_info, &new_hdl, &attrs, output))) 02438 return rc; 02439 02440 if(attrs.type != NF3DIR) 02441 { 02442 fprintf(output, "Error: %s is not a directory\n", glob_path); 02443 return ENOTDIR; 02444 } 02445 02446 /* verify lookup permission */ 02447 mask = ACCESS3_LOOKUP; 02448 if((rc = nfs_access(p_thr_info, &new_hdl, &mask, output))) 02449 return rc; 02450 02451 if(!(mask & ACCESS3_LOOKUP)) 02452 { 02453 fprintf(output, "Error: %s: permission denied.\n", glob_path); 02454 return EACCES; 02455 } 02456 02457 /* if so, apply changes */ 02458 strncpy(p_thr_info->current_path, glob_path, NFS2_MAXPATHLEN); 02459 p_thr_info->current_path_hdl = new_hdl; 02460 02461 { 02462 char buff[2 * NFS3_FHSIZE + 1]; 02463 fprintf(output, "Current directory is \"%s\" \n", p_thr_info->current_path); 02464 snprintmem(buff, 2 * NFS3_FHSIZE + 1, 02465 (caddr_t) p_thr_info->current_path_hdl.data_val, 02466 p_thr_info->current_path_hdl.data_len); 02467 fprintf(output, "Current File handle is \"@%s\" \n", buff); 02468 } 02469 02470 return 0; 02471 02472 } 02473 02475 int fn_nfs_create(int argc, /* IN : number of args in argv */ 02476 char **argv, /* IN : arg list */ 02477 FILE * output /* IN : output stream */ 02478 ) 02479 { 02480 static char format[] = "hv"; 02481 02482 const char help_create[] = 02483 "usage: create [-h][-v] <path> <mode>\n" 02484 " path: path of the file to be created\n" 02485 " mode: octal mode for the directory to be created (ex: 644)\n"; 02486 02487 char glob_path[NFS2_MAXPATHLEN]; 02488 shell_fh3_t new_hdl; 02489 shell_fh3_t subdir_hdl; 02490 int rc, option; 02491 int flag_v = 0; 02492 int flag_h = 0; 02493 int err_flag = 0; 02494 int mode = 0644; 02495 02496 char tmp_path[NFS2_MAXPATHLEN]; 02497 char *path; 02498 char *file; 02499 char *strmode; 02500 02501 cmdnfs_thr_info_t *p_thr_info = NULL; 02502 02503 if(is_nfs_layer_initialized != TRUE) 02504 { 02505 fprintf(output, "\tNFS layer not initialized.\n"); 02506 return -1; 02507 } 02508 02509 p_thr_info = GetNFSClient(); 02510 02511 /* check if a path has been mounted */ 02512 02513 if(p_thr_info->is_mounted_path != TRUE) 02514 { 02515 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 02516 return -1; 02517 } 02518 02519 /* analysing options */ 02520 getopt_init(); 02521 while((option = Getopt(argc, argv, format)) != -1) 02522 { 02523 switch (option) 02524 { 02525 case 'v': 02526 if(flag_v) 02527 fprintf(output, 02528 "create: warning: option 'v' has been specified more than once.\n"); 02529 else 02530 flag_v++; 02531 break; 02532 02533 case 'h': 02534 if(flag_h) 02535 fprintf(output, 02536 "create: warning: option 'h' has been specified more than once.\n"); 02537 else 02538 flag_h++; 02539 break; 02540 02541 case '?': 02542 fprintf(output, "create: unknown option : %c\n", Optopt); 02543 err_flag++; 02544 break; 02545 } 02546 } 02547 02548 if(flag_h) 02549 { 02550 fprintf(output, help_create); 02551 return 0; 02552 } 02553 02554 /* Exactly 2 args expected */ 02555 if(Optind != (argc - 2)) 02556 { 02557 err_flag++; 02558 } 02559 else 02560 { 02561 strncpy(tmp_path, argv[Optind], NFS2_MAXPATHLEN); 02562 split_path(tmp_path, &path, &file); 02563 02564 strmode = argv[Optind + 1]; 02565 02566 /* converting mode string to posix mode */ 02567 mode = atomode(strmode); 02568 if(mode < 0) 02569 err_flag++; 02570 } 02571 02572 if(err_flag) 02573 { 02574 fprintf(output, help_create); 02575 return -1; 02576 } 02577 02578 /* copy current path. */ 02579 strncpy(glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 02580 02581 /* retrieves path handle */ 02582 if((rc = nfs_solvepath(p_thr_info, glob_path, NFS2_MAXPATHLEN, 02583 path, &p_thr_info->current_path_hdl, &subdir_hdl, output))) 02584 return rc; 02585 02586 if((rc = nfs_create(p_thr_info, &subdir_hdl, file, mode, &new_hdl, output))) 02587 return rc; 02588 02589 if(flag_v) 02590 { 02591 char buff[2 * NFS3_FHSIZE + 1]; 02592 snprintmem(buff, 2 * NFS3_FHSIZE + 1, (caddr_t) new_hdl.data_val, new_hdl.data_len); 02593 fprintf(output, "%s/%s successfully created.\n(handle=@%s)\n", glob_path, file, 02594 buff); 02595 } 02596 02597 return 0; 02598 02599 } 02600 02602 int fn_nfs_mkdir(int argc, /* IN : number of args in argv */ 02603 char **argv, /* IN : arg list */ 02604 FILE * output /* IN : output stream */ 02605 ) 02606 { 02607 static char format[] = "hv"; 02608 02609 const char help_mkdir[] = 02610 "usage: mkdir [-h][-v] <path> <mode>\n" 02611 " path: path of the directory to be created\n" 02612 " mode: octal mode for the dir to be created (ex: 755)\n"; 02613 02614 char glob_path[NFS2_MAXPATHLEN]; 02615 shell_fh3_t new_hdl; 02616 shell_fh3_t subdir_hdl; 02617 int rc, option; 02618 int flag_v = 0; 02619 int flag_h = 0; 02620 int err_flag = 0; 02621 int mode = 0755; 02622 02623 char tmp_path[NFS2_MAXPATHLEN]; 02624 char *path; 02625 char *file; 02626 char *strmode; 02627 02628 cmdnfs_thr_info_t *p_thr_info = NULL; 02629 02630 if(is_nfs_layer_initialized != TRUE) 02631 { 02632 fprintf(output, "\tNFS layer not initialized.\n"); 02633 return -1; 02634 } 02635 02636 p_thr_info = GetNFSClient(); 02637 02638 /* check if a path has been mounted */ 02639 02640 if(p_thr_info->is_mounted_path != TRUE) 02641 { 02642 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 02643 return -1; 02644 } 02645 02646 /* analysing options */ 02647 getopt_init(); 02648 while((option = Getopt(argc, argv, format)) != -1) 02649 { 02650 switch (option) 02651 { 02652 case 'v': 02653 if(flag_v) 02654 fprintf(output, 02655 "mkdir: warning: option 'v' has been specified more than once.\n"); 02656 else 02657 flag_v++; 02658 break; 02659 02660 case 'h': 02661 if(flag_h) 02662 fprintf(output, 02663 "mkdir: warning: option 'h' has been specified more than once.\n"); 02664 else 02665 flag_h++; 02666 break; 02667 02668 case '?': 02669 fprintf(output, "mkdir: unknown option : %c\n", Optopt); 02670 err_flag++; 02671 break; 02672 } 02673 } 02674 02675 if(flag_h) 02676 { 02677 fprintf(output, help_mkdir); 02678 return 0; 02679 } 02680 02681 /* Exactly 2 args expected */ 02682 if(Optind != (argc - 2)) 02683 { 02684 err_flag++; 02685 } 02686 else 02687 { 02688 strncpy(tmp_path, argv[Optind], NFS2_MAXPATHLEN); 02689 split_path(tmp_path, &path, &file); 02690 02691 strmode = argv[Optind + 1]; 02692 02693 /* converting mode string to posix mode */ 02694 mode = atomode(strmode); 02695 if(mode < 0) 02696 err_flag++; 02697 } 02698 02699 if(err_flag) 02700 { 02701 fprintf(output, help_mkdir); 02702 return -1; 02703 } 02704 02705 /* copy current path. */ 02706 strncpy(glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 02707 02708 /* retrieves path handle */ 02709 if((rc = nfs_solvepath(p_thr_info, glob_path, NFS2_MAXPATHLEN, 02710 path, &p_thr_info->current_path_hdl, &subdir_hdl, output))) 02711 return rc; 02712 02713 if((rc = nfs_mkdir(p_thr_info, &subdir_hdl, file, mode, &new_hdl, output))) 02714 return rc; 02715 02716 if(flag_v) 02717 { 02718 char buff[2 * NFS3_FHSIZE + 1]; 02719 snprintmem(buff, 2 * NFS3_FHSIZE + 1, (caddr_t) new_hdl.data_val, new_hdl.data_len); 02720 fprintf(output, "%s/%s successfully created.\n(handle=@%s)\n", glob_path, file, 02721 buff); 02722 } 02723 02724 return 0; 02725 02726 } 02727 02729 int fn_nfs_unlink(int argc, /* IN : number of args in argv */ 02730 char **argv, /* IN : arg list */ 02731 FILE * output /* IN : output stream */ 02732 ) 02733 { 02734 static char format[] = "hv"; 02735 02736 const char help_unlink[] = 02737 "usage: unlink [-h][-v] <path>\n" 02738 " path: path of the directory to be unlinkd\n"; 02739 02740 char glob_path_parent[NFS2_MAXPATHLEN]; 02741 char glob_path_object[NFS2_MAXPATHLEN]; 02742 shell_fh3_t subdir_hdl; 02743 shell_fh3_t obj_hdl; 02744 fattr3 attrs; 02745 int rc, option; 02746 int flag_v = 0; 02747 int flag_h = 0; 02748 int err_flag = 0; 02749 02750 char tmp_path[NFS2_MAXPATHLEN]; 02751 char *path; 02752 char *file; 02753 02754 cmdnfs_thr_info_t *p_thr_info = NULL; 02755 02756 if(is_nfs_layer_initialized != TRUE) 02757 { 02758 fprintf(output, "\tNFS layer not initialized.\n"); 02759 return -1; 02760 } 02761 02762 p_thr_info = GetNFSClient(); 02763 02764 /* check if a path has been mounted */ 02765 02766 if(p_thr_info->is_mounted_path != TRUE) 02767 { 02768 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 02769 return -1; 02770 } 02771 02772 /* analysing options */ 02773 getopt_init(); 02774 while((option = Getopt(argc, argv, format)) != -1) 02775 { 02776 switch (option) 02777 { 02778 case 'v': 02779 if(flag_v) 02780 fprintf(output, 02781 "unlink: warning: option 'v' has been specified more than once.\n"); 02782 else 02783 flag_v++; 02784 break; 02785 02786 case 'h': 02787 if(flag_h) 02788 fprintf(output, 02789 "unlink: warning: option 'h' has been specified more than once.\n"); 02790 else 02791 flag_h++; 02792 break; 02793 02794 case '?': 02795 fprintf(output, "unlink: unknown option : %c\n", Optopt); 02796 err_flag++; 02797 break; 02798 } 02799 } 02800 02801 if(flag_h) 02802 { 02803 fprintf(output, help_unlink); 02804 return 0; 02805 } 02806 02807 /* Exactly 1 args expected */ 02808 if(Optind != (argc - 1)) 02809 { 02810 err_flag++; 02811 } 02812 else 02813 { 02814 strncpy(tmp_path, argv[Optind], NFS2_MAXPATHLEN); 02815 split_path(tmp_path, &path, &file); 02816 } 02817 02818 /* copy current path. */ 02819 strncpy(glob_path_parent, p_thr_info->current_path, NFS2_MAXPATHLEN); 02820 02821 /* retrieves parent dir handle */ 02822 if((rc = nfs_solvepath(p_thr_info, glob_path_parent, NFS2_MAXPATHLEN, 02823 path, &p_thr_info->current_path_hdl, &subdir_hdl, output))) 02824 return rc; 02825 02826 /* copy parent path */ 02827 strncpy(glob_path_object, glob_path_parent, NFS2_MAXPATHLEN); 02828 02829 /* lookup on child object */ 02830 if((rc = nfs_solvepath(p_thr_info, glob_path_object, NFS2_MAXPATHLEN, 02831 file, &subdir_hdl, &obj_hdl, output))) 02832 return rc; 02833 02834 /* get attributes of child object */ 02835 if(flag_v) 02836 fprintf(output, "Getting attributes for %s...\n", glob_path_object); 02837 02838 if((rc = nfs_getattr(p_thr_info, &obj_hdl, &attrs, output))) 02839 return rc; 02840 02841 if(attrs.type != NF3DIR) 02842 { 02843 if(flag_v) 02844 fprintf(output, "%s is not a directory: calling nfs3_remove...\n", 02845 glob_path_object); 02846 02847 if((rc = nfs_remove(p_thr_info, &subdir_hdl, file, output))) 02848 return rc; 02849 } 02850 else 02851 { 02852 if(flag_v) 02853 fprintf(output, "%s is a directory: calling nfs3_rmdir...\n", glob_path_object); 02854 02855 if((rc = nfs_rmdir(p_thr_info, &subdir_hdl, file, output))) 02856 return rc; 02857 } 02858 02859 if(flag_v) 02860 fprintf(output, "%s successfully removed.\n", glob_path_object); 02861 02862 return 0; 02863 02864 } 02865 02867 int fn_nfs_setattr(int argc, /* IN : number of args in argv */ 02868 char **argv, /* IN : arg list */ 02869 FILE * output /* IN : output stream */ ) 02870 { 02871 02872 static char format[] = "hv"; 02873 02874 const char help_setattr[] = 02875 "usage: setattr [-h][-v] <path> <attr>=<value>,<attr>=<value>,...\n" 02876 " where <attr> can be :\n" 02877 " mode(octal value),\n" 02878 " uid, gid, (unsigned 32 bits integer)\n" 02879 " size, (unsigned 64 bits integer)\n" 02880 " atime, mtime (format: YYYYMMDDHHMMSS.nnnnnnnnn)\n"; 02881 02882 char glob_path[NFS2_MAXPATHLEN]; /* absolute path of the object */ 02883 02884 shell_fh3_t obj_hdl; /* handle of the object */ 02885 sattr3 set_attrs; /* attributes to be setted */ 02886 char *attr_string; 02887 02888 int rc, option; 02889 int flag_v = 0; 02890 int flag_h = 0; 02891 int err_flag = 0; 02892 02893 char file[NFS2_MAXPATHLEN]; /* the relative path to the object */ 02894 02895 cmdnfs_thr_info_t *p_thr_info = NULL; 02896 02897 if(is_nfs_layer_initialized != TRUE) 02898 { 02899 fprintf(output, "\tNFS layer not initialized.\n"); 02900 return -1; 02901 } 02902 02903 p_thr_info = GetNFSClient(); 02904 02905 /* check if a path has been mounted */ 02906 02907 if(p_thr_info->is_mounted_path != TRUE) 02908 { 02909 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 02910 return -1; 02911 } 02912 02913 /* analysing options */ 02914 getopt_init(); 02915 02916 while((option = Getopt(argc, argv, format)) != -1) 02917 { 02918 switch (option) 02919 { 02920 case 'v': 02921 if(flag_v) 02922 fprintf(output, 02923 "setattr: warning: option 'v' has been specified more than once.\n"); 02924 else 02925 flag_v++; 02926 break; 02927 02928 case 'h': 02929 if(flag_h) 02930 fprintf(output, 02931 "setattr: warning: option 'h' has been specified more than once.\n"); 02932 else 02933 flag_h++; 02934 break; 02935 02936 case '?': 02937 fprintf(output, "setattr: unknown option : %c\n", Optopt); 02938 err_flag++; 02939 break; 02940 } 02941 } 02942 02943 if(flag_h) 02944 { 02945 /* print usage */ 02946 fprintf(output, help_setattr); 02947 return 0; 02948 } 02949 02950 /* Exactly 2 args expected */ 02951 02952 if(Optind != (argc - 2)) 02953 { 02954 err_flag++; 02955 } 02956 else 02957 { 02958 strcpy(file, argv[Optind]); 02959 attr_string = argv[Optind + 1]; 02960 } 02961 02962 if(err_flag) 02963 { 02964 fprintf(output, help_setattr); 02965 return -1; 02966 } 02967 02968 /* copy current absolute path to a local variable. */ 02969 strncpy(glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 02970 02971 /* retrieve handle to the file whose attributes are to be changed */ 02972 if((rc = 02973 nfs_solvepath(p_thr_info, glob_path, NFS2_MAXPATHLEN, file, 02974 &p_thr_info->current_path_hdl, &obj_hdl, output))) 02975 return rc; 02976 02977 /* Convert the peer (attr_name,attr_val) to an sattr3 structure. */ 02978 if(cmdnfs_sattr3(CMDNFS_ENCODE, 02979 1, &attr_string, 0, NULL, (caddr_t) & set_attrs) == FALSE) 02980 { 02981 fprintf(output, "Invalid nfs arguments.\n"); 02982 fprintf(output, help_setattr); 02983 return -1; 02984 } 02985 02986 /* executes set attrs */ 02987 if((rc = nfs_setattr(p_thr_info, &obj_hdl, &set_attrs, output))) 02988 return rc; 02989 02990 if(flag_v) 02991 fprintf(output, "Attributes of \"%s\" successfully changed.\n", glob_path); 02992 02993 return 0; 02994 } /* fn_nfs_setattr */ 02995 02997 int fn_nfs_rename(int argc, /* IN : number of args in argv */ 02998 char **argv, /* IN : arg list */ 02999 FILE * output /* IN : output stream */ 03000 ) 03001 { 03002 03003 static char format[] = "hv"; 03004 03005 const char help_rename[] = "usage: rename [-h][-v] <src> <dest>\n"; 03006 03007 char src_glob_path[NFS2_MAXPATHLEN]; 03008 char tgt_glob_path[NFS2_MAXPATHLEN]; 03009 03010 shell_fh3_t src_path_handle, tgt_path_handle; 03011 03012 int rc, option; 03013 int flag_v = 0; 03014 int flag_h = 0; 03015 int err_flag = 0; 03016 03017 char tmp_path1[NFS2_MAXPATHLEN]; 03018 char tmp_path2[NFS2_MAXPATHLEN]; 03019 char *src_path; 03020 char *src_file; 03021 char *tgt_path; 03022 char *tgt_file; 03023 03024 cmdnfs_thr_info_t *p_thr_info = NULL; 03025 03026 if(is_nfs_layer_initialized != TRUE) 03027 { 03028 fprintf(output, "\tNFS layer not initialized.\n"); 03029 return -1; 03030 } 03031 03032 p_thr_info = GetNFSClient(); 03033 03034 /* check if a path has been mounted */ 03035 03036 if(p_thr_info->is_mounted_path != TRUE) 03037 { 03038 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 03039 return -1; 03040 } 03041 03042 /* analysing options */ 03043 getopt_init(); 03044 while((option = Getopt(argc, argv, format)) != -1) 03045 { 03046 switch (option) 03047 { 03048 case 'v': 03049 if(flag_v) 03050 fprintf(output, 03051 "rename: warning: option 'v' has been specified more than once.\n"); 03052 else 03053 flag_v++; 03054 break; 03055 case 'h': 03056 if(flag_h) 03057 fprintf(output, 03058 "rename: warning: option 'h' has been specified more than once.\n"); 03059 else 03060 flag_h++; 03061 break; 03062 case '?': 03063 fprintf(output, "rename: unknown option : %c\n", Optopt); 03064 err_flag++; 03065 break; 03066 } 03067 } 03068 03069 if(flag_h) 03070 { 03071 fprintf(output, help_rename); 03072 return 0; 03073 } 03074 03075 /* Exactly 2 args expected */ 03076 if(Optind != (argc - 2)) 03077 { 03078 err_flag++; 03079 } 03080 else 03081 { 03082 03083 strncpy(tmp_path1, argv[Optind], NFS2_MAXPATHLEN); 03084 split_path(tmp_path1, &src_path, &src_file); 03085 03086 strncpy(tmp_path2, argv[Optind + 1], NFS2_MAXPATHLEN); 03087 split_path(tmp_path2, &tgt_path, &tgt_file); 03088 03089 } 03090 03091 if(err_flag) 03092 { 03093 fprintf(output, help_rename); 03094 return -1; 03095 } 03096 03097 if(flag_v) 03098 fprintf(output, "Renaming %s (dir %s) to %s (dir %s)\n", 03099 src_file, src_path, tgt_file, tgt_path); 03100 03101 /* copy current path. */ 03102 strncpy(src_glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 03103 strncpy(tgt_glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 03104 03105 /* retrieves paths handles */ 03106 if((rc = 03107 nfs_solvepath(p_thr_info, src_glob_path, NFS2_MAXPATHLEN, 03108 src_path, &p_thr_info->current_path_hdl, &src_path_handle, output))) 03109 return rc; 03110 03111 if((rc = 03112 nfs_solvepath(p_thr_info, tgt_glob_path, NFS2_MAXPATHLEN, 03113 tgt_path, &p_thr_info->current_path_hdl, &tgt_path_handle, output))) 03114 return rc; 03115 03116 /* Rename operation */ 03117 03118 if((rc = nfs_rename(p_thr_info, &src_path_handle, /* IN */ 03119 src_file, /* IN */ 03120 &tgt_path_handle, /* IN */ 03121 tgt_file, /* IN */ 03122 output))) 03123 return rc; 03124 03125 if(flag_v) 03126 fprintf(output, "%s/%s successfully renamed to %s/%s\n", 03127 src_glob_path, src_file, tgt_glob_path, tgt_file); 03128 03129 return 0; 03130 03131 } 03132 03134 int fn_nfs_hardlink(int argc, /* IN : number of args in argv */ 03135 char **argv, /* IN : arg list */ 03136 FILE * output /* IN : output stream */ 03137 ) 03138 { 03139 03140 static char format[] = "hv"; 03141 03142 const char help_hardlink[] = 03143 "hardlink: create a hard link.\n" 03144 "usage: hardlink [-h][-v] <target> <new_path>\n" 03145 " target: path of an existing file.\n" 03146 " new_path: path of the hardlink to be created\n"; 03147 03148 char glob_path_target[NFS2_MAXPATHLEN]; 03149 char glob_path_link[NFS2_MAXPATHLEN]; 03150 03151 shell_fh3_t target_hdl, dir_hdl; 03152 03153 int rc, option; 03154 int flag_v = 0; 03155 int flag_h = 0; 03156 int err_flag = 0; 03157 03158 char *target = NULL; 03159 03160 char tmp_path[NFS2_MAXPATHLEN]; 03161 char *path; 03162 char *name; 03163 03164 cmdnfs_thr_info_t *p_thr_info = NULL; 03165 03166 if(is_nfs_layer_initialized != TRUE) 03167 { 03168 fprintf(output, "\tNFS layer not initialized.\n"); 03169 return -1; 03170 } 03171 03172 p_thr_info = GetNFSClient(); 03173 03174 /* check if a path has been mounted */ 03175 03176 if(p_thr_info->is_mounted_path != TRUE) 03177 { 03178 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 03179 return -1; 03180 } 03181 03182 /* analysing options */ 03183 getopt_init(); 03184 while((option = Getopt(argc, argv, format)) != -1) 03185 { 03186 switch (option) 03187 { 03188 case 'v': 03189 if(flag_v) 03190 fprintf(output, 03191 "hardlink: warning: option 'v' has been specified more than once.\n"); 03192 else 03193 flag_v++; 03194 break; 03195 case 'h': 03196 if(flag_h) 03197 fprintf(output, 03198 "hardlink: warning: option 'h' has been specified more than once.\n"); 03199 else 03200 flag_h++; 03201 break; 03202 case '?': 03203 fprintf(output, "hardlink: unknown option : %c\n", Optopt); 03204 err_flag++; 03205 break; 03206 } 03207 } 03208 03209 if(flag_h) 03210 { 03211 fprintf(output, help_hardlink); 03212 return 0; 03213 } 03214 03215 /* 2 args expected */ 03216 03217 if(Optind == (argc - 2)) 03218 { 03219 03220 target = argv[Optind]; 03221 03222 strncpy(tmp_path, argv[Optind + 1], NFS2_MAXPATHLEN); 03223 split_path(tmp_path, &path, &name); 03224 03225 } 03226 else 03227 { 03228 err_flag++; 03229 } 03230 03231 if(err_flag) 03232 { 03233 fprintf(output, help_hardlink); 03234 return -1; 03235 } 03236 03237 /* copy current path. */ 03238 strncpy(glob_path_target, p_thr_info->current_path, NFS2_MAXPATHLEN); 03239 strncpy(glob_path_link, p_thr_info->current_path, NFS2_MAXPATHLEN); 03240 03241 /* retrieves path handle for target */ 03242 if((rc = 03243 nfs_solvepath(p_thr_info, glob_path_target, NFS2_MAXPATHLEN, 03244 target, &p_thr_info->current_path_hdl, &target_hdl, output))) 03245 return rc; 03246 03247 /* retrieves path handle for parent dir */ 03248 if((rc = 03249 nfs_solvepath(p_thr_info, glob_path_link, NFS2_MAXPATHLEN, 03250 path, &p_thr_info->current_path_hdl, &dir_hdl, output))) 03251 return rc; 03252 03253 rc = nfs_link(p_thr_info, &target_hdl, /* IN - target file */ 03254 &dir_hdl, /* IN - parent dir handle */ 03255 name, /* IN - link name */ 03256 output); /* OUT - new attributes */ 03257 03258 if(rc) 03259 return rc; 03260 03261 if(flag_v) 03262 fprintf(output, "%s/%s <=> %s successfully created\n", path, name, glob_path_target); 03263 03264 return 0; 03265 03266 } 03267 03270 int fn_nfs_ln(int argc, /* IN : number of args in argv */ 03271 char **argv, /* IN : arg list */ 03272 FILE * output /* IN : output stream */ 03273 ) 03274 { 03275 03276 static char format[] = "hv"; 03277 03278 const char help_ln[] = 03279 "ln: create a symbolic link.\n" 03280 "usage: ln [-h][-v] <link_content> <link_path>\n" 03281 " link_content: content of the symbolic link to be created\n" 03282 " link_path: path of the symbolic link to be created\n"; 03283 03284 char glob_path[NFS2_MAXPATHLEN]; 03285 shell_fh3_t path_hdl, link_hdl; 03286 sattr3 set_attrs; 03287 int rc, option; 03288 int flag_v = 0; 03289 int flag_h = 0; 03290 int err_flag = 0; 03291 03292 char *content = NULL; 03293 char tmp_path[NFS2_MAXPATHLEN]; 03294 char *path; 03295 char *name; 03296 03297 cmdnfs_thr_info_t *p_thr_info = NULL; 03298 03299 if(is_nfs_layer_initialized != TRUE) 03300 { 03301 fprintf(output, "\tNFS layer not initialized.\n"); 03302 return -1; 03303 } 03304 03305 p_thr_info = GetNFSClient(); 03306 03307 /* check if a path has been mounted */ 03308 03309 if(p_thr_info->is_mounted_path != TRUE) 03310 { 03311 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 03312 return -1; 03313 } 03314 03315 /* analysing options */ 03316 getopt_init(); 03317 while((option = Getopt(argc, argv, format)) != -1) 03318 { 03319 switch (option) 03320 { 03321 case 'v': 03322 if(flag_v) 03323 fprintf(output, 03324 "ln: warning: option 'v' has been specified more than once.\n"); 03325 else 03326 flag_v++; 03327 break; 03328 case 'h': 03329 if(flag_h) 03330 fprintf(output, 03331 "ln: warning: option 'h' has been specified more than once.\n"); 03332 else 03333 flag_h++; 03334 break; 03335 case '?': 03336 fprintf(output, "ln: unknown option : %c\n", Optopt); 03337 err_flag++; 03338 break; 03339 } 03340 } 03341 03342 if(flag_h) 03343 { 03344 fprintf(output, help_ln); 03345 return 0; 03346 } 03347 03348 /* 2 args expected */ 03349 03350 if(Optind == (argc - 2)) 03351 { 03352 03353 content = argv[Optind]; 03354 03355 strncpy(tmp_path, argv[Optind + 1], NFS2_MAXPATHLEN); 03356 split_path(tmp_path, &path, &name); 03357 03358 } 03359 else 03360 { 03361 err_flag++; 03362 } 03363 03364 if(err_flag) 03365 { 03366 fprintf(output, help_ln); 03367 return -1; 03368 } 03369 03370 /* copy current path. */ 03371 strncpy(glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 03372 03373 /* retrieves path handle */ 03374 if((rc = 03375 nfs_solvepath(p_thr_info, glob_path, NFS2_MAXPATHLEN, 03376 path, &p_thr_info->current_path_hdl, &path_hdl, output))) 03377 return rc; 03378 03379 /* Prepare link attributes : empty sattr3 list */ 03380 03381 if(cmdnfs_sattr3(CMDNFS_ENCODE, 0, NULL, 0, NULL, (caddr_t) & set_attrs) == FALSE) 03382 { 03383 /* invalid handle */ 03384 fprintf(output, "\tError encoding nfs arguments.\n"); 03385 return -1; 03386 } 03387 03388 rc = nfs_symlink(p_thr_info, path_hdl, /* IN - parent dir handle */ 03389 name, /* IN - link name */ 03390 content, /* IN - link content */ 03391 &set_attrs, /* Link attributes */ 03392 &link_hdl, /* OUT - link handle */ 03393 output); 03394 03395 if(rc) 03396 return rc; 03397 03398 if(flag_v) 03399 { 03400 char buff[2 * NFS3_FHSIZE + 1]; 03401 snprintmem(buff, 2 * NFS3_FHSIZE + 1, (caddr_t) link_hdl.data_val, 03402 link_hdl.data_len); 03403 03404 fprintf(output, "%s/%s -> %s successfully created (@%s) \n", path, name, content, 03405 buff); 03406 } 03407 03408 return 0; 03409 } 03410 03412 int fn_nfs_stat(int argc, /* IN : number of args in argv */ 03413 char **argv, /* IN : arg list */ 03414 FILE * output) /* IN : output stream */ 03415 { 03416 03417 shell_fh3_t handle_tmp; 03418 fattr3 attrs; 03419 03420 int rc = 0; 03421 char glob_path[NFS2_MAXPATHLEN]; 03422 03423 static char format[] = "hvHz"; 03424 const char help_stat[] = "usage: stat [options] <path>\n" 03425 "options :\n" 03426 "\t-h print this help\n" 03427 "\t-v verbose mode\n" 03428 "\t-H print the NFS handle\n" "\t-z silent mode (print nothing)\n"; 03429 03430 int option; 03431 char *str_name = NULL; 03432 int flag_v = 0; 03433 int flag_h = 0; 03434 int flag_H = 0; 03435 int flag_z = 0; 03436 int err_flag = 0; 03437 03438 cmdnfs_thr_info_t *p_thr_info = NULL; 03439 03440 if(is_nfs_layer_initialized != TRUE) 03441 { 03442 fprintf(output, "\tNFS layer not initialized.\n"); 03443 return -1; 03444 } 03445 03446 p_thr_info = GetNFSClient(); 03447 03448 /* check if a path has been mounted */ 03449 03450 if(p_thr_info->is_mounted_path != TRUE) 03451 { 03452 fprintf(output, "\t%s: no mounted path. Use \"mount\" command first.\n", argv[0]); 03453 return -1; 03454 } 03455 03456 /* analysing options */ 03457 getopt_init(); 03458 03459 while((option = Getopt(argc, argv, format)) != -1) 03460 { 03461 switch (option) 03462 { 03463 case 'v': 03464 if(flag_v) 03465 fprintf(output, 03466 "stat: warning: option 'v' has been specified more than once.\n"); 03467 else 03468 flag_v++; 03469 break; 03470 03471 case 'h': 03472 if(flag_h) 03473 fprintf(output, 03474 "stat: warning: option 'h' has been specified more than once.\n"); 03475 else 03476 flag_h++; 03477 break; 03478 03479 case 'z': 03480 if(flag_z) 03481 fprintf(output, 03482 "stat: warning: option 'z' has been specified more than once.\n"); 03483 else 03484 flag_z++; 03485 break; 03486 03487 case 'H': 03488 if(flag_H) 03489 fprintf(output, 03490 "stat: warning: option 'H' has been specified more than once.\n"); 03491 else 03492 flag_H++; 03493 break; 03494 03495 case '?': 03496 fprintf(output, "stat: unknown option : %c\n", Optopt); 03497 err_flag++; 03498 break; 03499 } 03500 } /* while */ 03501 03502 if(flag_z + flag_v > 1) 03503 { 03504 fprintf(output, "stat: can't use -z and -v at the same time\n"); 03505 err_flag++; 03506 } 03507 03508 if(flag_h) 03509 { 03510 fprintf(output, help_stat); 03511 return 0; 03512 } 03513 03514 if(Optind != argc - 1) 03515 { 03516 fprintf(output, "stat: Missing argument: <path>\n"); 03517 err_flag++; 03518 } 03519 else 03520 { 03521 str_name = argv[Optind]; 03522 } 03523 03524 if(err_flag) 03525 { 03526 fprintf(output, help_stat); 03527 return -1; 03528 } 03529 03530 /* copy current global path */ 03531 strncpy(glob_path, p_thr_info->current_path, NFS2_MAXPATHLEN); 03532 03533 /* retrieving handle */ 03534 if((rc = nfs_solvepath(p_thr_info, 03535 glob_path, 03536 NFS2_MAXPATHLEN, 03537 str_name, &p_thr_info->current_path_hdl, &handle_tmp, output))) 03538 return rc; 03539 03540 if(flag_v) 03541 fprintf(output, "proceeding stat (using NFS protocol) on \"%s\"\n", glob_path); 03542 03543 if((rc = nfs_getattr(p_thr_info, &handle_tmp, &attrs, output))) 03544 return rc; 03545 03546 if(flag_H) 03547 { 03548 if(!flag_z) 03549 { 03550 char buff[2 * NFS3_FHSIZE + 1]; 03551 03552 snprintmem(buff, 2 * NFS3_FHSIZE + 1, (caddr_t) handle_tmp.data_val, 03553 handle_tmp.data_len); 03554 fprintf(output, "%s (@%s)\n", str_name, buff); 03555 } 03556 } 03557 else if(!flag_z) 03558 { 03559 /*fprintf(output,"%s :\n",str_name); */ 03560 print_nfs_attributes(&attrs, output); 03561 } 03562 03563 return 0; 03564 } /* fn_nfs_stat */ 03565 03567 int fn_nfs_su(int argc, /* IN : number of args in argv */ 03568 char **argv, /* IN : arg list */ 03569 FILE * output) /* IN : output stream */ 03570 { 03571 int rc, i; 03572 char *str_uid; 03573 uid_t uid; 03574 fsal_status_t st; 03575 struct passwd *pw_struct; 03576 03577 #define MAX_GRPS 128 03578 gid_t groups_tab[MAX_GRPS]; 03579 int nb_grp; 03580 03581 const char help_su[] = "usage: su <uid>\n"; 03582 03583 cmdnfs_thr_info_t *p_thr_info = NULL; 03584 03585 if(is_nfs_layer_initialized != TRUE) 03586 { 03587 fprintf(output, "\tNFS layer not initialized.\n"); 03588 return -1; 03589 } 03590 03591 /* UID arg expected */ 03592 if(argc != 2) 03593 { 03594 fprintf(output, help_su); 03595 return -1; 03596 } 03597 else 03598 { 03599 str_uid = argv[1]; 03600 } 03601 03602 p_thr_info = GetNFSClient(); 03603 03604 if(p_thr_info->is_thread_init != TRUE) 03605 { 03606 if((rc = InitNFSClient(p_thr_info))) 03607 { 03608 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 03609 return -1; 03610 } 03611 } 03612 03613 if(isdigit(str_uid[0])) 03614 { 03615 if((uid = my_atoi(str_uid)) == (uid_t) - 1) 03616 { 03617 fprintf(output, "Error: invalid uid \"%s\"\n", str_uid); 03618 return -1; 03619 } 03620 pw_struct = getpwuid(uid); 03621 } 03622 else 03623 { 03624 pw_struct = getpwnam(str_uid); 03625 } 03626 03627 if(pw_struct == NULL) 03628 { 03629 fprintf(output, "Unknown user %s\n", str_uid); 03630 return errno; 03631 } 03632 03633 nb_grp = getugroups(MAX_GRPS, groups_tab, pw_struct->pw_name, pw_struct->pw_gid); 03634 03635 fprintf(output, "Changing user to : %s ( uid = %d, gid = %d )\n", 03636 pw_struct->pw_name, pw_struct->pw_uid, pw_struct->pw_gid); 03637 03638 if(nb_grp > 1) 03639 { 03640 fprintf(output, "altgroups = "); 03641 for(i = 1; i < nb_grp; i++) 03642 { 03643 if(i == 1) 03644 fprintf(output, "%d", groups_tab[i]); 03645 else 03646 fprintf(output, ", %d", groups_tab[i]); 03647 } 03648 fprintf(output, "\n"); 03649 } 03650 03651 st = FSAL_GetClientContext(&p_thr_info->context, &p_thr_info->exp_context, 03652 pw_struct->pw_uid, pw_struct->pw_gid, groups_tab, nb_grp); 03653 03654 if(FSAL_IS_ERROR(st)) 03655 { 03656 fprintf(output, "Error executing FSAL_GetUserCred:"); 03657 print_fsal_status(output, st); 03658 fprintf(output, "\n"); 03659 return st.major; 03660 } 03661 03662 fprintf(output, "Done.\n"); 03663 03664 return 0; 03665 03666 } 03667 03668 int fn_nfs_id(int argc, /* IN : number of args in argv */ 03669 char **argv, /* IN : arg list */ 03670 FILE * output) /* IN : output stream */ 03671 { 03672 int rc; 03673 cmdnfs_thr_info_t *p_thr_info = NULL; 03674 03675 if(is_nfs_layer_initialized != TRUE) 03676 { 03677 fprintf(output, "\tNFS layer not initialized.\n"); 03678 return -1; 03679 } 03680 03681 p_thr_info = GetNFSClient(); 03682 03683 if(p_thr_info->is_thread_init != TRUE) 03684 { 03685 if((rc = InitNFSClient(p_thr_info))) 03686 { 03687 fprintf(output, "\t%s: Error %d during thread initialization.\n", argv[0], rc); 03688 return -1; 03689 } 03690 } 03691 #ifdef _USE_POSIX 03692 { 03693 posixfsal_op_context_t * p_cred 03694 = (posixfsal_op_context_t *)&p_thr_info->context; 03695 fprintf(output, "Current user : uid = %d, gid = %d\n", 03696 p_cred->credential.user, p_cred->credential.group); 03697 } 03698 #endif 03699 03700 return 0; 03701 }