]>
jfr.im git - irc/quakenet/newserv.git/blob - core/modules.c
4 * Provides functions for dealing with dynamic modules.
10 #include "../lib/array.h"
11 #include "../lib/sstring.h"
12 #include "../lib/irc_string.h"
34 freesstring(modsuffix
);
36 moddir
=getcopyconfigitem("core","moduledir",".",100);
37 modsuffix
=getcopyconfigitem("core","modulesuffix",".so",5);
39 /* Check for auto-load modules */
40 autoloads
=getconfigitems("core","loadmodule");
41 if (autoloads
!=NULL
) {
42 mods
=(sstring
**)(autoloads
->content
);
43 for (i
=0;i
<autoloads
->cursi
;i
++) {
44 insmod(mods
[i
]->content
);
50 array_init(&modules
,sizeof(module));
51 array_setlim1(&modules
,5);
52 array_setlim2(&modules
,10);
59 int insmod(char *modulename
) {
62 char buf
[1024], buf2
[1024]; /* must be the same! */
63 const char *(*verinfo
)(void);
65 delchars(modulename
,"./\\;");
67 if (isloaded(modulename
)) {
68 Error("core",ERR_DEBUG
,"Tried to load already loaded module: %s",modulename
);
72 if (strlen(modulename
)>100) {
73 Error("core",ERR_WARNING
,"Module name too long: %s",modulename
);
77 i
=array_getfreeslot(&modules
);
78 mods
=(module *)(modules
.content
);
80 sprintf(buf
,"%s/%s%s",moddir
->content
,modulename
,modsuffix
->content
);
83 n
= readlink(buf
, buf2
, sizeof(buf2
));
88 Error("core",ERR_ERROR
,"Loading symlink module %s failed: %s",modulename
, strerror(errno
));
89 array_delslot(&modules
,i
);
95 memcpy(buf
, buf2
, sizeof(buf
));
98 mods
[i
].handle
=dlopen(buf
,RTLD_NOW
|RTLD_GLOBAL
);
100 if(mods
[i
].handle
==NULL
) {
101 Error("core",ERR_ERROR
,"Loading module %s failed: %s",modulename
,dlerror());
102 array_delslot(&modules
,i
);
106 mods
[i
].name
=getsstring(modulename
,MODULENAMELEN
);
108 verinfo
=dlsym(mods
[i
].handle
,"_version");
110 mods
[i
].version
=verinfo();
112 mods
[i
].version
=NULL
;
115 Error("core",ERR_INFO
,"Loaded module %s OK.",modulename
);
120 int getindex(char *modulename
) {
124 mods
=(module *)(modules
.content
);
125 for(i
=0;i
<modules
.cursi
;i
++)
126 if (!strcmp(mods
[i
].name
->content
,modulename
))
132 char *lsmod(int index
) {
135 if (index
< 0 || index
>= modules
.cursi
)
138 mods
=(module *)(modules
.content
);
139 return mods
[index
].name
->content
;
142 const char *lsmodver(int index
) {
145 if (index
< 0 || index
>= modules
.cursi
)
148 mods
=(module *)(modules
.content
);
149 return mods
[index
].version
;
152 int isloaded(char *modulename
) {
153 if (getindex(modulename
)==-1)
159 int rmmod(char *modulename
) {
163 delchars(modulename
,"./\\;");
165 i
=getindex(modulename
);
169 mods
=(module *)(modules
.content
);
171 #ifdef BROKEN_DLCLOSE
174 fini
= dlsym(mods
[i
].handle
, "__fini");
180 dlclose(mods
[i
].handle
);
181 freesstring(mods
[i
].name
);
182 array_delslot(&modules
,i
);
184 Error("core",ERR_INFO
,"Removed module %s.",modulename
);