|
Packit |
8480eb |
/* ----------------------------------------------------------------------- *
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* module.c - common module-management functions
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* Copyright 1997 Transmeta Corporation - All Rights Reserved
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8480eb |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8480eb |
* the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139,
|
|
Packit |
8480eb |
* USA; either version 2 of the License, or (at your option) any later
|
|
Packit |
8480eb |
* version; incorporated herein by reference.
|
|
Packit |
8480eb |
*
|
|
Packit |
8480eb |
* ----------------------------------------------------------------------- */
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#include <stdio.h>
|
|
Packit |
8480eb |
#include <dlfcn.h>
|
|
Packit |
8480eb |
#include <string.h>
|
|
Packit |
8480eb |
#include <stdlib.h>
|
|
Packit |
8480eb |
#include "automount.h"
|
|
Packit |
8480eb |
#include "nsswitch.h"
|
|
Packit |
8480eb |
|
|
Packit Service |
42268b |
int load_autofs4_module(void)
|
|
Packit Service |
42268b |
{
|
|
Packit Service |
42268b |
FILE *fp;
|
|
Packit Service |
42268b |
char buf[PATH_MAX];
|
|
Packit Service |
42268b |
int ret;
|
|
Packit Service |
42268b |
|
|
Packit Service |
42268b |
/*
|
|
Packit Service |
42268b |
* Check if module already loaded or compiled in.
|
|
Packit Service |
42268b |
* If both autofs v3 and v4 are coplied in and
|
|
Packit Service |
42268b |
* the v3 module registers first or the v4 module
|
|
Packit Service |
42268b |
* is an older version we will catch it at mount
|
|
Packit Service |
42268b |
* time.
|
|
Packit Service |
42268b |
*/
|
|
Packit Service |
42268b |
fp = open_fopen_r("/proc/filesystems");
|
|
Packit Service |
42268b |
if (!fp) {
|
|
Packit Service |
42268b |
logerr("cannot open /proc/filesystems");
|
|
Packit Service |
42268b |
return 0;
|
|
Packit Service |
42268b |
}
|
|
Packit Service |
42268b |
|
|
Packit Service |
42268b |
while (fgets(buf, sizeof(buf), fp)) {
|
|
Packit Service |
42268b |
if (strstr(buf, "autofs")) {
|
|
Packit Service |
42268b |
fclose(fp);
|
|
Packit Service |
42268b |
return 1;
|
|
Packit Service |
42268b |
}
|
|
Packit Service |
42268b |
}
|
|
Packit Service |
42268b |
fclose(fp);
|
|
Packit Service |
42268b |
|
|
Packit Service |
42268b |
ret = spawnl(LOGOPT_NONE, PATH_MODPROBE, PATH_MODPROBE,
|
|
Packit Service |
42268b |
"-q", FS_MODULE_NAME, NULL);
|
|
Packit Service |
42268b |
if (ret)
|
|
Packit Service |
42268b |
return 0;
|
|
Packit Service |
42268b |
|
|
Packit Service |
42268b |
return 1;
|
|
Packit Service |
42268b |
}
|
|
Packit Service |
42268b |
|
|
Packit |
8480eb |
int open_lookup(const char *name, const char *err_prefix, const char *mapfmt,
|
|
Packit |
8480eb |
int argc, const char *const *argv, struct lookup_mod **lookup)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct lookup_mod *mod;
|
|
Packit |
8480eb |
char buf[MAX_ERR_BUF];
|
|
Packit |
8480eb |
char fnbuf[PATH_MAX];
|
|
Packit |
8480eb |
size_t size;
|
|
Packit |
8480eb |
char *type;
|
|
Packit |
8480eb |
void *dh;
|
|
Packit |
8480eb |
int *ver;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
*lookup = NULL;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
mod = malloc(sizeof(struct lookup_mod));
|
|
Packit |
8480eb |
if (!mod) {
|
|
Packit |
8480eb |
if (err_prefix) {
|
|
Packit |
8480eb |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr("%s%s", err_prefix, estr);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
type = strdup(name);
|
|
Packit |
8480eb |
if (!type) {
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
if (err_prefix) {
|
|
Packit |
8480eb |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr("%s%s", err_prefix, estr);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
size = snprintf(fnbuf, sizeof(fnbuf),
|
|
Packit |
8480eb |
"%s/lookup_%s.so", AUTOFS_LIB_DIR, name);
|
|
Packit |
8480eb |
if (size >= sizeof(fnbuf)) {
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
free(type);
|
|
Packit |
8480eb |
if (err_prefix) {
|
|
Packit |
8480eb |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr("%s%s", err_prefix, estr);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(dh = dlopen(fnbuf, RTLD_NOW))) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%scannot open lookup module %s (%s)",
|
|
Packit |
8480eb |
err_prefix, name, dlerror());
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
free(type);
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(ver = (int *) dlsym(dh, "lookup_version"))
|
|
Packit |
8480eb |
|| *ver != AUTOFS_LOOKUP_VERSION) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%slookup module %s version mismatch",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
free(type);
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(mod->lookup_init = (lookup_init_t) dlsym(dh, "lookup_init")) ||
|
|
Packit |
8480eb |
!(mod->lookup_reinit = (lookup_reinit_t) dlsym(dh, "lookup_reinit")) ||
|
|
Packit |
8480eb |
!(mod->lookup_read_master = (lookup_read_master_t) dlsym(dh, "lookup_read_master")) ||
|
|
Packit |
8480eb |
!(mod->lookup_read_map = (lookup_read_map_t) dlsym(dh, "lookup_read_map")) ||
|
|
Packit |
8480eb |
!(mod->lookup_mount = (lookup_mount_t) dlsym(dh, "lookup_mount")) ||
|
|
Packit |
8480eb |
!(mod->lookup_done = (lookup_done_t) dlsym(dh, "lookup_done"))) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%slookup module %s corrupt", err_prefix, name);
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
free(type);
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (mod->lookup_init(mapfmt, argc, argv, &mod->context)) {
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
free(type);
|
|
Packit |
8480eb |
return NSS_STATUS_UNKNOWN;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
mod->type = type;
|
|
Packit |
8480eb |
mod->dlhandle = dh;
|
|
Packit |
8480eb |
*lookup = mod;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return NSS_STATUS_SUCCESS;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int reinit_lookup(struct lookup_mod *mod, const char *name,
|
|
Packit |
8480eb |
const char *err_prefix, const char *mapfmt,
|
|
Packit |
8480eb |
int argc, const char *const *argv)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
if (mod->lookup_reinit(mapfmt, argc, argv, &mod->context)) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%scould not reinit lookup module %s",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
return 1;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return 0;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int close_lookup(struct lookup_mod *mod)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
int rv = mod->lookup_done(mod->context);
|
|
Packit |
8480eb |
dlclose(mod->dlhandle);
|
|
Packit |
8480eb |
free(mod->type);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return rv;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
struct parse_mod *open_parse(const char *name, const char *err_prefix,
|
|
Packit |
8480eb |
int argc, const char *const *argv)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct parse_mod *mod;
|
|
Packit |
8480eb |
char buf[MAX_ERR_BUF];
|
|
Packit |
8480eb |
char fnbuf[PATH_MAX];
|
|
Packit |
8480eb |
size_t size;
|
|
Packit |
8480eb |
void *dh;
|
|
Packit |
8480eb |
int *ver;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
mod = malloc(sizeof(struct parse_mod));
|
|
Packit |
8480eb |
if (!mod) {
|
|
Packit |
8480eb |
if (err_prefix) {
|
|
Packit |
8480eb |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr("%s%s", err_prefix, estr);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
size = snprintf(fnbuf, sizeof(fnbuf),
|
|
Packit |
8480eb |
"%s/parse_%s.so", AUTOFS_LIB_DIR, name);
|
|
Packit |
8480eb |
if (size >= sizeof(fnbuf)) {
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
if (err_prefix) {
|
|
Packit |
8480eb |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr("%s%s", err_prefix, estr);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(dh = dlopen(fnbuf, RTLD_NOW))) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%scannot open parse module %s (%s)",
|
|
Packit |
8480eb |
err_prefix, name, dlerror());
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(ver = (int *) dlsym(dh, "parse_version"))
|
|
Packit |
8480eb |
|| *ver != AUTOFS_PARSE_VERSION) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%sparse module %s version mismatch",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(mod->parse_init = (parse_init_t) dlsym(dh, "parse_init")) ||
|
|
Packit |
8480eb |
!(mod->parse_reinit = (parse_reinit_t) dlsym(dh, "parse_reinit")) ||
|
|
Packit |
8480eb |
!(mod->parse_mount = (parse_mount_t) dlsym(dh, "parse_mount")) ||
|
|
Packit |
8480eb |
!(mod->parse_done = (parse_done_t) dlsym(dh, "parse_done"))) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%sparse module %s corrupt",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (mod->parse_init(argc, argv, &mod->context)) {
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
mod->dlhandle = dh;
|
|
Packit |
8480eb |
return mod;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int reinit_parse(struct parse_mod *mod, const char *name,
|
|
Packit |
8480eb |
const char *err_prefix, int argc, const char *const *argv)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
if (mod->parse_reinit(argc, argv, &mod->context)) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%scould not reinit parse module %s",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
return 1;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return 0;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int close_parse(struct parse_mod *mod)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
int rv = mod->parse_done(mod->context);
|
|
Packit |
8480eb |
dlclose(mod->dlhandle);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return rv;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
struct mount_mod *open_mount(const char *name, const char *err_prefix)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct mount_mod *mod;
|
|
Packit |
8480eb |
char buf[MAX_ERR_BUF];
|
|
Packit |
8480eb |
char fnbuf[PATH_MAX];
|
|
Packit |
8480eb |
size_t size;
|
|
Packit |
8480eb |
void *dh;
|
|
Packit |
8480eb |
int *ver;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
mod = malloc(sizeof(struct mount_mod));
|
|
Packit |
8480eb |
if (!mod) {
|
|
Packit |
8480eb |
if (err_prefix) {
|
|
Packit |
8480eb |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr("%s%s", err_prefix, estr);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
size = snprintf(fnbuf, sizeof(fnbuf),
|
|
Packit |
8480eb |
"%s/mount_%s.so", AUTOFS_LIB_DIR, name);
|
|
Packit |
8480eb |
if (size >= sizeof(fnbuf)) {
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
if (err_prefix) {
|
|
Packit |
8480eb |
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
|
Packit |
8480eb |
logerr("%s%s", err_prefix, estr);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(dh = dlopen(fnbuf, RTLD_NOW))) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%scannot open mount module %s (%s)",
|
|
Packit |
8480eb |
err_prefix, name, dlerror());
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(ver = (int *) dlsym(dh, "mount_version"))
|
|
Packit |
8480eb |
|| *ver != AUTOFS_MOUNT_VERSION) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%smount module %s version mismatch",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!(mod->mount_init = (mount_init_t) dlsym(dh, "mount_init")) ||
|
|
Packit |
8480eb |
!(mod->mount_reinit = (mount_reinit_t) dlsym(dh, "mount_reinit")) ||
|
|
Packit |
8480eb |
!(mod->mount_mount = (mount_mount_t) dlsym(dh, "mount_mount")) ||
|
|
Packit |
8480eb |
!(mod->mount_done = (mount_done_t) dlsym(dh, "mount_done"))) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%smount module %s corrupt",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (mod->mount_init(&mod->context)) {
|
|
Packit |
8480eb |
dlclose(dh);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return NULL;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
mod->dlhandle = dh;
|
|
Packit |
8480eb |
return mod;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int reinit_mount(struct mount_mod *mod, const char *name, const char *err_prefix)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
if (mod->mount_reinit(&mod->context)) {
|
|
Packit |
8480eb |
if (err_prefix)
|
|
Packit |
8480eb |
logerr("%scould not reinit mount module %s",
|
|
Packit |
8480eb |
err_prefix, name);
|
|
Packit |
8480eb |
return 1;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
return 0;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
int close_mount(struct mount_mod *mod)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
int rv = mod->mount_done(mod->context);
|
|
Packit |
8480eb |
dlclose(mod->dlhandle);
|
|
Packit |
8480eb |
free(mod);
|
|
Packit |
8480eb |
return rv;
|
|
Packit |
8480eb |
}
|