|
|
1.1 root 1: /* tag: plugin interface for openbios forth kernel
2: *
3: * Copyright (C) 2003, 2004 Stefan Reinauer
4: *
5: * See the file "COPYING" for further information about
6: * the copyright and warranty status of this work.
7: */
8:
9: #include "sysinclude.h"
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <string.h>
13: #include <dlfcn.h>
14:
15: #include "unix/plugins.h"
16:
17: unsigned char *plugindir = "/usr/share/OpenBIOS/plugins";
18: #define PLUGINDIR plugindir
19: #define PATHSIZE 256
20:
21: #define CONFIG_DEBUG_PLUGINS
22:
23: typedef struct iorange iorange_t;
24: struct iorange {
25: const char *name;
26: unsigned int start;
27: unsigned int end;
28: io_ops_t *ops;
29: iorange_t *next;
30: };
31:
32: static iorange_t *ioranges = NULL;
33:
34: typedef struct plugin plugin_t;
35: struct plugin {
36: const char *name;
37: plugin_t *next;
38: };
39:
40: static plugin_t *plugins = NULL;
41:
42: io_ops_t *find_iorange(u32 reg)
43: {
44: iorange_t *range = ioranges;
45: while (range) {
46: if (range->start <= reg && range->end >= reg)
47: return range->ops;
48: range = range->next;
49: }
50: return NULL;
51: }
52:
53: int register_iorange(const char *name, io_ops_t * ops, unsigned int rstart,
54: unsigned int rend)
55: {
56: iorange_t *newrange;
57:
58: /* intersection check */
59: newrange = ioranges;
60: while (newrange) {
61: int fail = 0;
62: /* new section swallows old section */
63: if (newrange->start >= rstart && newrange->end <= rend)
64: fail = -1;
65: /* new section start or end point are within range */
66: if (newrange->start <= rstart && newrange->end >= rstart)
67: fail = -1;
68: if (newrange->start <= rend && newrange->end >= rend)
69: fail = -1;
70: if (fail) {
71: printf("Error: overlapping IO regions: %s and %s\n",
72: newrange->name, name);
73: return -1;
74: }
75: newrange = newrange->next;
76: }
77:
78: newrange = malloc(sizeof(iorange_t));
79:
80: newrange->name = name;
81: newrange->ops = ops;
82: newrange->start = rstart;
83: newrange->end = rend;
84: newrange->next = ioranges;
85:
86: ioranges = newrange;
87:
88: return 0;
89: }
90:
91: int is_loaded(const char *plugin_name)
92: {
93: plugin_t *p = plugins;
94: while (p) {
95: if (!strcmp(plugin_name, p->name))
96: return -1;
97: p = p->next;
98: }
99: return 0;
100: }
101:
102: int load_plugin(const char *plugin_name)
103: {
104: void *handle;
105: char *error;
106: char path[PATHSIZE];
107:
108: int (*init_plugin) (void);
109: char **deps;
110: char **plugin_info;
111: plugin_t *p;
112:
113: if (is_loaded(plugin_name)) {
114: printf("Plugin %s already loaded.\n", plugin_name);
115: return 0;
116: }
117:
118: strncpy(path, PLUGINDIR, PATHSIZE);
119: strncat(path, "/plugin_", PATHSIZE);
120: strncat(path, plugin_name, PATHSIZE);
121: strncat(path, ".so", PATHSIZE);
122:
123: #if DEBUG
124: printf("Opening plugin %s\n", path);
125: #endif
126:
127: handle = dlopen(path, RTLD_LAZY | RTLD_GLOBAL);
128: if (!handle) {
129: error = dlerror();
130: printf("Error: Could not open plugin \"%s\": %s\n",
131: plugin_name, error);
132: exit(1);
133: }
134: #ifdef CONFIG_DEBUG_PLUGINS
135: plugin_info = dlsym(handle, "plugin_author");
136: if ((error = dlerror()) == NULL)
137: printf("Plugin %s author: %s\n", plugin_name, *plugin_info);
138: plugin_info = dlsym(handle, "plugin_license");
139: if ((error = dlerror()) == NULL)
140: printf("Plugin %s license: %s\n", plugin_name, *plugin_info);
141: plugin_info = dlsym(handle, "plugin_description");
142: if ((error = dlerror()) == NULL)
143: printf("Plugin %s descr.: %s\n", plugin_name, *plugin_info);
144: #endif
145: p = malloc(sizeof(plugin_t));
146: p->next = plugins;
147: p->name = plugin_name;
148: plugins = p;
149:
150: deps = dlsym(handle, "plugin_deps");
151: if ((error = dlerror()) != NULL)
152: deps = NULL;
153:
154:
155: strncpy(path, "plugin_", PATHSIZE);
156: strncat(path, plugin_name, PATHSIZE);
157: strncat(path, "_init", PATHSIZE);
158:
159: init_plugin = dlsym(handle, path);
160: if ((error = dlerror()) != NULL) {
161: printf("error: %s\n", error);
162: exit(1);
163: }
164:
165: if (deps) {
166: int i = 0;
167: char *walk = deps[0];
168: #ifdef CONFIG_DEBUG_PLUGINS
169: printf("\nPlugin %s dependencies:", plugin_name);
170: #endif
171: while (walk) {
172: printf(" %s", walk);
173: if (!is_loaded(walk)) {
174: #ifdef CONFIG_DEBUG_PLUGINS
175: printf("(loading)\n");
176: #endif
177: load_plugin(walk);
178: }
179: #ifdef CONFIG_DEBUG_PLUGINS
180: else {
181: printf("(loaded)");
182: }
183: #endif
184: walk = deps[++i];
185: }
186: }
187:
188: printf("\n");
189: #if DEBUG
190: printf("Initializing module:\n");
191: #endif
192:
193: return init_plugin();
194:
195: // We don't dlclose the handle here since
196: // we want to keep our symbols for later use.
197: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.