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

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2005 by CERN
00003  */
00004 
00005 /*
00006  * @(#)$RCSfile: gfal.c,v $ $Revision: 1.1.1.1 $ $Date: 2006/09/06 08:54:53 $ CERN Jean-Philippe Baud
00007  */
00008 
00009 #include <sys/types.h>
00010 #include <errno.h>
00011 #include <stdio.h>
00012 #include <dirent.h>
00013 #include <fcntl.h>
00014 #include <time.h>
00015 #include <sys/stat.h>
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #if defined(_WIN32)
00019 #include <io.h>
00020 #else
00021 #include <unistd.h>
00022 #endif
00023 #include "gfal.h"
00024 #include "gfal_api.h"
00025 #if !defined(OFF_MAX)
00026 #define OFF_MAX 2147483647
00027 #endif
00028 
00029 static struct dir_info *di_array[GFAL_OPEN_MAX];
00030 static struct xfer_info *xi_array[GFAL_OPEN_MAX];
00031 
00032 static struct dir_info *
00033 alloc_di (DIR *dir)
00034 {
00035         int i;
00036 
00037         for (i = 0; i < GFAL_OPEN_MAX; i++) {
00038                 if (di_array[i] == NULL) {
00039                         if ((di_array[i] = (struct dir_info *) calloc (1, sizeof(struct dir_info))) == NULL)
00040                                 return (NULL);
00041                         di_array[i]->dir = dir;
00042                         return (di_array[i]);
00043                 }
00044         }
00045         errno = EMFILE;
00046         return (NULL);
00047 }
00048 
00049 static struct xfer_info *
00050 alloc_xi (int fd)
00051 {
00052         if (fd >= 0 && fd < GFAL_OPEN_MAX && xi_array[fd] == NULL)
00053                 return (xi_array[fd] = (struct xfer_info *) calloc (1, sizeof(struct xfer_info)));
00054         errno = EBADF;
00055         return (NULL);
00056 }
00057 
00058 static struct dir_info *
00059 find_di (DIR *dir)
00060 {
00061         int i;
00062 
00063         for (i = 0; i < GFAL_OPEN_MAX; i++) {
00064                 if (di_array[i] && di_array[i]->dir == dir)
00065                         return (di_array[i]);
00066         }
00067         errno = EBADF;
00068         return (NULL);
00069 }
00070 
00071 static struct xfer_info *
00072 find_xi (int fd)
00073 {
00074         if (fd >= 0 && fd < GFAL_OPEN_MAX && xi_array[fd])
00075                 return (xi_array[fd]);
00076         errno = EBADF;
00077         return (NULL);
00078 }
00079 
00080 static int
00081 free_di (struct dir_info *di)
00082 {
00083         free (di);
00084         di = NULL;
00085 }
00086 
00087 static int
00088 free_xi (int fd)
00089 {
00090         if (fd >= 0 && fd < GFAL_OPEN_MAX && xi_array[fd]) {
00091                 free (xi_array[fd]);
00092                 xi_array[fd] = NULL;
00093         }
00094         return (0);
00095 }
00096 
00097 gfal_access (const char *path, int amode)
00098 {
00099         char errbuf[256];
00100         char pathbuf[1024];
00101         char *pfn;
00102         struct proto_ops *pops;
00103         char protocol[64];
00104 
00105         if (strncmp (path, "lfn:", 4) == 0 ||
00106             strncmp (path, "guid:", 5) == 0 ||
00107             strncmp (path, "srm:", 4) == 0 ||
00108             strncmp (path, "sfn:", 4) == 0) {
00109                 errno = EPROTONOSUPPORT;
00110                 return (-1);
00111         }
00112         if (parseturl (path, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf)) < 0)
00113                 return (-1);
00114         if ((pops = find_pops (protocol)) == NULL)
00115                 return (-1);
00116         if (pops->access (pfn, amode) < 0) {
00117                 errno = pops->maperror (pops, 0);
00118                 return (-1);
00119         }
00120         return (0);
00121 }
00122 
00123 gfal_chmod (const char *path, mode_t mode)
00124 {
00125         char errbuf[256];
00126         char pathbuf[1024];
00127         char *pfn;
00128         struct proto_ops *pops;
00129         char protocol[64];
00130 
00131         if (strncmp (path, "lfn:", 4) == 0 ||
00132             strncmp (path, "guid:", 5) == 0 ||
00133             strncmp (path, "srm:", 4) == 0 ||
00134             strncmp (path, "sfn:", 4) == 0) {
00135                 errno = EPROTONOSUPPORT;
00136                 return (-1);
00137         }
00138         if (parseturl (path, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf)) < 0)
00139                 return (-1);
00140         if ((pops = find_pops (protocol)) == NULL)
00141                 return (-1);
00142         if (pops->chmod (pfn, mode) < 0) {
00143                 errno = pops->maperror (pops, 0);
00144                 return (-1);
00145         }
00146         return (0);
00147 }
00148 
00149 gfal_close (int fd)
00150 {
00151         char errbuf[256];
00152         int rc;
00153         int rc1 = 0;
00154         int sav_errno;
00155         struct xfer_info *xi;
00156 
00157         if ((xi = find_xi (fd)) == NULL)
00158                 return (-1);
00159         if ((rc = xi->pops->close (fd)) < 0)
00160                 sav_errno = xi->pops->maperror (xi->pops, 1);
00161 
00162         /* set status "done" */
00163 
00164         if (xi->surl) {
00165                 rc1 = set_xfer_done (xi->surl, xi->reqid, xi->fileid,
00166                     xi->token, xi->oflag, errbuf, sizeof(errbuf), 0);
00167                 free (xi->surl);
00168                 if (xi->token) free (xi->token);
00169         }
00170         (void) free_xi (fd);
00171         if (rc) {
00172                 errno = sav_errno;
00173                 return (-1);
00174         }
00175         return (rc1);
00176 }
00177 
00178 gfal_closedir (DIR *dir)
00179 {
00180         struct dir_info *di;
00181         int rc;
00182 
00183         if (di = find_di (dir)) {
00184                 if ((rc = di->pops->closedir (dir)) < 0)
00185                         errno = di->pops->maperror (di->pops, 0);
00186                 (void) free_di (di);
00187                 return (rc);
00188         } else
00189                 return (-1);
00190 }
00191 
00192 gfal_creat (const char *filename, mode_t mode)
00193 {
00194         return (gfal_open (filename, O_WRONLY|O_CREAT|O_TRUNC, mode));
00195 }
00196 
00197 gfal_creat64 (const char *filename, mode_t mode)
00198 {
00199         return (gfal_open64 (filename, O_WRONLY|O_CREAT|O_TRUNC, mode));
00200 }
00201 
00202 gfal_errmsg (char *errbuf, int errbufsz, const char *errmsg)
00203 {
00204         if (errbuf == NULL)
00205                 fprintf (stderr, "%s\n", errmsg);
00206         else {
00207                 strncpy (errbuf, errmsg, errbufsz - 1);
00208                 *(errbuf+errbufsz-1) = '\0';
00209         }
00210 }
00211 
00212 off_t
00213 gfal_lseek (int fd, off_t offset, int whence)
00214 {
00215         off_t offset_out;
00216         struct xfer_info *xi;
00217 
00218         if ((xi = find_xi (fd)) == NULL)
00219                 return (-1);
00220         if ((offset_out = xi->pops->lseek (fd, offset, whence)) < 0)
00221                 errno = xi->pops->maperror (xi->pops, 1);
00222         return (offset_out);
00223 }
00224 
00225 off64_t
00226 gfal_lseek64 (int fd, off64_t offset, int whence)
00227 {
00228         off64_t offset_out;
00229         struct xfer_info *xi;
00230 
00231         if ((xi = find_xi (fd)) == NULL)
00232                 return (-1);
00233         if ((offset_out = xi->pops->lseek64 (fd, offset, whence)) < 0)
00234                 errno = xi->pops->maperror (xi->pops, 1);
00235         return (offset_out);
00236 }
00237 
00238 gfal_lstat (const char *filename, struct stat *statbuf)
00239 {
00240         char errbuf[256];
00241         char *fn;
00242         char *guid;
00243         char pathbuf[1024];
00244         char *pfn;
00245         struct proto_ops *pops;
00246         char protocol[64];
00247         int rc;
00248         struct stat64 statb64;
00249         char *turl;
00250 
00251         if (strncmp (filename, "lfn:", 4) == 0) {
00252                 if ((guid = guidfromlfn (filename + 4, errbuf, sizeof(errbuf))) == NULL)
00253                         return (-1);
00254                 if ((fn = surlfromguid (guid, errbuf, sizeof(errbuf))) == NULL) {
00255                         free (guid);
00256                         return (-1);
00257                 }
00258                 free (guid);
00259         } else if (strncmp (filename, "guid:", 5) == 0) {
00260                 if ((fn = surlfromguid (filename + 5, errbuf, sizeof(errbuf))) == NULL)
00261                         return (-1);
00262         } else
00263                 fn = (char *)filename;
00264         if (strncmp (fn, "srm:", 4) == 0) {
00265                 if ((rc = getfilemd (fn, &statb64, errbuf, sizeof(errbuf), 0)) == 0)
00266                         rc = mdtomd32 (&statb64, statbuf);
00267                 if (fn != filename) free (fn);
00268                 return (rc);
00269         }
00270         if (strncmp (fn, "sfn:", 4) == 0) {
00271                 if ((turl = turlfromsfn (fn, NULL, errbuf, sizeof(errbuf))) == NULL) {
00272                         if (fn != filename) free (fn);
00273                         return (-1);
00274                 }
00275         } else          /* assume that is a pfn */
00276                 turl = fn;
00277         if ((rc = parseturl (turl, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf))) == 0) {
00278                 if ((pops = find_pops (protocol)) != NULL) {
00279                         if ((rc = pops->lstat (pfn, statbuf)) < 0)
00280                                 errno = pops->maperror (pops, 0);
00281                 }
00282         }
00283         if (fn != filename) free (fn);
00284         if (turl != fn) free (turl);
00285         if (rc < 0 || pops == NULL)
00286                 return (-1);
00287         return (0);
00288 }
00289 
00290 gfal_lstat64 (const char *filename, struct stat64 *statbuf)
00291 {
00292         char errbuf[256];
00293         char *fn;
00294         char *guid;
00295         char pathbuf[1024];
00296         char *pfn;
00297         struct proto_ops *pops;
00298         char protocol[64];
00299         int rc;
00300         char *turl;
00301 
00302         if (strncmp (filename, "lfn:", 4) == 0) {
00303                 if ((guid = guidfromlfn (filename + 4, errbuf, sizeof(errbuf))) == NULL)
00304                         return (-1);
00305                 if ((fn = surlfromguid (guid, errbuf, sizeof(errbuf))) == NULL) {
00306                         free (guid);
00307                         return (-1);
00308                 }
00309                 free (guid);
00310         } else if (strncmp (filename, "guid:", 5) == 0) {
00311                 if ((fn = surlfromguid (filename + 5, errbuf, sizeof(errbuf))) == NULL)
00312                         return (-1);
00313         } else
00314                 fn = (char *)filename;
00315         if (strncmp (fn, "srm:", 4) == 0) {
00316                 rc = getfilemd (fn, statbuf, errbuf, sizeof(errbuf), 0);
00317                 if (fn != filename) free (fn);
00318                 return (rc);
00319         }
00320         if (strncmp (fn, "sfn:", 4) == 0) {
00321                 if ((turl = turlfromsfn (fn, NULL, errbuf, sizeof(errbuf))) == NULL) {
00322                         if (fn != filename) free (fn);
00323                         return (-1);
00324                 }
00325         } else          /* assume that is a pfn */
00326                 turl = fn;
00327         if ((rc = parseturl (turl, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf))) == 0) {
00328                 if ((pops = find_pops (protocol)) != NULL) {
00329                         if ((rc = pops->lstat64 (pfn, statbuf)) < 0)
00330                                 errno = pops->maperror (pops, 0);
00331                 }
00332         }
00333         if (fn != filename) free (fn);
00334         if (turl != fn) free (turl);
00335         if (rc < 0 || pops == NULL)
00336                 return (-1);
00337         return (0);
00338 }
00339 
00340 gfal_mkdir (const char *dirname, mode_t mode)
00341 {
00342         char errbuf[256];
00343         char pathbuf[1024];
00344         char *pfn;
00345         struct proto_ops *pops;
00346         char protocol[64];
00347 
00348         if (strncmp (dirname, "lfn:", 4) == 0 ||
00349             strncmp (dirname, "guid:", 5) == 0 ||
00350             strncmp (dirname, "srm:", 4) == 0 ||
00351             strncmp (dirname, "sfn:", 4) == 0) {
00352                 errno = EPROTONOSUPPORT;
00353                 return (-1);
00354         }
00355         if (parseturl (dirname, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf)) < 0)
00356                 return (-1);
00357         if ((pops = find_pops (protocol)) == NULL)
00358                 return (-1);
00359         if (pops->mkdir (pfn, mode) < 0) {
00360                 errno = pops->maperror (pops, 0);
00361                 return (-1);
00362         }
00363         return (0);
00364 }
00365 
00366 gfal_open (const char *filename, int flags, mode_t mode)
00367 {
00368         char errbuf[256];
00369         int fd;
00370         int fileid;
00371         char *fn;
00372         char *guid = NULL;
00373         char pathbuf[1024];
00374         char *pfn;
00375         struct proto_ops *pops;
00376         char protocol[64];
00377         int reqid;
00378         char **supported_protocols;
00379         char *token = NULL;
00380         char *turl = NULL;
00381         struct xfer_info *xi;
00382 
00383         supported_protocols = get_sup_proto ();
00384 
00385         if (strncmp (filename, "lfn:", 4) == 0) {
00386                 if ((guid = guidfromlfn (filename + 4, errbuf, sizeof(errbuf))) == NULL)
00387                         return (-1);
00388                 if ((fn = surlfromguid (guid, errbuf, sizeof(errbuf))) == NULL) {
00389                         free (guid);
00390                         return (-1);
00391                 }
00392         } else if (strncmp (filename, "guid:", 5) == 0) {
00393                 if ((fn = surlfromguid (filename + 5, errbuf, sizeof(errbuf))) == NULL)
00394                         return (-1);
00395         } else
00396                 fn = (char *)filename;
00397         if (strncmp (fn, "srm:", 4) == 0) {
00398                 if ((turl = turlfromsurl (fn, supported_protocols, flags,
00399                     &reqid, &fileid, &token, errbuf, sizeof(errbuf), 0)) == NULL)
00400                         goto err;
00401         } else if (strncmp (fn, "sfn:", 4) == 0) {
00402                 if ((turl = turlfromsfn (fn, supported_protocols, errbuf, sizeof(errbuf))) == NULL)
00403                         goto err;
00404         } else          /* assume that is a pfn */
00405                 turl = fn;
00406         if (parseturl (turl, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf)) < 0)
00407                 goto err;
00408         if ((pops = find_pops (protocol)) == NULL)
00409                 goto err;
00410         if ((fd = pops->open (pfn, flags, mode)) < 0) {
00411                 errno = pops->maperror (pops, 1);
00412                 goto err;
00413         }
00414         if ((xi = alloc_xi (fd)) == NULL)
00415                 goto err;
00416         xi->fd = fd;
00417         xi->oflag = flags;
00418         xi->pops = pops;
00419         if (strncmp (fn, "srm:", 4) == 0) {
00420                 xi->surl = strdup (fn);
00421                 xi->reqid = reqid;
00422                 xi->fileid = fileid;
00423                 if (token) {
00424                         xi->token = strdup (token);
00425                         free (token);
00426                 }
00427                 (void) set_xfer_running (xi->surl, xi->reqid, xi->fileid,
00428                     xi->token, errbuf, sizeof(errbuf), 0);
00429         }
00430 
00431         if (guid) free (guid);
00432         if (fn != filename) free (fn);
00433         if (turl != fn) free (turl);
00434         return (fd);
00435 err:
00436         if (guid) free (guid);
00437         if (fn != filename) free (fn);
00438         if (turl && turl != fn) free (turl);
00439         return (-1);
00440 }
00441 
00442 gfal_open64 (const char *filename, int flags, mode_t mode)
00443 {
00444         return (gfal_open (filename, flags | O_LARGEFILE, mode));
00445 }
00446 
00447 DIR *
00448 gfal_opendir (const char *dirname)
00449 {
00450         struct dir_info *di;
00451         DIR *dir;
00452         char errbuf[256];
00453         char pathbuf[1024];
00454         char *pfn;
00455         struct proto_ops *pops;
00456         char protocol[64];
00457 
00458         if (strncmp (dirname, "lfn:", 4) == 0 ||
00459             strncmp (dirname, "guid:", 5) == 0 ||
00460             strncmp (dirname, "srm:", 4) == 0 ||
00461             strncmp (dirname, "sfn:", 4) == 0) {
00462                 errno = EPROTONOSUPPORT;
00463                 return (NULL);
00464         }
00465         if (parseturl (dirname, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf)) < 0)
00466                 return (NULL);
00467         if ((pops = find_pops (protocol)) == NULL)
00468                 return (NULL);
00469         if ((dir = pops->opendir (pfn)) == NULL) {
00470                 errno = pops->maperror (pops, 0);
00471                 return (NULL);
00472         }
00473         if ((di = alloc_di (dir)) == NULL)
00474                 return (NULL);
00475         di->pops = pops;
00476         return (dir);
00477 }
00478 
00479 ssize_t
00480 gfal_read (int fd, void *buf, size_t size)
00481 {
00482         int rc;
00483         struct xfer_info *xi;
00484 
00485         if ((xi = find_xi (fd)) == NULL)
00486                 return (-1);
00487         if ((rc = xi->pops->read (fd, buf, size)) < 0)
00488                 errno = xi->pops->maperror (xi->pops, 1);
00489         return (rc);
00490 }
00491 
00492 struct dirent *
00493 gfal_readdir (DIR *dir)
00494 {
00495         struct dirent *de;
00496         struct dir_info *di;
00497 
00498         if ((di = find_di (dir)) == NULL)
00499                 return (NULL);
00500         if ((de = di->pops->readdir (dir)) == NULL)
00501                 errno = di->pops->maperror (di->pops, 0);
00502         return (de);
00503 }
00504 
00505 struct dirent64 *
00506 gfal_readdir64 (DIR *dir)
00507 {
00508         struct dirent64 *de;
00509         struct dir_info *di;
00510 
00511         if ((di = find_di (dir)) == NULL)
00512                 return (NULL);
00513         if ((de = di->pops->readdir64 (dir)) == NULL)
00514                 errno = di->pops->maperror (di->pops, 0);
00515         return (de);
00516 }
00517 
00518 gfal_rename (const char *old_name, const char *new_name)
00519 {
00520         char *new_pfn;
00521         char *old_pfn;
00522         char errbuf[256];
00523         char pathbuf1[1024];
00524         char pathbuf2[1024];
00525         struct proto_ops *pops;
00526         char protocol1[64];
00527         char protocol2[64];
00528 
00529         if (strncmp (old_name, "lfn:", 4) == 0 ||
00530             strncmp (old_name, "guid:", 5) == 0 ||
00531             strncmp (old_name, "srm:", 4) == 0 ||
00532             strncmp (old_name, "sfn:", 4) == 0) {
00533                 errno = EPROTONOSUPPORT;
00534                 return (-1);
00535         }
00536         if (strncmp (new_name, "lfn:", 4) == 0 ||
00537             strncmp (new_name, "guid:", 5) == 0 ||
00538             strncmp (new_name, "srm:", 4) == 0 ||
00539             strncmp (new_name, "sfn:", 4) == 0) {
00540                 errno = EPROTONOSUPPORT;
00541                 return (-1);
00542         }
00543         if (parseturl (old_name, protocol1, sizeof(protocol1), pathbuf1, sizeof(pathbuf1), &old_pfn, errbuf, sizeof(errbuf)) < 0)
00544                 return (-1);
00545         if (parseturl (new_name, protocol2, sizeof(protocol2), pathbuf2, sizeof(pathbuf2), &new_pfn, errbuf, sizeof(errbuf)) < 0)
00546                 return (-1);
00547         if (strcmp (protocol1, protocol2)) {
00548                 errno = EINVAL;
00549                 return (-1);
00550         }
00551         if ((pops = find_pops (protocol1)) == NULL)
00552                 return (-1);
00553         if (pops->rename (old_pfn, new_pfn) < 0) {
00554                 errno = pops->maperror (pops, 0);
00555                 return (-1);
00556         }
00557         return (0);
00558 }
00559 
00560 gfal_rmdir (const char *dirname)
00561 {
00562         char errbuf[256];
00563         char pathbuf[1024];
00564         char *pfn;
00565         struct proto_ops *pops;
00566         char protocol[64];
00567 
00568         if (strncmp (dirname, "lfn:", 4) == 0 ||
00569             strncmp (dirname, "guid:", 5) == 0 ||
00570             strncmp (dirname, "srm:", 4) == 0 ||
00571             strncmp (dirname, "sfn:", 4) == 0) {
00572                 errno = EPROTONOSUPPORT;
00573                 return (-1);
00574         }
00575         if (parseturl (dirname, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf)) < 0)
00576                 return (-1);
00577         if ((pops = find_pops (protocol)) == NULL)
00578                 return (-1);
00579         if (pops->rmdir (pfn) < 0) {
00580                 errno = pops->maperror (pops, 0);
00581                 return (-1);
00582         }
00583         return (0);
00584 }
00585 
00586 ssize_t
00587 gfal_setfilchg (int fd, const void *buf, size_t size)
00588 {
00589         int rc;
00590         struct xfer_info *xi;
00591 
00592         if ((xi = find_xi (fd)) == NULL)
00593                 return (-1);
00594         if ((rc = xi->pops->setfilchg (fd, buf, size)) < 0)
00595                 errno = xi->pops->maperror (xi->pops, 1);
00596         return (rc);
00597 }
00598 
00599 gfal_stat (const char *filename, struct stat *statbuf)
00600 {
00601         char errbuf[256];
00602         char *fn;
00603         char *guid;
00604         char pathbuf[1024];
00605         char *pfn;
00606         struct proto_ops *pops;
00607         char protocol[64];
00608         int rc;
00609         struct stat64 statb64;
00610         char *turl;
00611 
00612         if (strncmp (filename, "lfn:", 4) == 0) {
00613                 if ((guid = guidfromlfn (filename + 4, errbuf, sizeof(errbuf))) == NULL)
00614                         return (-1);
00615                 if ((fn = surlfromguid (guid, errbuf, sizeof(errbuf))) == NULL) {
00616                         free (guid);
00617                         return (-1);
00618                 }
00619                 free (guid);
00620         } else if (strncmp (filename, "guid:", 5) == 0) {
00621                 if ((fn = surlfromguid (filename + 5, errbuf, sizeof(errbuf))) == NULL)
00622                         return (-1);
00623         } else
00624                 fn = (char *)filename;
00625         if (strncmp (fn, "srm:", 4) == 0) {
00626                 if ((rc = getfilemd (fn, &statb64, errbuf, sizeof(errbuf), 0)) == 0)
00627                         rc = mdtomd32 (&statb64, statbuf);
00628                 if (fn != filename) free (fn);
00629                 return (rc);
00630         }
00631         if (strncmp (fn, "sfn:", 4) == 0) {
00632                 if ((turl = turlfromsfn (fn, NULL, errbuf, sizeof(errbuf))) == NULL) {
00633                         if (fn != filename) free (fn);
00634                         return (-1);
00635                 }
00636         } else          /* assume that is a pfn */
00637                 turl = fn;
00638         if ((rc = parseturl (turl, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf))) == 0) {
00639                 if ((pops = find_pops (protocol)) != NULL) {
00640                         if ((rc = pops->stat (pfn, statbuf)) < 0)
00641                                 errno = pops->maperror (pops, 0);
00642                 }
00643         }
00644         if (fn != filename) free (fn);
00645         if (turl != fn) free (turl);
00646         if (rc < 0 || pops == NULL)
00647                 return (-1);
00648         return (0);
00649 }
00650 
00651 gfal_stat64 (const char *filename, struct stat64 *statbuf)
00652 {
00653         char errbuf[256];
00654         char *fn;
00655         char *guid;
00656         char pathbuf[1024];
00657         char *pfn;
00658         struct proto_ops *pops;
00659         char protocol[64];
00660         int rc;
00661         char *turl;
00662 
00663         if (strncmp (filename, "lfn:", 4) == 0) {
00664                 if ((guid = guidfromlfn (filename + 4, errbuf, sizeof(errbuf))) == NULL)
00665                         return (-1);
00666                 if ((fn = surlfromguid (guid, errbuf, sizeof(errbuf))) == NULL) {
00667                         free (guid);
00668                         return (-1);
00669                 }
00670                 free (guid);
00671         } else if (strncmp (filename, "guid:", 5) == 0) {
00672                 if ((fn = surlfromguid (filename + 5, errbuf, sizeof(errbuf))) == NULL)
00673                         return (-1);
00674         } else
00675                 fn = (char *)filename;
00676         if (strncmp (fn, "srm:", 4) == 0) {
00677                 rc = getfilemd (fn, statbuf, errbuf, sizeof(errbuf), 0);
00678                 if (fn != filename) free (fn);
00679                 return (rc);
00680         }
00681         if (strncmp (fn, "sfn:", 4) == 0) {
00682                 if ((turl = turlfromsfn (fn, NULL, errbuf, sizeof(errbuf))) == NULL) {
00683                         if (fn != filename) free (fn);
00684                         return (-1);
00685                 }
00686         } else          /* assume that is a pfn */
00687                 turl = fn;
00688         if ((rc = parseturl (turl, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf),
00689             &pfn, errbuf, sizeof(errbuf))) == 0) {
00690                 if ((pops = find_pops (protocol)) != NULL) {
00691                         if ((rc = pops->stat64 (pfn, statbuf)) < 0)
00692                                 errno = pops->maperror (pops, 0);
00693                 }
00694         }
00695         if (fn != filename) free (fn);
00696         if (turl != fn) free (turl);
00697         if (rc < 0 || pops == NULL)
00698                 return (-1);
00699         return (0);
00700 }
00701 
00702 gfal_unlink (const char *filename)
00703 {
00704         char errbuf[256];
00705         int i = 0;
00706         char **pfns;
00707         int rc = 0;
00708 
00709         if (strncmp (filename, "lfn:", 4) == 0) {
00710                 errno = EPROTONOSUPPORT;
00711                 return (-1);
00712         } else if (strncmp (filename, "guid:", 5) == 0) {
00713                 /* must try to delete all PFNs mapped to this guid */
00714                 if ((pfns = surlsfromguid (filename + 5, errbuf, sizeof(errbuf))) == NULL)
00715                         return (-1);
00716                 while (pfns[i]) {
00717                         rc += deletepfn (pfns[i], filename + 5, errbuf, sizeof(errbuf));
00718                         free (pfns[i++]);
00719                 }
00720                 free (pfns);
00721                 return (rc == 0 ? 0 : -1);
00722         } else
00723                 return (deletepfn (filename, NULL, errbuf, sizeof(errbuf)));
00724 }
00725 
00726 ssize_t
00727 gfal_write (int fd, const void *buf, size_t size)
00728 {
00729         int rc;
00730         struct xfer_info *xi;
00731 
00732         if ((xi = find_xi (fd)) == NULL)
00733                 return (-1);
00734         if ((rc = xi->pops->write (fd, buf, size)) < 0)
00735                 errno = xi->pops->maperror (xi->pops, 1);
00736         return (rc);
00737 }
00738 
00739 deletepfn (const char *fn, const char *guid, char *errbuf, int errbufsz)
00740 {
00741         char pathbuf[1024];
00742         char *pfn;
00743         struct proto_ops *pops;
00744         char protocol[64];
00745         int rc;
00746         char *turl;
00747 
00748         if (strncmp (fn, "srm:", 4) == 0) {
00749                 if (deletesurl (fn, errbuf, errbufsz, 0) < 0)
00750                         return (-1);
00751         } else {
00752                 if (strncmp (fn, "sfn:", 4) == 0) {
00753                         if ((turl = turlfromsfn (fn, NULL, errbuf, errbufsz)) == NULL)
00754                                 return (-1);
00755                 } else          /* assume that is a pfn */
00756                         turl = (char *)fn;
00757                 if ((rc = parseturl (turl, protocol, sizeof(protocol), pathbuf, sizeof(pathbuf), &pfn, errbuf, sizeof(errbuf))) == 0) {
00758                         if ((pops = find_pops (protocol)) != NULL) {
00759                                 if ((rc = pops->unlink (pfn)) < 0)
00760                                         errno = pops->maperror (pops, 0);
00761                         }
00762                 }
00763                 if (turl != fn) free (turl);
00764                 if (rc < 0 || pops == NULL)
00765                         return (-1);
00766         }
00767         return (0);
00768 }
00769 
00770 deletesurl (const char *surl, char *errbuf, int errbufsz, int timeout)
00771 {
00772         char *se_type;
00773 
00774         if (setypefromsurl (surl, &se_type, errbuf, errbufsz) < 0)
00775                 return (-1);
00776         if (strcmp (se_type, "srm_v1") == 0) {
00777                 free (se_type);
00778                 return (srm_deletesurl (surl, errbuf, errbufsz, timeout));
00779         } else if (strcmp (se_type, "edg-se") == 0) {
00780                 free (se_type);
00781                 return (se_deletesurl (surl, errbuf, errbufsz, timeout));
00782         } else {
00783                 free (se_type);
00784                 gfal_errmsg(errbuf, errbufsz, "The Storage Element type is neither 'srm_v1' nor 'edg-se'.");
00785                 errno = EINVAL;
00786                 return (-1);
00787         }
00788 }
00789 
00790 getfilemd (const char *surl, struct stat64 *statbuf, char *errbuf, int errbufsz, int timeout)
00791 {
00792         char *se_type;
00793         int ret;
00794         ret=setypefromsurl (surl, &se_type, errbuf, errbufsz);
00795         if (ret < 0)
00796                 return (-1);
00797         if (strcmp (se_type, "srm_v1") == 0) {
00798                 free (se_type);
00799                 return (srm_getfilemd (surl, statbuf, errbuf, errbufsz, timeout));
00800         } else if (strcmp (se_type, "edg-se") == 0) {
00801                 free (se_type);
00802                 return (se_getfilemd (surl, statbuf, errbuf, errbufsz, timeout));
00803         } else {
00804                 free (se_type);
00805                 gfal_errmsg(errbuf, errbufsz, "The Storage Element type is neither 'srm_v1' nor 'edg-se'.");
00806                 errno = EINVAL;
00807                 return (-1);
00808         }
00809 }
00810 
00811 static int
00812 mdtomd32 (struct stat64 *statb64, struct stat *statbuf)
00813 {
00814         if (statb64->st_size > OFF_MAX && sizeof(off_t) == 4) {
00815 #if defined(_WIN32)
00816                 errno = EINVAL
00817 #else
00818                 errno = EOVERFLOW;
00819 #endif
00820                 return (-1);
00821         }
00822         memset (statbuf, 0, sizeof(struct stat));
00823         statbuf->st_mode = statb64->st_mode;
00824         statbuf->st_nlink = statb64->st_nlink;
00825         statbuf->st_uid = statb64->st_uid;
00826         statbuf->st_gid = statb64->st_gid;
00827         statbuf->st_size = (off_t) statb64->st_size;
00828         return (0);
00829 }
00830 
00831 #define SRM_EP_PATH "/srm/managerv1"
00832 #define SRM_PORT 8443
00833 parsesurl (const char *surl, char *endpoint, int srm_endpointsz, char **sfn,
00834         char *errbuf, int errbufsz)
00835 {
00836         int len;
00837         int len1;
00838         int lenp;
00839         char *p;
00840         char *p1, *p2;
00841         char *se_endpoint;
00842         int se_port;
00843 
00844         if (strncmp (surl, "srm://", 6)) {
00845                 gfal_errmsg(errbuf, errbufsz, "Source URL doesn't start with \"srm://\".");
00846                 errno = EINVAL;
00847                 return (-1);
00848         }
00849         if (p = strstr (surl + 6, "?SFN=")) {
00850                 *sfn = p + 5;
00851                 for (p1 = (char *)surl + 6; p1 < p; p1++)
00852                         if (*p1 == '/') break;
00853         } else if (p = strchr (surl + 6, '/')) {
00854                 *sfn = p;
00855                 p1 = p;
00856         } else {
00857                 gfal_errmsg(errbuf, errbufsz, "Bad Source URL syntax.");
00858                 errno = EINVAL;
00859                 return (-1);
00860         }
00861 #ifdef GFAL_SECURE
00862         strcpy (endpoint, "https://");
00863         lenp = 8;
00864 #else
00865         strcpy (endpoint, "http://");
00866         lenp = 7;
00867 #endif
00868         /* copy hostname */
00869 
00870         len = p1 - surl - 6;
00871         if (lenp + len >= srm_endpointsz) {
00872                 gfal_errmsg(errbuf, errbufsz, "Source URL too long.");
00873                 errno = ENAMETOOLONG;
00874                 return (-1);
00875         }
00876         strncpy (endpoint + lenp, surl + 6, len);
00877         *(endpoint + lenp + len) = '\0';
00878 
00879         if (p1 == p) {  /* no user specified endpoint */
00880 
00881                 /* try to get endpoint from Information Service */
00882 
00883                 if ((p2 = strchr (endpoint + lenp, ':')))
00884                         *p2 = '\0';
00885                 if (get_se_endpoint (endpoint + lenp, &se_endpoint) == 0) {
00886                         strcpy (endpoint, se_endpoint);
00887                         free (se_endpoint);
00888                         return (0);
00889                 } else
00890                         if (p2)
00891                                 *p2 = ':';
00892         }
00893 
00894         /* set port number if not specified by user */
00895 
00896         if ((p2 = strchr (endpoint + lenp, ':')) == NULL) {     /* no port specified */
00897                 if (get_se_port (endpoint + lenp, &se_port) < 0)
00898                         se_port = SRM_PORT;
00899                 if (lenp + len + 6 >= srm_endpointsz) {
00900                         gfal_errmsg(errbuf, errbufsz, "Source URL too long");
00901                         errno = ENAMETOOLONG;
00902                         return (-1);
00903                 }
00904                 len1 = sprintf (endpoint + lenp + len, ":%d", se_port);
00905         } else
00906                 len1 = 0;
00907         len1 += lenp + len;
00908 
00909         /* copy endpoint */
00910 
00911         if (p1 != p) {  /* user specified endpoint */
00912                 if (len1 + (p - p1) >= srm_endpointsz) {
00913                         gfal_errmsg(errbuf, errbufsz, "Source URL too long.");
00914                         errno = ENAMETOOLONG;
00915                         return (-1);
00916                 }
00917                 strncpy (endpoint + len1, p1, p - p1);
00918                 *(endpoint + len1 + (p - p1)) = '\0';
00919         } else {
00920                 if (len1 + strlen (SRM_EP_PATH) >= srm_endpointsz) {
00921                         gfal_errmsg(errbuf, errbufsz, "Source URL too long.");
00922                         errno = ENAMETOOLONG;
00923                         return (-1);
00924                 }
00925                 strcpy (endpoint + len1, SRM_EP_PATH);
00926         }
00927         return (0);
00928 }
00929 
00930 parseturl (const char *turl, char *protocol, int protocolsz, char *pathbuf, int pathbufsz, char **pfn, char* errbuf, int errbufsz)
00931 {
00932         int len;
00933         char *p;
00934 
00935         /* get protocol */
00936 
00937         if ((p = strstr (turl, ":/")) == NULL) {
00938                 gfal_errmsg(errbuf, errbufsz, "Bad destination URL syntax.");
00939                 errno = EINVAL;
00940                 return (-1);
00941         }
00942         if ((len = p - turl) > (protocolsz - 1)) {
00943                 gfal_errmsg(errbuf, errbufsz, "Destination URL too long.");
00944                 errno = ENAMETOOLONG;
00945                 return (-1);
00946         }
00947         strncpy (protocol, turl, len);
00948         *(protocol + len) = '\0';
00949 
00950         if (strcmp (protocol, "file") == 0) {
00951                 *pfn = p + 1;
00952         } else if (strcmp (protocol, "rfio") == 0) {
00953                 p += 2;
00954                 if (*p != '/') {
00955                         gfal_errmsg(errbuf, errbufsz, "Bad destination URL syntax.");
00956                         errno = EINVAL;
00957                         return (-1);
00958                 }
00959                 p++;
00960                 if (*p == '/' && *(p + 1) == '/') {     /* no hostname */
00961                         *pfn = p + 1;
00962                 } else {
00963                         if (strlen (p) > pathbufsz) {
00964                                 gfal_errmsg(errbuf, errbufsz, "Destination URL too long.");
00965                                 errno = ENAMETOOLONG;
00966                                 return (-1);
00967                         }
00968                         strcpy (pathbuf, p);
00969                         if (p = strstr (pathbuf, "//"))
00970                                 *p = ':';
00971                         *pfn = pathbuf;
00972                 }
00973         } else 
00974                 *pfn = (char *) turl;
00975         return (0);
00976 }
00977 
00978 set_xfer_done (const char *surl, int reqid, int fileid, char *token, int oflag,
00979         char *errbuf, int errbufsz, int timeout)
00980 {
00981         char *se_type;
00982 
00983         if (setypefromsurl (surl, &se_type, errbuf, errbufsz) < 0)
00984                 return (-1);
00985         if (strcmp (se_type, "srm_v1") == 0) {
00986                 free (se_type);
00987                 return (srm_set_xfer_done (surl, reqid, fileid, token, oflag,
00988                     errbuf, errbufsz, timeout));
00989         } else if (strcmp (se_type, "edg-se") == 0) {
00990                 free (se_type);
00991                 return (se_set_xfer_done (surl, reqid, fileid, token, oflag,
00992                     errbuf, errbufsz, timeout));
00993         } else {
00994                 free (se_type);
00995                 gfal_errmsg(errbuf, errbufsz, "The Storage Element type is neither 'srm_v1' nor 'edg-se'.");
00996                 errno = EINVAL;
00997                 return (-1);
00998         }
00999 }
01000 
01001 set_xfer_running (const char *surl, int reqid, int fileid, char *token,
01002         char *errbuf, int errbufsz, int timeout)
01003 {
01004         char *se_type;
01005 
01006         if (setypefromsurl (surl, &se_type, errbuf, errbufsz) < 0)
01007                 return (-1);
01008         if (strcmp (se_type, "srm_v1") == 0) {
01009                 free (se_type);
01010                 return (srm_set_xfer_running (surl, reqid, fileid, token,
01011                     errbuf, errbufsz, timeout));
01012         } else if (strcmp (se_type, "edg-se") == 0) {
01013                 free (se_type);
01014                 return (se_set_xfer_running (surl, reqid, fileid, token,
01015                     errbuf, errbufsz));
01016         } else {
01017                 free (se_type);
01018                 gfal_errmsg(errbuf, errbufsz, "The Storage Element type is neither 'srm_v1' nor 'edg-se'.");
01019                 errno = EINVAL;
01020                 return (-1);
01021         }
01022 }
01023 
01024 setypefromsurl (const char *surl, char **se_type,
01025         char *errbuf, int errbufsz)
01026 {
01027         int len;
01028         char *p;
01029         char server[256];
01030 
01031         if ((p = strchr (surl + 6, '/')) == NULL) {
01032                 gfal_errmsg(errbuf, errbufsz, "Bad source URL syntax.");
01033                 errno = EINVAL;
01034                 return (-1);
01035         }
01036         if ((len = p - surl - 6) >= sizeof(server)) {
01037                 gfal_errmsg(errbuf, errbufsz, "Host name too long.");
01038                 errno = ENAMETOOLONG;
01039                 return (-1);
01040         }
01041         strncpy (server, surl + 6, len);
01042         server[len] = '\0';
01043         if ((p = strchr (server, ':'))) *p = '\0';
01044         return (get_se_typex (server, se_type, errbuf, errbufsz));
01045 }
01046 
01047 char *
01048 turlfromsfn (const char *sfn, char **protocols, char *errbuf, int errbufsz)
01049 {
01050         char **ap;
01051         int i;
01052         int len;
01053         char *p;
01054         int *pn;
01055         int port = 0;
01056         char **protoarray;
01057         char server[64];
01058         char *turl;
01059 
01060         if (strncmp (sfn, "sfn://", 6)) {
01061                 gfal_errmsg(errbuf, errbufsz, "File doesn't start with \"sfn://\".");
01062                 errno = EINVAL;
01063                 return (NULL);
01064         }
01065         if ((p = strchr (sfn + 6, '/')) == NULL ||
01066             (len = p - (sfn + 6)) > sizeof(server)) {
01067                 gfal_errmsg(errbuf, errbufsz, "Host name too long.");
01068                 errno = ENAMETOOLONG;
01069                 return (NULL);
01070         }
01071 
01072         /* check that RFIO library is available */
01073 
01074         if (protocols == NULL)
01075                 protoarray = get_sup_proto ();
01076         else
01077                 protoarray = protocols;
01078         for (i = 0; *protoarray[i]; i++)
01079                 if (strcmp (protoarray[i], "rfio") == 0) break;
01080         if (*protoarray[i] == '\0') {
01081                 errno = EPROTONOSUPPORT;
01082                 return (NULL);
01083         }
01084 
01085         /* check that the SE supports RFIO */
01086 
01087         strncpy (server, sfn + 6, len);
01088         *(server + len) = '\0';
01089         if (get_seap_infox (server, &ap, &pn, errbuf, errbufsz) < 0)
01090                 return (NULL);
01091         i = 0;
01092         while (ap[i]) {
01093                 if (strcmp (ap[i], "rfio") == 0) port = pn[i];
01094                 free (ap[i]);
01095                 i++;
01096         }
01097         free (ap);
01098         free (pn);
01099         if (! port) {
01100                 gfal_errmsg(errbuf, errbufsz, "rfio protocol not supported by Storage Element.");
01101                 errno = EPROTONOSUPPORT;
01102                 return (NULL);
01103         }
01104         if ((turl = malloc (strlen (sfn) + 2)) == NULL)
01105                 return (NULL);
01106         strcpy (turl, "rfio");
01107         strcpy (turl + 4, sfn + 3);
01108         return (turl);
01109 }
01110 
01111 char *
01112 turlfromsurlx (const char *surl, GFAL_LONG64 filesize, char **protocols,
01113         int oflag, int *reqid, int *fileid, char **token, char *errbuf,
01114         int errbufsz, int timeout)
01115 {
01116         int *fileids;
01117         char *p;
01118         char *se_type;
01119         char **turls;
01120 
01121         if (setypefromsurl (surl, &se_type, errbuf, errbufsz) < 0)
01122                 return (NULL);
01123         if (strcmp (se_type, "srm_v1") == 0) {
01124                 free (se_type);
01125                 if (srm_turlsfromsurls (1, &surl, &filesize, protocols, oflag,
01126                     reqid, &fileids, token, &turls, errbuf, errbufsz, timeout) <= 0)
01127                         return (NULL);
01128                 *fileid = fileids[0];
01129                p = turls[0];
01130                free (fileids);
01131                free (turls);
01132                return (p);
01133         } else if (strcmp (se_type, "edg-se") == 0) {
01134                 free (se_type);
01135                 return (se_turlfromsurl (surl, protocols, oflag, reqid, fileid,
01136                     token, errbuf, errbufsz, timeout));
01137         } else {
01138                 free (se_type);
01139                 gfal_errmsg(errbuf, errbufsz, "The Storage Element type is neither 'srm_v1' nor 'edg-se'.");
01140                 errno = EINVAL;
01141                 return (NULL);
01142         }
01143 }
01144 
01145 char *
01146 turlfromsurl (const char *surl, char **protocols, int oflag, int *reqid,
01147         int *fileid, char **token, char *errbuf, int errbufsz, int timeout)
01148 {
01149         GFAL_LONG64 zero = 0;
01150 
01151         return (turlfromsurlx (surl, zero, protocols, oflag, reqid, fileid,
01152             token, errbuf, errbufsz, timeout));
01153 }
01154 
01155 get_cat_type (char **cat_type) {
01156         char *cat_env;
01157         char *default_cat = GFAL_DEFAULT_CATALOG_TYPE;
01158 
01159         if((cat_env = getenv ("LCG_CATALOG_TYPE")) == NULL) {
01160                 /* default catalogs if no environment variable specified */
01161                 cat_env = default_cat;          
01162         }
01163         if((*cat_type = strdup(cat_env)) == NULL) {
01164                 return (-1);
01165         }
01166         return 0;
01167 }
01168 
01169 getfilesizeg (const char *guid, GFAL_LONG64 *filesize, char *errbuf, int errbufsz)
01170 {
01171         char *cat_type;
01172         if (get_cat_type (&cat_type) < 0) {
01173                 return (-1);
01174         }
01175         if (strcmp (cat_type, "edg") == 0) {
01176                 free (cat_type);
01177                 gfal_errmsg(errbuf, errbufsz, "The EDG catalog doesn't support the getfilesizeg() method.");
01178                 errno = EINVAL;
01179         } else if (strcmp (cat_type, "lfc") == 0) {
01180                 free (cat_type);
01181                 return (lfc_getfilesizeg (guid, filesize, errbuf, errbufsz));
01182         } else {
01183                 free (cat_type);
01184                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01185                 errno = EINVAL;
01186                 return (-1);
01187         }
01188 }
01189 
01190 char *get_catalog_endpoint (char *errbuf, int errbufsz)
01191 {
01192         char *cat_type;
01193         if (get_cat_type (&cat_type) < 0) {
01194                 return (NULL);
01195         }
01196         if (strcmp (cat_type, "edg") == 0) {
01197                 free (cat_type);
01198                 return (lrc_get_catalog_endpoint (errbuf, errbufsz));
01199         } else if (strcmp (cat_type, "lfc") == 0) {
01200                 free (cat_type);
01201                 return (lfc_get_catalog_endpoint (errbuf, errbufsz));
01202         } else {
01203                 free (cat_type);
01204                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01205                 errno = EINVAL;
01206                 return (NULL);
01207         }
01208 }
01209 
01210 char *
01211 guidforpfn (const char *pfn, char *errbuf, int errbufsz)
01212 {
01213         char *cat_type;
01214         if (get_cat_type (&cat_type) < 0) {
01215                 return (NULL);
01216         }
01217         if (strcmp (cat_type, "edg") == 0) {
01218                 free (cat_type);
01219                 return (lrc_guidforpfn (pfn, errbuf, errbufsz));
01220         } else if (strcmp (cat_type, "lfc") == 0) {
01221                 free (cat_type);
01222                 return (lfc_guidforpfn (pfn, errbuf, errbufsz));
01223         } else {
01224                 free (cat_type);
01225                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01226                 errno = EINVAL;
01227                 return (NULL);
01228         }
01229 }
01230 
01231 guid_exists (const char *guid, char *errbuf, int errbufsz)
01232 {
01233         char *cat_type;
01234         if (get_cat_type (&cat_type) < 0) {
01235                 return (-1);
01236         }
01237         if (strcmp (cat_type, "edg") == 0) {
01238                 free (cat_type);
01239                 return (lrc_guid_exists (guid, errbuf, errbufsz));
01240         } else if (strcmp (cat_type, "lfc") == 0) {
01241                 free (cat_type);
01242                 return (lfc_guid_exists (guid, errbuf, errbufsz));
01243         } else {
01244                 free (cat_type);
01245                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01246                 errno = EINVAL;
01247                 return (-1);
01248         }
01249 }
01250 
01251 register_pfn (const char *guid, const char *pfn, char *errbuf, int errbufsz)
01252 {
01253         char *cat_type;
01254         if (get_cat_type (&cat_type) < 0) {
01255                 return (-1);
01256         }
01257         if (strcmp (cat_type, "edg") == 0) {
01258                 free (cat_type);
01259                 return (lrc_register_pfn (guid, pfn, errbuf, errbufsz));
01260         } else if (strcmp (cat_type, "lfc") == 0) {
01261                 free (cat_type);
01262                 return (lfc_register_pfn (guid, pfn, errbuf, errbufsz));
01263         } else {
01264                 free (cat_type);
01265                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01266                 errno = EINVAL;
01267                 return (-1);
01268         }
01269 }
01270 
01271 setfilesize (const char *pfn, GFAL_LONG64 filesize, char *errbuf, int errbufsz)
01272 {
01273         char *cat_type;
01274         if (get_cat_type (&cat_type) < 0) {
01275                 return (-1);
01276         }
01277         if (strcmp (cat_type, "edg") == 0) {
01278                 free (cat_type);
01279                 return (lrc_setfilesize (pfn, filesize, errbuf, errbufsz));
01280         } else if (strcmp (cat_type, "lfc") == 0) {
01281                 free (cat_type);
01282                 gfal_errmsg(errbuf, errbufsz, "The LFC catalog doesn't support the setfilesize() method.");
01283                 errno = EINVAL;
01284         } else {
01285                 free (cat_type);
01286                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01287                 errno = EINVAL;
01288                 return (-1);
01289         }
01290 }
01291 
01292 char *
01293 surlfromguid (const char *guid, char *errbuf, int errbufsz)
01294 {
01295         char *cat_type;
01296         if (get_cat_type (&cat_type) < 0) {
01297                 return (NULL);
01298         }
01299         if (strcmp (cat_type, "edg") == 0) {
01300                 free (cat_type);
01301                 return (lrc_surlfromguid (guid, errbuf, errbufsz));
01302         } else if (strcmp (cat_type, "lfc") == 0) {
01303                 free (cat_type);
01304                 return (lfc_surlfromguid (guid, errbuf, errbufsz));
01305         } else {
01306                 free (cat_type);
01307                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01308                 errno = EINVAL;
01309                 return (NULL);
01310         }
01311 }
01312 
01313 char **
01314 surlsfromguid (const char *guid, char *errbuf, int errbufsz)
01315 {
01316         char *cat_type;
01317         if (get_cat_type (&cat_type) < 0) {
01318                 return (NULL);
01319         }
01320         if (strcmp (cat_type, "edg") == 0) {
01321                 free (cat_type);
01322                 return (lrc_surlsfromguid (guid, errbuf, errbufsz));
01323         } else if (strcmp (cat_type, "lfc") == 0) {
01324                 free (cat_type);
01325                 return (lfc_surlsfromguid (guid, errbuf, errbufsz));
01326         } else {
01327                 free (cat_type);
01328                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01329                 errno = EINVAL;
01330                 return (NULL);
01331         }
01332 }
01333 
01334 unregister_pfn (const char *guid, const char *pfn, char *errbuf, int errbufsz)
01335 {
01336         char *cat_type;
01337         if (get_cat_type (&cat_type) < 0) {
01338                 return (-1);
01339         }
01340         if (strcmp (cat_type, "edg") == 0) {
01341                 free (cat_type);
01342                 return (lrc_unregister_pfn (guid, pfn, errbuf, errbufsz));
01343         } else if (strcmp (cat_type, "lfc") == 0) {
01344                 free (cat_type);
01345                 return (lfc_unregister_pfn (guid, pfn, errbuf, errbufsz));
01346         } else {
01347                 free (cat_type);
01348                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01349                 errno = EINVAL;
01350                 return (-1);
01351         }
01352 }
01353 
01354 char *
01355 guidfromlfn (const char *lfn, char *errbuf, int errbufsz)
01356 {
01357         char *cat_type;
01358         if (get_cat_type (&cat_type) < 0) {
01359                 return (NULL);
01360         }
01361         if (strcmp (cat_type, "edg") == 0) {
01362                 free (cat_type);
01363                 return (rmc_guidfromlfn (lfn, errbuf, errbufsz));
01364         } else if (strcmp (cat_type, "lfc") == 0) {
01365                 free (cat_type);
01366                 return (lfc_guidfromlfn (lfn, errbuf, errbufsz));
01367         } else {
01368                 free (cat_type);
01369                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01370                 errno = EINVAL;
01371                 return (NULL);
01372         }
01373 }
01374 
01375 char **
01376 lfnsforguid (const char *guid, char *errbuf, int errbufsz)
01377 {
01378         char *cat_type;
01379         if (get_cat_type (&cat_type) < 0) {
01380                 return (NULL);
01381         }
01382         if (strcmp (cat_type, "edg") == 0) {
01383                 free (cat_type);
01384                 return (rmc_lfnsforguid (guid, errbuf, errbufsz));
01385         } else if (strcmp (cat_type, "lfc") == 0) {
01386                 free (cat_type);
01387                 return (lfc_lfnsforguid (guid, errbuf, errbufsz));
01388         } else {
01389                 free (cat_type);
01390                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01391                 errno = EINVAL;
01392                 return (NULL);
01393         }
01394 }
01395 
01396 int
01397 replica_exists(const char* guid, char *errbuf, int errbufsz) 
01398 {
01399         char *cat_type;
01400         if (get_cat_type (&cat_type) < 0) {
01401                 return (-1);
01402         }
01403         if (strcmp (cat_type, "edg") == 0) {
01404                 free (cat_type);
01405                 return (lrc_replica_exists (guid, errbuf, errbufsz));
01406         } else if (strcmp (cat_type, "lfc") == 0) {
01407                 free (cat_type);
01408                 return (lfc_replica_exists (guid, errbuf, errbufsz));
01409         } else {
01410                 free (cat_type);
01411                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01412                 errno = EINVAL;
01413                 return (-1);
01414         }
01415 }
01416 
01417 create_alias (const char *guid, const char *lfn, GFAL_LONG64 size, char *errbuf,
01418         int errbufsz)
01419 {
01420         char *cat_type;
01421         if (get_cat_type (&cat_type) < 0) {
01422                 return (-1);
01423         }
01424         if (strcmp (cat_type, "edg") == 0) {
01425                 free (cat_type);
01426                 return (rmc_register_alias (guid, lfn, errbuf, errbufsz));
01427         } else if (strcmp (cat_type, "lfc") == 0) {
01428                 free (cat_type);
01429                 return (lfc_create_alias (guid, lfn, size, errbuf, errbufsz));
01430         } else {
01431                 free (cat_type);
01432                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01433                 errno = EINVAL;
01434                 return (-1);
01435         }
01436 }
01437 
01438 register_alias (const char *guid, const char *lfn, char *errbuf, int errbufsz)
01439 {
01440         char *cat_type;
01441         if (get_cat_type (&cat_type) < 0) {
01442                 return (-1);
01443         }
01444         if (strcmp (cat_type, "edg") == 0) {
01445                 free (cat_type);
01446                 return (rmc_register_alias (guid, lfn, errbuf, errbufsz));
01447         } else if (strcmp (cat_type, "lfc") == 0) {
01448                 free (cat_type);
01449                 return (lfc_register_alias (guid, lfn, errbuf, errbufsz));
01450         } else {
01451                 free (cat_type);
01452                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01453                 errno = EINVAL;
01454                 return (-1);
01455         }
01456 }
01457 
01458 unregister_alias (const char *guid, const char *lfn, char *errbuf, int errbufsz)
01459 {
01460         char *cat_type;
01461         if (get_cat_type (&cat_type) < 0) {
01462                 return (-1);
01463         }
01464         if (strcmp (cat_type, "edg") == 0) {
01465                 free (cat_type);
01466                 return (rmc_unregister_alias (guid, lfn, errbuf, errbufsz));
01467         } else if (strcmp (cat_type, "lfc") == 0) {
01468                 free (cat_type);
01469                 return (lfc_unregister_alias (guid, lfn, errbuf, errbufsz));
01470         } else {
01471                 free (cat_type);
01472                 gfal_errmsg(errbuf, errbufsz, "The catalog type is neither 'edg' nor 'lfc'.");
01473                 errno = EINVAL;
01474                 return (-1);
01475         }
01476 }
01477 
01478 int
01479 getdomainnm (char *name, int namelen)
01480 {
01481   FILE *fd;
01482   char line[300];
01483   char *p, *q;
01484   
01485   if ((fd = fopen ("/etc/resolv.conf", "r")) != NULL) {
01486     while (fgets (line, sizeof(line), fd) != NULL) {
01487       if (strncmp (line, "domain", 6) == 0 ||
01488           strncmp (line, "search", 6) == 0) {
01489         p = line + 6;
01490         while (*p == ' ' || *p == '\t')
01491           p++;
01492         if (*p == '\0' || *p == '\n')
01493           continue;
01494         fclose (fd);
01495         q = p + strlen (p) - 1;
01496         if (*q == '\n')
01497           *q = '\0';
01498         q = p;
01499         while (*q != '\0' && *q != ' ' && *q != '\t')
01500           q++;
01501         if (*q)
01502           *q = '\0';
01503         if (strlen (p) > namelen) {
01504           return (-1);
01505         }
01506         strcpy (name, p);
01507         return (0);
01508       }
01509     }
01510     fclose (fd);
01511   }
01512   return (-1);
01513 }
01514 
01515 char *
01516 getbestfile(char **surls, int size, char *errbuf, int errbufsz)
01517 {
01518   char dname[64];
01519   int first;
01520   int i;
01521   char  *p1, *p2;
01522   char *p;
01523   int ret;
01524   char *default_se;
01525   int  localsurl, default_match;
01526 
01527   /* skip entries not in the form srm: or sfn:
01528    * take entry on same domain if it exists else
01529    * take the first supported entry
01530    */
01531   first = -1;
01532   localsurl = -1;
01533   *dname = '\0';
01534   (void) getdomainnm (dname, sizeof(dname));
01535 
01536   /* and get the default SE, it there is one */
01537   if((default_se = get_default_se(NULL, errbuf, errbufsz)) == NULL) 
01538           return (NULL);
01539 
01540   for (i = 0; i < size; i++) {
01541     p = surls[i];
01542     if (strncmp (p, "srm://", 6) && strncmp (p, "sfn://", 6))
01543       continue;
01544     if ((p1 = strchr (p + 6, '/')) == NULL) continue;
01545     *p1 = '\0';
01546     if ((p2 = strchr (p + 6, ':')))
01547       *p2 = '\0';
01548     if (first < 0) first = i;
01549     default_match = -1;
01550     if(default_se != NULL) {
01551       default_match = strcmp(p + 6, default_se);
01552     }
01553     if ((p = strchr (p + 6, '.')) == NULL) continue;
01554     ret = strcmp (p + 1, dname);
01555     *p1 = '/';
01556     if (p2) *p2 = ':';
01557     if (default_match == 0) break; /* default se match => replica on default SE */
01558     if (ret == 0) localsurl = i;        /* domains match ==> local replica */
01559   }
01560   if (i == size) {      /* no default SE entry */
01561     if (first < 0) {    /* only non suported entries */
01562       gfal_errmsg(errbuf, errbufsz, "Only non supported entries. No replica entry starting with \"srm://\" or \"sfn://\".");
01563       errno = EINVAL;
01564       return (NULL);
01565     } else if(localsurl >= 0) {
01566       i = localsurl;
01567     } else {
01568       /* seed with current time */
01569       srand( (unsigned)time( NULL ) );
01570       i = (int)((double)size * rand()/(RAND_MAX));
01571     }
01572   }
01573   return surls[i];
01574 }
01575 
01576 
01577 char *
01578 get_default_se(char *vo, char *errbuf, int errbufsz) 
01579 {
01580         char *default_se;
01581         int i;
01582         char se_env[64];
01583         char *vo_env;
01584         char error_str[128];
01585 
01586         if(vo == NULL) {
01587                 if ((vo_env = getenv ("LCG_GFAL_VO")) == NULL) {
01588                         gfal_errmsg (errbuf, errbufsz, "LCG_GFAL_VO not set");
01589                         errno = EINVAL;
01590                         return (NULL);
01591                 }
01592                 vo = vo_env;
01593         }
01594         if(strlen(vo) + 15 >= 64) {
01595                 errno = ENAMETOOLONG;
01596                 gfal_errmsg(errbuf, errbufsz, "VO Name too long");
01597                 return (NULL);
01598         }
01599         sprintf(se_env, "VO_%s_DEFAULT_SE", vo);
01600         for(i = 3; i < 3 + strlen(vo); ++i) {
01601                 if (se_env[i] == '.' || se_env[i] == '-') 
01602                         se_env[i] = '_';
01603                 else
01604                         se_env[i] = toupper(se_env[i]);
01605         } 
01606         default_se = getenv(se_env);
01607         if(default_se == NULL) {
01608                 snprintf(error_str, 128, "No Default SE: %s not set", se_env);
01609                 gfal_errmsg(errbuf, errbufsz, error_str);
01610                 errno = EINVAL;
01611                 return (NULL);
01612         }
01613         return default_se;
01614 }

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