extern unsigned long dllversion(void* dll, const char* path) { Dll_plugin_version_f pvf; if (pvf = (Dll_plugin_version_f)dlllook(dll, "plugin_version")) return (*pvf)(); if (path) { state.error = 1; sfsprintf(state.errorbuf, sizeof(state.errorbuf), "plugin_version() not found"); errorf("dll", NiL, 1, "dllversion: %s: %s", path, state.errorbuf); } return 0; }
int pzlib(register Pz_t* pz, register const char* name, int ignore) { register Pzdll_t* dll; register Pzdllpz_t* pzs; char* id; char buf[64]; char path[PATH_MAX]; if (id = strrchr(state.id, ':')) id++; else id = (char*)state.id; /* * see if the dll is already loaded */ for (dll = state.dll; dll && !streq(dll->name, name); dll = dll->next); if (!dll) { /* * add to the list and open */ if (!(dll = newof(0, Pzdll_t, 1, strlen(name) + 1))) return -1; dll->name = strcpy((char*)(dll + 1), name); dll->next = state.dll; state.dll = dll; if (ignore) return 0; if (!(dll->dll = dllplugin(id, dll->name, NiL, PZ_PLUGIN_VERSION, NiL, RTLD_LAZY, path, sizeof(path)))) { if (pz->disc && pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, ERROR_SYSTEM|2, "%s: %s", dll->name, dlerror()); return -1; } /* * get the initialization function */ sfsprintf(buf, sizeof(buf), "%s_init", id); if (!(dll->initf = (Pzinit_f)dlllook(dll->dll, buf))) { if (pz->disc && pz->disc->errorf) (*pz->disc->errorf)(pz, pz->disc, 2, "%s: %s: initialization function not found in library", path, buf); return -1; } } /* * see if pz already initialized */ if (dll->initf) { for (pzs = dll->pzs; pzs && pzs->pz != pz; pzs = pzs->next); if (!pzs) { if (!(pzs = newof(0, Pzdllpz_t, 1, 0))) return -1; pzs->pz = pz; pzs->next = dll->pzs; dll->pzs = pzs; if (!(dll->usage = pzinit(pz, dll->name, dll->initf))) return -1; } } return 0; }
int b_dlls(int argc, char** argv, Shbltin_t* context) { int i; int r; int flags; int only; unsigned long ver; char** syms; char* arg[3]; void* dll; void* sym; Dllscan_t* dls; Dllent_t* dle; Dllinfo_t* dli; cmdinit(argc, argv, context, ERROR_CATALOG, 0); flags = 0; only = 0; for (;;) { switch (optget(argv, usage)) { case 0: break; case 'b': flags |= LIST_BASE; continue; case 'c': only = 1; continue; case 'i': flags |= LIST_INFO; continue; case 'l': flags |= LIST_LONG; continue; case 'p': flags |= LIST_PATH; continue; case ':': error(2, "%s", opt_info.arg); continue; case '?': error(ERROR_usage(2), "%s", opt_info.arg); continue; } break; } argv += opt_info.index; if (error_info.errors) error(ERROR_usage(2), "%s", optusage(NiL)); r = 0; if (flags & LIST_INFO) { if (!(dli = dllinfo())) error(2, "cannot determine native dll info"); sfprintf(sfstdout, "sibling=(%s", dli->sibling[0]); for (i = 1; dli->sibling[i]; i++) sfprintf(sfstdout, " %s", dli->sibling[i]); sfprintf(sfstdout, ") env=%s prefix=%s suffix=%s flags=", dli->env, dli->prefix, dli->suffix); i = 0; if (dli->flags & DLL_INFO_PREVER) { i = 1; sfprintf(sfstdout, "PREVER"); } if (dli->flags & DLL_INFO_DOTVER) { if (i) sfputc(sfstdout, '|'); sfprintf(sfstdout, "DOTVER"); } sfputc(sfstdout, '\n'); } else if (!(flags & (LIST_BASE|LIST_PATH))) flags |= LIST_BASE|LIST_PATH; if (flags &= (LIST_BASE|LIST_PATH|LIST_LONG)) { for (i = 0; i < elementsof(arg); i++) if (arg[i] = *argv) argv++; if (only && !*argv) error(ERROR_usage(2), "%s", optusage(NiL)); r = 1; for (;;) { if (dls = dllsopen(arg[0], arg[1], arg[2])) { while (dle = dllsread(dls)) { r = 0; if (!only) { if (!(flags & LIST_LONG)) dll = 0; else if (dll = dlopen(dle->path, RTLD_LAZY)) ver = dllversion(dll, NiL); else ver = 0; switch (flags) { case LIST_BASE: sfprintf(sfstdout, "%s\n", dle->name); break; case LIST_BASE|LIST_LONG: sfprintf(sfstdout, "%14s %08lu\n", dle->name, ver); break; case LIST_PATH|LIST_LONG: sfprintf(sfstdout, "%08lu %s\n", ver, dle->path); break; case LIST_PATH: sfprintf(sfstdout, "%s\n", dle->path); break; case LIST_BASE|LIST_PATH: sfprintf(sfstdout, "%14s %s\n", dle->name, dle->path); break; default: sfprintf(sfstdout, "%14s %08lu %s\n", dle->name, ver, dle->path); break; } if (*(syms = argv)) { if (dll || (dll = dlopen(dle->path, RTLD_LAZY))) { do { sfprintf(sfstdout, " %14s ", *syms); if (sym = dlllook(dll, *syms)) sfprintf(sfstdout, "%p\n", sym); else sfprintf(sfstdout, "%s\n", dlerror()); } while (*++syms); dlclose(dll); } else sfprintf(sfstdout, " %s\n", dlerror()); } } else if (dll = dlopen(dle->path, RTLD_LAZY)) { i = 1; for (syms = argv; *syms; syms++) if (sym = dlllook(dll, *syms)) { if (i) { i = 0; switch (flags) { case LIST_BASE: sfprintf(sfstdout, "%s\n", dle->name); break; case LIST_PATH: sfprintf(sfstdout, "%s\n", dle->path); break; default: sfprintf(sfstdout, "%14s %s\n", dle->name, dle->path); break; } } sfprintf(sfstdout, " %14s %p\n", *syms, sym); } dlclose(dll); } } dllsclose(dls); } if (!r || !arg[0] || streq(arg[0], "-") || !arg[1] || streq(arg[1], "-")) break; arg[0] = 0; } } return r || error_info.errors; }