Back to index

im-sdk  12.3.91
fop.c
Go to the documentation of this file.
00001 /*
00002  * fop.c: iml file operation - interface
00003  */
00004 
00005 #include <fcntl.h>
00006 #include <stdarg.h>
00007 #include <stdlib.h>
00008 #include <string.h>
00009 #include <limits.h>
00010 #include <stdio.h>
00011 #include <sys/types.h>
00012 #include <errno.h>
00013 
00014 #include <SunIM.h>
00015 #include "iml_fop.h"
00016 #include "fop.h"
00017 
00018 #define URI(uri, p)  ((NULL != (uri)) ? ((uri)->path) : (p))
00019 
00020 typedef enum {
00021        FOP__FOPC_CREATE = 0,
00022        FOP__FOPC_FREE,
00023 
00024        FOP_CLOSE,
00025        FOP_CREAT,
00026        FOP_FTRUNCATE,
00027        FOP_LSEEK,
00028        FOP_OPEN,
00029        FOP_READ,
00030        FOP_TRUNCATE,
00031        FOP_WRITE,
00032 
00033        FOP_LINK,
00034        FOP_READLINK,
00035        FOP_RENAME,
00036        FOP_SYMLINK,
00037        FOP_UNLINK,
00038 
00039        FOP_CHMOD,
00040        FOP_CHOWN,
00041        FOP_FCHMOD,
00042        FOP_FCHOWN,
00043 #if defined(fop_not_supported)
00044        FOP_LCHOWN,
00045 #endif /* fop_not_supported */
00046 
00047        FOP_UTIME,
00048        FOP_UTIMES,
00049 
00050        FOP_FSTAT,
00051        FOP_LSTAT,
00052        FOP_STAT,
00053        FOP_ACCESS,
00054 
00055        FOP_CLOSEDIR,
00056        FOP_OPENDIR,
00057        FOP_READDIR,
00058        FOP_REWINDDIR,
00059        FOP_SEEKDIR,
00060        FOP_TELLDIR,
00061 
00062        FOP_MKDIR,
00063        FOP_RMDIR,
00064 
00065        FOP_FCNTL,
00066 
00067 #if defined(fop_not_defined)
00068        FOP_READV,
00069        FOP_WRITEV,
00070 
00071        FOP_PATHCONF,
00072        FOP_FPATHCONF,
00073 #endif /* fop_not_defined */
00074 
00075        FOP_FUNC_LAST        /* last element */
00076 } fop_func_type_t;
00077 
00078 
00079 typedef struct _fop_scheme {
00080     char *                  name;
00081     int                            id;
00082     void **                 function;
00083     struct _fop_scheme *    next;
00084 } fop_scheme_t;
00085 
00086 
00087 typedef struct {
00088     fop_func_type_t  type;
00089     char *           name;
00090     void *           function;
00091 } fop_name_function_t;
00092 
00093 
00094 struct _fop_file {
00095     int                     id;
00096     int                     scheme;       /* scheme */
00097     void *           value; /* scheme specific value */
00098     struct _fop_file *      next;
00099 };
00100 
00101 
00102 struct _fop_uri {
00103     int                     scheme;
00104     char *           path;
00105     mode_t           mode;
00106     struct _fop_uri *       requireuri;
00107     struct _fop_uri *       next;
00108 };
00109 
00110 
00111 typedef struct _fop_vardir_ext {
00112     char *                  le_name;
00113     char *                  var_dir;
00114     struct _fop_vardir_ext *       next;
00115 } fop_vardir_ext_t;
00116 
00117 
00118 static void   fop_scheme_initialize(void);
00119 
00120 static fop_scheme_t *       fop_scheme;
00121 
00122 
00123 static fop_file_t *
00124 fop_file_insert(
00125     fop_file_t *     head,
00126     fop_file_t *     file
00127 )
00128 {
00129     int                     id;
00130     fop_file_t *     cur;
00131     fop_file_t *     prev;
00132 
00133     if (NULL == head) {
00134        file->id = 0;
00135        file->next = NULL;
00136        return file;
00137     }
00138 
00139     id = 0;
00140     prev = NULL;
00141     for (cur = head; NULL != cur; cur = cur->next, id += 1) {
00142        if (id != cur->id) {
00143            file->id = id;
00144            file->next = cur;
00145            if (NULL == prev) {
00146               return file;
00147            } else {
00148               prev->next = file;
00149               return head;
00150            }
00151        }
00152        prev = cur;
00153     }
00154 
00155     file->id = id;
00156     prev->next = file;
00157     file->next = NULL;
00158 
00159     return head;
00160 }
00161 
00162 
00163 static fop_file_t *
00164 fop_file_remove_id(
00165     fop_file_t *     head,
00166     int                     id
00167 )
00168 {
00169     fop_file_t *     cur;
00170     fop_file_t *     prev;
00171 
00172     if (NULL == head) {
00173        return NULL;
00174     }
00175 
00176     prev = NULL;
00177     for (cur = head; NULL != cur; cur = cur->next) {
00178        if (id == cur->id) {
00179            if (NULL == prev) return cur->next;
00180 
00181            prev->next = cur->next;
00182            return head;
00183        }
00184        prev = cur;
00185     }
00186 
00187     return head;
00188 }
00189 
00190 
00191 static fop_file_t *
00192 fop_file_remove_value(
00193     fop_file_t *     head,
00194     void *           value
00195 )
00196 {
00197     fop_file_t *     cur;
00198     fop_file_t *     prev;
00199 
00200     if (NULL == head) {
00201        return NULL;
00202     }
00203 
00204     prev = NULL;
00205     for (cur = head; NULL != cur; cur = cur->next) {
00206        if (value == cur->value) {
00207            if (NULL == prev) return cur->next;
00208 
00209            prev->next = cur->next;
00210            return head;
00211        }
00212        prev = cur;
00213     }
00214 
00215     return head;
00216 }
00217 
00218 
00219 static fop_file_t *
00220 fop_file_search_id(
00221     fop_file_t *     head,
00222     int                     id
00223 )
00224 {
00225     fop_file_t *     cur;
00226 
00227     if (NULL == head) {
00228        return NULL;
00229     }
00230 
00231     for (cur = head; NULL != cur; cur = cur->next) {
00232        if (id == cur->id) return cur;
00233     }
00234 
00235     return NULL;
00236 }
00237 
00238 
00239 static fop_file_t *
00240 fop_file_search_value(
00241     fop_file_t *     head,
00242     void *           value
00243 )
00244 {
00245     fop_file_t *     cur;
00246 
00247     if (NULL == head) {
00248        return NULL;
00249     }
00250 
00251     for (cur = head; NULL != cur; cur = cur->next) {
00252        if (value == cur->value) return cur;
00253     }
00254 
00255     return NULL;
00256 }
00257 
00258 
00259 static fop_uri_t *
00260 fop_uri_simple_new(
00261     int                     scheme,
00262     const char *     path)
00263 {
00264     fop_uri_t *             uri;
00265 
00266     uri = (fop_uri_t *)malloc(sizeof (fop_uri_t));
00267     if (NULL == uri) return NULL;
00268 
00269     uri->scheme = scheme;
00270     uri->path = strdup(path);
00271     uri->mode = 0700;
00272     uri->requireuri = NULL;
00273     uri->next = NULL;
00274 
00275     return uri;
00276 }
00277 
00278 
00279 static void
00280 fop_uri_delete(
00281     fop_uri_t *      uri
00282 )
00283 {
00284     if (NULL == uri) return;
00285 
00286     free(uri->path);
00287     fop_uri_delete(uri->requireuri);
00288     fop_uri_delete(uri->next);
00289 
00290     free(uri);
00291 }
00292 
00293 
00294 static fop_uri_t *
00295 fop_uri_new(
00296     int                     scheme,
00297     const char *     le,
00298     const char *     user,
00299     const char *     path,
00300     const char *     leadingdir,
00301     const char *     var_dir
00302 )
00303 {
00304     fop_uri_t *             uri;
00305     fop_uri_t *             requireuri;
00306     size_t           l;
00307     size_t           length;
00308     char             buf[PATH_MAX];
00309 
00310     if (NULL != leadingdir) {
00311        l = strlen(leadingdir);
00312 
00313        if (0 != strncmp(path, leadingdir, l)) return NULL;
00314 
00315        if (NULL == var_dir) {
00316            snprintf(buf, (sizeof (buf)), "%s/users/%s", le, (path + l));
00317            uri = fop_uri_simple_new(scheme, buf);
00318            if (NULL == uri) return NULL;
00319 
00320            snprintf(buf, (sizeof (buf)), "%s", le);
00321            uri->requireuri = fop_uri_simple_new(scheme, buf);
00322            if (NULL == uri->requireuri) {
00323               fop_uri_delete(uri);
00324               return NULL;
00325            }
00326 
00327            snprintf(buf, (sizeof (buf)), "%s/users", le);
00328            uri->requireuri->next = fop_uri_simple_new(scheme, buf);
00329            if (NULL == uri->requireuri->next) {
00330               fop_uri_delete(uri);
00331               return NULL;
00332            }
00333        } else {
00334            snprintf(buf, (sizeof (buf)),
00335                    "%s/%s/users/%s", var_dir, le, (path + l));
00336            uri = fop_uri_simple_new(scheme, buf);
00337            if (NULL == uri) return NULL;
00338 
00339            snprintf(buf, (sizeof (buf)), "%s/%s", var_dir, le);
00340            uri->requireuri = fop_uri_simple_new(scheme, buf);
00341            if (NULL == uri->requireuri) {
00342               fop_uri_delete(uri);
00343               return NULL;
00344            }
00345 
00346            snprintf(buf, (sizeof (buf)), "%s/%s/users", var_dir, le);
00347            uri->requireuri->next = fop_uri_simple_new(scheme, buf);
00348            if (NULL == uri->requireuri->next) {
00349               fop_uri_delete(uri);
00350               return NULL;
00351            }
00352        }
00353     } else {
00354        if (NULL != user) {
00355            snprintf(buf, (sizeof (buf)),
00356                    "%s/%s/users/%s/%s", var_dir, le, user, path);
00357            uri = fop_uri_simple_new(scheme, buf);
00358            if (NULL == uri) return NULL;
00359 
00360            snprintf(buf, (sizeof (buf)), "%s/%s/users/", var_dir, le);
00361            uri->requireuri = fop_uri_simple_new(scheme, buf);
00362            if (NULL == uri->requireuri) {
00363               fop_uri_delete(uri);
00364               return NULL;
00365            }
00366 
00367            snprintf(buf, (sizeof (buf)), "%s/%s/users/%s", var_dir, le, user);
00368            uri->requireuri->next = fop_uri_simple_new(scheme, buf);
00369            if (NULL == uri->requireuri->next) {
00370               fop_uri_delete(uri);
00371               return NULL;
00372            }
00373        } else {
00374            snprintf(buf, (sizeof (buf)), "%s/%s", le, path);
00375            uri = fop_uri_simple_new(scheme, buf);
00376            if (NULL == uri) return NULL;
00377 
00378            snprintf(buf, (sizeof (buf)), "%s", le);
00379            uri->requireuri = fop_uri_simple_new(scheme, buf);
00380            if (NULL == uri->requireuri) {
00381               fop_uri_delete(uri);
00382               return NULL;
00383            }
00384        }
00385     }
00386 
00387     return uri;
00388 }
00389 
00390 
00391 static fop_uri_t *
00392 fop_uri_requireuri_cache(
00393     fopc_t *         fopc,
00394     int                     scheme,
00395     const char *     path)
00396 {
00397     fop_uri_t *             uri;
00398 
00399     for (uri = fopc->requireuri; NULL != uri; uri = uri->next) {
00400        if ((scheme == uri->scheme) && (0 == strcmp(path, uri->path))) {
00401            return uri;
00402        }
00403     }
00404 
00405     uri = fop_uri_simple_new(scheme, path);
00406     if (NULL != uri) {
00407        uri->next = fopc->requireuri;
00408        fopc->requireuri = uri;
00409     }
00410 
00411     return NULL;
00412 }
00413 
00414 
00415 static fop_vardir_ext_t *
00416 fop_vardir_ext_new(
00417     const char *     var_dir
00418 )
00419 {
00420     fop_vardir_ext_t *             vde_top;
00421     fop_vardir_ext_t *             vde_last;
00422     fop_vardir_ext_t *             vde;
00423     const char *            p;
00424     const char *            p_le;
00425     const char *            p_dir;
00426     size_t                  p_le_len;
00427     size_t                  p_dir_len;
00428 
00429     vde_last = NULL;
00430     p_le = var_dir;
00431 
00432     while ('\0' != *p_le) {
00433        p = strchr(p_le, '=');
00434        if (NULL == p) break;
00435        p_dir = (p + 1);
00436        if ('\0' == *p_dir) break;
00437        if (',' == *p_dir) {
00438            p_le = (p_dir + 1);
00439            continue;
00440        }
00441        p_le_len = (p_dir - p_le - 1);
00442 
00443        p = strchr(p, ',');
00444        if (NULL == p) {
00445            p_dir_len = strlen(p_dir);
00446        } else {
00447            p_dir_len = (p - p_dir);
00448        }
00449 
00450        vde = (fop_vardir_ext_t *)malloc(sizeof (fop_vardir_ext_t));
00451        if (NULL == vde) return NULL;
00452 
00453        vde->le_name = malloc(p_le_len + 1);
00454        vde->var_dir = malloc(p_dir_len + 1);
00455        if ((NULL == vde->le_name) || (NULL == vde->var_dir)) {
00456            free(vde->le_name);
00457            free(vde->var_dir);
00458            free(vde);
00459            return NULL;
00460        }
00461 
00462        strncpy(vde->le_name, p_le, p_le_len);
00463        *(vde->le_name + p_le_len) = '\0';
00464        strncpy(vde->var_dir, p_dir, p_dir_len);
00465        *(vde->var_dir + p_dir_len) = '\0';
00466        vde->next = NULL;
00467 
00468        if (NULL == vde_last) {
00469            vde_top = vde;
00470        } else {
00471            vde_last->next = vde;
00472        }
00473        vde_last = vde;
00474     }
00475 
00476     return vde_top;
00477 }
00478 
00479 
00480 static const char *
00481 fop_vardir_ext_find(
00482     const char *            var_dir_default,
00483     const char *            le_name,
00484     const fop_vardir_ext_t *       var_dir_ext)
00485 {
00486     const fop_vardir_ext_t *       vde;
00487 
00488     for (vde = var_dir_ext; NULL != vde; vde = vde->next) {
00489        if (0 == strcmp(le_name, vde->le_name)) return vde->var_dir;
00490     }
00491 
00492     return var_dir_default;
00493 }
00494 
00495 
00496 static int
00497 fop_path_to_uri(
00498     fopc_t *         fopc,
00499     const char *     path,
00500     fop_uri_t **     uri_ret)
00501 {
00502     fop_uri_t *                    uri;
00503     iml_desktop_t *         desktop;
00504     iml_if                  If;
00505     char                    leadingdir[PATH_MAX];
00506     int                            scheme_client_available;
00507     const char *            p;
00508     static int                     iiimd_desktop;
00509     static char *           var_dir;
00510     static char *           var_lib_dir;
00511     static fop_vardir_ext_t *      var_dir_ext;
00512 
00513     if (NULL == var_lib_dir) {
00514        if (NULL != getenv("IIIMD_OPTION_DESKTOP")) {
00515            iiimd_desktop = 1;
00516        }
00517 
00518        var_dir = getenv("IIIMD_OPTION_VARDIR_EXT");
00519        if (NULL != var_dir) {
00520            var_dir_ext = fop_vardir_ext_new(var_dir);
00521        }
00522 
00523        var_dir = getenv("IIIMD_OPTION_VARDIR");
00524        if (NULL != var_dir) {
00525            var_dir = strdup(var_dir);
00526            if (NULL == var_dir) return -1;
00527        }
00528 
00529        var_lib_dir = "/var/lib/iiim/le";
00530     }
00531 
00532     uri = NULL;
00533 
00534     /*
00535      * 2005-08-23
00536      * "client" scheme is not available now.
00537      * When the scheme becomes available, this variable will be
00538      * removed and sensible testing will be done.
00539      */
00540     scheme_client_available = 0;
00541 
00542     if (0 == strncmp("///", path, 3)) {
00543        /*
00544         * when a path starts with "///", no mapping will be applied
00545         */
00546        return 0;
00547     }
00548 
00549     switch (fopc->type) {
00550     case IML_FOPC_TYPE_LE:
00551        /*
00552         * 2005-08-24
00553         * this IML_FOPC_TYPE_LE case will be removed soon, and
00554         * IML_FOPC_TYPE_LE case below will be enabled.
00555         */
00556     case IML_FOPC_TYPE_DESKTOP:
00557        desktop = (iml_desktop_t *)(fopc->owner);
00558 
00559        if ('/' == *path) {  /* absolute path */
00560            if (1 == iiimd_desktop) {
00561               /* iiimd serves only one user */
00562               snprintf(leadingdir, (sizeof (leadingdir)),
00563                       "%s/%s/users/", var_lib_dir, fopc->le);
00564               p = fop_vardir_ext_find(var_dir, fopc->le, var_dir_ext);
00565               uri = fop_uri_new(0, fopc->le, NULL, path, leadingdir, p);
00566            } else if (0 == scheme_client_available) {
00567               /* iiimd serves multipe users and iiim-fop is not running */
00568            } else {
00569               /* iiimd serves multipe users and iiim-fop is running */
00570               snprintf(leadingdir, (sizeof (leadingdir)),
00571                       "%s/%s/users/", var_lib_dir, fopc->le);
00572               uri = fop_uri_new(1, fopc->le, NULL, path, leadingdir, NULL);
00573            }
00574        } else {      /* relative path */
00575            if (1 == iiimd_desktop) {
00576               /* iiimd serves only one user */
00577               p = fop_vardir_ext_find(var_dir, fopc->le, var_dir_ext);
00578               uri = fop_uri_new(0, fopc->le, NULL, path, NULL, p);
00579            } else if (0 == scheme_client_available) {
00580               /* iiimd serves multipe users and iiim-fop is not running */
00581               uri = fop_uri_new(0, fopc->le, desktop->user_name, path,
00582                               NULL, var_lib_dir);
00583            } else {
00584               /* iiimd serves multipe users and iiim-fop is running */
00585               uri = fop_uri_new(1, fopc->le, NULL, path, NULL, NULL);
00586            }
00587        }
00588        break;
00589 #if 0
00590     case IML_FOPC_TYPE_LE:
00591        /*
00592         * no default mapping
00593         */
00594        If = (iml_if)(fopc->owner);
00595        break;
00596 #endif /* 0 */
00597     default:  /* unknown IML_FOPC_TYPE_ */
00598        return -1;
00599     }
00600 
00601     *uri_ret = uri;
00602 
00603     return ((NULL == uri) ? 0 : uri->scheme);
00604 }
00605 
00606 
00607 static void *
00608 fop_scheme_func(
00609     int                     scheme,
00610     fop_func_type_t  func_type
00611 )
00612 {
00613     fop_scheme_t *   s;
00614 
00615     if (NULL == fop_scheme) fop_scheme_initialize();
00616 
00617     for (s = fop_scheme; NULL != s; s = s->next) {
00618        if (scheme == s->id) return *(s->function + func_type);
00619     }
00620 
00621     return NULL;
00622 }
00623 
00624 
00625 static void *
00626 fop__fopc_create(
00627     const char *     le,
00628     int                     type,
00629     void *           owner
00630 )
00631 {
00632     fopc_t *         fopc;
00633 
00634     fopc = (fopc_t *)malloc(sizeof (fopc_t));
00635     if (NULL == fopc) return NULL;
00636 
00637     fopc->le = strdup(le);
00638     if (NULL == fopc->le) {
00639        free(fopc);
00640        return NULL;
00641     }
00642     fopc->type = type;
00643     fopc->owner = owner;
00644     fopc->requireuri = NULL;
00645     fopc->file = NULL;
00646 
00647     return fopc;
00648 }
00649 
00650 
00651 static void
00652 fop__fopc_free(
00653     void *    fopc
00654 )
00655 {
00656     if (NULL != fopc) free(((fopc_t *)fopc)->le);
00657     fop_uri_delete(((fopc_t *)fopc)->requireuri);
00658     free(fopc);
00659 
00660     return;
00661 }
00662 
00663 
00664 static void
00665 fop_mkdir_required(
00666     void *           fopc,
00667     fop_uri_t *             uri
00668 )
00669 {
00670     fop_uri_t *             req_uri;
00671     fop_uri_t *             u;
00672     fop_mkdir_t             func;
00673 
00674     /*
00675      * no error recovery
00676      */
00677 
00678     for (req_uri = uri->requireuri; NULL != req_uri; req_uri = req_uri->next) {
00679        func = (fop_mkdir_t)fop_scheme_func(req_uri->scheme, FOP_MKDIR);
00680        if (NULL == func) continue;
00681 
00682        u = fop_uri_requireuri_cache(fopc, req_uri->scheme, req_uri->path);
00683        if (NULL != u) continue;
00684 
00685        (void)func(fopc, req_uri->path, req_uri->mode);
00686     }
00687 
00688     return;
00689 }
00690 
00691 
00692 static int
00693 fop_open(
00694     void *           fopc,
00695     const char *     path,
00696     int                     oflag,
00697     ...
00698 )
00699 {
00700     va_list          ap;
00701     int                     scheme;
00702     fop_uri_t *             uri;
00703     mode_t           mode;
00704     fop_open_t              func;
00705     int                     fop_errno;
00706     void *           value;
00707     fop_file_t *     file;
00708 
00709     if (0 != (O_CREAT & oflag)) {
00710        va_start(ap, oflag);
00711        mode = va_arg(ap, mode_t);
00712        va_end(ap);
00713     } else {
00714        mode = 0;
00715     }
00716 
00717     scheme = fop_path_to_uri(fopc, path, &uri);
00718     if (scheme < 0) {
00719        errno = EINVAL;
00720        return -1;
00721     }
00722 
00723     if ((0 != (O_CREAT & oflag)) && (NULL != uri)) {
00724        fop_mkdir_required(fopc, uri);
00725     }
00726 
00727     func = (fop_open_t)fop_scheme_func(scheme, FOP_OPEN);
00728     if (NULL == func) {
00729        fop_uri_delete(uri);
00730        errno = EPERM;
00731        return -1;
00732     }
00733 
00734     file = (fop_file_t *)malloc(sizeof (fop_file_t));
00735     if (NULL == file) {
00736        fop_errno = errno;
00737        fop_uri_delete(uri);
00738        errno = fop_errno;
00739        return -1;
00740     }
00741 
00742     value = func(fopc, URI(uri, path), oflag, mode);
00743     if (NULL == value) {
00744        fop_errno = errno;
00745        fop_uri_delete(uri);
00746        free(file);
00747        errno = fop_errno;
00748         return -1;
00749     }
00750 
00751     file->scheme = scheme;
00752     file->value = value;
00753 
00754     ((fopc_t *)fopc)->file = fop_file_insert(((fopc_t *)fopc)->file, file);
00755 
00756     fop_uri_delete(uri);
00757 
00758     return file->id;
00759 }
00760 
00761 
00762 static int
00763 fop_close(
00764     void *           fopc,
00765     int                     fd
00766 )
00767 {
00768     fop_close_t             func;
00769     int                     rv;
00770     int                     fop_errno;
00771     fop_file_t *     file;
00772 
00773     file = fop_file_search_id(((fopc_t *)fopc)->file, fd);
00774     if (NULL == file) {
00775        errno = EBADF;
00776        return -1;
00777     }
00778 
00779     func = (fop_close_t)fop_scheme_func(file->scheme, FOP_CLOSE);
00780     if (NULL == func) {
00781        errno = EPERM;
00782        return -1;
00783     }
00784 
00785     rv = func(fopc, file->value);
00786 
00787     ((fopc_t *)fopc)->file = fop_file_remove_id(((fopc_t *)fopc)->file, fd);
00788 
00789     fop_errno = errno;
00790     free(file);
00791     errno = fop_errno;
00792 
00793     return rv;
00794 }
00795 
00796 
00797 static int
00798 fop_creat(
00799     void *           fopc,
00800     const char *     path,
00801     mode_t           mode
00802 )
00803 {
00804     return fop_open(fopc, path, (O_WRONLY | O_CREAT | O_TRUNC), mode);
00805 
00806 #if 0
00807     int                     scheme;
00808     fop_uri_t *             uri;
00809     fop_creat_t             func;
00810     int                     fop_errno;
00811     void *           value;
00812     fop_file_t *     file;
00813 
00814     scheme = fop_path_to_uri(fopc, path, &uri);
00815     if (scheme < 0) {
00816        errno = EINVAL;
00817        return -1;
00818     }
00819 
00820     func = (fop_creat_t)fop_scheme_func(scheme, FOP_CREAT);
00821     if (NULL == func) {
00822        fop_uri_delete(uri);
00823        errno = EPERM;
00824        return -1;
00825     }
00826 
00827     file = (fop_file_t *)malloc(sizeof (fop_file_t));
00828     if (NULL == file) {
00829        fop_errno = errno;
00830        fop_uri_delete(uri);
00831        errno = fop_errno;
00832        return -1;
00833     }
00834 
00835     value = func(fopc, URI(uri, path), mode);
00836     if (NULL == value) {
00837        fop_errno = errno;
00838        fop_uri_delete(uri);
00839        free(file);
00840        errno = fop_errno;
00841         return -1;
00842     }
00843 
00844     file->scheme = scheme;
00845     file->value = value;
00846 
00847     ((fopc_t *)fopc)->file = fop_file_insert(((fopc_t *)fopc)->file, file);
00848 
00849     fop_uri_delete(uri);
00850 
00851     return file->id;
00852 #endif /* 0 */
00853 }
00854 
00855 
00856 static ssize_t
00857 fop_read(
00858     void *           fopc,
00859     int                     fildes,
00860     void *           buf,
00861     size_t           nbyte
00862 )
00863 {
00864     fop_read_t              func;
00865     fop_file_t *     file;
00866 
00867     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
00868     if (NULL == file) {
00869        errno = EBADF;
00870        return -1;
00871     }
00872 
00873     func = (fop_read_t)fop_scheme_func(file->scheme, FOP_READ);
00874     if (NULL == func) {
00875        errno = EPERM;
00876        return -1;
00877     }
00878 
00879     return func(fopc, file->value, buf, nbyte);
00880 }
00881 
00882 
00883 #if defined(fop_not_defined)
00884 static ssize_t
00885 fop_readv(
00886     void *                  fopc,
00887     int                            fildes,
00888     const struct iovec *    iov,
00889     int                            iovcnt
00890 )
00891 {
00892     fop_readv_t             func;
00893     fop_file_t *     file;
00894 
00895     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
00896     if (NULL == file) {
00897        errno = EBADF;
00898        return -1;
00899     }
00900 
00901     func = (fop_readv_t)fop_scheme_func(file->scheme, FOP_READV);
00902     if (NULL == func) {
00903        errno = EPERM;
00904        return -1;
00905     }
00906 
00907     return func(fopc, file->value, iov, iovcnt);
00908 }
00909 #endif /* fop_not_defined */
00910 
00911 
00912 static ssize_t
00913 fop_write(
00914     void *           fopc,
00915     int                     fildes,
00916     const void *     buf,
00917     size_t           nbyte
00918 )
00919 {
00920     fop_write_t             func;
00921     fop_file_t *     file;
00922 
00923     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
00924     if (NULL == file) {
00925        errno = EBADF;
00926        return -1;
00927     }
00928 
00929     func = (fop_write_t)fop_scheme_func(file->scheme, FOP_WRITE);
00930     if (NULL == func) {
00931        errno = EPERM;
00932        return -1;
00933     }
00934 
00935     return func(fopc, file->value, buf, nbyte);
00936 }
00937 
00938 
00939 #if defined(fop_not_defined)
00940 static ssize_t
00941 fop_writev(
00942     void *                  fopc,
00943     int                            fildes,
00944     const struct iovec *    iov,
00945     int                            iovcnt
00946 )
00947 {
00948     fop_writev_t     func;
00949     fop_file_t *     file;
00950 
00951     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
00952     if (NULL == file) {
00953        errno = EBADF;
00954        return -1;
00955     }
00956 
00957     func = (fop_writev_t)fop_scheme_func(file->scheme, FOP_WRITEV);
00958     if (NULL == func) {
00959        errno = EPERM;
00960        return -1;
00961     }
00962 
00963     return func(fopc, file->value, iov, iovcnt);
00964 }
00965 #endif /* fop_not_defined */
00966 
00967 
00968 static off_t
00969 fop_lseek(
00970     void *           fopc,
00971     int                     fildes,
00972     off_t            offset,
00973     int                     whence
00974 )
00975 {
00976     fop_lseek_t             func;
00977     fop_file_t *     file;
00978 
00979     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
00980     if (NULL == file) {
00981        errno = EBADF;
00982        return -1;
00983     }
00984 
00985     func = (fop_lseek_t)fop_scheme_func(file->scheme, FOP_LSEEK);
00986     if (NULL == func) {
00987        errno = EPERM;
00988        return -1;
00989     }
00990 
00991     return func(fopc, file->value, offset, whence);
00992 }
00993 
00994 
00995 static int
00996 fop_stat(
00997     void *           fopc,
00998     const char *     path,
00999     struct stat *    buf
01000 )
01001 {
01002     int                     scheme;
01003     fop_uri_t *             uri;
01004     fop_stat_t              func;
01005     int                     rv;
01006     int                     fop_errno;
01007 
01008     scheme = fop_path_to_uri(fopc, path, &uri);
01009     if (scheme < 0) {
01010        errno = EINVAL;
01011        return -1;
01012     }
01013 
01014     func = (fop_stat_t)fop_scheme_func(scheme, FOP_STAT);
01015     if (NULL == func) {
01016        fop_uri_delete(uri);
01017        errno = EPERM;
01018        return -1;
01019     }
01020 
01021     rv = func(fopc, URI(uri, path), buf);
01022     if (NULL != uri) {
01023        fop_errno = errno;
01024        fop_uri_delete(uri);
01025        errno = fop_errno;
01026     }
01027 
01028     return rv;
01029 }
01030 
01031 
01032 static int
01033 fop_lstat(
01034     void *           fopc,
01035     const char *     path,
01036     struct stat *    buf
01037 )
01038 {
01039     int                     scheme;
01040     fop_uri_t *             uri;
01041     fop_lstat_t             func;
01042     int                     rv;
01043     int                     fop_errno;
01044 
01045     scheme = fop_path_to_uri(fopc, path, &uri);
01046     if (scheme < 0) {
01047        errno = EINVAL;
01048        return -1;
01049     }
01050 
01051     func = (fop_lstat_t)fop_scheme_func(scheme, FOP_LSTAT);
01052     if (NULL == func) {
01053        fop_uri_delete(uri);
01054        errno = EPERM;
01055        return -1;
01056     }
01057 
01058     rv = func(fopc, URI(uri, path), buf);
01059     if (NULL != uri) {
01060        fop_errno = errno;
01061        fop_uri_delete(uri);
01062        errno = fop_errno;
01063     }
01064 
01065     return rv;
01066 }
01067 
01068 
01069 static int
01070 fop_fstat(
01071     void *           fopc,
01072     int                     fildes,
01073     struct stat *    buf
01074 )
01075 {
01076     fop_fstat_t             func;
01077     fop_file_t *     file;
01078 
01079     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
01080     if (NULL == file) {
01081        errno = EBADF;
01082        return -1;
01083     }
01084 
01085     func = (fop_fstat_t)fop_scheme_func(file->scheme, FOP_FSTAT);
01086     if (NULL == func) {
01087        errno = EPERM;
01088        return -1;
01089     }
01090 
01091     return func(fopc, file->value, buf);
01092 }
01093 
01094 
01095 static int
01096 fop_symlink(
01097     void *           fopc,
01098     const char *     name1,
01099     const char *     name2
01100 )
01101 {
01102     int                     scheme1;
01103     int                     scheme2;
01104     fop_uri_t *             uri1;
01105     fop_uri_t *             uri2;
01106     fop_symlink_t    func;
01107     int                     rv;
01108     int                     fop_errno;
01109 
01110     scheme1 = fop_path_to_uri(fopc, name1, &uri1);
01111     if (scheme1 < 0) {
01112        errno = EPERM;
01113        return -1;
01114     }
01115 
01116     scheme2 = fop_path_to_uri(fopc, name2, &uri2);
01117     if (scheme2 < 0) {
01118        fop_uri_delete(uri1);
01119        errno = EPERM;
01120        return -1;
01121     }
01122 
01123     if (scheme1 != scheme2) {
01124        fop_uri_delete(uri1);
01125        fop_uri_delete(uri2);
01126        errno = EPERM;
01127        return -1;
01128     }
01129 
01130     func = (fop_symlink_t)fop_scheme_func(scheme1, FOP_SYMLINK);
01131     if (NULL == func) {
01132        fop_uri_delete(uri1);
01133        fop_uri_delete(uri2);
01134        errno = EPERM;
01135        return -1;
01136     }
01137 
01138     if (NULL != uri2) fop_mkdir_required(fopc, uri2);
01139 
01140     rv = func(fopc, URI(uri1, name1), URI(uri2, name2));
01141     fop_errno = errno;
01142     fop_uri_delete(uri1);
01143     fop_uri_delete(uri2);
01144     errno = fop_errno;
01145 
01146     return rv;
01147 }
01148 
01149 
01150 static int
01151 fop_readlink(
01152     void *           fopc,
01153     const char *     path,
01154     char *           buf,
01155     size_t           bufsiz
01156 )
01157 {
01158     int                     scheme;
01159     fop_uri_t *             uri;
01160     fop_readlink_t   func;
01161     int                     rv;
01162     int                     fop_errno;
01163 
01164     scheme = fop_path_to_uri(fopc, path, &uri);
01165     if (scheme < 0) {
01166        errno = EINVAL;
01167        return -1;
01168     }
01169 
01170     func = (fop_readlink_t)fop_scheme_func(scheme, FOP_READLINK);
01171     if (NULL == func) {
01172        fop_uri_delete(uri);
01173        errno = EPERM;
01174        return -1;
01175     }
01176 
01177     rv = func(fopc, URI(uri, path), buf, bufsiz);
01178     fop_errno = errno;
01179     fop_uri_delete(uri);
01180     errno = fop_errno;
01181 
01182     return rv;
01183 }
01184 
01185 
01186 static int
01187 fop_link(
01188     void *           fopc,
01189     const char *     existing,
01190     const char *     new
01191 )
01192 {
01193     int                     scheme1;
01194     int                     scheme2;
01195     fop_uri_t *             uri1;
01196     fop_uri_t *             uri2;
01197     fop_link_t              func;
01198     int                     rv;
01199     int                     fop_errno;
01200 
01201     scheme1 = fop_path_to_uri(fopc, existing, &uri1);
01202     if (scheme1 < 0) {
01203        errno = EINVAL;
01204        return -1;
01205     }
01206 
01207     scheme2 = fop_path_to_uri(fopc, new, &uri2);
01208     if (scheme2 < 0) {
01209        fop_uri_delete(uri1);
01210        errno = EINVAL;
01211        return -1;
01212     }
01213 
01214     if (scheme1 != scheme2) {
01215        fop_uri_delete(uri1);
01216        fop_uri_delete(uri2);
01217        errno = EPERM;
01218        return -1;
01219     }
01220 
01221     func = (fop_link_t)fop_scheme_func(scheme1, FOP_LINK);
01222     if (NULL == func) {
01223        fop_uri_delete(uri1);
01224        fop_uri_delete(uri2);
01225        errno = EPERM;
01226        return -1;
01227     }
01228 
01229     if (NULL != uri2) fop_mkdir_required(fopc, uri2);
01230 
01231     rv = func(fopc, URI(uri1, existing), URI(uri2, new));
01232     fop_errno = errno;
01233     fop_uri_delete(uri1);
01234     fop_uri_delete(uri2);
01235     errno = fop_errno;
01236 
01237     return rv;
01238 }
01239 
01240 
01241 static int
01242 fop_unlink(
01243     void *           fopc,
01244     const char *     path
01245 )
01246 {
01247     int                     scheme;
01248     fop_uri_t *             uri;
01249     fop_unlink_t     func;
01250     int                     rv;
01251     int                     fop_errno;
01252 
01253     scheme = fop_path_to_uri(fopc, path, &uri);
01254     if (scheme < 0) {
01255        errno = EINVAL;
01256        return -1;
01257     }
01258 
01259     func = (fop_unlink_t)fop_scheme_func(scheme, FOP_UNLINK);
01260     if (NULL == func) {
01261        fop_uri_delete(uri);
01262        errno = EPERM;
01263        return -1;
01264     }
01265 
01266     rv = func(fopc, URI(uri, path));
01267     if (NULL != uri) {
01268        fop_errno = errno;
01269        fop_uri_delete(uri);
01270        errno = fop_errno;
01271     }
01272 
01273     return rv;
01274 }
01275 
01276 
01277 static int
01278 fop_rename(
01279     void *           fopc,
01280     const char *     old,
01281     const char *     new
01282 )
01283 {
01284     int                     scheme1;
01285     int                     scheme2;
01286     fop_uri_t *             uri1;
01287     fop_uri_t *             uri2;
01288     fop_rename_t     func;
01289     int                     rv;
01290     int                     fop_errno;
01291 
01292     scheme1 = fop_path_to_uri(fopc, old, &uri1);
01293     if (scheme1 < 0) {
01294        errno = EINVAL;
01295        return -1;
01296     }
01297 
01298     scheme2 = fop_path_to_uri(fopc, new, &uri2);
01299     if (scheme2 < 0) {
01300        fop_uri_delete(uri1);
01301        errno = EINVAL;
01302        return -1;
01303     }
01304 
01305     if (scheme1 != scheme2) {
01306        fop_uri_delete(uri1);
01307        fop_uri_delete(uri2);
01308        errno = EPERM;
01309        return -1;
01310     }
01311 
01312     func = (fop_rename_t)fop_scheme_func(scheme1, FOP_RENAME);
01313     if (NULL == func) {
01314        fop_uri_delete(uri1);
01315        fop_uri_delete(uri2);
01316        errno = EPERM;
01317        return -1;
01318     }
01319 
01320     if (NULL != uri2) fop_mkdir_required(fopc, uri2);
01321 
01322     rv = func(fopc, URI(uri1, old), URI(uri2, new));
01323     if ((NULL != uri1) || (NULL != uri2)) {
01324        fop_errno = errno;
01325        fop_uri_delete(uri1);
01326        fop_uri_delete(uri2);
01327        errno = fop_errno;
01328     }
01329 
01330     return rv;
01331 }
01332 
01333 
01334 static int
01335 fop_fcntl(
01336     void *           fopc,
01337     int                     fildes,
01338     int                     cmd,
01339     ...
01340 )
01341 {
01342     va_list          ap;
01343     fop_fcntl_t             func;
01344     fop_file_t *     file;
01345     int                     arg_int;
01346     struct flock *   arg_flock;
01347 #if defined(F_FREESP64) || defined(F_GETLK64) || \
01348     defined(F_SETLK64) || defined(F_SETLKW64)
01349     struct flock64 * arg_flock64;
01350 #endif /* F_FREESP64 || F_GETLK64 || F_SETLK64 || F_SETLKW64 */
01351     int                     rv;
01352 
01353     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
01354     if (NULL == file) {
01355        errno = EBADF;
01356        return -1;
01357     }
01358 
01359     func = (fop_fcntl_t)fop_scheme_func(file->scheme, FOP_FCNTL);
01360     if (NULL == func) {
01361        errno = EPERM;
01362        return -1;
01363     }
01364 
01365     va_start(ap, cmd);
01366     switch(cmd) {
01367     case F_DUPFD:
01368 #if defined(F_DUP2FD)
01369     case F_DUP2FD:
01370 #endif /* F_DUP2FD */
01371        /* not supported */
01372        errno = EPERM;
01373        rv = -1;
01374        break;
01375     case F_SETFD:
01376     case F_SETFL:
01377     case F_SETOWN:
01378        arg_int = va_arg(ap, int);
01379        rv = func(fopc, file->value, cmd, arg_int);
01380        break;
01381 #if defined(F_FREESP)
01382     case F_FREESP:
01383 #endif /* F_FREESP */
01384     case F_GETLK:
01385     case F_SETLK:
01386     case F_SETLKW:
01387        arg_flock = va_arg(ap, struct flock *);
01388        rv = func(fopc, file->value, cmd, arg_flock);
01389        break;
01390 #if __WORDSIZE != 64 && !defined(__USE_FILE_OFFSET64)
01391        /* When __WORDSIZE is 64 or __USE_FILE_OFFSET64 is defined,
01392           F_*64 has similar number to F_*(non-64) */
01393 #if defined(F_FREESP64)
01394     case F_FREESP64:
01395 #endif /* F_FREESP64 */
01396 #if defined(F_GETLK64)
01397     case F_GETLK64:
01398 #endif /* F_GETLK64 */
01399 #if defined(F_SETLK64)
01400     case F_SETLK64:
01401 #endif /* F_SETLK64 */
01402 #if defined(F_SETLKW64)
01403     case F_SETLKW64:
01404 #endif /* F_SETLKW64 */
01405 
01406 #if defined(F_FREESP64) || defined(F_GETLK64) || defined(F_SETLK64) || defined(F_SETLKW64)
01407        arg_flock64 = va_arg(ap, struct flock64 *);
01408        rv = func(fopc, file->value, cmd, arg_flock64);
01409        break;
01410 #endif /* F_FREESP64 || F_GETLK64 || F_SETLK64 || F_SETLKW64 */
01411 #endif
01412     default:
01413        rv = func(fopc, file->value, cmd, 0);
01414        break;
01415     }
01416     va_end(ap);
01417 
01418     return rv;
01419 }
01420 
01421 
01422 static int
01423 fop_truncate(
01424     void *           fopc,
01425     const char *     path,
01426     off_t            length
01427 )
01428 {
01429     int                     scheme;
01430     fop_uri_t *             uri;
01431     fop_truncate_t   func;
01432     int                     rv;
01433     int                     fop_errno;
01434 
01435     scheme = fop_path_to_uri(fopc, path, &uri);
01436     if (scheme < 0) {
01437        errno = EINVAL;
01438        return -1;
01439     }
01440 
01441     func = (fop_truncate_t)fop_scheme_func(scheme, FOP_TRUNCATE);
01442     if (NULL == func) {
01443        fop_uri_delete(uri);
01444        errno = EPERM;
01445        return -1;
01446     }
01447 
01448     rv = func(fopc, URI(uri, path), length);
01449     if (NULL != uri) {
01450        fop_errno = errno;
01451        fop_uri_delete(uri);
01452        errno = fop_errno;
01453     }
01454 
01455     return rv;
01456 }
01457 
01458 
01459 static int
01460 fop_ftruncate(
01461     void *           fopc,
01462     int                     fildes,
01463     off_t            length
01464 )
01465 {
01466     fop_ftruncate_t  func;
01467     fop_file_t *     file;
01468 
01469     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
01470     if (NULL == file) {
01471        errno = EBADF;
01472        return -1;
01473     }
01474 
01475     func = (fop_ftruncate_t)fop_scheme_func(file->scheme, FOP_FTRUNCATE);
01476     if (NULL == func) {
01477        errno = EPERM;
01478        return -1;
01479     }
01480 
01481     return func(fopc, file->value, length);
01482 }
01483 
01484 
01485 static int
01486 fop_mkdir(
01487     void *           fopc,
01488     const char *     path,
01489     mode_t           mode
01490 )
01491 {
01492     int                     scheme;
01493     fop_uri_t *             uri;
01494     fop_mkdir_t             func;
01495     int                     rv;
01496     int                     fop_errno;
01497 
01498     scheme = fop_path_to_uri(fopc, path, &uri);
01499     if (scheme < 0) {
01500        errno = EINVAL;
01501        return -1;
01502     }
01503 
01504     func = (fop_mkdir_t)fop_scheme_func(scheme, FOP_MKDIR);
01505     if (NULL == func) {
01506        fop_uri_delete(uri);
01507        errno = EPERM;
01508        return -1;
01509     }
01510 
01511     if (NULL != uri) fop_mkdir_required(fopc, uri);
01512 
01513     rv = func(fopc, URI(uri, path), mode);
01514     if (NULL != uri) {
01515        fop_errno = errno;
01516        fop_uri_delete(uri);
01517        errno = fop_errno;
01518     }
01519 
01520     return rv;
01521 }
01522 
01523 
01524 static int
01525 fop_rmdir(
01526     void *           fopc,
01527     const char *     path
01528 )
01529 {
01530     int                     scheme;
01531     fop_uri_t *             uri;
01532     fop_rmdir_t             func;
01533     int                     rv;
01534     int                     fop_errno;
01535 
01536     scheme = fop_path_to_uri(fopc, path, &uri);
01537     if (scheme < 0) {
01538        errno = EINVAL;
01539        return -1;
01540     }
01541 
01542     func = (fop_rmdir_t)fop_scheme_func(scheme, FOP_RMDIR);
01543     if (NULL == func) {
01544        fop_uri_delete(uri);
01545        errno = EPERM;
01546        return -1;
01547     }
01548 
01549     rv = func(fopc, URI(uri, path));
01550     if (NULL != uri) {
01551        fop_errno = errno;
01552        fop_uri_delete(uri);
01553        errno = fop_errno;
01554     }
01555 
01556     return rv;
01557 }
01558 
01559 
01560 static DIR *
01561 fop_opendir(
01562     void *           fopc,
01563     const char *     dirname
01564 )
01565 {
01566     int                     scheme;
01567     fop_uri_t *             uri;
01568     fop_opendir_t    func;
01569     int                     fop_errno;
01570     void *           value;
01571     fop_file_t *     file;
01572 
01573     scheme = fop_path_to_uri(fopc, dirname, &uri);
01574     if (scheme < 0) {
01575        errno = EINVAL;
01576        return NULL;
01577     }
01578 
01579     func = (fop_opendir_t)fop_scheme_func(scheme, FOP_OPENDIR);
01580     if (NULL == func) {
01581        fop_uri_delete(uri);
01582        errno = EPERM;
01583        return NULL;
01584     }
01585 
01586     file = (fop_file_t *)malloc(sizeof (fop_file_t));
01587     if (NULL == file) {
01588        fop_errno = errno;
01589        fop_uri_delete(uri);
01590        errno = fop_errno;
01591        return NULL;
01592     }
01593 
01594     if (NULL != uri) fop_mkdir_required(fopc, uri);
01595 
01596     value = func(fopc, URI(uri, dirname));
01597     if (NULL == value) {
01598        fop_errno = errno;
01599        fop_uri_delete(uri);
01600        free(file);
01601        errno = fop_errno;
01602         return NULL;
01603     }
01604 
01605     file->scheme = scheme;
01606     file->value = value;
01607 
01608     ((fopc_t *)fopc)->file = fop_file_insert(((fopc_t *)fopc)->file, file);
01609 
01610     fop_uri_delete(uri);
01611 
01612     return (DIR *)(file->value);
01613 }
01614 
01615 
01616 static struct dirent *
01617 fop_readdir(
01618     void *           fopc,
01619     DIR *            dirp
01620 )
01621 {
01622     fop_readdir_t    func;
01623     fop_file_t *     file;
01624 
01625     file = fop_file_search_value(((fopc_t *)fopc)->file, (void *)dirp);
01626     if (NULL == file) {
01627        errno = EBADF;
01628        return NULL;
01629     }
01630 
01631     func = (fop_readdir_t)fop_scheme_func(file->scheme, FOP_READDIR);
01632     if (NULL == func) {
01633        errno = EPERM;
01634        return NULL;
01635     }
01636 
01637     return func(fopc, file->value);
01638 }
01639 
01640 
01641 static int
01642 fop_closedir(
01643     void *           fopc,
01644     DIR *            dirp
01645 )
01646 {
01647     fop_closedir_t   func;
01648     fop_file_t *     file;
01649     int                     rv;
01650     int                     fop_errno;
01651 
01652     file = fop_file_search_value(((fopc_t *)fopc)->file, dirp);
01653     if (NULL == file) {
01654        errno = EBADF;
01655        return -1;
01656     }
01657 
01658     func = (fop_closedir_t)fop_scheme_func(file->scheme, FOP_CLOSEDIR);
01659     if (NULL == func) {
01660        errno = EPERM;
01661        return -1;
01662     }
01663 
01664     rv = func(fopc, file->value);
01665 
01666     ((fopc_t *)fopc)->file = fop_file_remove_value(((fopc_t *)fopc)->file, dirp);
01667 
01668     fop_errno = errno;
01669     free(file);
01670     errno = fop_errno;
01671 
01672     return rv;
01673 }
01674 
01675 
01676 static void
01677 fop_rewinddir(
01678     void *           fopc,
01679     DIR *            dirp
01680 )
01681 {
01682     fop_rewinddir_t  func;
01683     fop_file_t *     file;
01684 
01685     file = fop_file_search_value(((fopc_t *)fopc)->file, (void *)dirp);
01686     if (NULL == file) {
01687        errno = EBADF;
01688        return;
01689     }
01690 
01691     func = (fop_rewinddir_t)fop_scheme_func(file->scheme, FOP_REWINDDIR);
01692     if (NULL == func) {
01693        errno = EPERM;
01694        return;
01695     }
01696 
01697     func(fopc, file->value);
01698     return;
01699 }
01700 
01701 
01702 static void
01703 fop_seekdir(
01704     void *           fopc,
01705     DIR *            dirp,
01706     long int         loc
01707 )
01708 {
01709     fop_seekdir_t    func;
01710     fop_file_t *     file;
01711 
01712     file = fop_file_search_value(((fopc_t *)fopc)->file, (void *)dirp);
01713     if (NULL == file) {
01714        errno = EBADF;
01715        return;
01716     }
01717 
01718     func = (fop_seekdir_t)fop_scheme_func(file->scheme, FOP_SEEKDIR);
01719     if (NULL == func) {
01720        errno = EPERM;
01721        return;
01722     }
01723 
01724     func(fopc, file->value, loc);
01725     return;
01726 }
01727 
01728 
01729 static long int
01730 fop_telldir(
01731     void *           fopc,
01732     DIR *            dirp
01733 )
01734 {
01735     fop_telldir_t    func;
01736     fop_file_t *     file;
01737 
01738     file = fop_file_search_value(((fopc_t *)fopc)->file, (void *)dirp);
01739     if (NULL == file) {
01740        errno = EBADF;
01741        return NULL;
01742     }
01743 
01744     func = (fop_telldir_t)fop_scheme_func(file->scheme, FOP_TELLDIR);
01745     if (NULL == func) {
01746        errno = EPERM;
01747        return NULL;
01748     }
01749 
01750     return func(fopc, file->value);
01751 }
01752 
01753 
01754 static int
01755 fop_access(
01756     void *           fopc,
01757     const char *     path,
01758     int                     amode
01759 )
01760 {
01761     int                     scheme;
01762     fop_uri_t *             uri;
01763     fop_access_t     func;
01764     int                     rv;
01765     int                     fop_errno;
01766 
01767     scheme = fop_path_to_uri(fopc, path, &uri);
01768     if (scheme < 0) {
01769        errno = EINVAL;
01770        return -1;
01771     }
01772 
01773     func = (fop_access_t)fop_scheme_func(scheme, FOP_ACCESS);
01774     if (NULL == func) {
01775        fop_uri_delete(uri);
01776        errno = EPERM;
01777        return -1;
01778     }
01779 
01780     rv = func(fopc, URI(uri, path), amode);
01781     if (NULL != uri) {
01782        fop_errno = errno;
01783        fop_uri_delete(uri);
01784        errno = fop_errno;
01785     }
01786 
01787     return rv;
01788 }
01789 
01790 
01791 static int
01792 fop_chmod(
01793     void *           fopc,
01794     const char *     path,
01795     mode_t           mode
01796 )
01797 {
01798     int                     scheme;
01799     fop_uri_t *             uri;
01800     fop_chmod_t             func;
01801     int                     rv;
01802     int                     fop_errno;
01803 
01804     scheme = fop_path_to_uri(fopc, path, &uri);
01805     if (scheme < 0) {
01806        errno = EINVAL;
01807        return -1;
01808     }
01809 
01810     func = (fop_chmod_t)fop_scheme_func(scheme, FOP_CHMOD);
01811     if (NULL == func) {
01812        fop_uri_delete(uri);
01813        errno = EPERM;
01814        return -1;
01815     }
01816 
01817     rv = func(fopc, URI(uri, path), mode);
01818     if (NULL != uri) {
01819        fop_errno = errno;
01820        fop_uri_delete(uri);
01821        errno = fop_errno;
01822     }
01823 
01824     return rv;
01825 }
01826 
01827 
01828 static int
01829 fop_fchmod(
01830     void *           fopc,
01831     int                     fildes,
01832     mode_t           mode
01833 )
01834 {
01835     fop_fchmod_t     func;
01836     fop_file_t *     file;
01837 
01838     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
01839     if (NULL == file) {
01840        errno = EBADF;
01841        return -1;
01842     }
01843 
01844     func = (fop_fchmod_t)fop_scheme_func(file->scheme, FOP_FCHMOD);
01845     if (NULL == func) {
01846        errno = EPERM;
01847        return -1;
01848     }
01849 
01850     return func(fopc, file->value, mode);
01851 }
01852 
01853 
01854 static int
01855 fop_chown(
01856     void *           fopc,
01857     const char *     path,
01858     uid_t            owner,
01859     gid_t            group
01860 )
01861 {
01862     int                     scheme;
01863     fop_uri_t *             uri;
01864     fop_chown_t             func;
01865     int                     rv;
01866     int                     fop_errno;
01867 
01868     scheme = fop_path_to_uri(fopc, path, &uri);
01869     if (scheme < 0) {
01870        errno = EINVAL;
01871        return -1;
01872     }
01873 
01874     func = (fop_chown_t)fop_scheme_func(scheme, FOP_CHOWN);
01875     if (NULL == func) {
01876        fop_uri_delete(uri);
01877        errno = EPERM;
01878        return -1;
01879     }
01880 
01881     rv = func(fopc, URI(uri, path), owner, group);
01882     if (NULL != uri) {
01883        fop_errno = errno;
01884        fop_uri_delete(uri);
01885        errno = fop_errno;
01886     }
01887 
01888     return rv;
01889 }
01890 
01891 
01892 #if defined(fop_not_defined)
01893 static int
01894 fop_lchown(
01895     void *           fopc,
01896     const char *     path,
01897     uid_t            owner,
01898     gid_t            group
01899 )
01900 {
01901     int                     scheme;
01902     fop_uri_t *             uri;
01903     fop_chown_t             func;
01904     int                     rv;
01905     int                     fop_errno;
01906 
01907     scheme = fop_path_to_uri(fopc, path, &uri);
01908     if (scheme < 0) {
01909        errno = EINVAL;
01910        return -1;
01911     }
01912 
01913     func = (fop_chown_t)fop_scheme_func(scheme, FOP_LCHOWN);
01914     if (NULL == func) {
01915        fop_uri_delete(uri);
01916        errno = EPERM;
01917        return -1;
01918     }
01919 
01920     rv = func(fopc, URI(uri, path), owner, group);
01921     if (NULL != uri) {
01922        fop_errno = errno;
01923        fop_uri_delete(uri);
01924        errno = fop_errno;
01925     }
01926 
01927     return rv;
01928 }
01929 #endif /* fop_not_defined */
01930 
01931 
01932 static int
01933 fop_fchown(
01934     void *           fopc,
01935     int                     fildes,
01936     uid_t            owner,
01937     gid_t            group
01938 )
01939 {
01940     fop_fchown_t     func;
01941     fop_file_t *     file;
01942 
01943     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
01944     if (NULL == file) {
01945        errno = EBADF;
01946        return -1;
01947     }
01948 
01949     func = (fop_fchown_t)fop_scheme_func(file->scheme, FOP_FCHOWN);
01950     if (NULL == func) {
01951        errno = EPERM;
01952        return -1;
01953     }
01954 
01955     return func(fopc, file->value, owner, group);
01956 }
01957 
01958 
01959 #if defined(fop_not_defined)
01960 static long
01961 fop_pathconf(
01962     void *           fopc,
01963     const char *     path,
01964     int                     name
01965 )
01966 {
01967     int                     scheme;
01968     fop_uri_t *             uri;
01969     fop_pathconf_t   func;
01970     int                     rv;
01971     int                     fop_errno;
01972 
01973     scheme = fop_path_to_uri(fopc, path, &uri);
01974     if (scheme < 0) {
01975        errno = EINVAL;
01976        return -1;
01977     }
01978 
01979     func = (fop_pathconf_t)fop_scheme_func(scheme, FOP_PATHCONF);
01980     if (NULL == func) {
01981        fop_uri_delete(uri);
01982        errno = EPERM;
01983        return -1;
01984     }
01985 
01986     rv = func(fopc, URI(uri, path), name);
01987     if (NULL != uri) {
01988        fop_errno = errno;
01989        fop_uri_delete(uri);
01990        errno = fop_errno;
01991     }
01992 
01993     return rv;
01994 }
01995 #endif /* fop_not_defined */
01996 
01997 
01998 #if defined(fop_not_defined)
01999 static long
02000 fop_fpathconf(
02001     void *           fopc,
02002     int                     fildes,
02003     int                     name
02004 )
02005 {
02006     fop_fpathconf_t  func;
02007     fop_file_t *     file;
02008 
02009     file = fop_file_search_id(((fopc_t *)fopc)->file, fildes);
02010     if (NULL == file) {
02011        errno = EBADF;
02012        return -1;
02013     }
02014 
02015     func = (fop_fpathconf_t)fop_scheme_func(file->scheme, FOP_FPATHCONF);
02016     if (NULL == func) {
02017        errno = EPERM;
02018        return -1;
02019     }
02020 
02021     return func(fopc, file->value, name);
02022 }
02023 #endif /* fop_not_defined */
02024 
02025 
02026 static int
02027 fop_utime(
02028     void *                  fopc,
02029     const char *            path,
02030     const struct utimbuf *  times
02031 )
02032 {
02033     int                     scheme;
02034     fop_uri_t *             uri;
02035     fop_utime_t             func;
02036     int                     rv;
02037     int                     fop_errno;
02038 
02039     scheme = fop_path_to_uri(fopc, path, &uri);
02040     if (scheme < 0) {
02041        errno = EINVAL;
02042        return -1;
02043     }
02044 
02045     func = (fop_utime_t)fop_scheme_func(scheme, FOP_UTIME);
02046     if (NULL == func) {
02047        fop_uri_delete(uri);
02048        errno = EPERM;
02049        return -1;
02050     }
02051 
02052     rv = func(fopc, URI(uri, path), times);
02053     if (NULL != uri) {
02054        fop_errno = errno;
02055        fop_uri_delete(uri);
02056        errno = fop_errno;
02057     }
02058 
02059     return rv;
02060 }
02061 
02062 
02063 static int
02064 fop_utimes(
02065     void *                  fopc,
02066     const char *            path,
02067     const struct timeval *  times
02068 )
02069 {
02070     int                     scheme;
02071     fop_uri_t *             uri;
02072     fop_utimes_t     func;
02073     int                     rv;
02074     int                     fop_errno;
02075 
02076     scheme = fop_path_to_uri(fopc, path, &uri);
02077     if (scheme < 0) {
02078        errno = EINVAL;
02079        return -1;
02080     }
02081 
02082     func = (fop_utimes_t)fop_scheme_func(scheme, FOP_UTIMES);
02083     if (NULL == func) {
02084        fop_uri_delete(uri);
02085        errno = EPERM;
02086        return -1;
02087     }
02088 
02089     rv = func(fopc, URI(uri, path), times);
02090     if (NULL != uri) {
02091        fop_errno = errno;
02092        fop_uri_delete(uri);
02093        errno = fop_errno;
02094     }
02095 
02096     return rv;
02097 }
02098 
02099 
02100 static fop_name_function_t fop_name_function_list[] = {
02101        {FOP__FOPC_CREATE,   "_fopc_create",      (void *)fop__fopc_create},
02102        {FOP__FOPC_FREE,     "_fopc_free", (void *)fop__fopc_free},
02103 
02104        {FOP__FOPC_CREATE,   "_nsc_create",       (void *)fop__fopc_create},
02105        {FOP__FOPC_FREE,     "_nsc_free",  (void *)fop__fopc_free},
02106 
02107        {FOP_CLOSE,          "close",      (void *)fop_close},
02108        {FOP_CREAT,          "creat",      (void *)fop_creat},
02109        {FOP_FTRUNCATE,             "ftruncate",  (void *)fop_ftruncate},
02110        {FOP_LSEEK,          "lseek",      (void *)fop_lseek},
02111        {FOP_OPEN,           "open",              (void *)fop_open},
02112        {FOP_READ,           "read",              (void *)fop_read},
02113        {FOP_TRUNCATE,              "truncate",   (void *)fop_truncate},
02114        {FOP_WRITE,          "write",      (void *)fop_write},
02115 
02116        {FOP_LINK,           "link",              (void *)fop_link},
02117        {FOP_READLINK,              "readlink",   (void *)fop_readlink},
02118        {FOP_RENAME,         "rename",     (void *)fop_rename},
02119        {FOP_SYMLINK,        "symlink",    (void *)fop_symlink},
02120        {FOP_UNLINK,         "unlink",     (void *)fop_unlink},
02121 
02122        {FOP_CHMOD,          "chmod",      (void *)fop_chmod},
02123        {FOP_CHOWN,          "chown",      (void *)fop_chown},
02124        {FOP_FCHMOD,         "fchmod",     (void *)fop_fchmod},
02125        {FOP_FCHOWN,         "fchown",     (void *)fop_fchown},
02126 #if defined(fop_not_defined)
02127        {FOP_FCHOWN,         "lchown",     (void *)fop_lchown},
02128 #endif /* fop_not_defined */
02129 
02130        {FOP_UTIME,          "utime",      (void *)fop_utime},
02131        {FOP_UTIMES,         "utimes",     (void *)fop_utimes},
02132 
02133        {FOP_FSTAT,          "fstat",      (void *)fop_fstat},
02134        {FOP_LSTAT,          "lstat",      (void *)fop_lstat},
02135        {FOP_STAT,           "stat",              (void *)fop_stat},
02136        {FOP_ACCESS,         "access",     (void *)fop_access},
02137 
02138        {FOP_CLOSEDIR,              "closedir",   (void *)fop_closedir},
02139        {FOP_OPENDIR,        "opendir",    (void *)fop_opendir},
02140        {FOP_READDIR,        "readdir",    (void *)fop_readdir},
02141        {FOP_REWINDDIR,             "rewinddir",  (void *)fop_rewinddir},
02142        {FOP_SEEKDIR,        "seekdir",    (void *)fop_seekdir},
02143        {FOP_TELLDIR,        "telldir",    (void *)fop_telldir},
02144 
02145        {FOP_MKDIR,          "mkdir",      (void *)fop_mkdir},
02146        {FOP_RMDIR,          "rmdir",      (void *)fop_rmdir},
02147 
02148        {FOP_FCNTL,          "fcntl",      (void *)fop_fcntl},
02149 
02150 #if defined(fop_not_defined)
02151        {FOP_PATHCONF,              "pathconf",   (void *)fop_pathconf},
02152        {FOP_FPATHCONF,             "fpathconf",  (void *)fop_fpathconf},
02153        {FOP_READV,          "readv",      (void *)fop_readv},
02154        {FOP_WRITEV,         "writev",     (void *)fop_writev},
02155 #endif /* fop_not_defined */
02156 
02157        {FOP_FUNC_LAST,             NULL,         NULL}
02158 };
02159 
02160 
02161 void *
02162 fop_get_function(
02163     const char *     operation
02164 )
02165 {
02166     fop_name_function_t *   f;
02167 
02168     for (f = fop_name_function_list; NULL != f->name; f += 1) {
02169        if (0 == strcmp(operation, f->name)) {
02170            return f->function;
02171        }
02172     }
02173 
02174     if (0 == strcmp(operation, "_fop_basicfopset")) {
02175        static iml_fop_basic_fopset_t      bfopset = {
02176               fop_close,
02177               fop_creat,
02178               fop_ftruncate,
02179               fop_lseek,
02180               fop_open,
02181               fop_read,
02182               fop_truncate,
02183               fop_write,
02184 
02185               fop_link,
02186               fop_readlink,
02187               fop_rename,
02188               fop_symlink,
02189               fop_unlink,
02190 
02191               fop_chmod,
02192               fop_chown,
02193               fop_fchmod,
02194               fop_fchown,
02195               NULL, /* fop_lchown is not supported */
02196 
02197               fop_utime,
02198               fop_utimes,
02199 
02200               fop_fstat,
02201               fop_lstat,
02202               fop_stat,
02203               fop_access,
02204 
02205               fop_closedir,
02206               fop_opendir,
02207               fop_readdir,
02208               fop_rewinddir,
02209               fop_seekdir,
02210               fop_telldir,
02211 
02212               fop_mkdir,
02213               fop_rmdir,
02214 
02215               fop_fcntl
02216        };
02217 
02218 #if 0 /* not used */
02219        bfopset = malloc(sizeof (iml_fop_basic_fopset_t));
02220        if (NULL == bfopset) return NULL;
02221 
02222        bfopset->fop_close = fop_close;
02223        bfopset->fop_creat = fop_creat;
02224        bfopset->fop_ftruncate = fop_ftruncate;
02225        bfopset->fop_lseek = fop_lseek;
02226        bfopset->fop_open = fop_open;
02227        bfopset->fop_read = fop_read;
02228        bfopset->fop_truncate = fop_truncate;
02229        bfopset->fop_write = fop_write;
02230 
02231        bfopset->fop_link = fop_link;
02232        bfopset->fop_readlink = fop_readlink;
02233        bfopset->fop_rename = fop_rename;
02234        bfopset->fop_symlink = fop_symlink;
02235        bfopset->fop_unlink = fop_unlink;
02236 
02237        bfopset->fop_chmod = fop_chmod;
02238        bfopset->fop_chown = fop_chown;
02239        bfopset->fop_fchmod = fop_fchmod;
02240        bfopset->fop_fchown = fop_fchown;
02241        bfopset->fop_lchown = NULL; /* not supported */
02242 
02243        bfopset->fop_utime = fop_utime;
02244        bfopset->fop_utimes = fop_utimes;
02245 
02246        bfopset->fop_fstat = fop_fstat;
02247        bfopset->fop_lstat = fop_lstat;
02248        bfopset->fop_stat = fop_stat;
02249        bfopset->fop_access = fop_access;
02250 
02251        bfopset->fop_closedir = fop_closedir;
02252        bfopset->fop_opendir = fop_opendir;
02253        bfopset->fop_readdir = fop_readdir;
02254        bfopset->fop_rewinddir = fop_rewinddir;
02255        bfopset->fop_seekdir = fop_seekdir;
02256        bfopset->fop_telldir = fop_telldir;
02257 
02258        bfopset->fop_mkdir = fop_mkdir;
02259        bfopset->fop_rmdir = fop_rmdir;
02260 
02261        bfopset->fop_fcntl = fop_fcntl;
02262 #endif /* not used */
02263 
02264        return &bfopset;
02265     } else if (0 == strcmp(operation, "_nsc_basicfioset")) {
02266        /*
02267         * This interface is not defined yet.
02268         */
02269        typedef struct _iml_nsc_basic_fopset {
02270            iml_fop_open_t   fop_open;
02271            iml_fop_read_t   fop_read;
02272            iml_fop_stat_t   fop_stat;
02273            iml_fop_write_t  fop_write;
02274            iml_fop_close_t  fop_close;
02275            iml_fop_mkdir_t  fop_mkdir;
02276            iml_fop_rmdir_t  fop_rmdir;
02277            iml_fop_symlink_t       fop_symlink;
02278            iml_fop_lstat_t  fop_lstat;
02279            iml_fop_creat_t  fop_creat;
02280            iml_fop_lseek_t  fop_lseek;
02281            iml_fop_unlink_t fop_unlink;
02282            iml_fop_rename_t fop_rename;
02283            iml_fop_fcntl_t  fop_fcntl;
02284            iml_fop_truncate_t      fop_truncate;
02285            iml_fop_opendir_t       fop_opendir;
02286            iml_fop_readdir_t       fop_readdir;
02287            iml_fop_closedir_t      fop_closedir;
02288            iml_fop_fstat_t  fop_fstat;
02289            iml_fop_ftruncate_t     fop_ftruncate;
02290        } iml_nsc_basic_fopset_t;
02291        static iml_nsc_basic_fopset_t      bfopset = {
02292               fop_open,
02293               fop_read,
02294               fop_stat,
02295               fop_write,
02296               fop_close,
02297               fop_mkdir,
02298               fop_rmdir,
02299               fop_symlink,
02300               fop_lstat,
02301               fop_creat,
02302               fop_lseek,
02303               fop_unlink,
02304               fop_rename,
02305               fop_fcntl,
02306               fop_truncate,
02307               fop_opendir,
02308               fop_readdir,
02309               fop_closedir,
02310               fop_fstat,
02311               fop_ftruncate
02312        };
02313 
02314 #if 0 /* not used */
02315        bfopset = malloc(sizeof (iml_nsc_basic_fopset_t));
02316        if (NULL == bfopset) return NULL;
02317 
02318        bfopset->fop_open = fop_open;
02319        bfopset->fop_read = fop_read;
02320        bfopset->fop_stat = fop_stat;
02321        bfopset->fop_write = fop_write;
02322        bfopset->fop_close = fop_close;
02323        bfopset->fop_mkdir = fop_mkdir;
02324        bfopset->fop_rmdir = fop_rmdir;
02325        bfopset->fop_symlink = fop_symlink;
02326        bfopset->fop_lstat = fop_lstat;
02327        bfopset->fop_creat = fop_creat;
02328        bfopset->fop_lseek = fop_lseek;
02329        bfopset->fop_unlink = fop_unlink;
02330        bfopset->fop_rename = fop_rename;
02331        bfopset->fop_fcntl = fop_fcntl;
02332        bfopset->fop_truncate = fop_truncate;
02333        bfopset->fop_opendir = fop_opendir;
02334        bfopset->fop_readdir = fop_readdir;
02335        bfopset->fop_closedir = fop_closedir;
02336        bfopset->fop_fstat = fop_fstat;
02337        bfopset->fop_ftruncate = fop_ftruncate;
02338 #endif /* not used */
02339 
02340        return &bfopset;
02341     }
02342 
02343     return NULL;
02344 }
02345 
02346 
02347 static void
02348 fop_scheme_initialize(
02349 )
02350 {
02351     fop_name_function_t *   f;
02352     void **                 v;
02353     extern void *           fop_scheme_file_get_function(const char *);
02354 
02355     if (NULL != fop_scheme) return;
02356 
02357     fop_scheme = (fop_scheme_t *)malloc(sizeof (fop_scheme_t));
02358     if (NULL == fop_scheme) return;
02359 
02360     /*
02361      * load ``file'' scheme.
02362      */
02363     fop_scheme->name = strdup("file");
02364     fop_scheme->id = 0;
02365     fop_scheme->function =
02366        (void **)calloc(FOP_FUNC_LAST, (sizeof (void *)));
02367     if (NULL == fop_scheme->function) {
02368        free(fop_scheme);
02369        return;
02370     }
02371     v = fop_scheme->function;
02372     for (f = fop_name_function_list; NULL != f->name; f += 1) {
02373        *(v + f->type) = fop_scheme_file_get_function(f->name);
02374     }
02375 
02376     fop_scheme->next = NULL;
02377 
02378     /*
02379      * Other schemes can be loaded here.
02380      */
02381 
02382     return;
02383 }
02384 
02385 
02386 /* Local Variables: */
02387 /* c-file-style: "iiim-project" */
02388 /* End: */