/Home/aooliver/work/stagersvc/org.glite.data.lcg_gfal/src/lfc_ifce.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004 by CERN
00003  */
00004 
00005 /*
00006  * @(#)$RCSfile: lfc_ifce.c,v $ $Revision: 1.1.1.1 $ $Date: 2006/09/06 08:54:53 $ CERN James Casey
00007  */
00008 #include <sys/types.h>
00009 #include <dlfcn.h>
00010 #include <errno.h>
00011 #include <stdio.h>
00012 #include <string.h>
00013 #include <stdlib.h>
00014 #include <unistd.h>
00015 #include <uuid/uuid.h>
00016 
00017 #include "lfc_api.h"
00018 #include "gfal_api.h"
00019 #include "serrno.h"
00020 
00021 #define ALLOC_BLOCK_SIZE 16 /* the block size to allocate new pointers in */
00022 
00023 struct fc_ops {
00024         int     *serrno;
00025         char    *(*sstrerror)(int);
00026         int     (*addreplica)(const char *, struct lfc_fileid *, const char *, const char *, const char, const char, const char *, const char *);
00027         int     (*creatg)(const char *, const char *, mode_t);
00028         int     (*delreplica)(const char *, struct lfc_fileid *, const char *);
00029         int     (*endtrans)();
00030         int     (*getpath)(char *, u_signed64, char *);
00031         struct lfc_linkinfo *(*listlinks)(const char *, const char *, int, lfc_list *);
00032         struct lfc_filereplica *(*listreplica)(const char *, const char *, int, lfc_list *);
00033         int     (*lstat)(const char *, struct lfc_filestat *);
00034         int     (*mkdirg)(const char *, const char *, mode_t);
00035         int     (*seterrbuf)(char *, int);
00036         int     (*setfsizeg)(const char *, u_signed64, const char *, char *);
00037         int     (*starttrans)(const char *, const char *);
00038         int     (*statg)(const char *, const char *, struct lfc_filestatg *);
00039         int     (*statr)(const char *, struct lfc_filestatg *);
00040         int     (*symlink)(const char *, const char *);
00041         int     (*unlink)(const char *);
00042 };
00043 
00044 struct fc_ops fcops;
00045 char *lfc_host = NULL;
00046 
00047 static char lfc_env[64];
00048 static char lfc_penv[64];
00049 static char *gfal_version = VERSION;
00050 
00051 /** extract a hostname from a SURL.  We search for "://" to get the start of
00052     the hostname.  Then we keep going to the next slash, colon or end of the
00053     SURL. */
00054 char *
00055 get_hostname(const char *path, char *errbuf, int errbufsz) {
00056   char *start;
00057   char *cp;
00058   char *result;
00059   char c;
00060   char sav_path[CA_MAXSFNLEN+1];
00061 
00062   strcpy(sav_path, path);
00063 
00064   start = strchr(sav_path, ':');
00065   if ( start == NULL || *(start+1) != '/' || *(start+2) != '/') {
00066     gfal_errmsg(errbuf, errbufsz, "Path too long");
00067     errno = ENAMETOOLONG;
00068     return (NULL);
00069   }
00070   /* point start to beginning of hostname */
00071   start += 3;
00072   for(cp = start; *cp != '\0' && *cp != ':' && *cp != '/'; cp++)
00073     ;
00074   c = *cp;
00075   *cp = '\0';
00076   if((result = strdup(start)) == NULL) {
00077     return (NULL);
00078   }
00079   *cp = c;
00080   return result;
00081 }
00082 
00083 static int 
00084 lfc_init (char *errbuf, int errbufsz) {
00085   char *lfc_endpoint = NULL;
00086   char *p;
00087   char *lfc_port = NULL;
00088 
00089   if (lfc_host == NULL) {
00090     /* Try first from env */
00091     if((lfc_host = getenv("LFC_HOST")) != NULL) {
00092       lfc_port = getenv("LFC_PORT");
00093     } else { /* get endpoint from MDS */
00094       if(get_lfc_endpoint (&lfc_endpoint, errbuf, errbufsz) < 0) {
00095         return (-1);
00096       }
00097       if ((lfc_port = strchr (lfc_endpoint, ':')) != NULL) {
00098         *lfc_port = '\0';
00099         lfc_port++;
00100       }
00101 
00102       if (strncmp(lfc_endpoint, "lfc://", 6) == 0) {
00103         if((lfc_host = strdup(lfc_endpoint + 6)) == NULL) {
00104           free(lfc_endpoint);
00105           return (-1);
00106         }
00107       } else { /* just a plain hostname */
00108         lfc_host = lfc_endpoint;
00109       }
00110     }
00111     if(strlen(lfc_host) == 0) {
00112       gfal_errmsg(errbuf, errbufsz, "LFC host is set to empty string");
00113       errno = EINVAL;
00114       return (-1);
00115     }
00116 
00117     if( 10 + strlen(lfc_host) > 64) {
00118       gfal_errmsg(errbuf, errbufsz, "Host too long") ;
00119       errno = ENAMETOOLONG;
00120       return (-1);
00121     }
00122     sprintf(lfc_env, "LFC_HOST=%s", lfc_host);
00123     if(putenv(lfc_env) < 0) {
00124       return (-1);
00125     }
00126 
00127     if(lfc_port && *lfc_port != '\0') {
00128       if( 10 + strlen(lfc_port) > 64) {
00129         gfal_errmsg(errbuf, errbufsz, "Port too long") ;
00130         errno = ENAMETOOLONG;
00131         return (-1);
00132       }
00133       sprintf(lfc_penv, "LFC_PORT=%s", lfc_port);
00134       if(putenv(lfc_penv) < 0) {
00135         return (-1);
00136       }
00137     }
00138     {
00139       void *dlhandle;
00140       
00141       if ((dlhandle = dlopen ("liblfc.so", RTLD_LAZY)) == NULL)
00142         return (-1);
00143       fcops.serrno = (int *) dlsym (dlhandle, "serrno");
00144       fcops.sstrerror = (char * (*) (int)) dlsym (dlhandle, "sstrerror");
00145       fcops.addreplica = (int (*) (const char *, struct lfc_fileid *, const char *, const char *, const char, const char, const char *, const char *)) dlsym (dlhandle, "lfc_addreplica");
00146       fcops.creatg = (int (*) (const char *, const char *, mode_t)) dlsym (dlhandle, "lfc_creatg");
00147       fcops.delreplica = (int (*) (const char *, struct lfc_fileid *, const char *)) dlsym (dlhandle, "lfc_delreplica");
00148       fcops.endtrans = (int (*) ()) dlsym (dlhandle, "lfc_endtrans");
00149       fcops.getpath = (int (*) (char *, u_signed64, char *)) dlsym (dlhandle, "lfc_getpath");
00150       fcops.listlinks = (struct lfc_linkinfo * (*) (const char *, const char *, int, lfc_list *)) dlsym (dlhandle, "lfc_listlinks");
00151       fcops.listreplica = (struct lfc_filereplica * (*) (const char *, const char *, int, lfc_list *)) dlsym (dlhandle, "lfc_listreplica");
00152       fcops.lstat = (int (*) (const char *, struct lfc_filestat *)) dlsym (dlhandle, "lfc_lstat");
00153       fcops.mkdirg = (int (*) (const char *, const char *, mode_t)) dlsym (dlhandle, "lfc_mkdirg");
00154       fcops.seterrbuf = (int (*) (char *, int)) dlsym (dlhandle, "lfc_seterrbuf");
00155       fcops.setfsizeg = (int (*) (const char *, u_signed64, const char *, char *)) dlsym (dlhandle, "lfc_setfsizeg");
00156       fcops.starttrans = (int (*) (const char*, const char*)) dlsym (dlhandle, "lfc_starttrans");
00157       fcops.statg = (int (*) (const char *, const char *, struct lfc_filestatg *)) dlsym (dlhandle, "lfc_statg");
00158       fcops.statr = (int (*) (const char *, struct lfc_filestatg *)) dlsym (dlhandle, "lfc_statr");
00159       fcops.symlink = (int (*) (const char *, const char *)) dlsym (dlhandle, "lfc_symlink");
00160       fcops.unlink = (int (*) (const char *)) dlsym (dlhandle, "lfc_unlink");
00161     }
00162   }
00163   fcops.seterrbuf(errbuf, errbufsz);
00164   return (0);
00165 }
00166 
00167 char *
00168 lfc_get_catalog_endpoint(char *errbuf, int errbufsz) {
00169         if(lfc_init(errbuf, errbufsz) < 0)
00170                 return (NULL);
00171         return lfc_host;
00172 }
00173 
00174 int
00175 lfc_replica_exists(const char *guid, char *errbuf, int errbufsz) {
00176   lfc_list list;
00177   struct lfc_filereplica* rp;
00178 
00179   if(lfc_init(errbuf, errbufsz) < 0)
00180     return (-1);
00181   if((rp = fcops.listreplica(NULL, guid, CNS_LIST_BEGIN, &list)) == NULL) {
00182     (void) fcops.listreplica(NULL, guid, CNS_LIST_END, &list);
00183     return (0);
00184   } else { 
00185     (void) fcops.listreplica(NULL, guid, CNS_LIST_END, &list);
00186     return (1);
00187   }
00188 }
00189 
00190 int
00191 lfc_getfilesizeg(const char *guid, GFAL_LONG64 *sizep, char *errbuf, int errbufsz)
00192 {
00193   struct lfc_filestatg statg;
00194 
00195   if(lfc_init(errbuf, errbufsz) < 0)
00196     return (-1);
00197 
00198   if(fcops.statg(NULL, guid, &statg) < 0) {
00199     if (*fcops.serrno < 1000) 
00200       errno = *fcops.serrno;
00201     else {
00202       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00203       errno = ECOMM;
00204     }
00205     return (-1);
00206   }
00207   
00208   *sizep = (u_signed64) statg.filesize;
00209   return (0);
00210 }
00211 
00212 /** lfc_guidforpfn : Get the guid for a replica.  If the replica does not
00213     exist, fail with ENOENT */
00214 char *
00215 lfc_guidforpfn (const char *pfn, char *errbuf, int errbufsz)
00216 {
00217   char *p;
00218   struct lfc_filestatg statg;
00219 
00220   if(lfc_init(errbuf, errbufsz) < 0)
00221     return (NULL);
00222 
00223   if(fcops.statr(pfn, &statg) < 0) {
00224     if(*fcops.serrno < 1000)
00225       errno = *fcops.serrno;
00226     else {
00227       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00228       errno = ECOMM;
00229     }
00230     return (NULL);
00231   }
00232   if((p = strdup(statg.guid)) == NULL) {
00233     return (NULL);
00234   }
00235   return (p);
00236 }
00237 
00238 int
00239 lfc_guid_exists (const char *guid, char *errbuf, int errbufsz)
00240 {
00241   struct lfc_filestatg statg;
00242 
00243   if(lfc_init(errbuf, errbufsz) < 0)
00244     return (-1);
00245 
00246   if(fcops.statg(NULL, guid, &statg) < 0) {
00247     if(*fcops.serrno == ENOENT) 
00248         return (0);
00249     if (*fcops.serrno < 1000) 
00250       errno = *fcops.serrno;
00251     else {
00252       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00253       errno = ECOMM;
00254     }
00255     return (-1);
00256   }
00257   return (1);
00258 }
00259 
00260 int
00261 lfc_register_pfn (const char *guid, const char *pfn, char *errbuf, int errbufsz)
00262 {
00263   char *hostname;
00264 
00265   if(lfc_init(errbuf, errbufsz) < 0)
00266     return (-1);
00267   
00268   if((hostname = get_hostname(pfn, errbuf, errbufsz)) == NULL) {
00269     return (-1);
00270   }
00271   /* We always have available permanent files at the minute */
00272   if(fcops.addreplica(guid, NULL, hostname, pfn, '-', '\0', NULL, NULL) < 0) {
00273     if (*fcops.serrno < 1000)
00274       errno = *fcops.serrno;
00275     else {
00276       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00277       errno = ECOMM;
00278     }
00279     free(hostname);
00280     return (-1);
00281   }
00282   free(hostname);
00283   return (0);
00284 }
00285 
00286 char **
00287 lfc_surlsfromguid (const char *guid, char *errbuf, int errbufsz)
00288 {
00289   lfc_list list;
00290  struct lfc_filereplica* rp;
00291   int flags;
00292   char **p, **pp;
00293   size_t size = ALLOC_BLOCK_SIZE;
00294   size_t i = 0;
00295   
00296   if(lfc_init(errbuf, errbufsz) < 0)
00297     return (NULL);
00298 
00299   /* allocate some memory for the pointers */
00300   if((p = (char**)calloc(size, sizeof(char*))) == NULL) {
00301     return (NULL);
00302   }
00303 
00304   flags = CNS_LIST_BEGIN;
00305   while((rp = fcops.listreplica(NULL, guid, flags, &list)) != NULL) {
00306     if(flags == CNS_LIST_BEGIN) 
00307       flags = CNS_LIST_CONTINUE;
00308     
00309     if((p[i++] = strdup(rp->sfn)) == NULL) {
00310       (void) fcops.listreplica(NULL, guid, CNS_LIST_END, &list);
00311       free(p);
00312       return (NULL);
00313     }
00314     
00315     if(i == size) {
00316       size += ALLOC_BLOCK_SIZE;
00317       if((pp = (char**)realloc(p, size * sizeof(char*))) == NULL) {
00318         (void) fcops.listreplica(NULL, guid, CNS_LIST_END, &list);
00319         free(p);
00320         return (NULL);
00321       }
00322       p = pp;
00323     }
00324   } 
00325   (void) fcops.listreplica(NULL, guid, CNS_LIST_END, &list);
00326 
00327   /* and trim */
00328   if((pp = (char**)realloc(p, (i+1) * sizeof(char*))) == NULL) {
00329     free(p);
00330     return (NULL);
00331   }
00332   
00333   pp[i] = NULL;
00334   return (pp);
00335 }
00336 
00337 char *
00338 lfc_surlfromguid (const char *guid, char *errbuf, int errbufsz)
00339 {
00340   char **surls;
00341   char **cp;
00342   char *result;
00343   
00344   if(lfc_init(errbuf, errbufsz) < 0)
00345    return (NULL);
00346 
00347   if((surls = lfc_surlsfromguid(guid, errbuf, errbufsz)) == NULL) {
00348     return (NULL);
00349   } else if (*surls == NULL) {
00350     errno = ENOENT;
00351     return (NULL);
00352   }
00353   result = getbestfile(surls, (sizeof(surls)/sizeof(char*)), errbuf, errbufsz);
00354 
00355   for(cp = surls; *cp != NULL; ++cp) {
00356     if(*cp != result) {
00357       free (*cp);
00358     }
00359   }
00360   free (surls);
00361   return (result);
00362 }
00363 
00364 /** lfc_unregister_pfn : We unregister a pfn from a guid, but only if it a
00365     replica for that guid */
00366 int
00367 lfc_unregister_pfn (const char *guid, const char *pfn, char *errbuf, int errbufsz)
00368 {
00369   if(lfc_init(errbuf, errbufsz) < 0)
00370     return (-1);
00371   
00372   if(fcops.delreplica(guid, NULL, pfn) < 0) {
00373     if(*fcops.serrno == ENOENT) {
00374       return (0);
00375     }
00376     if(*fcops.serrno < 1000) 
00377       errno = *fcops.serrno;
00378     else {
00379       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00380       errno = ECOMM;
00381     }
00382     return (-1);
00383   }
00384   return (0);
00385 }
00386 
00387 char *
00388 lfc_guidfromlfn (const char *lfn, char *errbuf, int errbufsz)
00389 {
00390   struct lfc_filestatg statg;
00391   char *p;
00392 
00393   if(lfc_init(errbuf, errbufsz) < 0)
00394     return (NULL);
00395 
00396   if(fcops.statg(lfn, NULL, &statg) < 0) {
00397     if(*fcops.serrno < 1000)
00398       errno = *fcops.serrno;
00399     else {
00400       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00401       errno = ECOMM;
00402     }
00403     return (NULL);
00404   }
00405   if((p = strdup(statg.guid)) == NULL)
00406     return (NULL);
00407   return (p);
00408 }
00409 
00410 char **
00411 lfc_lfnsforguid (const char *guid, char *errbuf, int errbufsz)
00412 {
00413   lfc_list list;
00414   struct lfc_linkinfo* lp;
00415   int flags;
00416   char **p, **pp;
00417   size_t size = ALLOC_BLOCK_SIZE;
00418   size_t i = 0;
00419   
00420   if(lfc_init(errbuf, errbufsz) < 0)
00421     return (NULL);
00422 
00423   /* allocate some memory for the pointers */
00424   if((p = (char**)calloc(size, sizeof(char*))) == NULL) {
00425     return (NULL);
00426   }
00427 
00428   flags = CNS_LIST_BEGIN;
00429   while((lp = fcops.listlinks(NULL, guid, flags, &list)) != NULL) {
00430     if(flags == CNS_LIST_BEGIN) 
00431       flags = CNS_LIST_CONTINUE;
00432     
00433     if((p[i++] = strdup(lp->path)) == NULL) {
00434       (void) fcops.listlinks(NULL, guid, CNS_LIST_END, &list);
00435       free (p);
00436       return (NULL);
00437     }
00438     
00439     if(i == size) {
00440       size += ALLOC_BLOCK_SIZE;
00441       if((pp = (char**)realloc(p, size * sizeof(char*))) == NULL) {
00442         (void) fcops.listlinks(NULL, guid, CNS_LIST_END, &list);
00443         free (p);
00444         return (NULL);
00445       }
00446       p = pp;
00447     }
00448   } 
00449   (void) fcops.listlinks(NULL, guid, CNS_LIST_END, &list);
00450   /* no results */
00451   if( i== 0) {
00452     errno = ENOENT;
00453     free (p);
00454     return (NULL);
00455   }
00456 
00457   if((pp = (char**)realloc(p, (i+1) * sizeof(char*))) == NULL) {
00458     free (p);
00459     return (NULL);
00460   }
00461   pp[i] = NULL;
00462   return (pp);
00463 }
00464 
00465 int
00466 lfc_create_alias (const char *guid, const char *lfn, GFAL_LONG64 size, char *errbuf, int errbufsz)
00467 {
00468   if(lfc_init(errbuf, errbufsz) < 0)
00469     return (-1);
00470 
00471   fcops.starttrans(NULL, gfal_version);
00472   if(fcops.creatg(lfn, guid, 0666) < 0) {
00473     if(*fcops.serrno < 1000) 
00474       errno = *fcops.serrno;
00475     else {
00476       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00477       errno = ECOMM;
00478     }
00479     return (-1);
00480   }
00481   if(fcops.setfsizeg(guid, size, NULL, NULL) < 0) {
00482     if(*fcops.serrno < 1000)
00483       errno = *fcops.serrno;
00484     else {
00485       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00486       errno = ECOMM;
00487     }
00488     return (-1);
00489   }
00490   fcops.endtrans();
00491   return (0);
00492 }
00493 
00494 int
00495 lfc_register_alias (const char *guid, const char *lfn, char *errbuf, int errbufsz)
00496 {
00497   struct lfc_filestatg statg;
00498   char master_lfn[CA_MAXPATHLEN+1];
00499   
00500   if(lfc_init(errbuf, errbufsz) < 0)
00501     return (-1);
00502 
00503   fcops.starttrans(NULL, gfal_version);
00504   if(fcops.statg(NULL, guid, &statg) < 0) {
00505     if(*fcops.serrno < 1000) 
00506       errno = *fcops.serrno;
00507     else {
00508       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00509       errno = ECOMM;
00510     }
00511     return (-1);
00512   }
00513   /* now we do a getpath() to get the master lfn */
00514   if (fcops.getpath(lfc_host, statg.fileid, master_lfn) <0 ) {
00515     if (*fcops.serrno < 1000)
00516       errno = *fcops.serrno;
00517     else {
00518       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00519       errno = ECOMM;
00520     }
00521     return (-1);
00522   }
00523 
00524   /* and finally register */
00525   if(fcops.symlink(master_lfn, lfn) < 0) {
00526     if (*fcops.serrno < 1000)
00527       errno = *fcops.serrno;
00528     else {
00529       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00530       errno = ECOMM;
00531     }
00532     return (-1);
00533   }
00534   fcops.endtrans();
00535   return (0);
00536 }
00537 
00538 int 
00539 lfc_unregister_alias (const char *guid, const char *lfn, char *errbuf, int errbufsz)
00540 {
00541   struct lfc_filestatg statg;
00542   struct lfc_filestat stat;
00543 
00544   if(lfc_init(errbuf, errbufsz) < 0)
00545     return (-1);
00546 
00547   fcops.starttrans(NULL, gfal_version);
00548   /*  In the case of the master lfn being unlinked already, statg will
00549       return ENOENT.  We then check lstat in case it's a hanging link ?  */
00550   if(fcops.statg(lfn, guid, &statg) < 0 ) {
00551     if (*fcops.serrno == ENOENT) {
00552       if(fcops.lstat(lfn, &stat) < 0 ) {
00553         if(*fcops.serrno < 1000 ) 
00554           errno = *fcops.serrno;
00555         else {
00556           gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00557           errno = ECOMM;
00558         }
00559         return (-1);
00560       } else {
00561         /* all ok, continue */
00562       }
00563     } else {
00564       if(*fcops.serrno < 1000) 
00565         errno = *fcops.serrno;
00566       else {
00567         gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00568         errno = ECOMM;
00569       }
00570       return (-1);
00571     }
00572   }
00573 
00574   /* lfn maps to the guid - unlink it */
00575   if(fcops.unlink(lfn) < 0) {
00576     if(*fcops.serrno < 1000) 
00577       errno = *fcops.serrno;
00578     else {
00579       gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00580       errno = ECOMM;
00581     }
00582     return (-1);
00583   }
00584   fcops.endtrans();
00585   return (0);
00586 }
00587 
00588 int 
00589 lfc_mkdirp(const char *path, mode_t mode, char *errbuf, int errbufsz)
00590 {
00591   int c;
00592   char *lastslash = NULL;
00593   char *p;
00594   char *p1;
00595   char *q;
00596   char sav_path[CA_MAXPATHLEN+1];
00597   struct lfc_filestatg statbuf;
00598   uuid_t uuid;
00599   char uuid_buf[CA_MAXGUIDLEN+1];
00600 
00601   if(lfc_init(errbuf, errbufsz) < 0)
00602     return (-1);
00603 
00604   if (strlen (path) >= sizeof(sav_path)) {
00605     gfal_errmsg(errbuf, errbufsz, "Path too long");
00606     errno = ENAMETOOLONG;
00607     return (-1);
00608   }
00609   strcpy (sav_path, path);
00610   p1 = strchr (sav_path, '/');
00611   p = strrchr (sav_path, '/');
00612   while (p > p1) {
00613     if (lastslash == NULL) lastslash = p;
00614     *p = '\0';
00615     c = fcops.statg (sav_path, NULL, &statbuf);
00616     if (c == 0) {
00617       *p = '/';
00618       break;
00619     }
00620     if (*fcops.serrno != ENOENT) {
00621       if(*fcops.serrno < 1000) 
00622         errno = *fcops.serrno;
00623       else {
00624         gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00625         errno = ECOMM;
00626       }
00627       return (c);
00628     }
00629     q = strrchr (sav_path, '/');
00630     *p = '/';
00631     p = q;
00632   }
00633   c = 0;
00634   while (c == 0 && (p = strchr (p + 1, '/')) && p <= lastslash) {
00635     *p = '\0';
00636     uuid_generate(uuid);
00637     uuid_unparse(uuid, uuid_buf);
00638     c = fcops.mkdirg (sav_path, uuid_buf, mode);
00639     if(c != 0) {
00640       if (*fcops.serrno < 1000)
00641         errno = *fcops.serrno;
00642       else {
00643         gfal_errmsg(errbuf, errbufsz, fcops.sstrerror(*fcops.serrno));
00644         errno = ECOMM;
00645       }
00646     }
00647     *p = '/';
00648   }
00649   return (c);
00650 }
00651   

Generated on Fri Sep 8 20:20:47 2006 for GFAL by  doxygen 1.4.6