File: plugin.c

package info (click to toggle)
keytouch 2.2.2-2
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 4,212 kB
  • ctags: 1,399
  • sloc: ansic: 9,195; sh: 3,630; makefile: 399
file content (287 lines) | stat: -rw-r--r-- 6,782 bytes parent folder | download
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
/*---------------------------------------------------------------------------------
Name               : plugin.c
Author             : Marvin Raaijmakers
Description        : Manages the plugins
Date of last change: 20-Aug-2005

    Copyright (C) 2005 Marvin Raaijmakers

    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 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

    You can contact me at: marvinr(at)users(dot)sf(dot)net
    (replace (at) by @ and (dot) by .)
-----------------------------------------------------------------------------------*/
#include <string.h>
#include <dirent.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#include <keytouchd.h>


static void add_plugin (KeytouchPlugin *plugin, KTPluginList *plugin_list);
static KeytouchPlugin *load_plugin (char *file_name);
static void read_plugin_dir (char *dir, KTPluginList *plugin_list);
static int always_true (const struct dirent *file);


KTPluginFunction
*get_plugin_function (	char	*plugin_name,
			char	*function_name )
/*
Input:
	plugin_name	- The name of the plugin to find
	function_name	- The function in the plugin to find
Output:
	-
Global:
	plugin_list	- List containing al available plugins
Returns:
	A pointer to the KTPluginFunction named function_name of the plugin named
	plugin_name. If no such function was found it returns NULL.
Description:
	The function searches for a KTPluginFunction in the list of available
	plugins.
*/
{
	KeytouchPlugin	*plugin;
	int		count;
	
	plugin = find_plugin(plugin_name);
	
	/* If the plugin does not exist */
	if (plugin == NULL)
	{
		return (NULL);
	}
	/* Find the function */
	for (count = 0;
	      count < plugin->num_functions &&
	      strcmp(plugin->function[count].name, function_name) != EQUAL;
	     count++)
		; /* NULL Statement */
		
	/* If the function does not exist */
	if (count == plugin->num_functions)
	{
		return (NULL);
	}
	return (&plugin->function[count]);
}


KeytouchPlugin
*find_plugin (char *plugin_name)
/*
Input:
	plugin_name	- The name of the plugin to find
Output:
	-
Global:
	plugin_list	- List containing al available plugins
Returns:
	A pointer to the KeytouchPlugin named plugin_name. If no such plugin was
	found it returns NULL.
Description:
	The function searches for a KeytouchPlugin in the list of available plugins.
*/
{
	KTPluginListEntry *plugin;
	
	/* Find the plugin */
	for (plugin = plugin_list.head;
	     plugin != NULL && strcmp(plugin->plugin->info.name, plugin_name) != EQUAL;
	     plugin = plugin->next)
		; /* NULL Statement */
	
	/* If the plugin does not exist */
	if (plugin == NULL)
	{
		return (NULL);
	}
	
	return (plugin->plugin);
}


void
add_plugin (	KeytouchPlugin	*plugin,
		KTPluginList	*plugin_list  )
/*
Input:
	plugin		- The plugin to add to plugin_list
Output:
	plugin_list	- plugin is added to this list
Returns:
	-
Description:
	This function adds plugin to plugin_list.
*/
{
	KTPluginListEntry *entry;
	
	entry = keytouch_malloc(sizeof(KTPluginListEntry));
	entry->plugin = plugin;
	entry->next = NULL;
	if (plugin_list->head == NULL)
	{
		plugin_list->head = plugin_list->tail = entry;
	}
	else
	{
		plugin_list->tail->next = entry;
		plugin_list->tail = entry;
	}
}


int
always_true (const struct dirent *file)
{
	return (TRUE);
}


KeytouchPlugin
*load_plugin (char *file_name)
/*
Input:
	file_name	- The file name of the plugin
Output:
	-
Returns:
	A pointer to the KeytouchPlugin structure if the plugin was succesfully
	loaded, otherwise NULL.
Description:
	This function loads the plugin which file name is file_name.
*/
{
	void		*plugin_file;
	KeytouchPlugin	*plugin;
	
	/* Open the plugin */
	plugin_file = dlopen(file_name, RTLD_LAZY);
	if (plugin_file == NULL)
	{
		return (NULL);
        }
	/* Get the plugin structure */
	plugin = dlsym(plugin_file, "plugin_struct");
	/* If an error occured or the plugin is already in the list */
	if (dlerror() != NULL || find_plugin(plugin->info.name) != NULL)
	{
		dlclose (plugin); /* Close the opened plugin */
		return (NULL);
	}
	return (plugin);
}


void
read_plugin_dir (	char		*dir,
			KTPluginList	*plugin_list  )
/*
Input:
	dir		- The directory to read the plugins from.
Output:
	plugin_list	- The plugins in dir are added to this list.
Returns:
	-
Description:
	This function reads the plugins from the directory which path is dir and
	adds them to plugin_list.
*/
{
	struct dirent	**file_list;
	int		num_files,
			count;
	KeytouchPlugin	*plugin;
	char		*complete_file_name;
	
	num_files = scandir (dir, &file_list, always_true, alphasort);
	if (num_files >= 0)
	{
		for (count = 0; count < num_files; count++)
		{
			complete_file_name = keytouch_malloc(strlen(file_list[count]->d_name) +
			                                     strlen(dir) + 2);
			strcpy (complete_file_name, dir);
			strcat (complete_file_name, "/");
			strcat (complete_file_name, file_list[count]->d_name);
			plugin = load_plugin(complete_file_name);
			if (plugin != NULL)
			{
				add_plugin (plugin, plugin_list);
			}
			free (complete_file_name);
		}
	}
	else
	{
		KTError ("Plugin directory '%s' does not exist. "
		         "This program will continue without loading "
			 "the plugins in this directory.", dir);
	}
}


void
read_plugins (KTPluginList *plugin_list)
/*
Input:
	-
Output:
	plugin_list	- The plugins are added to this list.
Returns:
	-
Description:
	This function reads the plugins from the plugin directories and adds them to
	plugin_list.
*/
{
	char	*home_dir,
		*local_plugin_dir;
	int	local_plugin_dir_len;
	
	read_plugin_dir (PLUGIN_DIR, plugin_list);
	home_dir = getenv("HOME");
	if (home_dir != NULL)
	{
		local_plugin_dir_len = strlen(home_dir)+strlen("/"LOCAL_PLUGIN_DIR);
		local_plugin_dir = keytouch_malloc(local_plugin_dir_len+1);
		strcpy (local_plugin_dir, home_dir);
		strcat (local_plugin_dir, "/"LOCAL_PLUGIN_DIR);
		read_plugin_dir (local_plugin_dir, plugin_list);
		free (local_plugin_dir);
	}
}

void
init_plugins (KTPluginList *plugin_list)
/*
Input:
	-
Output:
	plugin_list	- Initialized empty plugin list.
Returns:
	-
Description:
	This function initializes plugin_list to be empty.
*/
{
	plugin_list->head = plugin_list->tail = NULL;
}