source: roaraudio/libroar/vio_dstr.c @ 3312:f425c2ff782d

Last change on this file since 3312:f425c2ff782d was 3312:f425c2ff782d, checked in by phi, 14 years ago

more general internal API, support to register types

File size: 23.6 KB
RevLine 
[1321]1//vio_dstr.c:
2
3/*
[3291]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2010
[1321]5 *
6 *  This file is part of libroar 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 *  libroar 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, 675 Mass Ave, Cambridge, MA 02139, USA.
22 *
23 *  NOTE for everyone want's to change something and send patches:
24 *  read README and HACKING! There a addition information on
25 *  the license of this document you need to read before you send
26 *  any patches.
27 *
28 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
29 *  or libpulse*:
30 *  The libs libroaresd, libroararts and libroarpulse link this lib
31 *  and are therefore GPL. Because of this it may be illigal to use
32 *  them with any software that uses libesd, libartsc or libpulse*.
33 */
34
35#include "libroar.h"
36
[1365]37#ifndef ROAR_WITHOUT_VIO_DSTR
[3312]38struct _roar_vio_dstr_type {
[1323]39 int    id;
40 char * name;
[3310]41 int (* setdef) (struct roar_vio_dstr_chain * cur,   struct roar_vio_dstr_chain * next);
42 int (* openvio)(struct roar_vio_calls      * calls, struct roar_vio_calls      * dst, struct roar_vio_dstr_chain * cur);
[1323]43 int    pdeftype[16];
44} _roar_vio_dstr_objs[] = {
45/*
46grep '^#define ROAR_VIO_DSTR_OBJT_' vio_dstr.h | cut -d' ' -f2 | while read objt; do name=`cut -d_ -f5,6,7,8,9,10 <<<$objt | tr A-Z a-z`; echo -e " {$objt,\t \"$name\","; echo "      {ROAR_VIO_DEF_TYPE_EOL}},"; done;
47*/
48 {ROAR_VIO_DSTR_OBJT_FILE,       "file",
[3310]49      NULL, NULL,
[1323]50      {ROAR_VIO_DEF_TYPE_EOL}},
51 {ROAR_VIO_DSTR_OBJT_FH,         "fh",
[3310]52      NULL, NULL,
[1323]53      {ROAR_VIO_DEF_TYPE_EOL}},
[1328]54 {ROAR_VIO_DSTR_OBJT_FD,         "fd",
[3310]55      NULL, NULL,
[1328]56      {ROAR_VIO_DEF_TYPE_EOL}},
[1323]57 {ROAR_VIO_DSTR_OBJT_SOCKETFH,   "socketfh",
[3310]58      NULL, NULL,
[1323]59      {ROAR_VIO_DEF_TYPE_EOL}},
60 {ROAR_VIO_DSTR_OBJT_PASS,       "pass",
[3310]61      NULL, NULL,
[1323]62      {ROAR_VIO_DEF_TYPE_EOL}},
63 {ROAR_VIO_DSTR_OBJT_RE,         "re",
[3310]64      NULL, NULL,
[1323]65      {ROAR_VIO_DEF_TYPE_EOL}},
[3309]66 {ROAR_VIO_DSTR_OBJT_JUMBO,      "jumbo", /* TODO */
[3310]67      NULL, NULL,
[3309]68      {ROAR_VIO_DEF_TYPE_EOL}},
[1323]69 {ROAR_VIO_DSTR_OBJT_EXEC,       "exec",
[3310]70      NULL, NULL,
[1323]71      {ROAR_VIO_DEF_TYPE_EOL}},
72
73 {ROAR_VIO_DSTR_OBJT_SOCKET,     "socket",
[3310]74      NULL, NULL,
[1323]75      {ROAR_VIO_DEF_TYPE_EOL}},
76 {ROAR_VIO_DSTR_OBJT_UNIX,       "unix",
[3310]77      NULL, NULL,
[1323]78      {ROAR_VIO_DEF_TYPE_EOL}},
79 {ROAR_VIO_DSTR_OBJT_DECNET,     "decnet",
[3310]80      NULL, NULL,
[1323]81      {ROAR_VIO_DEF_TYPE_EOL}},
82 {ROAR_VIO_DSTR_OBJT_TCP,        "tcp",
[3310]83      NULL, NULL,
[1323]84      {ROAR_VIO_DEF_TYPE_EOL}},
85 {ROAR_VIO_DSTR_OBJT_UDP,        "udp",
[3310]86      NULL, NULL,
[1323]87      {ROAR_VIO_DEF_TYPE_EOL}},
88 {ROAR_VIO_DSTR_OBJT_TCP6,       "tcp6",
[3310]89      NULL, NULL,
[1323]90      {ROAR_VIO_DEF_TYPE_EOL}},
91 {ROAR_VIO_DSTR_OBJT_UDP6,       "udp6",
[3310]92      NULL, NULL,
[1323]93      {ROAR_VIO_DEF_TYPE_EOL}},
94
95 {ROAR_VIO_DSTR_OBJT_SOCKS,      "socks",
[3310]96      NULL, NULL,
[1323]97      {ROAR_VIO_DEF_TYPE_EOL}},
98 {ROAR_VIO_DSTR_OBJT_SOCKS4,     "socks4",
[3310]99      NULL, NULL,
[1323]100      {ROAR_VIO_DEF_TYPE_EOL}},
101 {ROAR_VIO_DSTR_OBJT_SOCKS4A,    "socks4a",
[3310]102      NULL, NULL,
[1323]103      {ROAR_VIO_DEF_TYPE_EOL}},
104 {ROAR_VIO_DSTR_OBJT_SOCKS4D,    "socks4d",
[3310]105      NULL, NULL,
[1323]106      {ROAR_VIO_DEF_TYPE_EOL}},
107 {ROAR_VIO_DSTR_OBJT_SOCKS5,     "socks5",
[3310]108      NULL, NULL,
[1323]109      {ROAR_VIO_DEF_TYPE_EOL}},
110 {ROAR_VIO_DSTR_OBJT_SSH,        "ssh",
[3310]111      NULL, NULL,
[1323]112      {ROAR_VIO_DEF_TYPE_EOL}},
113
114 {ROAR_VIO_DSTR_OBJT_HTTP09,     "http09",
[3310]115      NULL, NULL,
[1323]116      {ROAR_VIO_DEF_TYPE_EOL}},
117 {ROAR_VIO_DSTR_OBJT_HTTP10,     "http10",
[3310]118      NULL, NULL,
[1323]119      {ROAR_VIO_DEF_TYPE_EOL}},
120 {ROAR_VIO_DSTR_OBJT_HTTP11,     "http11",
[3310]121      NULL, NULL,
[1323]122      {ROAR_VIO_DEF_TYPE_EOL}},
123 {ROAR_VIO_DSTR_OBJT_HTTP,       "http",
[3310]124      NULL, NULL,
[1323]125      {ROAR_VIO_DEF_TYPE_EOL}},
126 {ROAR_VIO_DSTR_OBJT_GOPHER,     "gopher",
[3310]127      NULL, NULL,
[1323]128      {ROAR_VIO_DEF_TYPE_EOL}},
[1349]129 {ROAR_VIO_DSTR_OBJT_GOPHER_PLUS,"gopher+",
[3310]130      NULL, NULL,
[1349]131      {ROAR_VIO_DEF_TYPE_EOL}},
[3078]132 {ROAR_VIO_DSTR_OBJT_ICY,        "icy",
[3310]133      NULL, NULL,
[3078]134      {ROAR_VIO_DEF_TYPE_EOL}},
[3277]135 {ROAR_VIO_DSTR_OBJT_RTP2,       "rtp2",
[3310]136      NULL, NULL,
[3277]137      {ROAR_VIO_DEF_TYPE_EOL}},
138 {ROAR_VIO_DSTR_OBJT_RTP,        "rtp",
[3310]139      NULL, NULL,
[3277]140      {ROAR_VIO_DEF_TYPE_EOL}},
[1323]141
142 {ROAR_VIO_DSTR_OBJT_GZIP,       "gzip",
[3310]143      NULL, NULL,
[1323]144      {ROAR_VIO_DEF_TYPE_EOL}},
145 {ROAR_VIO_DSTR_OBJT_BZIP2,      "bzip2",
[3310]146      NULL, NULL,
[1323]147      {ROAR_VIO_DEF_TYPE_EOL}},
148
149 {ROAR_VIO_DSTR_OBJT_PGP,        "pgp",
[3310]150      NULL, NULL,
[1323]151      {ROAR_VIO_DEF_TYPE_EOL}},
152 {ROAR_VIO_DSTR_OBJT_PGP_ENC,    "pgp_enc",
[3310]153      NULL, NULL,
[1323]154      {ROAR_VIO_DEF_TYPE_EOL}},
155 {ROAR_VIO_DSTR_OBJT_PGP_STORE,  "pgp_store",
[3310]156      NULL, NULL,
[1323]157      {ROAR_VIO_DEF_TYPE_EOL}},
158 {ROAR_VIO_DSTR_OBJT_SSL1,       "ssl1",
[3310]159      NULL, NULL,
[1323]160      {ROAR_VIO_DEF_TYPE_EOL}},
161 {ROAR_VIO_DSTR_OBJT_SSL2,       "ssl2",
[3310]162      NULL, NULL,
[1323]163      {ROAR_VIO_DEF_TYPE_EOL}},
164 {ROAR_VIO_DSTR_OBJT_SSL3,       "ssl3",
[3310]165      NULL, NULL,
[1323]166      {ROAR_VIO_DEF_TYPE_EOL}},
167 {ROAR_VIO_DSTR_OBJT_TLS,        "tls",
[3310]168      NULL, NULL,
[1323]169      {ROAR_VIO_DEF_TYPE_EOL}},
170 {ROAR_VIO_DSTR_OBJT_SSLTLS,     "ssltls",
[3310]171      NULL, NULL,
[1323]172      {ROAR_VIO_DEF_TYPE_EOL}},
173
[3309]174 {ROAR_VIO_DSTR_OBJT_TRANSCODE,  "transcode", /* TODO  */
[3310]175      NULL, NULL,
[3309]176      {ROAR_VIO_DEF_TYPE_EOL}},
177
178 {ROAR_VIO_DSTR_OBJT_RAUM,       "raum",      /* TODO */
[3310]179      NULL, NULL,
[3309]180      {ROAR_VIO_DEF_TYPE_EOL}},
181 {ROAR_VIO_DSTR_OBJT_OGG,        "ogg",       /* TODO */
[3310]182      NULL, NULL,
[3309]183      {ROAR_VIO_DEF_TYPE_EOL}},
184 {ROAR_VIO_DSTR_OBJT_TAR,        "tar",       /* TODO */
[3310]185      NULL, NULL,
[3309]186      {ROAR_VIO_DEF_TYPE_EOL}},
187
188
[1323]189 {ROAR_VIO_DSTR_OBJT_MAGIC,      "magic",
[3310]190      NULL, NULL,
[1323]191      {ROAR_VIO_DEF_TYPE_EOL}},
[3116]192 {ROAR_VIO_DSTR_OBJT_TANTALOS,   "tantalos",
[3310]193      NULL, NULL,
[3116]194      {ROAR_VIO_DEF_TYPE_EOL}},
[1323]195
196 {ROAR_VIO_DSTR_OBJT_INTERNAL, "INTERNAL",
[3310]197      NULL, NULL,
[1323]198      {ROAR_VIO_DEF_TYPE_FILE, ROAR_VIO_DEF_TYPE_SOCKET, ROAR_VIO_DEF_TYPE_FH, ROAR_VIO_DEF_TYPE_SOCKETFH,
199       ROAR_VIO_DEF_TYPE_EOL}},
[3310]200 {ROAR_VIO_DSTR_OBJT_EOL, NULL, NULL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}
[1323]201};
202
203int     roar_vio_dstr_get_type(char * str) {
204 int i;
205
206 for (i = 0; _roar_vio_dstr_objs[i].id != ROAR_VIO_DSTR_OBJT_EOL; i++) {
207  if ( strcasecmp(_roar_vio_dstr_objs[i].name, str) == 0 )
208   return _roar_vio_dstr_objs[i].id;
209 }
210
211 return -1;
212}
213
[3312]214struct _roar_vio_dstr_type * roar_vio_dstr_get_by_type (int type) {
[1323]215 int i;
216
217 for (i = 0; _roar_vio_dstr_objs[i].id != ROAR_VIO_DSTR_OBJT_EOL; i++) {
218  if ( _roar_vio_dstr_objs[i].id == type )
[3312]219   return &(_roar_vio_dstr_objs[i]);
[1323]220 }
221
[3312]222 return NULL;
223}
224
225char *  roar_vio_dstr_get_name(int type) {
226 struct _roar_vio_dstr_type * ret;
227
228 if ( (ret = roar_vio_dstr_get_by_type(type)) != NULL )
229  return ret->name;
230
[1325]231 if ( type == ROAR_VIO_DSTR_OBJT_EOL )
232  return "<<EOL>>";
233
[1323]234 return NULL;
235}
[3311]236
[3312]237int     roar_vio_dstr_register_type(int   type,
238                                    char *name,
239                                    int (*setdef) (struct roar_vio_dstr_chain * cur,
240                                                   struct roar_vio_dstr_chain * next),
241                                    int (*openvio)(struct roar_vio_calls      * calls,
242                                                   struct roar_vio_calls      * dst,
243                                                   struct roar_vio_dstr_chain * cur)) {
244 struct _roar_vio_dstr_type * ret;
245
246 if ( (ret = roar_vio_dstr_get_by_type(type)) == NULL ) /* we can currently not register new types */
247  return -1;
248
249
250 // check if things are allready set, we do not want to allow overwrite here.
251 if ( setdef != NULL && ret->setdef != NULL )
252  return -1;
253
254 if ( openvio != NULL && ret->openvio != NULL )
255  return -1;
256
257 if ( setdef != NULL )
258  ret->setdef = setdef;
259
260 if ( openvio != NULL )
261  ret->openvio = openvio;
262
263 return 0;
264}
265
[3311]266static void _roar_vio_dstr_init_otherlibs (void) {
267 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroardsp");
268 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroareio");
269 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroarlight");
270 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroarmidi");
271}
272
[1365]273#endif
[1323]274
275int     roar_vio_dstr_init_defaults (struct roar_vio_defaults * def, int type, int o_flags, mode_t o_mode) {
276 if ( def == NULL )
277  return -1;
278
279 memset(def, 0, sizeof(struct roar_vio_defaults));
280
281 def->type    = type;
282 def->o_flags = o_flags;
283 def->o_mode  = o_mode;
284
285 return 0;
286}
287
[1353]288int     roar_vio_dstr_init_defaults_c (struct roar_vio_defaults * def, int type, struct roar_vio_defaults * odef, int o_flags) {
289 if ( o_flags < 1 )
290  o_flags = O_RDONLY;
291
292 if ( odef == NULL ) {
293  return roar_vio_dstr_init_defaults(def, type, o_flags, 0644);
294 } else {
295  return roar_vio_dstr_init_defaults(def, type, odef->o_flags, odef->o_mode);
296 }
297}
298
[1365]299#ifndef ROAR_WITHOUT_VIO_DSTR
[3292]300int     roar_vio_open_default (struct roar_vio_calls * calls, struct roar_vio_defaults * def, char * opts) {
301 ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s') = ?", calls, def, opts);
302
[1330]303 if ( calls == NULL || def == NULL )
304  return -1;
305
306 switch (def->type) {
[3118]307  case ROAR_VIO_DEF_TYPE_NONE:
308   break;
[1330]309  case ROAR_VIO_DEF_TYPE_FILE:
310    if ( roar_vio_open_file(calls, def->d.file, def->o_flags, def->o_mode) == -1 )
311     return -1;
312   break;
313  case ROAR_VIO_DEF_TYPE_SOCKET:
[3293]314     if ( roar_vio_open_def_socket(calls, def, opts) == -1 )
[1333]315      return -1;
[1330]316   break;
317  case ROAR_VIO_DEF_TYPE_FH:
318    if ( roar_vio_open_fh(calls, def->d.fh) == -1 )
319     return -1;
320   break;
321  case ROAR_VIO_DEF_TYPE_SOCKETFH:
322    if ( roar_vio_open_fh_socket(calls, def->d.fh) == -1 )
323     return -1;
324   break;
325  default:
326    return -1;
327 }
328
329 return 0;
330}
[1365]331#endif
[1330]332
[1323]333int     roar_vio_open_dstr    (struct roar_vio_calls * calls, char * dstr, struct roar_vio_defaults * def, int dnum) {
334 return roar_vio_open_dstr_vio(calls, dstr, def, dnum, NULL);
335}
336
337#define _ret(x) free(dstr); return (x)
338
339int     roar_vio_open_dstr_vio(struct roar_vio_calls * calls,
340                               char * dstr, struct roar_vio_defaults * def, int dnum,
341                               struct roar_vio_calls * vio) {
[1365]342#ifndef ROAR_WITHOUT_VIO_DSTR
[1325]343 struct roar_vio_dstr_chain chain[ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN];
[1323]344 char * next;
345 char * this;
346 char * name;
347 char * opts;
348 char * dst;
349 char * c;
350 int    inopts;
351 int    type;
[1328]352 int    cc = 1; // current chain element
[1323]353
354 if ( calls == NULL || dstr == NULL )
355  return -1;
356
357 if ( dnum != 0 && def == NULL )
358  return -1;
359
[1325]360 if ( (dstr = strdup(dstr)) == NULL )
[1323]361  return -1;
362
[1325]363 memset(chain, 0, sizeof(chain));
[1323]364
[1328]365 chain[0].type = ROAR_VIO_DSTR_OBJT_INTERNAL;
366
[1323]367 next = dstr;
368
369 while (next != NULL) {
[1325]370  if ( (cc+1) == ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN ) {
371   _ret(-1);
372  }
373
[1323]374  this = next;
375  next = strstr(next, "##");
376
377  if (next != NULL) {
378   *next = 0;
379   next += 2;
380  }
381
382  // we have the current token in 'this'.
383
384  opts   = NULL;
385  dst    = NULL;
386
387  if ( strstr(this, ":") != NULL ) {
388   name   = this;
389   inopts = 0;
390   for (c = this; *c != 0; c++) {
391    if ( *c == '[' ) {
392     *c     = 0;
393     opts   = c + 1;
394     inopts = 1;
395    } else if ( *c == ']' &&  inopts ) {
396     *c     = 0;
397     inopts = 0;
398    } else if ( *c == ':' && !inopts ) {
399     *c     = 0;
400     dst    = *(c+1) == 0 ? NULL : c + 1;
401     break;
402    }
403   }
404  } else {
405   // we need to guess that this is here...
406   // currently we guess this is a file in all cases
407   name = "file";
408   dst  = this;
409  }
410
[1329]411  ROAR_DBG("roar_vio_open_dstr_vio(*): name='%s', opts='%s', dst='%s'", name, opts, dst);
[1323]412
413  if ( (type = roar_vio_dstr_get_type(name)) == -1 ) {
414   _ret(-1);
415  }
416
[1329]417  ROAR_DBG("roar_vio_open_dstr_vio(*): type=0x%.4x(%s)", type, roar_vio_dstr_get_name(type));
[1323]418
[1325]419  chain[cc].type     = type;
420  chain[cc].opts     = opts;
421  chain[cc].dst      = dst;
422  chain[cc].def      = NULL;
423  chain[cc].vio      = NULL;
424  chain[cc].need_vio = -1;
425  cc++;
426
427 }
428
429 chain[cc].type = ROAR_VIO_DSTR_OBJT_EOL;
430
[1616]431 ROAR_DBG("roar_vio_open_dstr_vio(*): chain=%p", chain);
[1328]432
[1325]433 if ( roar_vio_dstr_parse_opts(chain) == -1 ) {
434  _ret(-1);
435 }
436
437 if ( roar_vio_dstr_set_defaults(chain, cc, def, dnum) == -1 ) {
438  _ret(-1);
439 }
440
441 if ( roar_vio_dstr_build_chain(chain, calls, vio) == -1 ) {
442  _ret(-1);
[1323]443 }
444
[1325]445 _ret(0);
[1365]446#else
447 return -1;
448#endif
[1325]449}
450
451#undef _ret
452
[1365]453#ifndef ROAR_WITHOUT_VIO_DSTR
[1325]454int     roar_vio_dstr_parse_opts(struct roar_vio_dstr_chain * chain) {
455 if ( chain == NULL )
456  return -1;
457
458 // TODO: we should add some code here later...
459
460 return 0;
461}
462
463int     roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain, int len, struct roar_vio_defaults * def, int dnum) {
464 struct roar_vio_dstr_chain * c, * next;
465 int i;
[1328]466 int tmp[8];
[1325]467
468 if ( chain == NULL )
469  return -1;
470
471 if ( def == NULL && dnum != 0 )
472  return -1;
473
474 if ( dnum > 1 ) /* currently not supported */
475  return -1;
476
477 if ( dnum == 0 )
478  def = NULL;
479
480 chain[len].def = def;
481
482 for (i = len; i >= 0; i--) {
483  c    = &chain[i];
[1329]484
485  if ( i > 0 ) {
486   next = &chain[i-1];
487  } else {
488   next = NULL;
489
490   if ( c->type != ROAR_VIO_DSTR_OBJT_INTERNAL )
491    return -1;
492  }
[1325]493
[1328]494  memset(tmp, 0, sizeof(tmp));
495
[1350]496  ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s)", i, c->type & 0xFFFF, roar_vio_dstr_get_name(c->type));
[1616]497  ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): c->def=%p, c->def->type=%i", i, c->type & 0xFFFF,
[1325]498                   roar_vio_dstr_get_name(c->type), c->def, c->def == NULL ? -1 : c->def->type);
499
500  c->need_vio = 1;
501
502  switch (c->type) {
[1328]503   case ROAR_VIO_DSTR_OBJT_INTERNAL:
504     c->need_vio = 0;
505    break;
506   case ROAR_VIO_DSTR_OBJT_EOL:
507     tmp[0] = 1;
[1325]508   case ROAR_VIO_DSTR_OBJT_PASS:
509   case ROAR_VIO_DSTR_OBJT_RE:
[3277]510   case ROAR_VIO_DSTR_OBJT_RTP2: // we currently only forward the defs
[1325]511   case ROAR_VIO_DSTR_OBJT_GZIP:
512   case ROAR_VIO_DSTR_OBJT_BZIP2:
513   case ROAR_VIO_DSTR_OBJT_PGP:
514   case ROAR_VIO_DSTR_OBJT_PGP_ENC:
515   case ROAR_VIO_DSTR_OBJT_PGP_STORE:
516   case ROAR_VIO_DSTR_OBJT_SSL1:
517   case ROAR_VIO_DSTR_OBJT_SSL2:
518   case ROAR_VIO_DSTR_OBJT_SSL3:
519   case ROAR_VIO_DSTR_OBJT_TLS:
520   case ROAR_VIO_DSTR_OBJT_MAGIC:
[1328]521     if ( tmp[0] )
522      c->need_vio = 0;
523
[1325]524     next->def = c->def;
525    break;
[3118]526   case ROAR_VIO_DSTR_OBJT_TANTALOS:
527     next->def = &(next->store_def);
528     roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_NONE, NULL, -1);
529    break;
[1325]530   case ROAR_VIO_DSTR_OBJT_FILE:
531     if ( c->dst == NULL ) /* should we allow multible cascaed file: objects? */
532      return -1;
533
534     c->need_vio = 0;
535     next->def = &(next->store_def);
[1353]536     roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_FILE, c->def, -1);
[1325]537
538     if ( c->dst[0] == '/' && c->dst[1] == '/' ) {
539      next->def->d.file = c->dst + 1;
540     } else {
541      next->def->d.file = c->dst;
542     }
543    break;
[1328]544   case ROAR_VIO_DSTR_OBJT_FH:
545     tmp[0] = 1;
546   case ROAR_VIO_DSTR_OBJT_SOCKETFH:
547     c->need_vio = 0;
548     next->def = &(next->store_def);
549
550     if ( c->def != NULL ) {
551      tmp[2] = c->def->o_flags;
552      tmp[3] = c->def->o_mode;
553     } else {
554      tmp[2] = O_RDONLY;
555      tmp[3] = 0644;
556     }
557
558     if ( !strcasecmp(c->dst, "stdin") ) {
559      tmp[1] = ROAR_STDIN;
560      tmp[2] = O_RDONLY;
561     } else if ( !strcasecmp(c->dst, "stdout") ) {
562      tmp[1] = ROAR_STDOUT;
563      tmp[2] = O_WRONLY;
564     } else if ( !strcasecmp(c->dst, "stderr") ) {
565      tmp[1] = ROAR_STDERR;
566      tmp[2] = O_WRONLY;
567     } else {
568      if ( sscanf(c->dst, "%i", &tmp[1]) != 1 )
569       return -1;
570     }
571
572     roar_vio_dstr_init_defaults(next->def, tmp[0] ? ROAR_VIO_DEF_TYPE_FH : ROAR_VIO_DEF_TYPE_SOCKETFH, tmp[2], tmp[3]);
573     next->def->d.fh = tmp[1];
574    break;
[1337]575#ifdef ROAR_HAVE_UNIX
[1333]576   case ROAR_VIO_DSTR_OBJT_UNIX:
577     c->need_vio = 0;
578     next->def = &(next->store_def);
579
[1337]580     if ( c->dst == NULL ) { // we don't have a destination? -> slow way
[1353]581      if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
582       return -1;
583
[1337]584      if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_UNIX, SOCK_STREAM, c->def) == -1 )
585       return -1;
586     } else {                // we have a destination? -> fast way
[1353]587      if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
588       return -1;
[1337]589
590      if ( roar_vio_socket_init_unix_def(next->def, c->dst) == -1 )
591       return -1;
[1333]592     }
593    break;
[1337]594#endif
[1335]595   case ROAR_VIO_DSTR_OBJT_SOCKET:
596     c->need_vio = 0;
597     next->def = &(next->store_def);
598
[1353]599     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
600      return -1;
601
[1335]602     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, -1, SOCK_STREAM, c->def) == -1 )
603      return -1;
604    break;
605#ifdef ROAR_HAVE_LIBDNET
606   case ROAR_VIO_DSTR_OBJT_DECNET:
607     c->need_vio = 0;
608     next->def = &(next->store_def);
609
[1353]610     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
611      return -1;
612
[1335]613     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_DECnet, SOCK_STREAM, c->def) == -1 )
614      return -1;
615    break;
616#endif
[1359]617#ifdef ROAR_HAVE_IPV4
[1335]618   case ROAR_VIO_DSTR_OBJT_TCP:
619     c->need_vio = 0;
620     next->def = &(next->store_def);
621
[1353]622     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
623      return -1;
624
[1335]625     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_STREAM, c->def) == -1 )
626      return -1;
627    break;
628   case ROAR_VIO_DSTR_OBJT_UDP:
629     c->need_vio = 0;
630     next->def = &(next->store_def);
631
[1353]632     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
633      return -1;
634
[1335]635     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_DGRAM, c->def) == -1 )
636      return -1;
637    break;
[1359]638#endif
[1335]639#ifdef ROAR_HAVE_IPV6
640   case ROAR_VIO_DSTR_OBJT_TCP6:
641     c->need_vio = 0;
642     next->def = &(next->store_def);
643
[1353]644     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
645      return -1;
646
[1335]647     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_STREAM, c->def) == -1 )
648      return -1;
649    break;
650   case ROAR_VIO_DSTR_OBJT_UDP6:
651     c->need_vio = 0;
652     next->def = &(next->store_def);
653
[1353]654     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
655      return -1;
656
[1335]657     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_DGRAM, c->def) == -1 )
658      return -1;
659    break;
660#endif
[1349]661   case ROAR_VIO_DSTR_OBJT_HTTP09:
662   case ROAR_VIO_DSTR_OBJT_HTTP10:
663   case ROAR_VIO_DSTR_OBJT_HTTP11:
664     c->need_vio = 1;
665     next->def = &(next->store_def);
666
667     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 )
668      return -1;
669    break;
670   case ROAR_VIO_DSTR_OBJT_GOPHER:
671   case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS:
672     c->need_vio = 1;
673     next->def = &(next->store_def);
674
675     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 )
676      return -1;
677    break;
[3078]678   case ROAR_VIO_DSTR_OBJT_ICY:
679     c->need_vio = 1;
680     next->def = &(next->store_def);
681
682     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_ICY, c->def) == -1 )
683      return -1;
684    break;
[1325]685   default:
[3311]686    // TODO: FIXME: add code to use functions from type struct
687    _roar_vio_dstr_init_otherlibs();
[1325]688    return -1;
689  }
690
[1329]691  if ( next != NULL ) {
[1350]692   ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def=%p, next->def->type=%i", i,
[1329]693                    c->type & 0xFFFF, roar_vio_dstr_get_name(c->type),
694                    next->def, next->def == NULL ? -1 : next->def->type);
[1349]695   if ( next->def != NULL ) {
[1616]696    ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def->o_flags=%i", i,
[1349]697                     c->type & 0xFFFF, roar_vio_dstr_get_name(c->type),
698                     next->def->o_flags);
699   }
[1329]700  } else {
[1350]701   ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next=NULL", i,
[1329]702                    c->type & 0xFFFF, roar_vio_dstr_get_name(c->type));
703  }
[1325]704 }
705
[1616]706 ROAR_DBG("roar_vio_dstr_set_defaults(*) = 0");
[1328]707
[1325]708 return 0;
709}
710
[1616]711#define _ret(x) roar_vio_close(calls); ROAR_DBG("roar_vio_dstr_build_chain(*) = %i", (x)); return (x)
[1328]712
713int     roar_vio_dstr_build_chain(struct roar_vio_dstr_chain * chain, struct roar_vio_calls * calls,
714                                  struct roar_vio_calls * vio) {
715 struct roar_vio_dstr_chain * c;
716 struct roar_vio_defaults   * def;
717 struct roar_vio_calls      * tc, * prev;
718 int i;
719
[1616]720 ROAR_DBG("roar_vio_dstr_build_chain(*) = ?");
[1328]721
[1325]722 if ( chain == NULL || calls == NULL )
723  return -1;
724
[1328]725 if ( roar_vio_open_stack(calls) == -1 )
726  return -1;
727
[1329]728 ROAR_DBG("roar_vio_dstr_build_chain(*): chain=%p", chain);
[1328]729
730 if ( (def = chain->def) != NULL ) {
731  if ( (tc = malloc(sizeof(struct roar_vio_calls))) == NULL ) {
732   _ret(-1);
733  }
734
[1337]735  if ( roar_vio_init_calls(tc) == -1 ) {
736   free(tc);
737   _ret(-1);
738  }
739
[1328]740  if ( roar_vio_stack_add(calls, tc) == -1 ) {
741   _ret(-1);
742  }
743
[3292]744  if ( chain->opts == NULL ) {
745   if ( chain[1].type != ROAR_VIO_DSTR_OBJT_EOL ) {
746    chain->opts = chain[1].opts;
747   }
748  }
749
750  if ( roar_vio_open_default(tc, def, chain->opts) == -1 ) {
[1330]751   _ret(-1);
[1328]752  }
[1330]753
[1328]754  prev = tc;
755 } else {
756  prev = vio;
757 }
758
759 for (i = 0; (c = &chain[i])->type != ROAR_VIO_DSTR_OBJT_EOL; i++) {
[1353]760  ROAR_DBG("roar_vio_dstr_build_chain(*): i=%i, c->type=0x%.4x(%s): need_vio=%i, def->o_flags=%i", i,
761                   c->type & 0xFFFF, roar_vio_dstr_get_name(c->type), c->need_vio, c->def->o_flags);
[1349]762
[1328]763  if ( c->need_vio ) {
764   if ( (tc = malloc(sizeof(struct roar_vio_calls))) == NULL ) {
765    _ret(-1);
766   }
767
[1337]768   if ( roar_vio_init_calls(tc) == -1 ) {
769    free(tc);
770    _ret(-1);
771   }
772
[1328]773   if ( roar_vio_stack_add(calls, tc) == -1 ) {
774    _ret(-1);
775   }
776
[1349]777
[1328]778   switch (c->type) {
779    case ROAR_VIO_DSTR_OBJT_PASS:
780      if ( roar_vio_open_pass(tc, prev) == -1 ) {
781       _ret(-1);
782      }
783     break;
784    case ROAR_VIO_DSTR_OBJT_RE:
785      if ( roar_vio_open_re(tc, prev) == -1 ) {
786       _ret(-1);
787      }
788     break;
789    case ROAR_VIO_DSTR_OBJT_GZIP:
790      if ( roar_vio_open_gzip(tc, prev, -1) == -1 ) {
791       _ret(-1);
792      }
793     break;
794    case ROAR_VIO_DSTR_OBJT_BZIP2:
795    case ROAR_VIO_DSTR_OBJT_PGP:
796      if ( roar_vio_open_pgp_decrypt(tc, prev, NULL) == -1 ) {
797       _ret(-1);
798      }
799     break;
[1349]800    case ROAR_VIO_DSTR_OBJT_HTTP09:
801    case ROAR_VIO_DSTR_OBJT_HTTP10:
802    case ROAR_VIO_DSTR_OBJT_HTTP11:
[1353]803      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 ) {
[1349]804       _ret(-1);
805      }
806     break;
807    case ROAR_VIO_DSTR_OBJT_GOPHER:
808    case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS:
[1353]809      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 ) {
[1349]810       _ret(-1);
811      }
812     break;
[3078]813    case ROAR_VIO_DSTR_OBJT_ICY:
814      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_ICY, c->def) == -1 ) {
815       _ret(-1);
816      }
817     break;
[3277]818    case ROAR_VIO_DSTR_OBJT_RTP2:
819      if ( roar_vio_open_rtp(tc, prev, c->dst, c->def) == -1 ) {
820       _ret(-1);
821      }
822     break;
[1328]823    case ROAR_VIO_DSTR_OBJT_PGP_ENC:
824    case ROAR_VIO_DSTR_OBJT_PGP_STORE:
825      if ( roar_vio_open_pgp_store(tc, prev, ROAR_VIO_PGP_OPTS_NONE) == -1 ) {
826       _ret(-1);
827      }
828     break;
[3116]829    case ROAR_VIO_DSTR_OBJT_TANTALOS:
830      if ( roar_vio_open_tantalos(tc, prev, c->dst, c->def) == -1 ) {
831       _ret(-1);
832      }
833     break;
[1328]834    case ROAR_VIO_DSTR_OBJT_SSL1:
835    case ROAR_VIO_DSTR_OBJT_SSL2:
836    case ROAR_VIO_DSTR_OBJT_SSL3:
837    case ROAR_VIO_DSTR_OBJT_TLS:
838    case ROAR_VIO_DSTR_OBJT_MAGIC:
839      _ret(-1);
840     break;
841    default:
[3311]842      // TODO: FIXME: add code to use functions from type struct
843      _roar_vio_dstr_init_otherlibs();
[1328]844      _ret(-1);
845   }
846
847   prev = tc;
848  } // else we can skip to the next :)
849 }
850
[1616]851 ROAR_DBG("roar_vio_dstr_build_chain(*) = 0");
[1328]852 return 0;
[1323]853}
854
[1328]855#undef _ret
[1365]856#endif
[1328]857
[1321]858//ll
Note: See TracBrowser for help on using the repository browser.