]> git.saurik.com Git - apple/libinfo.git/blobdiff - lookup.subproj/lu_fstab.c
Libinfo-278.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_fstab.c
index 725255b4e7739c5866985caf07ba173c6ac446ad..05f7624c873680d588a40f3a8a5b4ef1a258b574 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <fstab.h>
 #include <pthread.h>
-
-#include "lookup.h"
-#include "_lu_types.h"
 #include "lu_utils.h"
 #include "lu_overrides.h"
 
+#define ENTRY_SIZE sizeof(struct fstab)
+#define ENTRY_KEY _li_data_key_fstab
+
 static pthread_mutex_t _fstab_lock = PTHREAD_MUTEX_INITIALIZER;
 
 #define FS_GET_SPEC 1
 #define FS_GET_FILE 2
 #define FS_GET_ENT 3
 
-static void
-free_fstab_data(struct fstab *f)
+static struct fstab *
+copy_fstab(struct fstab *in)
 {
-       if (f == NULL) return;
+       if (in == NULL) return NULL;
 
-       if (f->fs_spec != NULL) free(f->fs_spec);
-       if (f->fs_file != NULL) free(f->fs_file);
-       if (f->fs_vfstype != NULL) free(f->fs_vfstype);
-       if (f->fs_mntops != NULL) free(f->fs_mntops);
-       if (f->fs_type != NULL) free(f->fs_type);
+       return (struct fstab *)LI_ils_create("sssss44", in->fs_spec, in->fs_file, in->fs_vfstype, in->fs_mntops, in->fs_type, in->fs_freq, in->fs_passno);
 }
 
-static void
-free_fstab(struct fstab *f)
-{
-       if (f == NULL) return;
-       free_fstab_data(f);
-       free(f);
-}
-
-static void
-free_lu_thread_info_fstab(void *x)
+/*
+ * Extract the next fstab entry from a kvarray.
+ */
+static void *
+extract_fstab(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_fstab((struct fstab *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       struct fstab tmp;
+       uint32_t d, k, kcount;
 
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
+       if (in == NULL) return NULL;
 
-static struct fstab *
-extract_fstab(XDR *xdr)
-{
-       int i, j, nkeys, nvals, status;
-       char *key, **vals;
-       struct fstab *f;
+       d = in->curr;
+       in->curr++;
 
-       if (xdr == NULL) return NULL;
+       if (d >= in->count) return NULL;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       f = (struct fstab *)calloc(1, sizeof(struct fstab));
+       kcount = in->dict[d].kcount;
 
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "fs_spec"))
                {
-                       free_fstab(f);
-                       return NULL;
-               }
+                       if (tmp.fs_spec != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.fs_spec = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((f->fs_spec == NULL) && (!strcmp("name", key)))
+               else if (!strcmp(in->dict[d].key[k], "fs_file"))
                {
-                       f->fs_spec = vals[0];
-                       j = 1;
-               }
-               else if ((f->fs_file == NULL) && (!strcmp("dir", key)))
-               {
-                       f->fs_file = vals[0];
-                       j = 1;
-               }
-               else if ((f->fs_vfstype == NULL) && (!strcmp("vfstype", key)))
-               {
-                       f->fs_vfstype = vals[0];
-                       j = 1;
+                       if (tmp.fs_file != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_file = (char *)in->dict[d].val[k][0];
                }
-               else if ((f->fs_mntops == NULL) && (!strcmp("opts", key)))
+               else if (!strcmp(in->dict[d].key[k], "fs_vfstype"))
                {
-                       f->fs_mntops = vals[0];
-                       j = 1;
+                       if (tmp.fs_vfstype != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_vfstype = (char *)in->dict[d].val[k][0];
                }
-               else if ((f->fs_type == NULL) && (!strcmp("type", key)))
+               else if (!strcmp(in->dict[d].key[k], "fs_mntops"))
                {
-                       f->fs_type = vals[0];
-                       j = 1;
+                       if (tmp.fs_mntops != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_mntops = (char *)in->dict[d].val[k][0];
                }
-               else if (!strcmp("freq", key))
+               else if (!strcmp(in->dict[d].key[k], "fs_type"))
                {
-                       f->fs_freq = atoi(vals[0]);
+                       if (tmp.fs_type != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_type = (char *)in->dict[d].val[k][0];
                }
-               else if (!strcmp("passno", key))
+               else if (!strcmp(in->dict[d].key[k], "fs_freq"))
                {
-                       f->fs_passno = atoi(vals[0]);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.fs_freq = atoi(in->dict[d].val[k][0]);
                }
-
-               free(key);
-               if (vals != NULL)
+               else if (!strcmp(in->dict[d].key[k], "fs_passno"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.fs_passno = atoi(in->dict[d].val[k][0]);
                }
        }
 
-       if (f->fs_spec == NULL) f->fs_spec = strdup("");
-       if (f->fs_file == NULL) f->fs_file = strdup("");
-       if (f->fs_vfstype == NULL) f->fs_vfstype = strdup("");
-       if (f->fs_mntops == NULL) f->fs_mntops = strdup("");
-       if (f->fs_type == NULL) f->fs_type = strdup("");
-
-       return f;
-}
-
-static struct fstab *
-copy_fstab(struct fstab *in)
-{
-       struct fstab *f;
-
-       if (in == NULL) return NULL;
-
-       f = (struct fstab *)calloc(1, sizeof(struct fstab));
-
-       f->fs_spec = LU_COPY_STRING(in->fs_spec);
-       f->fs_file = LU_COPY_STRING(in->fs_file);
-       f->fs_vfstype = LU_COPY_STRING(in->fs_vfstype);
-       f->fs_mntops = LU_COPY_STRING(in->fs_mntops);
-       f->fs_type = LU_COPY_STRING(in->fs_type);
-
-       f->fs_freq = in->fs_freq;
-       f->fs_passno = in->fs_passno;
-
-       return f;
-}
-
-static void
-recycle_fstab(struct lu_thread_info *tdata, struct fstab *in)
-{
-       struct fstab *f;
-
-       if (tdata == NULL) return;
-       f = (struct fstab *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_fstab(f);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
-
-       free_fstab_data(f);
-
-       f->fs_spec = in->fs_spec;
-       f->fs_file = in->fs_file;
-       f->fs_vfstype = in->fs_vfstype;
-       f->fs_mntops = in->fs_mntops;
-       f->fs_type = in->fs_type;
-       f->fs_freq = in->fs_freq;
-       f->fs_passno = in->fs_passno;
+       if (tmp.fs_spec == NULL) tmp.fs_spec = "";
+       if (tmp.fs_file == NULL) tmp.fs_file = "";
+       if (tmp.fs_vfstype == NULL) tmp.fs_vfstype = "";
+       if (tmp.fs_mntops == NULL) tmp.fs_mntops = "";
+       if (tmp.fs_type == NULL) tmp.fs_type = "";
 
-       free(in);
+       return copy_fstab(&tmp);
 }
 
 static struct fstab *
-lu_getfsspec(const char *name)
+ds_getfsspec(const char *name)
 {
-       struct fstab *f;
-       unsigned datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "getfsbyname", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
-       }
-
-       xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
-       if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)namebuf, xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen)
-               != KERN_SUCCESS)
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       xdr_destroy(&outxdr);
 
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       f = extract_fstab(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return f;
+       return (struct fstab *)LI_getone("getfsbyname", &proc, extract_fstab, "name", name);
 }
 
 static void
-lu_endfsent(void)
+ds_endfsent(void)
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_fstab, free_lu_thread_info_fstab);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static int
-lu_setfsent(void)
+ds_setfsent(void)
 {
-       lu_endfsent();
+       ds_endfsent();
        return 1;
 }
 
 static struct fstab *
-lu_getfsent()
+ds_getfsent()
 {
        static int proc = -1;
-       struct lu_thread_info *tdata;
-       struct fstab *f;
 
-       tdata = _lu_data_create_key(_lu_data_key_fstab, free_lu_thread_info_fstab);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_fstab, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "getfsent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_endfsent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endfsent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endfsent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endfsent();
-               return NULL;
-       }
-
-       f = extract_fstab(tdata->lu_xdr);
-       if (f == NULL)
-       {
-               lu_endfsent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return f;
+       return (struct fstab *)LI_getent("getfsent", &proc, extract_fstab, ENTRY_KEY, ENTRY_SIZE);
 }
 
 static struct fstab *
-lu_getfsfile(const char *name)
+ds_getfsfile(const char *name)
 {
        struct fstab *fs;
 
-       if (name == NULL) return (struct fstab *)NULL;
+       if (name == NULL) return NULL;
 
-       setfsent();
-       for (fs = lu_getfsent(); fs != NULL; fs = lu_getfsent())
+       ds_setfsent();
+
+       for (fs = ds_getfsent(); fs != NULL; fs = ds_getfsent())
+       {
                if (!strcmp(fs->fs_file, name)) return fs;
+       }
 
-       endfsent();
-       return (struct fstab *)NULL;
+       ds_endfsent();
+
+       return NULL;
 }
 
 static struct fstab *
 getfs(const char *spec, const char *file, int source)
 {
        struct fstab *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_fstab, free_lu_thread_info_fstab);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_fstab, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
                switch (source)
                {
                        case FS_GET_SPEC:
-                               res = lu_getfsspec(spec);
+                               res = ds_getfsspec(spec);
                                break;
                        case FS_GET_FILE:
-                               res = lu_getfsfile(file);
+                               res = ds_getfsfile(file);
                                break;
                        case FS_GET_ENT:
-                               res = lu_getfsent();
-                               break;
+                               res = ds_getfsent();
+                       break;
                        default: res = NULL;
                }
        }
        else
        {
                pthread_mutex_lock(&_fstab_lock);
+
                switch (source)
                {
                        case FS_GET_SPEC:
@@ -434,11 +220,12 @@ getfs(const char *spec, const char *file, int source)
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_fstab_lock);
        }
 
-       recycle_fstab(tdata, res);
-       return (struct fstab *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct fstab *)tdata->li_entry;
 }
 
 
@@ -469,14 +256,13 @@ getfsent(void)
 int
 setfsent(void)
 {
-       if (_lu_running()) return (lu_setfsent());
+       if (_ds_running()) return (ds_setfsent());
        return (_old_setfsent());
 }
 
 void
 endfsent(void)
 {
-       if (_lu_running()) lu_endfsent();
+       if (_ds_running()) ds_endfsent();
        else _old_endfsent();
 }
-