PageRenderTime 19ms CodeModel.GetById 11ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/core/10.4/fusefs/load/load_fusefs.c

http://macfuse.googlecode.com/
C | 147 lines | 90 code | 23 blank | 34 comment | 27 complexity | 56915ea140aaef0c4ae1c9770e12ce99 MD5 | raw file
  1/*
  2 * Copyright (C) 2006-2008 Google. All Rights Reserved.
  3 * Amit Singh <singh@>
  4 */
  5
  6/*
  7 * Portions Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
  8 *
  9 * This file contains Original Code and/or Modifications of Original Code as
 10 * defined in and that are subject to the Apple Public Source License Version
 11 * 2.0 (the 'License'). You may not use this file except in compliance with
 12 * the License. Please obtain a copy of the License at
 13 * http://www.opensource.apple.com/apsl/ and read it before using this file.
 14 *
 15 * The Original Code and all software distributed under the License are
 16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
 19 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see
 20 * the License for the specific language governing rights and limitations
 21 * under the License.
 22 */
 23
 24#include <stdio.h>
 25#include <sys/errno.h>
 26#include <sys/param.h>
 27#include <sys/mount.h>
 28#include <sys/types.h>
 29#include <sys/wait.h>
 30#include <unistd.h>
 31#include <sys/sysctl.h>
 32
 33#include <grp.h>
 34#include <string.h>
 35
 36#include <fuse_param.h>
 37#include <fuse_version.h>
 38
 39int
 40main(__unused int argc, __unused const char *argv[])
 41{
 42    int    pid = -1;
 43    int    result = -1;
 44    union  wait status;
 45    char   version[MAXHOSTNAMELEN + 1] = { 0 };
 46    size_t version_len = MAXHOSTNAMELEN;
 47    size_t version_len_desired = 0;
 48    struct vfsconf vfc = { 0 };
 49
 50    result = getvfsbyname(MACFUSE_FS_TYPE, &vfc);
 51    if (result) { /* MacFUSE is not already loaded */
 52        result = -1;
 53        goto need_loading;
 54    }
 55
 56    /* some version of MacFUSE is already loaded; let us check it out */
 57
 58    result = sysctlbyname(SYSCTL_MACFUSE_VERSION_NUMBER, version,
 59                          &version_len, NULL, (size_t)0);
 60    if (result) {
 61        if (errno == ENOENT) {
 62            /* too old; doesn't even have the sysctl variable */
 63            goto need_unloading;
 64        }
 65        result = -1;
 66        goto out;
 67    }
 68
 69    /* sysctlbyname() includes the trailing '\0' in version_len */
 70    version_len_desired = strlen(MACFUSE_VERSION) + 1;
 71
 72    if ((version_len == version_len_desired) &&
 73        !strncmp(MACFUSE_VERSION, version, version_len)) {
 74        /* what's currently loaded is good */
 75        result = 0;
 76        goto out;
 77    }
 78
 79    /* mismatched version; need to unload what's loaded */
 80
 81need_unloading:
 82    pid = fork();
 83    if (pid == 0) {
 84        result = execl(SYSTEM_KEXTUNLOAD, SYSTEM_KEXTUNLOAD, "-b",
 85                       MACFUSE_BUNDLE_IDENTIFIER, NULL);
 86        /* We can only get here if the exec failed */
 87        goto out;
 88    }
 89
 90    if (pid == -1) {
 91        result = errno;
 92        goto out;
 93    }
 94
 95    /* Success! */
 96    if ((wait4(pid, (int *)&status, 0, NULL) == pid) && (WIFEXITED(status))) {
 97        result = status.w_retcode;
 98    } else {
 99        result = -1;
100    }
101
102    if (result != 0) {
103        /* unloading failed */
104        result = EBUSY;
105        goto out;
106    }
107
108    /* unloading succeeded; now load the on-disk version */
109
110need_loading:
111    pid = fork();
112    if (pid == 0) {
113        result = execl(SYSTEM_KEXTLOAD, SYSTEM_KEXTLOAD, MACFUSE_KEXT, NULL);
114        /* We can only get here if the exec failed */
115        goto out;
116    }
117    
118    if (pid == -1) {
119        result = errno;
120        goto out;
121    }
122    
123    /* Success! */
124    if ((wait4(pid, (int *)&status, 0, NULL) == pid) && (WIFEXITED(status))) {
125        result = status.w_retcode;
126    } else {
127        result = -1;
128    }
129
130    /* now do any kext-load-time settings we need to do as root */
131
132    if (result == 0) {
133        int admin_gid = 0;
134        struct group *g = getgrnam(MACOSX_ADMIN_GROUP_NAME);
135        if (!g) {
136            goto out;
137        }
138        admin_gid = g->gr_gid;
139
140        /* if this fails, we don't care */
141        (void)sysctlbyname(SYSCTL_MACFUSE_TUNABLES_ADMIN, NULL, NULL,
142                          &admin_gid, sizeof(admin_gid));
143    }
144    
145out:
146    _exit(result);
147}