musicmud-2.1.6/data/
musicmud-2.1.6/data/help/
musicmud-2.1.6/data/policy/
musicmud-2.1.6/data/wild/
musicmud-2.1.6/data/world/
musicmud-2.1.6/doc/
musicmud-2.1.6/src/ident/
musicmud-2.1.6/src/lua/
musicmud-2.1.6/src/lua/include/
musicmud-2.1.6/src/lua/src/lib/
musicmud-2.1.6/src/lua/src/lua/
musicmud-2.1.6/src/lua/src/luac/
/* 
 * 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);
}