nfs-ganesha 1.4

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