source: roaraudio/libroar/vio_dstr.c

tip
Last change on this file was 6052:d48765b2475e, checked in by phi, 9 years ago

updated copyright headers

File size: 31.1 KB
Line 
1//vio_dstr.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2015
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 roar_err_set(ROAR_ERROR_NOENT);
236 return -1;
237}
238
239struct _roar_vio_dstr_type * roar_vio_dstr_get_by_type (int type) {
240 int i;
241
242 for (i = 0; _roar_vio_dstr_objs[i].id != ROAR_VIO_DSTR_OBJT_EOL; i++) {
243  if ( _roar_vio_dstr_objs[i].id == type )
244   return &(_roar_vio_dstr_objs[i]);
245 }
246
247 roar_err_set(ROAR_ERROR_NOENT);
248 return NULL;
249}
250
251const char *  roar_vio_dstr_get_name(const int type) {
252 struct _roar_vio_dstr_type * ret;
253
254 if ( (ret = roar_vio_dstr_get_by_type(type)) != NULL )
255  return ret->name;
256
257 if ( type == ROAR_VIO_DSTR_OBJT_EOL )
258  return "<<EOL>>";
259
260 roar_err_set(ROAR_ERROR_NOENT);
261 return NULL;
262}
263
264int     roar_vio_dstr_register_type(int   type,
265                                    char *name,
266                                    int (*setdef) (struct roar_vio_dstr_chain * cur,
267                                                   struct roar_vio_dstr_chain * next),
268                                    int (*openvio)(struct roar_vio_calls      * calls,
269                                                   struct roar_vio_calls      * dst,
270                                                   struct roar_vio_dstr_chain * cur,
271                                                   struct roar_vio_dstr_chain * next)) {
272 struct _roar_vio_dstr_type * ret;
273
274 if ( (ret = roar_vio_dstr_get_by_type(type)) == NULL ) /* we can currently not register new types */
275  return -1;
276
277
278 // check if things are allready set, we do not want to allow overwrite here.
279 if ( setdef != NULL && ret->setdef != NULL )
280  return -1;
281
282 if ( openvio != NULL && ret->openvio != NULL )
283  return -1;
284
285 if ( setdef != NULL )
286  ret->setdef = setdef;
287
288 if ( openvio != NULL )
289  ret->openvio = openvio;
290
291 return 0;
292}
293
294static void _roar_vio_dstr_init_otherlibs (void) {
295 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroardsp",   NULL);
296 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroareio",   NULL);
297 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroarlight", NULL);
298 roar_dl_ra_init(ROAR_DL_HANDLE_DEFAULT, "libroarmidi",  NULL);
299}
300
301#endif
302
303int     roar_vio_dstr_init_defaults (struct roar_vio_defaults * def, int type, int o_flags, mode_t o_mode) {
304 if ( def == NULL )
305  return -1;
306
307 memset(def, 0, sizeof(struct roar_vio_defaults));
308
309 def->type    = type;
310 def->o_flags = o_flags;
311 def->o_mode  = o_mode;
312
313 return 0;
314}
315
316int     roar_vio_dstr_init_defaults_c (struct roar_vio_defaults * def, int type, struct roar_vio_defaults * odef, int o_flags) {
317 if ( o_flags < 1 )
318  o_flags = O_RDONLY;
319
320 if ( odef == NULL ) {
321  return roar_vio_dstr_init_defaults(def, type, o_flags, 0644);
322 } else {
323  return roar_vio_dstr_init_defaults(def, type, odef->o_flags, odef->o_mode);
324 }
325}
326
327#ifndef ROAR_WITHOUT_VIO_DSTR
328#ifdef ROAR_HAVE_IO_POSIX
329static int _open_file(struct roar_vio_calls * calls, const char * filename, int flags, mode_t mode) {
330 int fh;
331
332 if ( calls == NULL || filename == NULL ) {
333  roar_err_set(ROAR_ERROR_FAULT);
334  return -1;
335 }
336
337#ifdef ROAR_TARGET_WIN32
338 flags |= O_BINARY;
339#endif
340
341 ROAR_DBG("_open_file(calls=%p, filename='%s', flags=0x%x, mode=%i) = ?", calls, filename, flags, (int)mode);
342 roar_err_clear_all();
343 if ( (fh = open(filename, flags, mode)) == -1 ) {
344  roar_err_update();
345  return -1;
346 }
347
348 if ( roar_vio_open_fh(calls, fh) == -1 ) {
349  close(fh);
350  roar_err_to_errno();
351  return -1;
352 }
353
354 roar_err_update();
355 return 0;
356}
357#endif
358
359int     roar_vio_open_default (struct roar_vio_calls * calls, struct roar_vio_defaults * def, char * opts) {
360 ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s') = ?", calls, def, opts);
361
362 if ( calls == NULL || def == NULL ) {
363  roar_err_set(ROAR_ERROR_FAULT);
364  return -1;
365 }
366
367 switch (def->type) {
368  case ROAR_VIO_DEF_TYPE_NONE:
369    ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, dummy open", calls, def, opts, (int)def->type);
370   break;
371#ifdef ROAR_HAVE_IO_POSIX
372  case ROAR_VIO_DEF_TYPE_FILE:
373    ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, file open", calls, def, opts, (int)def->type);
374    if ( _open_file(calls, def->d.file, def->o_flags, def->o_mode) == -1 ) {
375     ROAR_DBG("roar_vio_open_default(*): Can not open file: %i", roar_error);
376     return -1;
377    }
378   break;
379#endif
380  case ROAR_VIO_DEF_TYPE_SOCKET:
381    ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, socket open", calls, def, opts, (int)def->type);
382     if ( roar_vio_open_def_socket(calls, def, opts) == -1 )
383      return -1;
384   break;
385  case ROAR_VIO_DEF_TYPE_FH:
386    ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, fh open", calls, def, opts, (int)def->type);
387    if ( roar_vio_open_fh(calls, def->d.fh) == -1 )
388     return -1;
389   break;
390  case ROAR_VIO_DEF_TYPE_SOCKETFH:
391    ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s'): def->type=%i, socket fh open", calls, def, opts, (int)def->type);
392    if ( roar_vio_open_fh_socket(calls, def->d.fh) == -1 )
393     return -1;
394   break;
395  default:
396    ROAR_DBG("roar_vio_open_default(calls=%p, def=%p, opts='%s') = -1 // error=NOTSUP", calls, def, opts);
397    roar_err_set(ROAR_ERROR_NOTSUP);
398    return -1;
399 }
400
401 return 0;
402}
403#endif
404
405int     roar_vio_open_dstr_simple(struct roar_vio_calls * calls, const char * dstr, int o_flags) {
406 struct roar_vio_defaults def;
407
408 if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, o_flags, 0644) == -1 )
409  return -1;
410
411 if ( roar_vio_open_dstr_vio(calls, dstr, &def, 1, NULL) == -1 )
412  return -1;
413
414 return 0;
415}
416
417struct roar_vio_calls * roar_vio_open_dstr_simple_new(const char * dstr, int o_flags) {
418 struct roar_vio_calls * ret = roar_mm_malloc(sizeof(struct roar_vio_calls));
419 int err;
420
421 if ( ret == NULL )
422  return NULL;
423
424 if ( roar_vio_open_dstr_simple(ret, dstr, o_flags) == -1 ) {
425  err = roar_error;
426  roar_mm_free(ret);
427  roar_error = err;
428  return NULL;
429 }
430
431 ret->flags |= ROAR_VIO_FLAGS_FREESELF;
432
433 return ret;
434}
435
436int     roar_vio_open_dstr    (struct roar_vio_calls * calls, const char * dstr, struct roar_vio_defaults * def, int dnum) {
437 return roar_vio_open_dstr_vio(calls, dstr, def, dnum, NULL);
438}
439
440#define _ret(x) do { roar_mm_free_noerror(dstr_copy); roar_err_to_errno(); return (x); } while (0)
441
442int     roar_vio_open_dstr_vio(struct roar_vio_calls * calls,
443                               const char * dstr, struct roar_vio_defaults * def, int dnum,
444                               struct roar_vio_calls * vio) {
445#ifndef ROAR_WITHOUT_VIO_DSTR
446 struct roar_vio_dstr_chain chain[ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN];
447 char * dstr_copy;
448 char * next;
449 char * this;
450 char * name;
451 char * opts;
452 char * dst;
453 char * c;
454 int    inopts;
455 int    type;
456 int    cc = 1; // current chain element
457
458 if ( calls == NULL || dstr == NULL )
459  return -1;
460
461 if ( dnum != 0 && def == NULL )
462  return -1;
463
464 if ( (dstr_copy = roar_mm_strdup(dstr)) == NULL )
465  return -1;
466
467 memset(chain, 0, sizeof(chain));
468
469 chain[0].type = ROAR_VIO_DSTR_OBJT_INTERNAL;
470
471 next = dstr_copy;
472
473 while (next != NULL) {
474  if ( (cc+1) == ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN ) {
475   _ret(-1);
476  }
477
478  this = next;
479  next = strstr(next, "##");
480
481  if (next != NULL) {
482   *next = 0;
483   next += 2;
484  }
485
486  // we have the current token in 'this'.
487
488  opts   = NULL;
489  dst    = NULL;
490
491  if ( strstr(this, ":") != NULL ) {
492   name   = this;
493   inopts = 0;
494   for (c = this; *c != 0; c++) {
495    if ( *c == '[' ) {
496     *c     = 0;
497     opts   = c + 1;
498     inopts = 1;
499    } else if ( *c == ']' &&  inopts ) {
500     *c     = 0;
501     inopts = 0;
502    } else if ( *c == ':' && !inopts ) {
503     *c     = 0;
504     dst    = *(c+1) == 0 ? NULL : c + 1;
505     break;
506    }
507   }
508  } else {
509   // we need to guess that this is here...
510   // currently we guess this is a file in all cases
511   name = "file";
512   dst  = this;
513  }
514
515  ROAR_DBG("roar_vio_open_dstr_vio(*): name='%s', opts='%s', dst='%s'", name, opts, dst);
516
517  if ( (type = roar_vio_dstr_get_type(name)) == -1 ) {
518   _ret(-1);
519  }
520
521  ROAR_DBG("roar_vio_open_dstr_vio(*): type=0x%.4x(%s)", type, roar_vio_dstr_get_name(type));
522
523  chain[cc].type     = type;
524  chain[cc].opts     = opts;
525  chain[cc].dst      = dst;
526  chain[cc].def      = NULL;
527  chain[cc].vio      = NULL;
528  chain[cc].need_vio = -1;
529  cc++;
530
531 }
532
533 chain[cc].type = ROAR_VIO_DSTR_OBJT_EOL;
534
535 ROAR_DBG("roar_vio_open_dstr_vio(*): chain=%p", chain);
536
537 if ( roar_vio_dstr_parse_opts(chain) == -1 ) {
538  _ret(-1);
539 }
540
541 if ( roar_vio_dstr_set_defaults(chain, cc, def, dnum) == -1 ) {
542  _ret(-1);
543 }
544
545 if ( roar_vio_dstr_build_chain(chain, calls, vio) == -1 ) {
546  _ret(-1);
547 }
548
549 _ret(0);
550#else
551 return -1;
552#endif
553}
554
555#undef _ret
556
557#ifndef ROAR_WITHOUT_VIO_DSTR
558int     roar_vio_dstr_parse_opts(struct roar_vio_dstr_chain * chain) {
559 if ( chain == NULL )
560  return -1;
561
562 // TODO: we should add some code here later...
563
564 return 0;
565}
566
567int     roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain, int len, struct roar_vio_defaults * def, int dnum) {
568 struct _roar_vio_dstr_type * type;
569 struct roar_vio_dstr_chain * c, * next;
570 int i;
571 int tmp[8];
572
573 if ( chain == NULL ) {
574  roar_err_set(ROAR_ERROR_FAULT);
575  return -1;
576 }
577
578 if ( def == NULL && dnum != 0 )
579  return -1;
580
581 if ( dnum > 1 ) /* currently not supported */
582  return -1;
583
584 if ( dnum == 0 )
585  def = NULL;
586
587 chain[len].def = def;
588
589 for (i = len; i >= 0; i--) {
590  c    = &chain[i];
591
592  if ( i > 0 ) {
593   next = &chain[i-1];
594  } else {
595   next = NULL;
596
597   if ( c->type != ROAR_VIO_DSTR_OBJT_INTERNAL )
598    return -1;
599  }
600
601  memset(tmp, 0, sizeof(tmp));
602
603  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));
604  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,
605                   roar_vio_dstr_get_name(c->type), c->def, c->def == NULL ? -1 : c->def->type);
606
607  c->need_vio = 1;
608
609  switch (c->type) {
610   case ROAR_VIO_DSTR_OBJT_INTERNAL:
611     c->need_vio = 0;
612    break;
613   case ROAR_VIO_DSTR_OBJT_EOL:
614     tmp[0] = 1;
615   case ROAR_VIO_DSTR_OBJT_PASS:
616   case ROAR_VIO_DSTR_OBJT_RE:
617   case ROAR_VIO_DSTR_OBJT_RTP2: // we currently only forward the defs
618   case ROAR_VIO_DSTR_OBJT_GZIP:
619   case ROAR_VIO_DSTR_OBJT_ZLIB:
620   case ROAR_VIO_DSTR_OBJT_BZIP2:
621   case ROAR_VIO_DSTR_OBJT_PGP:
622   case ROAR_VIO_DSTR_OBJT_PGP_ENC:
623   case ROAR_VIO_DSTR_OBJT_PGP_STORE:
624   case ROAR_VIO_DSTR_OBJT_SSL1:
625   case ROAR_VIO_DSTR_OBJT_SSL2:
626   case ROAR_VIO_DSTR_OBJT_SSL3:
627   case ROAR_VIO_DSTR_OBJT_TLS:
628   case ROAR_VIO_DSTR_OBJT_MAGIC:
629     if ( tmp[0] )
630      c->need_vio = 0;
631
632     next->def = c->def;
633    break;
634   case ROAR_VIO_DSTR_OBJT_NULL:
635   case ROAR_VIO_DSTR_OBJT_ZERO:
636   case ROAR_VIO_DSTR_OBJT_FULL:
637   case ROAR_VIO_DSTR_OBJT_NRANDOM:
638   case ROAR_VIO_DSTR_OBJT_TANTALOS:
639     next->def = &(next->store_def);
640     roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_NONE, NULL, -1);
641    break;
642   case ROAR_VIO_DSTR_OBJT_FILE:
643     if ( c->dst == NULL ) /* should we allow multible cascaed file: objects? */
644      return -1;
645
646     c->need_vio = 0;
647     next->def = &(next->store_def);
648     roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_FILE, c->def, -1);
649
650     if ( c->dst[0] == '/' && c->dst[1] == '/' ) {
651      next->def->d.file = c->dst + 1;
652     } else {
653      next->def->d.file = c->dst;
654     }
655    break;
656   case ROAR_VIO_DSTR_OBJT_FH:
657     tmp[0] = 1;
658   case ROAR_VIO_DSTR_OBJT_SOCKETFH:
659     c->need_vio = 0;
660     next->def = &(next->store_def);
661
662     if ( c->def != NULL ) {
663      tmp[2] = c->def->o_flags;
664      tmp[3] = c->def->o_mode;
665     } else {
666      tmp[2] = O_RDONLY;
667      tmp[3] = 0644;
668     }
669
670     if ( !strcasecmp(c->dst, "stdin") ) {
671      tmp[1] = ROAR_STDIN;
672      tmp[2] = O_RDONLY;
673     } else if ( !strcasecmp(c->dst, "stdout") ) {
674      tmp[1] = ROAR_STDOUT;
675      tmp[2] = O_WRONLY;
676     } else if ( !strcasecmp(c->dst, "stderr") ) {
677      tmp[1] = ROAR_STDERR;
678      tmp[2] = O_WRONLY;
679     } else {
680      if ( sscanf(c->dst, "%i", &tmp[1]) != 1 )
681       return -1;
682     }
683
684     roar_vio_dstr_init_defaults(next->def, tmp[0] ? ROAR_VIO_DEF_TYPE_FH : ROAR_VIO_DEF_TYPE_SOCKETFH, tmp[2], tmp[3]);
685     next->def->d.fh = tmp[1];
686    break;
687#ifdef ROAR_HAVE_UNIX
688   case ROAR_VIO_DSTR_OBJT_UNIX:
689     c->need_vio = 0;
690     next->def = &(next->store_def);
691
692     if ( c->dst == NULL ) { // we don't have a destination? -> slow 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_dstr_def(next->def, c->dst, AF_UNIX, SOCK_STREAM, c->def) == -1 )
697       return -1;
698     } else {                // we have a destination? -> fast way
699      if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
700       return -1;
701
702      if ( roar_vio_socket_init_unix_def(next->def, c->dst) == -1 )
703       return -1;
704     }
705    break;
706#endif
707   case ROAR_VIO_DSTR_OBJT_SOCKET:
708     c->need_vio = 0;
709     next->def = &(next->store_def);
710
711     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
712      return -1;
713
714     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, -1, SOCK_STREAM, c->def) == -1 )
715      return -1;
716    break;
717#ifdef ROAR_HAVE_LIBDNET
718   case ROAR_VIO_DSTR_OBJT_DECNET:
719     c->need_vio = 0;
720     next->def = &(next->store_def);
721
722     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
723      return -1;
724
725     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_DECnet, SOCK_STREAM, c->def) == -1 )
726      return -1;
727    break;
728#endif
729#ifdef ROAR_HAVE_IPV4
730   case ROAR_VIO_DSTR_OBJT_TCP:
731     c->need_vio = 0;
732     next->def = &(next->store_def);
733
734     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
735      return -1;
736
737     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_STREAM, c->def) == -1 )
738      return -1;
739    break;
740   case ROAR_VIO_DSTR_OBJT_UDP:
741     c->need_vio = 0;
742     next->def = &(next->store_def);
743
744     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
745      return -1;
746
747     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_DGRAM, c->def) == -1 )
748      return -1;
749    break;
750#endif
751#ifdef ROAR_HAVE_IPV6
752   case ROAR_VIO_DSTR_OBJT_TCP6:
753     c->need_vio = 0;
754     next->def = &(next->store_def);
755
756     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
757      return -1;
758
759     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_STREAM, c->def) == -1 )
760      return -1;
761    break;
762   case ROAR_VIO_DSTR_OBJT_UDP6:
763     c->need_vio = 0;
764     next->def = &(next->store_def);
765
766     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
767      return -1;
768
769     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_DGRAM, c->def) == -1 )
770      return -1;
771    break;
772#endif
773   case ROAR_VIO_DSTR_OBJT_HTTP09:
774   case ROAR_VIO_DSTR_OBJT_HTTP10:
775   case ROAR_VIO_DSTR_OBJT_HTTP11:
776     c->need_vio = 1;
777     next->def = &(next->store_def);
778
779     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 )
780      return -1;
781    break;
782   case ROAR_VIO_DSTR_OBJT_GOPHER:
783   case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS:
784     c->need_vio = 1;
785     next->def = &(next->store_def);
786
787     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 )
788      return -1;
789    break;
790   case ROAR_VIO_DSTR_OBJT_ICY:
791     c->need_vio = 1;
792     next->def = &(next->store_def);
793
794     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_ICY, c->def) == -1 )
795      return -1;
796    break;
797   default:
798     if ( (type = roar_vio_dstr_get_by_type(c->type)) == NULL ) {
799      return -1;
800     }
801
802     if ( type->setdef == NULL )
803      _roar_vio_dstr_init_otherlibs();
804
805     if ( type->setdef == NULL ) {
806      return -1;
807     }
808
809     if ( type->setdef(c, next) == -1 ) {
810      return -1;
811     }
812  }
813
814  if ( next != NULL ) {
815   ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def=%p, next->def->type=%i", i,
816                    c->type & 0xFFFF, roar_vio_dstr_get_name(c->type),
817                    next->def, next->def == NULL ? -1 : next->def->type);
818   if ( next->def != NULL ) {
819    ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def->o_flags=%i", i,
820                     c->type & 0xFFFF, roar_vio_dstr_get_name(c->type),
821                     next->def->o_flags);
822   }
823  } else {
824   ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next=NULL", i,
825                    c->type & 0xFFFF, roar_vio_dstr_get_name(c->type));
826  }
827 }
828
829 ROAR_DBG("roar_vio_dstr_set_defaults(*) = 0");
830
831 return 0;
832}
833
834#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)
835
836int     roar_vio_dstr_build_chain(struct roar_vio_dstr_chain * chain, struct roar_vio_calls * calls,
837                                  struct roar_vio_calls * vio) {
838 struct _roar_vio_dstr_type * type;
839 struct roar_vio_dstr_chain * c;
840 struct roar_vio_defaults   * def;
841 struct roar_vio_calls      * tc, * prev;
842 int i;
843
844 ROAR_DBG("roar_vio_dstr_build_chain(*) = ?");
845
846 if ( chain == NULL || calls == NULL ) {
847  roar_err_set(ROAR_ERROR_FAULT);
848  return -1;
849 }
850
851 if ( roar_vio_open_stack2(calls, NULL) == -1 )
852  return -1;
853
854 ROAR_DBG("roar_vio_dstr_build_chain(*): chain=%p", chain);
855
856 if ( (def = chain->def) != NULL ) {
857  if ( (tc = roar_mm_malloc(sizeof(struct roar_vio_calls))) == NULL ) {
858   _ret(-1);
859  }
860
861  if ( roar_vio_clear_calls(tc) == -1 ) {
862   roar_mm_free(tc);
863   _ret(-1);
864  }
865
866  if ( roar_vio_stack_add(calls, tc) == -1 ) {
867   _ret(-1);
868  }
869
870  if ( chain->opts == NULL ) {
871   if ( chain[1].type != ROAR_VIO_DSTR_OBJT_EOL ) {
872    chain->opts = chain[1].opts;
873   }
874  }
875
876  if ( roar_vio_open_default(tc, def, chain->opts) == -1 ) {
877   _ret(-1);
878  }
879
880  prev = tc;
881 } else {
882  prev = vio;
883 }
884
885 for (i = 0; (c = &(chain[i]))->type != ROAR_VIO_DSTR_OBJT_EOL; i++) {
886  ROAR_DBG("roar_vio_dstr_build_chain(*): i=%i, c->type=0x%.4x(%s): need_vio=%i, def(%p)->o_flags=%i", i,
887                   c->type & 0xFFFF, roar_vio_dstr_get_name(c->type), c->need_vio, c->def, c->def != NULL ? c->def->o_flags : -1);
888
889  if ( c->need_vio ) {
890   if ( (tc = roar_mm_malloc(sizeof(struct roar_vio_calls))) == NULL ) {
891    _ret(-1);
892   }
893
894   if ( roar_vio_clear_calls(tc) == -1 ) {
895    roar_mm_free(tc);
896    _ret(-1);
897   }
898
899   if ( roar_vio_stack_add(calls, tc) == -1 ) {
900    _ret(-1);
901   }
902
903
904   switch (c->type) {
905    case ROAR_VIO_DSTR_OBJT_PASS:
906      if ( roar_vio_open_pass(tc, prev) == -1 ) {
907       _ret(-1);
908      }
909     break;
910    case ROAR_VIO_DSTR_OBJT_RE:
911      if ( roar_vio_open_re(tc, prev) == -1 ) {
912       _ret(-1);
913      }
914     break;
915#ifdef ROAR_HAVE_LIBZ
916    case ROAR_VIO_DSTR_OBJT_GZIP:
917      if ( roar_vio_open_zlib(tc, prev, -1, 1) == -1 ) {
918       _ret(-1);
919      }
920     break;
921    case ROAR_VIO_DSTR_OBJT_ZLIB:
922      if ( roar_vio_open_zlib(tc, prev, -1, 0) == -1 ) {
923       _ret(-1);
924      }
925     break;
926#endif
927    case ROAR_VIO_DSTR_OBJT_BZIP2:
928    case ROAR_VIO_DSTR_OBJT_PGP:
929      if ( roar_vio_open_pgp_decrypt(tc, prev, NULL) == -1 ) {
930       _ret(-1);
931      }
932     break;
933    case ROAR_VIO_DSTR_OBJT_HTTP09:
934    case ROAR_VIO_DSTR_OBJT_HTTP10:
935    case ROAR_VIO_DSTR_OBJT_HTTP11:
936      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 ) {
937       _ret(-1);
938      }
939     break;
940    case ROAR_VIO_DSTR_OBJT_GOPHER:
941    case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS:
942      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 ) {
943       _ret(-1);
944      }
945     break;
946    case ROAR_VIO_DSTR_OBJT_ICY:
947      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_ICY, c->def) == -1 ) {
948       _ret(-1);
949      }
950     break;
951    case ROAR_VIO_DSTR_OBJT_RTP2:
952      if ( roar_vio_open_rtp(tc, prev, c->dst, c->def) == -1 ) {
953       _ret(-1);
954      }
955     break;
956    case ROAR_VIO_DSTR_OBJT_PGP_ENC:
957    case ROAR_VIO_DSTR_OBJT_PGP_STORE:
958      if ( roar_vio_open_pgp_store(tc, prev, ROAR_VIO_PGP_OPTS_NONE) == -1 ) {
959       _ret(-1);
960      }
961     break;
962    case ROAR_VIO_DSTR_OBJT_TANTALOS:
963      if ( roar_vio_open_tantalos(tc, prev, c->dst, c->def) == -1 ) {
964       _ret(-1);
965      }
966     break;
967    case ROAR_VIO_DSTR_OBJT_NULL:
968    case ROAR_VIO_DSTR_OBJT_ZERO:
969    case ROAR_VIO_DSTR_OBJT_FULL:
970    case ROAR_VIO_DSTR_OBJT_NRANDOM:
971      if ( roar_vio_open_misc_by_name(tc, roar_vio_dstr_get_name(c->type)) == -1 ) {
972       _ret(-1);
973      }
974     break;
975    case ROAR_VIO_DSTR_OBJT_SSL1:
976    case ROAR_VIO_DSTR_OBJT_SSL2:
977    case ROAR_VIO_DSTR_OBJT_SSL3:
978    case ROAR_VIO_DSTR_OBJT_TLS:
979    case ROAR_VIO_DSTR_OBJT_MAGIC:
980      _ret(-1);
981     break;
982    default:
983      if ( (type = roar_vio_dstr_get_by_type(c->type)) == NULL ) {
984       _ret(-1);
985      }
986
987      if ( type->openvio == NULL )
988       _roar_vio_dstr_init_otherlibs();
989
990      if ( type->openvio == NULL ) {
991       _ret(-1);
992      }
993
994      if ( type->openvio(tc, prev, c, &(chain[i+1])) == -1 ) {
995       _ret(-1);
996      }
997   }
998
999   prev = tc;
1000  } // else we can skip to the next :)
1001 }
1002
1003 ROAR_DBG("roar_vio_dstr_build_chain(*) = 0");
1004 return 0;
1005}
1006
1007#undef _ret
1008
1009static inline ssize_t __libroar_dir_part_len(char * p, size_t len) {
1010 ssize_t i, c;
1011
1012 c = -1;
1013
1014 for (i = 0; i < len; i++, p++)
1015  if ( *p == '/' )
1016   c = i;
1017
1018 return c;
1019}
1020
1021char *  roar_vio_dstr_cat(char * buffer, ssize_t bufferlen, const struct roar_vio_dstr_pathelement * elements, size_t elementslen) {
1022 size_t needed = 0;
1023 size_t rootelement = 0;
1024 ssize_t ret;
1025 char * p;
1026 size_t i;
1027
1028 if ( buffer == NULL )
1029  bufferlen = -1;
1030
1031 if ( elementslen == 0 ) {
1032  if ( bufferlen == -1 ) {
1033   if ( (buffer = roar_mm_malloc(2)) == NULL )
1034    return NULL;
1035   bufferlen = 2;
1036  }
1037
1038  if ( bufferlen >= 2 ) {
1039   buffer[0] = '.';
1040   buffer[1] = 0;
1041   return buffer;
1042  } else {
1043   roar_err_set(ROAR_ERROR_NOSPC);
1044   return NULL;
1045  }
1046 }
1047
1048 if ( elements == NULL ) {
1049  roar_err_set(ROAR_ERROR_FAULT);
1050  return NULL;
1051 }
1052
1053 for (i = 0; i < elementslen; i++) {
1054  if ( elements[i].dstr == NULL ) {
1055   roar_err_set(ROAR_ERROR_FAULT);
1056   return NULL;
1057  }
1058
1059  if ( !(elements[i].flags & ROAR_VIO_DSTR_PEF_ALLOW_MULTI) && strstr(elements[i].dstr, "##") != NULL ) {
1060   roar_err_set(ROAR_ERROR_INVAL);
1061   return NULL;
1062  }
1063
1064  if ( !(elements[i].flags & ROAR_VIO_DSTR_PEF_ALLOW_PARENT) && strstr(elements[i].dstr, "..") != NULL ) {
1065   roar_err_set(ROAR_ERROR_INVAL);
1066   return NULL;
1067  }
1068
1069  if ( strstr(elements[i].dstr, "##") != NULL ) {
1070   roar_err_set(ROAR_ERROR_NOTSUP);
1071   return NULL;
1072  }
1073
1074  if ( strstr(elements[i].dstr, ":") != NULL ) {
1075   if ( !(elements[i].flags & ROAR_VIO_DSTR_PEF_ALLOW_ABSOLUTE) ) {
1076    roar_err_set(ROAR_ERROR_INVAL);
1077    return NULL;
1078   }
1079   rootelement = i;
1080   needed = 0;
1081  }
1082
1083  needed += roar_mm_strlen(elements[i].dstr);
1084 }
1085
1086 elements += rootelement;
1087 elementslen -= rootelement;
1088
1089 if ( elementslen == 1 ) {
1090  if ( bufferlen == -1 ) {
1091   bufferlen = needed+1;
1092   if ( (buffer = roar_mm_malloc(bufferlen)) == NULL )
1093    return NULL;
1094  }
1095
1096  if ( bufferlen >= (elementslen + 1) ) {
1097   memcpy(buffer, elements[0].dstr, needed+1);
1098   return buffer;
1099  } else {
1100   roar_err_set(ROAR_ERROR_NOSPC);
1101   return NULL;
1102  }
1103 }
1104
1105 needed += elementslen * 2; // for '.', '/' and '\0'.
1106
1107 if ( bufferlen == -1 ) {
1108  bufferlen = needed;
1109  if ( (buffer = roar_mm_malloc(bufferlen)) == NULL )
1110   return NULL;
1111 }
1112
1113 if ( bufferlen < needed ) {
1114  roar_err_set(ROAR_ERROR_NOSPC);
1115  return NULL;
1116 }
1117
1118 p = buffer;
1119 for (i = 0; i < elementslen; i++) {
1120  ret = roar_mm_strlen(elements[i].dstr);
1121  memcpy(p, elements[i].dstr, ret);
1122  if ( i == (elementslen-1) || elements[i].flags & ROAR_VIO_DSTR_PEF_IS_DIR ) {
1123   p += ret;
1124  } else {
1125   ret = __libroar_dir_part_len(p, ret);
1126   if ( ret == -1 ) {
1127    *p = '.';
1128    p++;
1129   } else {
1130    p += ret;
1131   }
1132  }
1133
1134  *p = '/';
1135  p++;
1136 }
1137
1138 p--;
1139 *p = 0;
1140 return buffer;
1141}
1142#endif
1143
1144//ll
Note: See TracBrowser for help on using the repository browser.