source: roaraudio/roarclients/roarpluginrunner.c @ 5715:0ead15b11f72

Last change on this file since 5715:0ead15b11f72 was 5715:0ead15b11f72, checked in by phi, 12 years ago

added CPI support, manpage still needs to be updated

File size: 19.8 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 RUN_AS_APPLICATION,
34 EXPLAIN
35};
36
37static struct roar_dl_librarypara * g_para  = NULL;
38static struct roar_scheduler      * g_sched = NULL;
39static struct roar_scheduler_source g_s_service   = {.type = ROAR_SCHEDULER_CPI_SERVICE};
40
41static void usage (const char * progname) {
42 fprintf(stderr, "Usage: %s [OPTIONS]... PLUGIN\n", progname);
43
44 fprintf(stderr, "\nOptions:\n\n");
45
46 fprintf(stderr, " -h --help               - This help.\n"
47                 " -v --verbose            - Be verbose. Can be used multiple times.\n"
48                 "    --server SERVER      - Set default server to SERVER.\n"
49                 "    --run                - Run plugin.\n"
50                 "    --run-as-application - Same as --run except all tailing arguments are\n"
51                 "                           passed to the plugin.\n"
52                 "    --explain            - Explain plugin.\n"
53                 "    --appname NAME       - Sets the appname.\n"
54                 "    --abiversion ABI     - Set the ABI version.\n"
55                 "    --args ARGS          - Set plugin arguments.\n"
56        );
57
58 fprintf(stderr, "\nCPI Options:\n\n");
59 fprintf(stderr, " -t --tcp                - Use TCP listen socket\n"
60                 " -u --unix               - Use UNIX Domain listen socket (default)\n"
61                 " -n --decnet             - use DECnet listen socket\n"
62                 "    --port PORT          - TCP Port to bind to\n"
63                 "    --bind ADDR          - Node/Hostname/Path to bind to\n"
64                 "    --proto PROTO        - Use PROTO as protocol on Socket\n"
65                 "    --new-sock           - Parameters for new socket follow\n"
66                 "    --client-fh FH       - Comunicate with a client over this handle\n"
67                 "\n"
68        );
69}
70
71static int do_run(const char * name) {
72 struct roar_scheduler_source s_container;
73 struct roar_plugincontainer * cont = roar_plugincontainer_new(g_para);
74 int err;
75
76 if ( cont == NULL )
77  return -1;
78
79 memset(&s_container, 0, sizeof(s_container));
80 s_container.type = ROAR_SCHEDULER_PLUGINCONTAINER;
81 s_container.handle.container = cont;
82 roar_scheduler_source_add(g_sched, &s_container);
83
84 if ( roar_plugincontainer_load(cont, name, NULL) == -1 ) {
85  err = roar_error;
86  roar_scheduler_source_del(g_sched, &s_container);
87  roar_plugincontainer_unref(cont);
88  roar_error = err;
89  return -1;
90 }
91
92 roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_INIT);
93
94/*
95 while (roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_WAIT) == 0)
96  roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_UPDATE);
97*/
98 roar_scheduler_run(g_sched);
99
100 roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_UPDATE);
101 roar_plugincontainer_appsched_trigger(cont, ROAR_DL_APPSCHED_FREE);
102
103 roar_scheduler_source_del(g_sched, &s_container);
104 roar_plugincontainer_unref(cont);
105 return 0;
106}
107
108static const char * _ptr2str(const void * p) {
109#if defined(ROAR_HAVE_H_DLFCN) && defined(ROAR_HAVE_DLADDR)
110 static char buf[80];
111 Dl_info info;
112#else
113 static char buf[24];
114#endif
115
116 if ( p == NULL )
117  return "<not set>";
118
119#if defined(ROAR_HAVE_H_DLFCN) && defined(ROAR_HAVE_DLADDR)
120 if ( dladdr(p, &info) != 0 ) {
121  if ( p == info.dli_saddr ) {
122   snprintf(buf, sizeof(buf), "%p <%s in \"%s\">", p, info.dli_sname, info.dli_fname);
123   return buf;
124  }
125 }
126#endif
127
128 snprintf(buf, sizeof(buf), "%p", p);
129
130 return buf;
131}
132
133static const char * _ptrrange2str(const void * p, size_t len) {
134 static char buf[80];
135
136 if ( p == NULL )
137  return "<not set>";
138
139 if ( len == 0 )
140  return _ptr2str(p);
141
142 snprintf(buf, sizeof(buf), "%p-%p", p, p + len);
143
144 return buf;
145}
146
147static int do_explain(const char * name) {
148 struct roar_dl_lhandle * lhandle = roar_dl_open(name, ROAR_DL_FLAG_LAZY|ROAR_DL_FLAG_PLUGINPATH, 0, g_para);
149 struct roar_dl_libraryinst * (*func)(struct roar_dl_librarypara * para);
150 struct roar_dl_libraryinst * lib;
151 int libok = 0, libnameok = 0, libdepok = 0;
152 int tmp;
153 int i;
154 size_t iter;
155 char c;
156
157 if ( lhandle == NULL )
158  return -1;
159
160 func = roar_dl_getsym(lhandle, "_roaraudio_library_init", -1);
161 if ( func == NULL ) {
162  fprintf(stderr, "Warning: Not a RA lib: %s\n", name);
163  roar_dl_unref(lhandle);
164  return 0;
165 }
166
167 lib = func(g_para);
168 if ( lib == NULL ) {
169  fprintf(stderr, "Warning: Can not RA init: %s: %s\n", name, roar_error2str(roar_error));
170  roar_dl_unref(lhandle);
171  return 0;
172 }
173
174 if ( lib->version == ROAR_DL_LIBINST_VERSION && lib->len == sizeof(*lib) ) {
175  libok = 1;
176 }
177
178 printf("lib                     = %s\n", _ptr2str(lib));
179 if ( g_verbose || !libok ) {
180  printf("|-> version             = %i (%smatch)\n", lib->version, lib->version == ROAR_DL_LIBINST_VERSION ? "" : "no ");
181  printf("%c-> len                 = %zu (%smatch)\n", libok ? '|' : '\\', lib->len, lib->len == sizeof(*lib) ? "" : "no ");
182 }
183
184 if ( libok ) {
185  if ( g_verbose || lib->unload != NULL )
186   printf("|-> unload              = %s\n", _ptr2str(lib->unload));
187  printf("|-> func                = {");
188  i = 0;
189  while (i < ROAR_DL_FN_MAX) {
190   for (tmp = 0; i < ROAR_DL_FN_MAX; i++) {
191    if ( lib->func[i] != NULL ) {
192     break;
193    }
194    tmp++;
195   }
196   if (tmp)
197    printf("%i x <not set>%s", tmp, i < (ROAR_DL_FN_MAX-1) ? ", " : "");
198
199   if ( i < ROAR_DL_FN_MAX ) {
200    printf("[%i] = %s%s", i, _ptr2str(lib->func[i]), i < (ROAR_DL_FN_MAX-1) ? ", " : "");
201    i++;
202   }
203  }
204
205  printf("}\n");
206  printf("|-> libname             = %s\n", _ptr2str(lib->libname));
207  if ( lib->libname != NULL ) {
208   if ( lib->libname->version == ROAR_DL_LIBNAME_VERSION && lib->libname->len == sizeof(*(lib->libname)) ) {
209    libnameok = 1;
210   }
211   if ( g_verbose || !libnameok ) {
212    printf("|   |-> version         = %i (%smatch)\n", lib->libname->version,
213                                                       lib->libname->version == ROAR_DL_LIBNAME_VERSION ? "" : "no ");
214    printf("|   %c-> len             = %zu (%smatch)\n", libnameok ? '|' : '\\', lib->libname->len,
215                                                         lib->libname->len == sizeof(*(lib->libname)) ? "" : "no ");
216   }
217
218   if ( libnameok ) {
219#define _ps(k,name) \
220    tmp = (lib->libname->name) != NULL; \
221    if ( tmp || g_verbose || (k) == '\\' ) \
222    printf("|   %c-> %-15s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \
223                                    tmp ? (lib->libname->name) : "<not set>", tmp ? "\"" : "");
224
225    _ps('|', name);
226    _ps('|', libname);
227    _ps('|', libversion);
228    _ps('|', abiversion);
229    _ps('|', description);
230    _ps('|', contact);
231    _ps('|', authors);
232    _ps('\\', license);
233#undef _ps
234   }
235  }
236  if ( g_verbose || lib->global_data_pointer != NULL )
237   printf("|-> global_data_len     = %zu\n", lib->global_data_len);
238  if ( g_verbose || lib->global_data_init != NULL )
239   printf("|-> global_data_init    = %s\n", _ptrrange2str(lib->global_data_init, lib->global_data_len));
240  if ( g_verbose || lib->global_data_pointer != NULL )
241   printf("|-> global_data_pointer = %s\n", _ptr2str(lib->global_data_pointer));
242
243  if ( lib->libdep != NULL && lib->libdep_len ) {
244   printf("|-> libdep              = %s\n", _ptr2str(lib->libdep));
245   for (iter = 0; iter < lib->libdep_len; iter++) {
246    printf("|   %c-> Table entry %zu   = %p\n", iter == (lib->libdep_len-1) ? '\\' : '|', iter, &(lib->libdep[iter]));
247    c = iter == (lib->libdep_len-1) ? ' ' : '|';
248    if ( lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION &&
249         lib->libdep[iter].len     == sizeof(struct roar_dl_librarydep) ) {
250     libdepok = 1;
251    } else {
252     libdepok = 0;
253    }
254    if ( g_verbose || !libdepok ) {
255     printf("|   %c   |-> version     = %i (%smatch)\n", c, lib->libdep[iter].version,
256                                                         lib->libdep[iter].version == ROAR_DL_LIBDEP_VERSION ? "" : "no ");
257     printf("|   %c   %c-> len         = %zu (%smatch)\n", c, libdepok ? '|' : '\\',
258                                                        lib->libdep[iter].len,
259                                                        lib->libdep[iter].len == sizeof(struct roar_dl_librarydep) ?
260                                                        "" : "no ");
261    }
262
263    if ( libdepok ) {
264     printf("|   %c   |-> flags       = 0x%.8lX\n", c, (unsigned long int)lib->libdep[iter].flags);
265#define _ps(k,name) \
266    tmp = (lib->libdep[iter].name) != NULL; \
267    if ( tmp || g_verbose || (k) == '\\' ) \
268    printf("|   %c   %c-> %-11s = %s%s%s\n", c, (k), #name, tmp ? "\"" : "", \
269                                    tmp ? (lib->libdep[iter].name) : "<not set>", tmp ? "\"" : "");
270     _ps('|', name);
271     _ps('|', libname);
272     _ps('\\', abiversion);
273#undef _ps
274    }
275   }
276   printf("|-> libdep_len          = %zu\n", lib->libdep_len);
277  } else if ( (lib->libdep == NULL && lib->libdep_len) || (lib->libdep != NULL && !lib->libdep_len) ) {
278   printf("|-> libdep              = %s (invalid)\n", _ptr2str(lib->libdep));
279   printf("|-> libdep_len          = %zu (invalid)\n", lib->libdep_len);
280  }
281  if ( g_verbose || lib->appsched != NULL ) {
282   printf("|-> appsched            = %s\n", _ptr2str(lib->appsched));
283   if ( lib->appsched != NULL ) {
284    if ( g_verbose || lib->appsched->init != NULL )
285     printf("|   |-> init            = %s\n", _ptr2str(lib->appsched->init));
286    if ( g_verbose || lib->appsched->free != NULL )
287     printf("|   |-> free            = %s\n", _ptr2str(lib->appsched->free));
288    if ( g_verbose || lib->appsched->update != NULL )
289     printf("|   |-> update          = %s\n", _ptr2str(lib->appsched->update));
290    if ( g_verbose || lib->appsched->tick != NULL )
291     printf("|   |-> tick            = %s\n", _ptr2str(lib->appsched->tick));
292    printf("|   \\-> wait            = %s\n", _ptr2str(lib->appsched->wait));
293   }
294  }
295#define _ps(k,name) \
296    tmp = (lib->name) != NULL; \
297    if ( tmp || g_verbose || (k) == '\\' ) \
298    printf("%c-> %-19s = %s%s%s\n", (k), #name, tmp ? "\"" : "", \
299                                    tmp ? (lib->name) : "<not set>", tmp ? "\"" : "");
300  _ps('|', host_appname);
301  _ps('\\', host_abiversion);
302#undef _ps
303 }
304
305 roar_dl_unref(lhandle);
306 return 0;
307}
308
309static int do_plugin(enum action action, const char * name) {
310 switch (action) {
311  case EXPLAIN:
312    return do_explain(name);
313   break;
314  case RUN:
315  case RUN_AS_APPLICATION:
316    return do_run(name);
317   break;
318  default:
319    roar_err_set(ROAR_ERROR_BADRQC);
320    return -1;
321   break;
322 }
323}
324
325static inline void _clear_para(void) {
326 if ( g_para == NULL )
327  return;
328
329 roar_dl_para_unref(g_para);
330 g_para = NULL;
331}
332
333static inline int _add_para(struct roar_dl_librarypara * para, const char * pluginargs, size_t argc, char * argv[]) {
334 struct roar_keyval * kv;
335 ssize_t argslen, argvlen;
336 ssize_t arglen;
337 ssize_t pluginargc;
338 size_t argv_phys = argc;
339 size_t i;
340 int error;
341 char * sp, * c;
342 int after_parser_end;
343
344 if ( pluginargs == NULL )
345  pluginargs = "";
346
347 argslen = roar_mm_strlen(pluginargs) + 1 /* tailing '\0' */;
348
349 after_parser_end = 0;
350 argvlen = 0;
351 for (i = 0; i < argv_phys; i++) {
352  arglen   = roar_mm_strlen(argv[i]);
353  argvlen += arglen;
354  if ( !after_parser_end ) {
355   if ( !strcmp(argv[i], "--") ) {
356    after_parser_end = 1;
357    argc--;
358   } else if ( arglen > 1 && argv[i][0] == '-' && !(arglen > 2 && argv[i][1] == '-') ) {
359    argc += arglen - 2;
360   }
361  }
362 }
363 argvlen += argc; // the '\0's.
364
365 para->args_store = roar_mm_malloc(argslen+argvlen);
366 if ( para == NULL )
367  return -1;
368
369 memcpy(para->args_store, pluginargs, argslen);
370
371 pluginargc = roar_keyval_split(&kv, para->args_store, NULL, NULL, 1);
372 if ( pluginargc == -1 ) {
373  error = roar_error;
374  roar_mm_free(para->args_store);
375  para->args_store = NULL;
376  roar_error = error;
377  return -1;
378 }
379
380 para->argv = roar_mm_malloc((pluginargc+argc)*sizeof(struct roar_keyval));
381 if ( para->argv == NULL ) {
382  error = roar_error;
383  roar_mm_free(kv);
384  roar_mm_free(para->args_store);
385  para->args_store = NULL;
386  roar_error = error;
387  return -1;
388 }
389
390 para->argc = pluginargc + argc;
391
392 memcpy(para->argv, kv, pluginargc*sizeof(struct roar_keyval));
393 roar_mm_free(kv);
394
395 sp = para->args_store + argslen;
396 kv = para->argv + pluginargc;
397
398 after_parser_end = 0;
399 for (i = 0; i < argv_phys; i++) {
400  arglen = roar_mm_strlen(argv[i]) + 1;
401  if ( after_parser_end || !(arglen > 2 && argv[i][0] == '-' && !(arglen > 3 && argv[i][1] == '-')) )
402   memcpy(sp, argv[i], arglen);
403
404  if ( !after_parser_end && !strcmp(argv[i], "--") ) {
405   after_parser_end = 1;
406   continue;
407  } else if ( !after_parser_end && arglen > 3 && sp[0] == '-' && sp[1] == '-' ) {
408   kv->key = sp + 2;
409   kv->value = NULL;
410   for (c = sp + 2; *c; c++) {
411    if (*c == '=') {
412     *c = 0;
413     c++;
414     kv->value = c;
415     break;
416    }
417   }
418  } else if ( !after_parser_end && arglen > 2 && argv[i][0] == '-' ) {
419   for (c = argv[i] + 1; *c; c++) {
420    sp[0] = *c;
421    sp[1] = 0;
422    kv->key = sp;
423    kv->value = NULL;
424    sp += 2;
425    kv++;
426   }
427   continue;
428  } else {
429   kv->key = NULL;
430   kv->value = sp;
431  }
432
433  sp += arglen;
434  kv++;
435 }
436
437 return 0;
438}
439
440static struct roar_scheduler_source * add_cpi_common(int proto) {
441 struct roar_scheduler_source * source;
442 int err;
443
444 if ( proto == -1 ) {
445  roar_err_set(ROAR_ERROR_INVAL);
446  return NULL;
447 }
448
449 source = roar_mm_malloc(sizeof(struct roar_scheduler_source));
450 if ( source == NULL )
451  return NULL;
452
453 memset(source, 0, sizeof(struct roar_scheduler_source));
454
455 source->vio   = roar_mm_malloc(sizeof(struct roar_vio_calls));
456 if ( source->vio == NULL ) {
457  err = roar_error;
458  roar_mm_free(source);
459  roar_error = err;
460  return NULL;
461 }
462
463 source->flags = ROAR_SCHEDULER_FLAG_FREE;
464 source->handle.cpi.proto = proto;
465
466 return source;
467}
468
469static int add_cpi_listen(int proto, int type, const char * host, int port) {
470 struct roar_scheduler_source * source = add_cpi_common(proto);
471 int err;
472
473 if ( source == NULL )
474  return -1;
475
476 if ( roar_vio_open_socket_listen(source->vio, type, host, port) == -1 ) {
477  err = roar_error;
478  roar_mm_free(source->vio);
479  roar_mm_free(source);
480  roar_error = err;
481  return -1;
482 }
483
484 source->type  = ROAR_SCHEDULER_CPI_LISTEN;
485
486 source->vio->flags |= ROAR_VIO_FLAGS_FREESELF;
487
488 if ( roar_scheduler_source_add(g_sched, source) == -1 ) {
489  err = roar_error;
490  roar_vio_close(source->vio);
491  roar_mm_free(source);
492  roar_error = err;
493  return -1;
494 }
495
496 return 0;
497}
498
499static int add_cpi_client(int proto, int fh) {
500 struct roar_scheduler_source * source = add_cpi_common(proto);
501 struct roar_dl_librarypara * para;
502 int err;
503
504 if ( source == NULL )
505  return -1;
506
507 if ( roar_vio_open_fh(source->vio, fh) == -1 ) {
508  err = roar_error;
509  roar_mm_free(source->vio);
510  roar_mm_free(source);
511  roar_error = err;
512  return -1;
513 }
514
515 source->type  = ROAR_SCHEDULER_CPI_CLIENT;
516
517 source->vio->flags |= ROAR_VIO_FLAGS_FREESELF;
518
519 if ( roar_scheduler_source_add(g_sched, source) == -1 ) {
520  err = roar_error;
521  roar_vio_close(source->vio);
522  roar_mm_free(source);
523  roar_error = err;
524  return -1;
525 }
526
527 if ( source->flags & ROAR_SCHEDULER_FLAG_STUB ) {
528  ROAR_ERR("Can not handle proto STUB clients. Try to use --client-fh as last argument.");
529
530  roar_scheduler_source_del(g_sched, source);
531
532  return -1;
533 }
534
535 if ( source->handle.cpi.impl->set_proto != NULL ) {
536  para = roar_dl_getpara(source->lhandle);
537
538  if ( source->lhandle != NULL )
539   roar_dl_context_restore(source->lhandle);
540  source->handle.cpi.impl->set_proto(source->handle.cpi.client, source->vio, &(source->handle.cpi.obuffer), &(source->handle.cpi.userdata), source->handle.cpi.protopara, source->handle.cpi.protoparalen, para);
541  if ( source->lhandle != NULL )
542   roar_dl_context_store(source->lhandle);
543
544  if ( para != NULL )
545   roar_dl_para_unref(para);
546 }
547
548 return 0;
549}
550
551int main (int argc, char * argv[]) {
552 const char * appname    = "roarpluginrunner " ROAR_VSTR_ROARAUDIO;
553 const char * abiversion = "1.0beta0";
554 const char * pluginargs = NULL;
555 enum action action = RUN;
556 int ret = 0;
557 int i;
558 const char * k;
559 int cpi_type = ROAR_SOCKET_TYPE_UNKNOWN;
560 int cpi_proto = -1;
561 int cpi_port = 0;
562 int cpi_touched = 0;
563 const char * cpi_host = NULL;
564
565 g_sched = roar_scheduler_new(ROAR_SCHEDULER_FLAG_NONE, ROAR_SCHEDULER_STRATEGY_DEFAULT);
566 if ( g_sched == NULL ) {
567  fprintf(stderr, "Error creating scheduler object: %s\n", roar_error2str(roar_error));
568  return 1;
569 }
570
571 roar_scheduler_source_add(g_sched, &g_s_service);
572
573 for (i = 1; i < argc; i++) {
574  k = argv[i];
575
576  if ( !strcmp(k, "-h") || !strcmp(k, "--help") ) {
577   usage(argv[0]);
578   roar_scheduler_unref(g_sched);
579   return 0;
580  } else if ( !strcmp(k, "--run") ) {
581   action = RUN;
582  } else if ( !strcmp(k, "--run-as-application") ) {
583   action = RUN_AS_APPLICATION;
584  } else if ( !strcmp(k, "--explain") ) {
585   action = EXPLAIN;
586  } else if ( !strcmp(k, "-v") || !strcmp(k, "--verbose") ) {
587   g_verbose++;
588  } else if ( !strcmp(k, "--server") ) {
589   roar_libroar_set_server(argv[++i]);
590
591  } else if ( !strcmp(k, "--tcp") || !strcmp(k, "-t") ) {
592   cpi_type = ROAR_SOCKET_TYPE_TCP;
593   cpi_touched++;
594  } else if ( !strcmp(k, "--unix") || !strcmp(k, "-u") ) {
595   cpi_type = ROAR_SOCKET_TYPE_UNIX;
596   cpi_touched++;
597  } else if ( !strcmp(k, "--decnet") || !strcmp(k, "-n") ) {
598   cpi_type = ROAR_SOCKET_TYPE_DECNET;
599   cpi_touched++;
600  } else if ( !strcmp(k, "--port") ) {
601   cpi_port = atoi(argv[++i]);
602   cpi_touched++;
603  } else if ( !strcmp(k, "--bind") ) {
604   cpi_host = argv[++i];
605   cpi_touched++;
606  } else if ( !strcmp(k, "--proto") ) {
607   cpi_proto = roar_str2proto(argv[++i]);
608   if ( cpi_proto == -1 ) {
609    fprintf(stderr, "Unknown protocol: %s: %s\n", argv[i], roar_error2str(roar_error));
610    return 1;
611   }
612  } else if ( !strcmp(k, "--new-sock") ) {
613   if ( cpi_touched && add_cpi_listen(cpi_proto, cpi_type, cpi_host, cpi_port) == -1 ) {
614    fprintf(stderr, "Can not open socket for CPI: %s\n", roar_error2str(roar_error));
615    return 1;
616   }
617   cpi_touched = 0;
618  } else if ( !strcmp(k, "--client-fh") ) {
619   if ( add_cpi_client(cpi_proto, atoi(argv[++i])) == -1 ) {
620    fprintf(stderr, "Can not add CPI client: %s\n", roar_error2str(roar_error));
621    return 1;
622   }
623
624  } else if ( !strcmp(k, "--appname") ) {
625   appname = argv[++i];
626   _clear_para();
627  } else if ( !strcmp(k, "--abiversion") ) {
628   abiversion = argv[++i];
629   _clear_para();
630  } else if ( !strcmp(k, "--args") ) {
631   pluginargs = argv[++i];
632   _clear_para();
633  } else {
634   if ( cpi_touched && add_cpi_listen(cpi_proto, cpi_type, cpi_host, cpi_port) == -1 ) {
635    fprintf(stderr, "Can not open socket for CPI: %s\n", roar_error2str(roar_error));
636    return 1;
637   }
638   cpi_touched = 0;
639
640   if ( g_para == NULL )
641    g_para = roar_dl_para_new(action == RUN_AS_APPLICATION ? NULL : pluginargs, NULL, appname, abiversion);
642   if ( action == RUN_AS_APPLICATION && _add_para(g_para, pluginargs, argc - i - 1, &(argv[i+1])) == -1 ) {
643    fprintf(stderr, "Error parsing plugin arguments: %s\n", roar_error2str(roar_error));
644   } else {
645    roar_err_set(ROAR_ERROR_NONE);
646    if ( do_plugin(action, k) == -1 ) {
647     fprintf(stderr, "Error loading plugin: %s\n",
648                     roar_error != ROAR_ERROR_NONE ? roar_error2str(roar_error) : roar_dl_errstr(NULL));
649     ret = 1;
650    }
651   }
652   if ( action == RUN_AS_APPLICATION )
653    break; // end looping over arguments
654  }
655 }
656
657 _clear_para();
658
659 roar_scheduler_unref(g_sched);
660 return ret;
661}
662
663//ll
Note: See TracBrowser for help on using the repository browser.