source: roaraudio/roarclients/roarpluginrunner.c @ 5381:430b1d26e12d

Last change on this file since 5381:430b1d26e12d was 5381:430b1d26e12d, checked in by phi, 10 years ago

updated copyright years

File size: 10.9 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_dl_lhandle * lhandle = roar_dl_open(name, ROAR_DL_FLAG_DEFAULTS, 1, g_para);
56
57 if ( lhandle == NULL )
58  return -1;
59
60 roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_INIT);
61
62 while (roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_WAIT) == 0)
63  roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_UPDATE);
64
65 roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_UPDATE);
66 roar_dl_appsched_trigger(lhandle, ROAR_DL_APPSCHED_FREE);
67
68 roar_dl_unref(lhandle);
69 return 0;
70}
71
72static const char * _ptr2str(const void * p) {
73#if defined(ROAR_HAVE_LIBDL) && defined(ROAR_HAVE_DLADDR)
74 static char buf[80];
75 Dl_info info;
76#else
77 static char buf[24];
78#endif
79
80 if ( p == NULL )
81  return "<not set>";
82
83#if defined(ROAR_HAVE_LIBDL) && defined(ROAR_HAVE_DLADDR)
84 if ( dladdr(p, &info) != 0 ) {
85  if ( p == info.dli_saddr ) {
86   snprintf(buf, sizeof(buf), "%p <%s in \"%s\">", p, info.dli_sname, info.dli_fname);
87   return buf;
88  }
89 }
90#endif
91
92 snprintf(buf, sizeof(buf), "%p", p);
93
94 return buf;
95}
96
97static const char * _ptrrange2str(const void * p, size_t len) {
98 static char buf[80];
99
100 if ( p == NULL )
101  return "<not set>";
102
103 if ( len == 0 )
104  return _ptr2str(p);
105
106 snprintf(buf, sizeof(buf), "%p-%p", p, p + len);
107
108 return buf;
109}
110
111static int do_explain(const char * name) {
112 struct roar_dl_lhandle * lhandle = roar_dl_open(name, ROAR_DL_FLAG_LAZY, 0, NULL);
113 struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
114 struct roar_dl_libraryinst * lib;
115 int libok = 0, libnameok = 0, libdepok = 0;
116 int tmp;
117 int i;
118 size_t iter;
119 char c;
120
121 if ( lhandle == NULL )
122  return -1;
123
124 func = roar_dl_getsym(lhandle, "_roaraudio_library_init", -1);
125 if ( func == NULL ) {
126  fprintf(stderr, "Warning: Not a RA lib: %s\n", name);
127  roar_dl_unref(lhandle);
128  return 0;
129 }
130
131 lib = func(g_para);
132 if ( lib == NULL ) {
133  fprintf(stderr, "Warning: Can not RA init: %s: %s\n", name, roar_error2str(roar_error));
134  roar_dl_unref(lhandle);
135  return 0;
136 }
137
138 if ( lib->version == ROAR_DL_LIBINST_VERSION && lib->len == sizeof(*lib) ) {
139  libok = 1;
140 }
141
142 printf("lib                     = %s\n", _ptr2str(lib));
143 if ( g_verbose || !libok ) {
144  printf("|-> version             = %i (%smatch)\n", lib->version, lib->version == ROAR_DL_LIBINST_VERSION ? "" : "no ");
145  printf("%c-> len                 = %zu (%smatch)\n", libok ? '|' : '\\', lib->len, lib->len == sizeof(*lib) ? "" : "no ");
146 }
147
148 if ( libok ) {
149  if ( g_verbose || lib->unload != NULL )
150   printf("|-> unload              = %s\n", _ptr2str(lib->unload));
151  printf("|-> func                = {");
152  i = 0;
153  while (i < ROAR_DL_FN_MAX) {
154   for (tmp = 0; i < ROAR_DL_FN_MAX; i++) {
155    if ( lib->func[i] != NULL ) {
156     break;
157    }
158    tmp++;
159   }
160   if (tmp)
161    printf("%i x <not set>%s", tmp, i < (ROAR_DL_FN_MAX-1) ? ", " : "");
162
163   if ( i < ROAR_DL_FN_MAX ) {
164    printf("[%i] = %s%s", i, _ptr2str(lib->func[i]), i < (ROAR_DL_FN_MAX-1) ? ", " : "");
165    i++;
166   }
167  }
168
169  printf("}\n");
170  printf("|-> libname             = %s\n", _ptr2str(lib->libname));
171  if ( lib->libname != NULL ) {
172   if ( lib->libname->version == ROAR_DL_LIBNAME_VERSION && lib->libname->len == sizeof(*(lib->libname)) ) {
173    libnameok = 1;
174   }
175   if ( g_verbose || !libnameok ) {
176    printf("|   |-> version         = %i (%smatch)\n", lib->libname->version,
177                                                       lib->libname->version == ROAR_DL_LIBNAME_VERSION ? "" : "no ");
178    printf("|   %c-> len             = %zu (%smatch)\n", libnameok ? '|' : '\\', lib->libname->len,
179                                                         lib->libname->len == sizeof(*(lib->libname)) ? "" : "no ");
180   }
181
182   if ( libnameok ) {
183#define _ps(k,name) \
184    tmp = (lib->libname->name) != NULL; \
185    if ( tmp || g_verbose || (k) == '\\' ) \
186    printf("|   %c-> %-15s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \
187                                    tmp ? (lib->libname->name) : "<not set>", tmp ? "\"" : "");
188
189    _ps('|', name);
190    _ps('|', libname);
191    _ps('|', libversion);
192    _ps('|', abiversion);
193    _ps('|', description);
194    _ps('|', contact);
195    _ps('|', authors);
196    _ps('\\', license);
197#undef _ps
198   }
199  }
200  if ( g_verbose || lib->global_data_pointer != NULL )
201   printf("|-> global_data_len     = %zu\n", lib->global_data_len);
202  if ( g_verbose || lib->global_data_init != NULL )
203   printf("|-> global_data_init    = %s\n", _ptrrange2str(lib->global_data_init, lib->global_data_len));
204  if ( g_verbose || lib->global_data_pointer != NULL )
205   printf("|-> global_data_pointer = %s\n", _ptr2str(lib->global_data_pointer));
206
207  if ( lib->libdep != NULL && lib->libdep_len ) {
208   printf("|-> libdep              = %s\n", _ptr2str(lib->libdep));
209   for (iter = 0; iter < lib->libdep_len; iter++) {
210    printf("|   %c-> Table entry %zu   = %p\n", iter == (lib->libdep_len-1) ? '\\' : '|', iter, &(lib->libdep[iter]));
211    c = iter == (lib->libdep_len-1) ? ' ' : '|';
212    if ( lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION &&
213         lib->libdep[iter].len     == sizeof(struct roar_dl_librarydep) ) {
214     libdepok = 1;
215    } else {
216     libdepok = 0;
217    }
218    if ( g_verbose || !libdepok ) {
219     printf("|   %c   |-> version     = %i (%smatch)\n", c, lib->libdep[iter].version,
220                                                         lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION ? "" : "no ");
221     printf("|   %c   %c-> len         = %zu (%smatch)\n", c, libdepok ? '|' : '\\',
222                                                        lib->libdep[iter].len,
223                                                        lib->libdep[iter].len == sizeof(struct roar_dl_librarydep) ?
224                                                        "" : "no ");
225    }
226
227    if ( libdepok ) {
228     printf("|   %c   |-> flags       = 0x%.8lX\n", c, (unsigned long int)lib->libdep[iter].flags);
229#define _ps(k,name) \
230    tmp = (lib->libdep[iter].name) != NULL; \
231    if ( tmp || g_verbose || (k) == '\\' ) \
232    printf("|   %c   %c-> %-11s = %s%s%s\n", c, (k), #name, tmp ? "\"" : "", \
233                                    tmp ? (lib->libdep[iter].name) : "<not set>", tmp ? "\"" : "");
234     _ps('|', name);
235     _ps('|', libname);
236     _ps('\\', abiversion);
237#undef _ps
238    }
239   }
240   printf("|-> libdep_len          = %zu\n", lib->libdep_len);
241  } else if ( (lib->libdep == NULL && lib->libdep_len) || (lib->libdep != NULL && !lib->libdep_len) ) {
242   printf("|-> libdep              = %s (invalid)\n", _ptr2str(lib->libdep));
243   printf("|-> libdep_len          = %zu (invalid)\n", lib->libdep_len);
244  }
245  if ( g_verbose || lib->appsched != NULL ) {
246   printf("|-> appsched            = %s\n", _ptr2str(lib->appsched));
247   if ( lib->appsched != NULL ) {
248    if ( g_verbose || lib->appsched->init != NULL )
249     printf("|   |-> init            = %s\n", _ptr2str(lib->appsched->init));
250    if ( g_verbose || lib->appsched->free != NULL )
251     printf("|   |-> free            = %s\n", _ptr2str(lib->appsched->free));
252    if ( g_verbose || lib->appsched->update != NULL )
253     printf("|   |-> update          = %s\n", _ptr2str(lib->appsched->update));
254    if ( g_verbose || lib->appsched->tick != NULL )
255     printf("|   |-> tick            = %s\n", _ptr2str(lib->appsched->tick));
256    printf("|   \\-> wait            = %s\n", _ptr2str(lib->appsched->wait));
257   }
258  }
259#define _ps(k,name) \
260    tmp = (lib->name) != NULL; \
261    if ( tmp || g_verbose || (k) == '\\' ) \
262    printf("%c-> %-19s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \
263                                    tmp ? (lib->name) : "<not set>", tmp ? "\"" : "");
264  _ps('|', host_appname);
265  _ps('\\', host_abiversion);
266#undef _ps
267 }
268
269 roar_dl_unref(lhandle);
270 return 0;
271}
272
273static int do_plugin(enum action action, const char * name) {
274 switch (action) {
275  case EXPLAIN:
276    return do_explain(name);
277   break;
278  case RUN:
279    return do_run(name);
280   break;
281  default:
282    roar_err_set(ROAR_ERROR_BADRQC);
283    return -1;
284   break;
285 }
286}
287
288static inline void _clear_para(void) {
289 if ( g_para == NULL )
290  return;
291
292 roar_dl_para_unref(g_para);
293 g_para = NULL;
294}
295
296int main (int argc, char * argv[]) {
297 const char * appname    = "roarpluginrunner " ROAR_VSTR_ROARAUDIO;
298 const char * abiversion = "1.0beta0";
299 const char * pluginargs = NULL;
300 enum action action = RUN;
301 int ret = 0;
302 int i;
303 char * k;
304
305 for (i = 1; i < argc; i++) {
306  k = argv[i];
307
308  if ( !strcmp(k, "-h") || !strcmp(k, "--help") ) {
309   usage(argv[0]);
310   return 0;
311  } else if ( !strcmp(k, "--run") ) {
312   action = RUN;
313  } else if ( !strcmp(k, "--explain") ) {
314   action = EXPLAIN;
315  } else if ( !strcmp(k, "-v") || !strcmp(k, "--verbose") ) {
316   g_verbose++;
317  } else if ( !strcmp(k, "--server") ) {
318   roar_libroar_set_server(argv[++i]);
319  } else if ( !strcmp(k, "--appname") ) {
320   appname = argv[++i];
321   _clear_para();
322  } else if ( !strcmp(k, "--abiversion") ) {
323   abiversion = argv[++i];
324   _clear_para();
325  } else if ( !strcmp(k, "--args") ) {
326   pluginargs = argv[++i];
327   _clear_para();
328  } else {
329   if ( g_para == NULL )
330    g_para = roar_dl_para_new(pluginargs, NULL, appname, abiversion);
331   roar_err_set(ROAR_ERROR_NONE);
332   if ( do_plugin(action, k) == -1 ) {
333    fprintf(stderr, "Error loading plugin: %s\n",
334                    roar_error != ROAR_ERROR_NONE ? roar_error2str(roar_error) : roar_dl_errstr(NULL));
335    ret = 1;
336   }
337  }
338 }
339
340 _clear_para();
341
342 return ret;
343}
344
345//ll
Note: See TracBrowser for help on using the repository browser.