/* * MusicMUD Daemon, version 1.0 * Copyright (C) 1998-2003 Abigail Brady * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * */ #include <dlfcn.h> #include <sys/stat.h> #include <sys/types.h> #include "musicmud.h" #include "Library.h" #include "pflags.h" void Library::stamp(const char *buffer) { struct stat thing; ::stat(buffer, &thing); set("timestamp", (int)thing.st_mtime); } void *Library::find_symbol(const char *name) const { return dlsym(dlhandle, name); } static int areset = 0; Library::Library(const char *filename, bool exprt, bool trap) : Object(filename) { valid = false; exported = exprt; string buffer = (string)(exprt?"src/support/":"src/extras/")+filename; set("pathname", buffer); set("loaded", (int)now); if (!exprt || trap) { dlhandle = dlopen(buffer.c_str(), RTLD_NOW); if (dlhandle) { stamp(buffer.c_str()); if (!trap) { procedure register_verbs = get_sym("register_verbs"); if (register_verbs) { register_verbs(); valid = true; if (areset) after_reset(); } else { log(PFL_CODER, 0, "library", "loading %s failed : %s", filename, dlerror()); } } else { exported = true; valid = true; } } else { log(PFL_CODER, 0, "library", "loading %s failed : %s ", filename, dlerror()); } } else { dlhandle = dlopen(buffer.c_str(), RTLD_NOW | RTLD_GLOBAL); if (!dlhandle) log(PFL_CODER, 0, "library", "loading %s failed : %s", filename, dlerror()); else stamp(buffer.c_str()); } } void Library::after_reset() { procedure a = get_sym("after_reset"); if (a) a(); areset = 1; } void Library::cleanup() { procedure cleanup = get_sym("reboot"); if (cleanup) cleanup(); } Library::~Library() { if (dlhandle) { if (!exported) { procedure remove_verbs = get_sym("remove_verbs"); if (remove_verbs) { remove_verbs(); } else { log(PFL_CODER, 0, "library", "couldn't clean up library : %s", id); } } dlclose(dlhandle); } } void *Library::find_symbol(const char *libname, const char *symbol) { Library *l = libs->get(libname);; if (!l) return 0; return l->find_symbol(symbol); }