-
Notifications
You must be signed in to change notification settings - Fork 1
/
plugin.c
99 lines (88 loc) · 2.49 KB
/
plugin.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <dirent.h>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <syslog.h>
#include "config.h"
#include "pcre.h"
#include "plugin.h"
void **PLUGINS = NULL;
int NUMPLUGINS = 0;
int load_plugins_dir(char *plugin_path)
{
DIR *dirp;
struct dirent *ent;
char *pattern;
const char *errmsg;
int erroffset;
pcre *re;
int status;
int outputvec[3];
char dlpath[256];
dirp = opendir(plugin_path);
if(dirp == NULL)
{
syslog(LOG_WARNING, "%s(): opendir failed", __func__);
return 1;
}
pattern = "^[\\w\\.]+" SO_SUFFIX "$";
re = pcre_compile( pattern,
0,
&errmsg,
&erroffset,
NULL);
if(re == NULL)
{
syslog(LOG_CRIT, "%s(): PCRE compilation error", __func__);
return 2;
}
// FIXME all erroneous returns farther down leak the memory for re
while((ent = readdir(dirp)) != NULL)
{
status = pcre_exec( re,
NULL,
ent->d_name,
strlen(ent->d_name),
0, 0, outputvec, 3);
/* Status > 0 is a match */
/*** Note that pcre_exec() never returns 0 ***/
if(status > 0)
{
/* Load the plugin! */
sprintf(dlpath, "%s/%s", plugin_path, ent->d_name);
load_plugin(dlpath);
}
/* Status < 0 is either a non-match or an error */
else if(status < 0)
{
switch(status)
{
case PCRE_ERROR_NOMATCH:
break;
default:
syslog(LOG_CRIT, "%s(): PCRE mattaching error %d on ent '%s'", __func__, status, ent->d_name);
return 3;
}
}
}
closedir(dirp);
free(re);
return 0;
}
int load_plugin(char *path)
{
void *DL;
DL = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
if(DL == NULL)
{
syslog(LOG_NOTICE, "%s(): dlopen errored: %s", __func__, dlerror());
return 1;
}
/* Store the handle to the plugin */
NUMPLUGINS++;
PLUGINS = realloc(PLUGINS, sizeof(void*) * (NUMPLUGINS));
PLUGINS[NUMPLUGINS - 1] = DL;
syslog(LOG_INFO, "%s(): module '%s' loaded as plugin #%d", __func__, path, NUMPLUGINS - 1);
return 0;
}