source: roaraudio/libroar/vio_dstr.c @ 5425:2c3f247e8f9a

Last change on this file since 5425:2c3f247e8f9a was 5408:c6d31c2e4a51, checked in by phi, 12 years ago

re-ported to f* s* bla win32 !*!*Dd*S!, I hate this.

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