1 /*
2 * gsat - a realtime satellite tracking graphical frontend to predict
3 *
4 * Copyright (C) 2001 by Xavier Crehueras, EB3CZS
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 * Look at the README for more information on the program.
21 */
22
23 /* Plugin functions */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 #include <errno.h>
30 #include <dlfcn.h>
31 #include <dirent.h>
32 #include <gtk/gtk.h>
33
34 #include "support.h"
35 #include "comms.h"
36
37 #include "globals.h"
38
close_uplink_plugin(void)39 void close_uplink_plugin( void )
40 {
41 if(uppluginenable==FALSE)
42 return;
43
44 /* close rig if it was open before closing plugin */
45 if( enableupdoppler==TRUE ) {
46 (*plugin_close_rig_uplink)();
47 enableupdoppler=FALSE;
48 }
49
50 dlclose(upplugin_handle);
51
52 uppluginenable=FALSE;
53 }
54
open_uplink_plugin(char * plugin)55 int open_uplink_plugin( char * plugin )
56 {
57 char * error;
58
59 /* if it's already open, close it first */
60 if( uppluginenable==TRUE )
61 close_uplink_plugin();
62
63 upplugin_handle=dlopen( plugin, RTLD_NOW );
64 if( upplugin_handle==NULL )
65 if( (error=dlerror()) != NULL ) {
66 fprintf(stderr,"Error opening uplink plugin: %s\n",error);
67 return FALSE;
68 }
69
70 plugin_info_uplink=dlsym(upplugin_handle,"plugin_info");
71 if( plugin_info_uplink==NULL )
72 if( (error=dlerror()) != NULL ) {
73 fprintf(stderr,"Error: plugin_info_uplink: %s\n",error);
74 return FALSE;
75 }
76
77 plugin_open_rig_uplink=dlsym(upplugin_handle,"plugin_open_rig");
78 if( plugin_open_rig_uplink==NULL )
79 if( (error=dlerror()) != NULL ) {
80 fprintf(stderr,"Error: plugin_open_rig_uplink: %s\n",error);
81 return FALSE;
82 }
83
84 plugin_close_rig_uplink=dlsym(upplugin_handle,"plugin_close_rig");
85 if( plugin_close_rig_uplink==NULL )
86 if( (error=dlerror()) != NULL ) {
87 fprintf(stderr,"Error: plugin_close_rig_uplink: %s\n",error);
88 return FALSE;
89 }
90
91 plugin_set_uplink_frequency=dlsym(upplugin_handle,"plugin_set_uplink_frequency");
92 if( plugin_set_uplink_frequency==NULL )
93 if( (error=dlerror()) != NULL ) {
94 fprintf(stderr,"Error: plugin_set_uplink_frequency: %s\n",error);
95 return FALSE;
96 }
97
98 uppluginenable=TRUE;
99
100 return TRUE;
101 }
102
close_downlink_plugin(void)103 void close_downlink_plugin( void )
104 {
105 if(downpluginenable==FALSE)
106 return;
107
108 /* close rig if it was open before closing plugin */
109 if( enabledowndoppler==TRUE ) {
110 (*plugin_close_rig_downlink)();
111 enabledowndoppler=FALSE;
112 }
113
114 dlclose(downplugin_handle);
115
116 downpluginenable=FALSE;
117 }
118
open_downlink_plugin(char * plugin)119 int open_downlink_plugin( char * plugin )
120 {
121 char * error;
122
123 /* if it's already open, close it first */
124 if( downpluginenable==TRUE )
125 close_downlink_plugin();
126
127 downplugin_handle=dlopen( plugin, RTLD_NOW );
128 if( downplugin_handle==NULL )
129 if( (error=dlerror()) != NULL ) {
130 fprintf(stderr,"Error opening downlink plugin: %s\n",error);
131 return FALSE;
132 }
133
134 plugin_info_downlink=dlsym(downplugin_handle,"plugin_info");
135 if( plugin_info_downlink==NULL )
136 if( (error=dlerror()) != NULL ) {
137 fprintf(stderr,"Error: plugin_info_downlink: %s\n",error);
138 return FALSE;
139 }
140 plugin_open_rig_downlink=dlsym(downplugin_handle,"plugin_open_rig");
141 if( plugin_open_rig_downlink==NULL )
142 if( (error=dlerror()) != NULL ) {
143 fprintf(stderr,"Error: plugin_open_rig_downlink: %s\n",error);
144 return FALSE;
145 }
146 plugin_close_rig_downlink=dlsym(downplugin_handle,"plugin_close_rig");
147 if( plugin_close_rig_downlink==NULL )
148 if( (error=dlerror()) != NULL ) {
149 fprintf(stderr,"Error: plugin_close_rig_downlink: %s\n",error);
150 return FALSE;
151 }
152 plugin_set_downlink_frequency=dlsym(downplugin_handle,"plugin_set_downlink_frequency");
153 if( plugin_set_downlink_frequency==NULL )
154 if( (error=dlerror()) != NULL ) {
155 fprintf(stderr,"Error: plugin_set_downlink_frequency: %s\n",error);
156 return FALSE;
157 }
158
159 downpluginenable=TRUE;
160
161 return TRUE;
162 }
163
close_beacon_plugin(void)164 void close_beacon_plugin( void )
165 {
166 if(beaconpluginenable==FALSE)
167 return;
168
169 /* close rig if it was open before closing plugin */
170 if( enablebeacondoppler==TRUE ) {
171 (*plugin_close_rig_beacon)();
172 enablebeacondoppler=FALSE;
173 }
174
175 dlclose(beaconplugin_handle);
176
177 beaconpluginenable=FALSE;
178 }
179
open_beacon_plugin(char * plugin)180 int open_beacon_plugin( char * plugin )
181 {
182 char * error;
183
184 /* if it's already open, close it first */
185 if( beaconpluginenable==TRUE )
186 close_beacon_plugin();
187
188 beaconplugin_handle=dlopen( plugin, RTLD_NOW );
189 if( beaconplugin_handle==NULL )
190 if( (error=dlerror()) != NULL ) {
191 fprintf(stderr,"Error opening beacon plugin: %s\n",error);
192 return FALSE;
193 }
194
195 plugin_info_beacon=dlsym(beaconplugin_handle,"plugin_info");
196 if( plugin_info_beacon==NULL )
197 if( (error=dlerror()) != NULL ) {
198 fprintf(stderr,"Error: plugin_info_beacon: %s\n",error);
199 return FALSE;
200 }
201 plugin_open_rig_beacon=dlsym(beaconplugin_handle,"plugin_open_rig");
202 if( plugin_open_rig_beacon==NULL )
203 if( (error=dlerror()) != NULL ) {
204 fprintf(stderr,"Error: plugin_open_rig_beacon: %s\n",error);
205 return FALSE;
206 }
207 plugin_close_rig_beacon=dlsym(beaconplugin_handle,"plugin_close_rig");
208 if( plugin_close_rig_beacon==NULL )
209 if( (error=dlerror()) != NULL ) {
210 fprintf(stderr,"Error: plugin_close_rig_beacon: %s\n",error);
211 return FALSE;
212 }
213 plugin_set_beacon_frequency=dlsym(beaconplugin_handle,"plugin_set_downlink_frequency");
214 if( plugin_set_beacon_frequency==NULL )
215 if( (error=dlerror()) != NULL ) {
216 fprintf(stderr,"Error: plugin_set_beacon_frequency: %s\n",error);
217 return FALSE;
218 }
219
220 beaconpluginenable=TRUE;
221
222 return TRUE;
223 }
224
check_radio_plugin_file(const struct dirent * plugdir)225 int check_radio_plugin_file( const struct dirent * plugdir )
226 {
227 return ! strncmp(plugdir->d_name,"radio_",6);
228 }
229
search_radio_plugins(void)230 void search_radio_plugins( void )
231 {
232 struct dirent **namelist;
233 int n, i;
234 GtkWidget * widget;
235 char filename[256];
236 DIR * dir;
237
238 /* empty plugin list if it was created */
239 n = g_list_length(pluginlist);
240 if( n > 0 ) {
241 pluginlist=g_list_first( pluginlist );
242 for( i=0; i<n; i++ )
243 pluginlist=g_list_remove( pluginlist, pluginlist->data );
244 for( i=0; i<n; i++ ) {
245 pluginfiles[i][0]='\0';
246 plugindescriptions[i][0]='\0';
247 }
248 }
249
250 strcpy( pluginfiles[0], "None");
251 strcpy( plugindescriptions[0], "No Plugin");
252 pluginlist=g_list_append( pluginlist, plugindescriptions[0] );
253
254 /* check plugin directory */
255 if( (dir=opendir( pluginsdir ))==NULL ) {
256 switch( errno ) {
257 case EACCES:
258 fprintf(stderr, "Error: You don't have access to plugin directory.\n");
259 error_dialog("You don't have access to plugin directory.");
260 break;
261 case ENOENT:
262 fprintf(stderr, "Error: Plugin directory doesn't exist.\n");
263 error_dialog("Plugin directory doesn't exist.");
264 break;
265 case ENOTDIR:
266 fprintf(stderr, "Error: Plugin directory is not a directory.\n");
267 error_dialog("Can't open plugin directory.");
268 break;
269 default:
270 fprintf(stderr, "Error: Can't open plugin directory.\n");
271 error_dialog("Can't open plugin directory.");
272 break;
273 }
274 /* Attach plugin list */
275 widget=lookup_widget( dialog_preferences, "combo_upplugin" );
276 gtk_combo_set_popdown_strings( GTK_COMBO(widget), pluginlist);
277 widget=lookup_widget( dialog_preferences, "combo_downplugin" );
278 gtk_combo_set_popdown_strings( GTK_COMBO(widget), pluginlist);
279 widget=lookup_widget( dialog_preferences, "combo_beaconplugin" );
280 gtk_combo_set_popdown_strings( GTK_COMBO(widget), pluginlist);
281 return;
282 }
283 closedir( dir );
284
285 /* scan plugin directory and create plugin list */
286 n = scandir(pluginsdir, &namelist, check_radio_plugin_file, alphasort);
287 if (n < 0) {
288 perror("scandir");
289 return;
290 }
291
292 for( i=0; i<n; i++ ) {
293 strcpy(filename, pluginsdir);
294 strcat(filename, namelist[i]->d_name);
295 if(open_downlink_plugin(filename)==TRUE) {
296 strncpy( pluginfiles[i+1], namelist[i]->d_name, 29);
297 strncpy( plugindescriptions[i+1], (*plugin_info_downlink)(), 29);
298 pluginlist=g_list_append( pluginlist, plugindescriptions[i+1] );
299 close_downlink_plugin();
300 }
301 }
302
303 /* Attach plugin list */
304 widget=lookup_widget( dialog_preferences, "combo_upplugin" );
305 gtk_combo_set_popdown_strings( GTK_COMBO(widget), pluginlist);
306 widget=lookup_widget( dialog_preferences, "combo_downplugin" );
307 gtk_combo_set_popdown_strings( GTK_COMBO(widget), pluginlist);
308 widget=lookup_widget( dialog_preferences, "combo_beaconplugin" );
309 gtk_combo_set_popdown_strings( GTK_COMBO(widget), pluginlist);
310 }
311
close_rotor_plugin(void)312 void close_rotor_plugin( void )
313 {
314 if(rotorpluginenable==FALSE)
315 return;
316
317 /* close rotor if it was open before closing plugin */
318 if( enablerotor==TRUE ) {
319 (*plugin_close_rotor)();
320 enablerotor=FALSE;
321 }
322
323 dlclose(rotorplugin_handle);
324
325 rotorpluginenable=FALSE;
326 }
327
open_rotor_plugin(char * plugin)328 int open_rotor_plugin( char * plugin )
329 {
330 char * error;
331
332 /* if it's already open, close it first */
333 if( rotorpluginenable==TRUE )
334 close_rotor_plugin();
335
336 rotorplugin_handle=dlopen( plugin, RTLD_NOW );
337 if( rotorplugin_handle==NULL )
338 if( (error=dlerror()) != NULL ) {
339 fprintf(stderr,"Error opening rotor plugin: %s\n",error);
340 return FALSE;
341 }
342
343 plugin_info_rotor=dlsym(rotorplugin_handle,"plugin_info");
344 if( plugin_info_rotor==NULL )
345 if( (error=dlerror()) != NULL ) {
346 fprintf(stderr,"Error: plugin_info_rotor: %s\n",error);
347 return FALSE;
348 }
349 plugin_open_rotor=dlsym(rotorplugin_handle,"plugin_open_rotor");
350 if( plugin_open_rotor==NULL )
351 if( (error=dlerror()) != NULL ) {
352 fprintf(stderr,"Error: plugin_open_rotor: %s\n",error);
353 return FALSE;
354 }
355 plugin_close_rotor=dlsym(rotorplugin_handle,"plugin_close_rotor");
356 if( plugin_close_rotor==NULL )
357 if( (error=dlerror()) != NULL ) {
358 fprintf(stderr,"Error: plugin_close_rotor: %s\n",error);
359 return FALSE;
360 }
361 plugin_set_rotor=dlsym(rotorplugin_handle,"plugin_set_rotor");
362 if( plugin_set_rotor==NULL )
363 if( (error=dlerror()) != NULL ) {
364 fprintf(stderr,"Error: plugin_set_rotor: %s\n",error);
365 return FALSE;
366 }
367
368 rotorpluginenable=TRUE;
369
370 return TRUE;
371 }
372
check_rotor_plugin_file(const struct dirent * plugdir)373 int check_rotor_plugin_file( const struct dirent * plugdir )
374 {
375 return ! strncmp(plugdir->d_name,"rotor_",6);
376 }
377
search_rotor_plugins(void)378 void search_rotor_plugins( void )
379 {
380 struct dirent **namelist;
381 int n, i;
382 GtkWidget * widget;
383 char filename[256];
384 DIR * dir;
385
386 /* empty plugin list if it was created */
387 n = g_list_length(rotorpluginlist);
388 if( n > 0 ) {
389 rotorpluginlist=g_list_first( rotorpluginlist );
390 for( i=0; i<n; i++ )
391 rotorpluginlist=g_list_remove( rotorpluginlist, rotorpluginlist->data );
392 for( i=0; i<n; i++ ) {
393 rotorpluginfiles[i][0]='\0';
394 rotorplugindescriptions[i][0]='\0';
395 }
396 }
397
398 strcpy( rotorpluginfiles[0], "None");
399 strcpy( rotorplugindescriptions[0], "No Plugin");
400 rotorpluginlist=g_list_append( rotorpluginlist, rotorplugindescriptions[0] );
401
402 /* check plugin directory */
403 if( (dir=opendir( pluginsdir ))==NULL ) {
404 switch( errno ) {
405 case EACCES:
406 fprintf(stderr, "Error: You don't have access to plugin directory.\n");
407 error_dialog("You don't have access to plugin directory.");
408 break;
409 case ENOENT:
410 fprintf(stderr, "Error: Plugin directory doesn't exist.\n");
411 error_dialog("Plugin directory doesn't exist.");
412 break;
413 case ENOTDIR:
414 fprintf(stderr, "Error: Plugin directory is not a directory.\n");
415 error_dialog("Can't open plugin directory.");
416 break;
417 default:
418 fprintf(stderr, "Error: Can't open plugin directory.\n");
419 error_dialog("Can't open plugin directory.");
420 break;
421 }
422 /* Attach rotor plugin list */
423 widget=lookup_widget( dialog_preferences, "combo_rotorplugin" );
424 gtk_combo_set_popdown_strings( GTK_COMBO(widget), rotorpluginlist);
425
426 return;
427 }
428 closedir( dir );
429
430 /* scan plugin directory and create plugin list */
431 n = scandir(pluginsdir, &namelist, check_rotor_plugin_file, alphasort);
432 if (n < 0) {
433 perror("scandir");
434 return;
435 }
436
437 for( i=0; i<n; i++ ) {
438 strcpy(filename, pluginsdir);
439 strcat(filename, namelist[i]->d_name);
440 if(open_rotor_plugin(filename)==TRUE) {
441 strncpy( rotorpluginfiles[i+1], namelist[i]->d_name, 29);
442 strncpy( rotorplugindescriptions[i+1], (*plugin_info_rotor)(), 29);
443 rotorpluginlist=g_list_append(rotorpluginlist, rotorplugindescriptions[i+1]);
444 close_rotor_plugin();
445 }
446 }
447
448 /* Attach plugin list */
449 widget=lookup_widget( dialog_preferences, "combo_rotorplugin" );
450 gtk_combo_set_popdown_strings( GTK_COMBO(widget), rotorpluginlist);
451 }
452