source: roaraudio/roarclients/roarpluginrunner.c @ 5442:e9a032849792

Last change on this file since 5442:e9a032849792 was 5442:e9a032849792, checked in by phi, 10 years ago

use plugin container to do the --run

File size: 11.1 KB
Line 
1//roarpluginrunner.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2012
5 *
6 *  This file is part of roarclients a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26int g_verbose = 0;
27#define ROAR_DBG_INFOVAR g_verbose
28
29#include <roaraudio.h>
30
31enum action {
32 RUN,
33 EXPLAIN
34};
35
36static struct roar_dl_librarypara * g_para = NULL;
37
38static void usage (const char * progname) {
39 fprintf(stderr, "Usage: %s [OPTIONS]... PLUGIN\n", progname);
40
41 fprintf(stderr, "\nOptions:\n\n");
42
43 fprintf(stderr, " -h --help            - This help.\n"
44                 " -v --verbose         - Be verbose. Can be used multiple times.\n"
45                 "    --server SERVER   - Set default server to SERVER.\n"
46                 "    --run             - Run plugin.\n"
47                 "    --explain         - Explain plugin.\n"
48                 "    --appname NAME    - Sets the appname.\n"
49                 "    --abiversion ABI  - Set the ABI version.\n"
50                 "    --args ARGS       - Set plugin arguments.\n"
51        );
52}
53
54static int do_run(const char * name) {
55 struct roar_plugincontainer * cont = roar_plugincontainer_new(g_para);
56 int err;
57
58 if ( cont == NULL )
59  return -1;
60
61 if ( roar_plugincontainer_load(cont, name, NULL) == -1 ) {
62  err = roar_error;
63  roar_plugincontainer_unref(cont);
64  roar_error = err;
65  return -1;
66 }
67
68 roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_INIT);
69
70 while (roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_WAIT) == 0)
71  roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_UPDATE);
72
73 roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_UPDATE);
74 roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_FREE);
75
76 roar_plugincontainer_unref(cont);
77 return 0;
78}
79
80static const char * _ptr2str(const void * p) {
81#if defined(ROAR_HAVE_LIBDL) && defined(ROAR_HAVE_DLADDR)
82 static char buf[80];
83 Dl_info info;
84#else
85 static char buf[24];
86#endif
87
88 if ( p == NULL )
89  return "<not set>";
90
91#if defined(ROAR_HAVE_LIBDL) && defined(ROAR_HAVE_DLADDR)
92 if ( dladdr(p, &info) != 0 ) {
93  if ( p == info.dli_saddr ) {
94   snprintf(buf, sizeof(buf), "%p <%s in \"%s\">", p, info.dli_sname, info.dli_fname);
95   return buf;
96  }
97 }
98#endif
99
100 snprintf(buf, sizeof(buf), "%p", p);
101
102 return buf;
103}
104
105static const char * _ptrrange2str(const void * p, size_t len) {
106 static char buf[80];
107
108 if ( p == NULL )
109  return "<not set>";
110
111 if ( len == 0 )
112  return _ptr2str(p);
113
114 snprintf(buf, sizeof(buf), "%p-%p", p, p + len);
115
116 return buf;
117}
118
119static int do_explain(const char * name) {
120 struct roar_dl_lhandle * lhandle = roar_dl_open(name, ROAR_DL_FLAG_LAZY|ROAR_DL_FLAG_PLUGINPATH, 0, g_para);
121 struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
122 struct roar_dl_libraryinst * lib;
123 int libok = 0, libnameok = 0, libdepok = 0;
124 int tmp;
125 int i;
126 size_t iter;
127 char c;
128
129 if ( lhandle == NULL )
130  return -1;
131
132 func = roar_dl_getsym(lhandle, "_roaraudio_library_init", -1);
133 if ( func == NULL ) {
134  fprintf(stderr, "Warning: Not a RA lib: %s\n", name);
135  roar_dl_unref(lhandle);
136  return 0;
137 }
138
139 lib = func(g_para);
140 if ( lib == NULL ) {
141  fprintf(stderr, "Warning: Can not RA init: %s: %s\n", name, roar_error2str(roar_error));
142  roar_dl_unref(lhandle);
143  return 0;
144 }
145
146 if ( lib->version == ROAR_DL_LIBINST_VERSION && lib->len == sizeof(*lib) ) {
147  libok = 1;
148 }
149
150 printf("lib                     = %s\n", _ptr2str(lib));
151 if ( g_verbose || !libok ) {
152  printf("|-> version             = %i (%smatch)\n", lib->version, lib->version == ROAR_DL_LIBINST_VERSION ? "" : "no ");
153  printf("%c-> len                 = %zu (%smatch)\n", libok ? '|' : '\\', lib->len, lib->len == sizeof(*lib) ? "" : "no ");
154 }
155
156 if ( libok ) {
157  if ( g_verbose || lib->unload != NULL )
158   printf("|-> unload              = %s\n", _ptr2str(lib->unload));
159  printf("|-> func                = {");
160  i = 0;
161  while (i < ROAR_DL_FN_MAX) {
162   for (tmp = 0; i < ROAR_DL_FN_MAX; i++) {
163    if ( lib->func[i] != NULL ) {
164     break;
165    }
166    tmp++;
167   }
168   if (tmp)
169    printf("%i x <not set>%s", tmp, i < (ROAR_DL_FN_MAX-1) ? ", " : "");
170
171   if ( i < ROAR_DL_FN_MAX ) {
172    printf("[%i] = %s%s", i, _ptr2str(lib->func[i]), i < (ROAR_DL_FN_MAX-1) ? ", " : "");
173    i++;
174   }
175  }
176
177  printf("}\n");
178  printf("|-> libname             = %s\n", _ptr2str(lib->libname));
179  if ( lib->libname != NULL ) {
180   if ( lib->libname->version == ROAR_DL_LIBNAME_VERSION && lib->libname->len == sizeof(*(lib->libname)) ) {
181    libnameok = 1;
182   }
183   if ( g_verbose || !libnameok ) {
184    printf("|   |-> version         = %i (%smatch)\n", lib->libname->version,
185                                                       lib->libname->version == ROAR_DL_LIBNAME_VERSION ? "" : "no ");
186    printf("|   %c-> len             = %zu (%smatch)\n", libnameok ? '|' : '\\', lib->libname->len,
187                                                         lib->libname->len == sizeof(*(lib->libname)) ? "" : "no ");
188   }
189
190   if ( libnameok ) {
191#define _ps(k,name) \
192    tmp = (lib->libname->name) != NULL; \
193    if ( tmp || g_verbose || (k) == '\\' ) \
194    printf("|   %c-> %-15s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \
195                                    tmp ? (lib->libname->name) : "<not set>", tmp ? "\"" : "");
196
197    _ps('|', name);
198    _ps('|', libname);
199    _ps('|', libversion);
200    _ps('|', abiversion);
201    _ps('|', description);
202    _ps('|', contact);
203    _ps('|', authors);
204    _ps('\\', license);
205#undef _ps
206   }
207  }
208  if ( g_verbose || lib->global_data_pointer != NULL )
209   printf("|-> global_data_len     = %zu\n", lib->global_data_len);
210  if ( g_verbose || lib->global_data_init != NULL )
211   printf("|-> global_data_init    = %s\n", _ptrrange2str(lib->global_data_init, lib->global_data_len));
212  if ( g_verbose || lib->global_data_pointer != NULL )
213   printf("|-> global_data_pointer = %s\n", _ptr2str(lib->global_data_pointer));
214
215  if ( lib->libdep != NULL && lib->libdep_len ) {
216   printf("|-> libdep              = %s\n", _ptr2str(lib->libdep));
217   for (iter = 0; iter < lib->libdep_len; iter++) {
218    printf("|   %c-> Table entry %zu   = %p\n", iter == (lib->libdep_len-1) ? '\\' : '|', iter, &(lib->libdep[iter]));
219    c = iter == (lib->libdep_len-1) ? ' ' : '|';
220    if ( lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION &&
221         lib->libdep[iter].len     == sizeof(struct roar_dl_librarydep) ) {
222     libdepok = 1;
223    } else {
224     libdepok = 0;
225    }
226    if ( g_verbose || !libdepok ) {
227     printf("|   %c   |-> version     = %i (%smatch)\n", c, lib->libdep[iter].version,
228                                                         lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION ? "" : "no ");
229     printf("|   %c   %c-> len         = %zu (%smatch)\n", c, libdepok ? '|' : '\\',
230                                                        lib->libdep[iter].len,
231                                                        lib->libdep[iter].len == sizeof(struct roar_dl_librarydep) ?
232                                                        "" : "no ");
233    }
234
235    if ( libdepok ) {
236     printf("|   %c   |-> flags       = 0x%.8lX\n", c, (unsigned long int)lib->libdep[iter].flags);
237#define _ps(k,name) \
238    tmp = (lib->libdep[iter].name) != NULL; \
239    if ( tmp || g_verbose || (k) == '\\' ) \
240    printf("|   %c   %c-> %-11s = %s%s%s\n", c, (k), #name, tmp ? "\"" : "", \
241                                    tmp ? (lib->libdep[iter].name) : "<not set>", tmp ? "\"" : "");
242     _ps('|', name);
243     _ps('|', libname);
244     _ps('\\', abiversion);
245#undef _ps
246    }
247   }
248   printf("|-> libdep_len          = %zu\n", lib->libdep_len);
249  } else if ( (lib->libdep == NULL && lib->libdep_len) || (lib->libdep != NULL && !lib->libdep_len) ) {
250   printf("|-> libdep              = %s (invalid)\n", _ptr2str(lib->libdep));
251   printf("|-> libdep_len          = %zu (invalid)\n", lib->libdep_len);
252  }
253  if ( g_verbose || lib->appsched != NULL ) {
254   printf("|-> appsched            = %s\n", _ptr2str(lib->appsched));
255   if ( lib->appsched != NULL ) {
256    if ( g_verbose || lib->appsched->init != NULL )
257     printf("|   |-> init            = %s\n", _ptr2str(lib->appsched->init));
258    if ( g_verbose || lib->appsched->free != NULL )
259     printf("|   |-> free            = %s\n", _ptr2str(lib->appsched->free));
260    if ( g_verbose || lib->appsched->update != NULL )
261     printf("|   |-> update          = %s\n", _ptr2str(lib->appsched->update));
262    if ( g_verbose || lib->appsched->tick != NULL )
263     printf("|   |-> tick            = %s\n", _ptr2str(lib->appsched->tick));
264    printf("|   \\-> wait            = %s\n", _ptr2str(lib->appsched->wait));
265   }
266  }
267#define _ps(k,name) \
268    tmp = (lib->name) != NULL; \
269    if ( tmp || g_verbose || (k) == '\\' ) \
270    printf("%c-> %-19s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \
271                                    tmp ? (lib->name) : "<not set>", tmp ? "\"" : "");
272  _ps('|', host_appname);
273  _ps('\\', host_abiversion);
274#undef _ps
275 }
276
277 roar_dl_unref(lhandle);
278 return 0;
279}
280
281static int do_plugin(enum action action, const char * name) {
282 switch (action) {
283  case EXPLAIN:
284    return do_explain(name);
285   break;
286  case RUN:
287    return do_run(name);
288   break;
289  default:
290    roar_err_set(ROAR_ERROR_BADRQC);
291    return -1;
292   break;
293 }
294}
295
296static inline void _clear_para(void) {
297 if ( g_para == NULL )
298  return;
299
300 roar_dl_para_unref(g_para);
301 g_para = NULL;
302}
303
304int main (int argc, char * argv[]) {
305 const char * appname    = "roarpluginrunner " ROAR_VSTR_ROARAUDIO;
306 const char * abiversion = "1.0beta0";
307 const char * pluginargs = NULL;
308 enum action action = RUN;
309 int ret = 0;
310 int i;
311 char * k;
312
313 for (i = 1; i < argc; i++) {
314  k = argv[i];
315
316  if ( !strcmp(k, "-h") || !strcmp(k, "--help") ) {
317   usage(argv[0]);
318   return 0;
319  } else if ( !strcmp(k, "--run") ) {
320   action = RUN;
321  } else if ( !strcmp(k, "--explain") ) {
322   action = EXPLAIN;
323  } else if ( !strcmp(k, "-v") || !strcmp(k, "--verbose") ) {
324   g_verbose++;
325  } else if ( !strcmp(k, "--server") ) {
326   roar_libroar_set_server(argv[++i]);
327  } else if ( !strcmp(k, "--appname") ) {
328   appname = argv[++i];
329   _clear_para();
330  } else if ( !strcmp(k, "--abiversion") ) {
331   abiversion = argv[++i];
332   _clear_para();
333  } else if ( !strcmp(k, "--args") ) {
334   pluginargs = argv[++i];
335   _clear_para();
336  } else {
337   if ( g_para == NULL )
338    g_para = roar_dl_para_new(pluginargs, NULL, appname, abiversion);
339   roar_err_set(ROAR_ERROR_NONE);
340   if ( do_plugin(action, k) == -1 ) {
341    fprintf(stderr, "Error loading plugin: %s\n",
342                    roar_error != ROAR_ERROR_NONE ? roar_error2str(roar_error) : roar_dl_errstr(NULL));
343    ret = 1;
344   }
345  }
346 }
347
348 _clear_para();
349
350 return ret;
351}
352
353//ll
Note: See TracBrowser for help on using the repository browser.