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