source: roaraudio/roarclients/roarpluginrunner.c @ 5950:7fe8f5df7a83

Last change on this file since 5950:7fe8f5df7a83 was 5950:7fe8f5df7a83, checked in by phi, 10 years ago

code cleanup and again a patch for checking commandlion parameters

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