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

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2003-2004 by CERN
00003  */
00004 
00005 /*
00006  * @(#)$RCSfile: checkprotolib.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 <dirent.h>
00012 #include <dlfcn.h>
00013 #include <fcntl.h>
00014 #include <sys/stat.h>
00015 #include <stdio.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 #if GFAL_ENABLE_DCAP
00024 #include "dcap.h"
00025 #endif
00026 #if GFAL_ENABLE_RFIO
00027 #include "rfio_api.h"
00028 #include "serrno.h"
00029 #endif
00030 #include "gfal.h"
00031 
00032 #if GFAL_ENABLE_DCAP
00033 off_t
00034 dc_lseek32 (int fildes, off_t offset, int whence)
00035 {
00036         off64_t off64in;
00037         off64_t off64out;
00038         struct proto_ops *pops;
00039 
00040         if ((pops = find_pops ("dcap")) == NULL)
00041                 return (-1);
00042         off64in = offset;
00043         off64out = pops->lseek64 (fildes, off64in, whence);
00044         if (off64out > (off64_t)2147483647 ) {
00045                 errno = EFBIG;
00046                 return (-1);
00047         }
00048         return ((off_t) off64out);
00049 }
00050 
00051 off64_t
00052 dc_lseek64 (int fildes, off64_t offset, int whence)
00053 {
00054         off_t off32in;
00055         off_t off32out;
00056         struct proto_ops *pops;
00057 
00058         if (offset > (off64_t)2147483647 ) {
00059                 errno = EFBIG;
00060                 return ((off64_t) -1);
00061         }
00062         if ((pops = find_pops ("dcap")) == NULL)
00063                 return ((off64_t) -1);
00064         off32in = offset;
00065         off32out = pops->lseek (fildes, off32in, whence);
00066         return ((off64_t) off32out);
00067 }
00068 
00069 checkdcaplib (struct proto_ops *pops)
00070 {
00071         void *dlhandle;
00072 
00073         if ((dlhandle = dlopen ("libdcap.so", RTLD_LAZY)) == NULL) {
00074                 pops->libok == -1;
00075                 return (-1);
00076         }
00077         pops->libok = 1;
00078         pops->geterror = (int (*) ()) dlsym (dlhandle, "__dc_errno");
00079         pops->access = (int (*) (const char *, int)) dlsym (dlhandle, "dc_access");
00080         pops->chmod = (int (*) (const char *, mode_t)) dlsym (dlhandle, "dc_chmod");
00081         pops->close = (int (*) (int)) dlsym (dlhandle, "dc_close");
00082         pops->closedir = (int (*) (DIR *)) dlsym (dlhandle, "dc_closedir");
00083         pops->lseek = (off_t (*) (int, off_t, int)) &dc_lseek32;
00084         pops->lseek64 = (off64_t (*) (int, off64_t, int)) dlsym (dlhandle, "dc_lseek");
00085         pops->lstat = (int (*) (const char *, struct stat *)) dlsym (dlhandle, "dc_lstat");
00086         pops->lstat64 = (int (*) (const char *, struct stat64 *)) dlsym (dlhandle, "dc_lstat64");
00087         pops->mkdir = (int (*) (const char *, mode_t)) dlsym (dlhandle, "dc_mkdir");
00088         pops->open = (int (*) (const char *, int, ...)) dlsym (dlhandle, "dc_open");
00089         pops->opendir = (DIR * (*) (const char *)) dlsym (dlhandle, "dc_opendir");
00090         pops->read = (ssize_t (*) (int, void *, size_t)) dlsym (dlhandle, "dc_read");
00091         pops->readdir = (struct dirent * (*) (DIR *)) dlsym (dlhandle, "dc_readdir");
00092         pops->readdir64 = (struct dirent64 * (*) (DIR *)) dlsym (dlhandle, "dc_readdir64");
00093         pops->rename = (int (*) (const char *, const char *)) &rename;
00094         pops->rmdir = (int (*) (const char *)) dlsym (dlhandle, "dc_rmdir");
00095         pops->setfilchg = (ssize_t (*) (int, const void *, size_t)) &dummysetfilchg;
00096         pops->stat = (int (*) (const char *, struct stat *)) dlsym (dlhandle, "dc_stat");
00097         pops->stat64 = (int (*) (const char *, struct stat64 *)) dlsym (dlhandle, "dc_stat64");
00098         pops->unlink = (int (*) (const char *)) dlsym (dlhandle, "dc_unlink");
00099         pops->write = (ssize_t (*) (int, const void *, size_t)) dlsym (dlhandle, "dc_write");
00100         return (0);
00101 }
00102 
00103 mapdcaperror (struct proto_ops *pops, int ioflag)
00104 {
00105         int *errp;
00106 
00107         if (! ioflag)
00108                 return (errno);
00109         errp = (int *) pops->geterror();
00110         switch (*errp) {
00111         case DEAD:
00112                 return (EACCES);
00113         case DENE:
00114                 return (ENOENT);
00115         case DEEVAL:
00116         case DEFLAGS:
00117                 return (EINVAL);
00118         case DEMALLOC:
00119                 return (ENOMEM);
00120         default:
00121                 return (ECOMM);
00122         }
00123 }
00124 #endif
00125 
00126 #if GFAL_ENABLE_RFIO
00127 checkrfiolib (struct proto_ops *pops)
00128 {
00129         void *dlhandle;
00130         char *p;
00131 
00132         p = getenv ("LCG_RFIO_TYPE");
00133         if (p && strcmp (p, "dpm") == 0) {
00134                 if ((dlhandle = dlopen ("libdpm.so", RTLD_LAZY)) == NULL) {
00135                         pops->libok == -1;
00136                         return (-1);
00137                 }
00138         } else if (p && strcmp (p, "castor") == 0) {
00139                 if ((dlhandle = dlopen ("libshift.so", RTLD_LAZY)) == NULL) {
00140                         pops->libok == -1;
00141                         return (-1);
00142                 }
00143         } else if ((dlhandle = dlopen ("libshift.so", RTLD_LAZY)) == NULL &&
00144             (dlhandle = dlopen ("libdpm.so", RTLD_LAZY)) == NULL) {
00145                 pops->libok == -1;
00146                 return (-1);
00147         }
00148         pops->libok = 1;
00149         pops->geterror = (int (*) ()) dlsym (dlhandle, "rfio_serrno");
00150         pops->access = (int (*) (const char *, int)) dlsym (dlhandle, "rfio_access");
00151         pops->chmod = (int (*) (const char *, mode_t)) dlsym (dlhandle, "rfio_chmod");
00152         pops->close = (int (*) (int)) dlsym (dlhandle, "rfio_close");
00153         pops->closedir = (int (*) (DIR *)) dlsym (dlhandle, "rfio_closedir");
00154         pops->lseek = (off_t (*) (int, off_t, int)) dlsym (dlhandle, "rfio_lseek");
00155         pops->lseek64 = (off64_t (*) (int, off64_t, int)) dlsym (dlhandle, "rfio_lseek64");
00156         pops->lstat = (int (*) (const char *, struct stat *)) dlsym (dlhandle, "rfio_lstat");
00157         pops->lstat64 = (int (*) (const char *, struct stat64 *)) dlsym (dlhandle, "rfio_lstat64");
00158         pops->mkdir = (int (*) (const char *, mode_t)) dlsym (dlhandle, "rfio_mkdir");
00159         pops->open = (int (*) (const char *, int, ...)) dlsym (dlhandle, "rfio_open");
00160         pops->opendir = (DIR * (*) (const char *)) dlsym (dlhandle, "rfio_opendir");
00161         pops->read = (ssize_t (*) (int, void *, size_t)) dlsym (dlhandle, "rfio_read");
00162         pops->readdir = (struct dirent * (*) (DIR *)) dlsym (dlhandle, "rfio_readdir");
00163         pops->readdir64 = (struct dirent64 * (*) (DIR *)) dlsym (dlhandle, "rfio_readdir64");
00164         pops->rename = (int (*) (const char *, const char *)) dlsym (dlhandle, "rfio_rename");
00165         pops->rmdir = (int (*) (const char *)) dlsym (dlhandle, "rfio_rmdir");
00166         pops->setfilchg = (ssize_t (*) (int, const void *, size_t)) dlsym (dlhandle, "rfio_HsmIf_FirstWrite");
00167         pops->stat = (int (*) (const char *, struct stat *)) dlsym (dlhandle, "rfio_stat");
00168         pops->stat64 = (int (*) (const char *, struct stat64 *)) dlsym (dlhandle, "rfio_stat64");
00169         pops->unlink = (int (*) (const char *)) dlsym (dlhandle, "rfio_unlink");
00170         pops->write = (ssize_t (*) (int, const void *, size_t)) dlsym (dlhandle, "rfio_write");
00171         return (0);
00172 }
00173 
00174 maprfioerror (struct proto_ops *pops, int ioflag)
00175 {
00176         int err;
00177 
00178         if ((err = pops->geterror()) < SEBASEOFF)
00179                 return (err);
00180         else
00181                 return (ECOMM);
00182 }
00183 #endif
00184 
00185 static struct proto_ops pops_array[] = {
00186         {
00187                 "file",
00188                 1,
00189                 NULL,
00190                 NULL,
00191                 &mapposixerror,
00192                 &access,
00193                 &chmod,
00194                 &close,
00195                 &closedir,
00196                 &lseek,
00197                 &lseek64,
00198                 &lstat,
00199                 &lstat64,
00200                 &mkdir,
00201                 &open,
00202                 &opendir,
00203                 &read,
00204                 &readdir,
00205                 &readdir64,
00206                 &rename,
00207                 &rmdir,
00208                 &dummysetfilchg,
00209                 &stat,
00210                 &stat64,
00211                 &unlink,
00212                 &write
00213         },
00214 
00215 #if GFAL_ENABLE_RFIO
00216         {
00217                 "rfio", 0, &checkrfiolib, NULL, &maprfioerror, NULL, NULL,
00218                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00219                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
00220         },
00221 #endif
00222 
00223 #if GFAL_ENABLE_DCAP
00224         {
00225                 "dcap", 0, &checkdcaplib, NULL, &mapdcaperror, NULL, NULL,
00226                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00227                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
00228         },
00229         {
00230                 "gsidcap", 0, &checkdcaplib, NULL, &mapdcaperror, NULL, NULL,
00231                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00232                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
00233         },
00234         {
00235                 "kdcap", 0, &checkdcaplib, NULL, &mapdcaperror, NULL, NULL,
00236                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00237                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
00238         },
00239 #endif
00240         {
00241                 "", 1, NULL, NULL, NULL, NULL, NULL,
00242                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
00243                 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
00244         }
00245 };
00246 
00247 static ssize_t
00248 dummysetfilchg (int fd, const void *buffer, size_t size)
00249 {
00250         return (0);
00251 }
00252 
00253 struct proto_ops *
00254 find_pops (const char *protocol)
00255 {
00256         struct proto_ops *pops;
00257         struct proto_ops *tmp;
00258 
00259         for (pops = pops_array; *pops->proto_name; pops++) {
00260                 if (strcmp (protocol, pops->proto_name) == 0)
00261                         break;
00262         }
00263         if (*pops->proto_name) {
00264                 if (pops->libok > 0)
00265                         return (pops);
00266                 if (pops->libok == 0 && pops->checkprotolib (pops) == 0) {
00267                         for (tmp = pops_array; *tmp->proto_name; tmp++) {
00268                                 if (tmp != pops &&
00269                                     tmp->checkprotolib == pops->checkprotolib)
00270                                         memcpy (&tmp->libok, &pops->libok,
00271                                             sizeof(struct proto_ops) - sizeof(char *));
00272                         }
00273                         return (pops);
00274                 }
00275         }
00276         errno = EPROTONOSUPPORT;
00277         return (NULL);
00278 }
00279 
00280 static int
00281 fnotsup ()
00282 {
00283         errno = ENOTSUP;
00284         return (-1);
00285 }
00286 
00287 char **
00288 get_sup_proto ()
00289 {
00290         int i = 0;
00291         struct proto_ops *pops;
00292         static char *supported_protocols[sizeof(pops_array)/sizeof(struct proto_ops)];
00293         struct proto_ops *tmp;
00294 
00295         for (pops = pops_array;; pops++) {
00296                 if (pops->libok < 0) continue;          /* library not accessible */
00297                 if (pops->libok == 0) {
00298                         if (pops->checkprotolib (pops))
00299                                 continue;
00300                         for (tmp = pops_array; *tmp->proto_name; tmp++) {
00301                                 if (tmp != pops &&
00302                                     tmp->checkprotolib == pops->checkprotolib)
00303                                         memcpy (&tmp->libok, &pops->libok,
00304                                             sizeof(struct proto_ops) - sizeof(char *));
00305                         }
00306                 }
00307                 supported_protocols[i++] = pops->proto_name;
00308                 if (*pops->proto_name == '\0') break;
00309         }
00310         return (supported_protocols);
00311 }
00312 
00313 mapposixerror (struct proto_ops *pops, int ioflag)
00314 {
00315         return (errno);
00316 }

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