source: roaraudio/libroar/vio_dstr.c @ 3292:af91815a4426

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

pass opts of last dstr to roar_vio_open_default()

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