nfs-ganesha 1.4

commands_NFS_remote.c

Go to the documentation of this file.
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, &current_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], &current_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, &current_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, &current_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, &current_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                           &current_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, &current_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, &current_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, &current_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, &current_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, &current_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, &current_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 }