source: roaraudio/libroar/vio_dstr.c @ 5396:e2e5f307ef8b

Last change on this file since 5396:e2e5f307ef8b was 5388:e5cc8e03a3e1, checked in by phi, 12 years ago

Added support for refcount based VIOs as well as dynamically allocated VIOs (non-stack or global VIOs) (Closes: #127)

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