source: roaraudio/libroar/vio_dstr.c @ 3115:ca30d8a58b9a

Last change on this file since 3115:ca30d8a58b9a was 3078:75efac535f8b, checked in by phi, 14 years ago

support protocol name ICY, identical to HTTP at the moment but defaults to port 8000

File size: 19.5 KB
Line 
1//vio_dstr.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009
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
104 {ROAR_VIO_DSTR_OBJT_GZIP,       "gzip",
105      {ROAR_VIO_DEF_TYPE_EOL}},
106 {ROAR_VIO_DSTR_OBJT_BZIP2,      "bzip2",
107      {ROAR_VIO_DEF_TYPE_EOL}},
108
109 {ROAR_VIO_DSTR_OBJT_PGP,        "pgp",
110      {ROAR_VIO_DEF_TYPE_EOL}},
111 {ROAR_VIO_DSTR_OBJT_PGP_ENC,    "pgp_enc",
112      {ROAR_VIO_DEF_TYPE_EOL}},
113 {ROAR_VIO_DSTR_OBJT_PGP_STORE,  "pgp_store",
114      {ROAR_VIO_DEF_TYPE_EOL}},
115 {ROAR_VIO_DSTR_OBJT_SSL1,       "ssl1",
116      {ROAR_VIO_DEF_TYPE_EOL}},
117 {ROAR_VIO_DSTR_OBJT_SSL2,       "ssl2",
118      {ROAR_VIO_DEF_TYPE_EOL}},
119 {ROAR_VIO_DSTR_OBJT_SSL3,       "ssl3",
120      {ROAR_VIO_DEF_TYPE_EOL}},
121 {ROAR_VIO_DSTR_OBJT_TLS,        "tls",
122      {ROAR_VIO_DEF_TYPE_EOL}},
123 {ROAR_VIO_DSTR_OBJT_SSLTLS,     "ssltls",
124      {ROAR_VIO_DEF_TYPE_EOL}},
125
126 {ROAR_VIO_DSTR_OBJT_MAGIC,      "magic",
127      {ROAR_VIO_DEF_TYPE_EOL}},
128
129 {ROAR_VIO_DSTR_OBJT_INTERNAL, "INTERNAL",
130      {ROAR_VIO_DEF_TYPE_FILE, ROAR_VIO_DEF_TYPE_SOCKET, ROAR_VIO_DEF_TYPE_FH, ROAR_VIO_DEF_TYPE_SOCKETFH,
131       ROAR_VIO_DEF_TYPE_EOL}},
132 {ROAR_VIO_DSTR_OBJT_EOL, NULL, {ROAR_VIO_DEF_TYPE_EOL}}
133};
134
135int     roar_vio_dstr_get_type(char * str) {
136 int i;
137
138 for (i = 0; _roar_vio_dstr_objs[i].id != ROAR_VIO_DSTR_OBJT_EOL; i++) {
139  if ( strcasecmp(_roar_vio_dstr_objs[i].name, str) == 0 )
140   return _roar_vio_dstr_objs[i].id;
141 }
142
143 return -1;
144}
145
146char *  roar_vio_dstr_get_name(int type) {
147 int i;
148
149 for (i = 0; _roar_vio_dstr_objs[i].id != ROAR_VIO_DSTR_OBJT_EOL; i++) {
150  if ( _roar_vio_dstr_objs[i].id == type )
151   return _roar_vio_dstr_objs[i].name;
152 }
153
154 if ( type == ROAR_VIO_DSTR_OBJT_EOL )
155  return "<<EOL>>";
156
157 return NULL;
158}
159#endif
160
161int     roar_vio_dstr_init_defaults (struct roar_vio_defaults * def, int type, int o_flags, mode_t o_mode) {
162 if ( def == NULL )
163  return -1;
164
165 memset(def, 0, sizeof(struct roar_vio_defaults));
166
167 def->type    = type;
168 def->o_flags = o_flags;
169 def->o_mode  = o_mode;
170
171 return 0;
172}
173
174int     roar_vio_dstr_init_defaults_c (struct roar_vio_defaults * def, int type, struct roar_vio_defaults * odef, int o_flags) {
175 if ( o_flags < 1 )
176  o_flags = O_RDONLY;
177
178 if ( odef == NULL ) {
179  return roar_vio_dstr_init_defaults(def, type, o_flags, 0644);
180 } else {
181  return roar_vio_dstr_init_defaults(def, type, odef->o_flags, odef->o_mode);
182 }
183}
184
185#ifndef ROAR_WITHOUT_VIO_DSTR
186int     roar_vio_open_default (struct roar_vio_calls * calls, struct roar_vio_defaults * def) {
187 if ( calls == NULL || def == NULL )
188  return -1;
189
190 switch (def->type) {
191  case ROAR_VIO_DEF_TYPE_FILE:
192    if ( roar_vio_open_file(calls, def->d.file, def->o_flags, def->o_mode) == -1 )
193     return -1;
194   break;
195  case ROAR_VIO_DEF_TYPE_SOCKET:
196     if ( roar_vio_open_def_socket(calls, def) == -1 )
197      return -1;
198   break;
199  case ROAR_VIO_DEF_TYPE_FH:
200    if ( roar_vio_open_fh(calls, def->d.fh) == -1 )
201     return -1;
202   break;
203  case ROAR_VIO_DEF_TYPE_SOCKETFH:
204    if ( roar_vio_open_fh_socket(calls, def->d.fh) == -1 )
205     return -1;
206   break;
207  default:
208    return -1;
209 }
210
211 return 0;
212}
213#endif
214
215int     roar_vio_open_dstr    (struct roar_vio_calls * calls, char * dstr, struct roar_vio_defaults * def, int dnum) {
216 return roar_vio_open_dstr_vio(calls, dstr, def, dnum, NULL);
217}
218
219#define _ret(x) free(dstr); return (x)
220
221int     roar_vio_open_dstr_vio(struct roar_vio_calls * calls,
222                               char * dstr, struct roar_vio_defaults * def, int dnum,
223                               struct roar_vio_calls * vio) {
224#ifndef ROAR_WITHOUT_VIO_DSTR
225 struct roar_vio_dstr_chain chain[ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN];
226 char * next;
227 char * this;
228 char * name;
229 char * opts;
230 char * dst;
231 char * c;
232 int    inopts;
233 int    type;
234 int    cc = 1; // current chain element
235
236 if ( calls == NULL || dstr == NULL )
237  return -1;
238
239 if ( dnum != 0 && def == NULL )
240  return -1;
241
242 if ( (dstr = strdup(dstr)) == NULL )
243  return -1;
244
245 memset(chain, 0, sizeof(chain));
246
247 chain[0].type = ROAR_VIO_DSTR_OBJT_INTERNAL;
248
249 next = dstr;
250
251 while (next != NULL) {
252  if ( (cc+1) == ROAR_VIO_DSTR_MAX_OBJ_PER_CHAIN ) {
253   _ret(-1);
254  }
255
256  this = next;
257  next = strstr(next, "##");
258
259  if (next != NULL) {
260   *next = 0;
261   next += 2;
262  }
263
264  // we have the current token in 'this'.
265
266  opts   = NULL;
267  dst    = NULL;
268
269  if ( strstr(this, ":") != NULL ) {
270   name   = this;
271   inopts = 0;
272   for (c = this; *c != 0; c++) {
273    if ( *c == '[' ) {
274     *c     = 0;
275     opts   = c + 1;
276     inopts = 1;
277    } else if ( *c == ']' &&  inopts ) {
278     *c     = 0;
279     inopts = 0;
280    } else if ( *c == ':' && !inopts ) {
281     *c     = 0;
282     dst    = *(c+1) == 0 ? NULL : c + 1;
283     break;
284    }
285   }
286  } else {
287   // we need to guess that this is here...
288   // currently we guess this is a file in all cases
289   name = "file";
290   dst  = this;
291  }
292
293  ROAR_DBG("roar_vio_open_dstr_vio(*): name='%s', opts='%s', dst='%s'", name, opts, dst);
294
295  if ( (type = roar_vio_dstr_get_type(name)) == -1 ) {
296   _ret(-1);
297  }
298
299  ROAR_DBG("roar_vio_open_dstr_vio(*): type=0x%.4x(%s)", type, roar_vio_dstr_get_name(type));
300
301  chain[cc].type     = type;
302  chain[cc].opts     = opts;
303  chain[cc].dst      = dst;
304  chain[cc].def      = NULL;
305  chain[cc].vio      = NULL;
306  chain[cc].need_vio = -1;
307  cc++;
308
309 }
310
311 chain[cc].type = ROAR_VIO_DSTR_OBJT_EOL;
312
313 ROAR_DBG("roar_vio_open_dstr_vio(*): chain=%p", chain);
314
315 if ( roar_vio_dstr_parse_opts(chain) == -1 ) {
316  _ret(-1);
317 }
318
319 if ( roar_vio_dstr_set_defaults(chain, cc, def, dnum) == -1 ) {
320  _ret(-1);
321 }
322
323 if ( roar_vio_dstr_build_chain(chain, calls, vio) == -1 ) {
324  _ret(-1);
325 }
326
327 _ret(0);
328#else
329 return -1;
330#endif
331}
332
333#undef _ret
334
335#ifndef ROAR_WITHOUT_VIO_DSTR
336int     roar_vio_dstr_parse_opts(struct roar_vio_dstr_chain * chain) {
337 if ( chain == NULL )
338  return -1;
339
340 // TODO: we should add some code here later...
341
342 return 0;
343}
344
345int     roar_vio_dstr_set_defaults(struct roar_vio_dstr_chain * chain, int len, struct roar_vio_defaults * def, int dnum) {
346 struct roar_vio_dstr_chain * c, * next;
347 int i;
348 int tmp[8];
349
350 if ( chain == NULL )
351  return -1;
352
353 if ( def == NULL && dnum != 0 )
354  return -1;
355
356 if ( dnum > 1 ) /* currently not supported */
357  return -1;
358
359 if ( dnum == 0 )
360  def = NULL;
361
362 chain[len].def = def;
363
364 for (i = len; i >= 0; i--) {
365  c    = &chain[i];
366
367  if ( i > 0 ) {
368   next = &chain[i-1];
369  } else {
370   next = NULL;
371
372   if ( c->type != ROAR_VIO_DSTR_OBJT_INTERNAL )
373    return -1;
374  }
375
376  memset(tmp, 0, sizeof(tmp));
377
378  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));
379  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,
380                   roar_vio_dstr_get_name(c->type), c->def, c->def == NULL ? -1 : c->def->type);
381
382  c->need_vio = 1;
383
384  switch (c->type) {
385   case ROAR_VIO_DSTR_OBJT_INTERNAL:
386     c->need_vio = 0;
387    break;
388   case ROAR_VIO_DSTR_OBJT_EOL:
389     tmp[0] = 1;
390   case ROAR_VIO_DSTR_OBJT_PASS:
391   case ROAR_VIO_DSTR_OBJT_RE:
392   case ROAR_VIO_DSTR_OBJT_GZIP:
393   case ROAR_VIO_DSTR_OBJT_BZIP2:
394   case ROAR_VIO_DSTR_OBJT_PGP:
395   case ROAR_VIO_DSTR_OBJT_PGP_ENC:
396   case ROAR_VIO_DSTR_OBJT_PGP_STORE:
397   case ROAR_VIO_DSTR_OBJT_SSL1:
398   case ROAR_VIO_DSTR_OBJT_SSL2:
399   case ROAR_VIO_DSTR_OBJT_SSL3:
400   case ROAR_VIO_DSTR_OBJT_TLS:
401   case ROAR_VIO_DSTR_OBJT_MAGIC:
402     if ( tmp[0] )
403      c->need_vio = 0;
404
405     next->def = c->def;
406    break;
407   case ROAR_VIO_DSTR_OBJT_FILE:
408     if ( c->dst == NULL ) /* should we allow multible cascaed file: objects? */
409      return -1;
410
411     c->need_vio = 0;
412     next->def = &(next->store_def);
413     roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_FILE, c->def, -1);
414
415     if ( c->dst[0] == '/' && c->dst[1] == '/' ) {
416      next->def->d.file = c->dst + 1;
417     } else {
418      next->def->d.file = c->dst;
419     }
420    break;
421   case ROAR_VIO_DSTR_OBJT_FH:
422     tmp[0] = 1;
423   case ROAR_VIO_DSTR_OBJT_SOCKETFH:
424     c->need_vio = 0;
425     next->def = &(next->store_def);
426
427     if ( c->def != NULL ) {
428      tmp[2] = c->def->o_flags;
429      tmp[3] = c->def->o_mode;
430     } else {
431      tmp[2] = O_RDONLY;
432      tmp[3] = 0644;
433     }
434
435     if ( !strcasecmp(c->dst, "stdin") ) {
436      tmp[1] = ROAR_STDIN;
437      tmp[2] = O_RDONLY;
438     } else if ( !strcasecmp(c->dst, "stdout") ) {
439      tmp[1] = ROAR_STDOUT;
440      tmp[2] = O_WRONLY;
441     } else if ( !strcasecmp(c->dst, "stderr") ) {
442      tmp[1] = ROAR_STDERR;
443      tmp[2] = O_WRONLY;
444     } else {
445      if ( sscanf(c->dst, "%i", &tmp[1]) != 1 )
446       return -1;
447     }
448
449     roar_vio_dstr_init_defaults(next->def, tmp[0] ? ROAR_VIO_DEF_TYPE_FH : ROAR_VIO_DEF_TYPE_SOCKETFH, tmp[2], tmp[3]);
450     next->def->d.fh = tmp[1];
451    break;
452#ifdef ROAR_HAVE_UNIX
453   case ROAR_VIO_DSTR_OBJT_UNIX:
454     c->need_vio = 0;
455     next->def = &(next->store_def);
456
457     if ( c->dst == NULL ) { // we don't have a destination? -> slow way
458      if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
459       return -1;
460
461      if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_UNIX, SOCK_STREAM, c->def) == -1 )
462       return -1;
463     } else {                // we have a destination? -> fast way
464      if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
465       return -1;
466
467      if ( roar_vio_socket_init_unix_def(next->def, c->dst) == -1 )
468       return -1;
469     }
470    break;
471#endif
472   case ROAR_VIO_DSTR_OBJT_SOCKET:
473     c->need_vio = 0;
474     next->def = &(next->store_def);
475
476     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
477      return -1;
478
479     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, -1, SOCK_STREAM, c->def) == -1 )
480      return -1;
481    break;
482#ifdef ROAR_HAVE_LIBDNET
483   case ROAR_VIO_DSTR_OBJT_DECNET:
484     c->need_vio = 0;
485     next->def = &(next->store_def);
486
487     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
488      return -1;
489
490     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_DECnet, SOCK_STREAM, c->def) == -1 )
491      return -1;
492    break;
493#endif
494#ifdef ROAR_HAVE_IPV4
495   case ROAR_VIO_DSTR_OBJT_TCP:
496     c->need_vio = 0;
497     next->def = &(next->store_def);
498
499     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
500      return -1;
501
502     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_STREAM, c->def) == -1 )
503      return -1;
504    break;
505   case ROAR_VIO_DSTR_OBJT_UDP:
506     c->need_vio = 0;
507     next->def = &(next->store_def);
508
509     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
510      return -1;
511
512     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET, SOCK_DGRAM, c->def) == -1 )
513      return -1;
514    break;
515#endif
516#ifdef ROAR_HAVE_IPV6
517   case ROAR_VIO_DSTR_OBJT_TCP6:
518     c->need_vio = 0;
519     next->def = &(next->store_def);
520
521     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
522      return -1;
523
524     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_STREAM, c->def) == -1 )
525      return -1;
526    break;
527   case ROAR_VIO_DSTR_OBJT_UDP6:
528     c->need_vio = 0;
529     next->def = &(next->store_def);
530
531     if ( roar_vio_dstr_init_defaults_c(next->def, ROAR_VIO_DEF_TYPE_SOCKET, c->def, O_WRONLY) == -1 )
532      return -1;
533
534     if ( roar_vio_socket_init_dstr_def(next->def, c->dst, AF_INET6, SOCK_DGRAM, c->def) == -1 )
535      return -1;
536    break;
537#endif
538   case ROAR_VIO_DSTR_OBJT_HTTP09:
539   case ROAR_VIO_DSTR_OBJT_HTTP10:
540   case ROAR_VIO_DSTR_OBJT_HTTP11:
541     c->need_vio = 1;
542     next->def = &(next->store_def);
543
544     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 )
545      return -1;
546    break;
547   case ROAR_VIO_DSTR_OBJT_GOPHER:
548   case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS:
549     c->need_vio = 1;
550     next->def = &(next->store_def);
551
552     if ( roar_vio_proto_init_def(next->def, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 )
553      return -1;
554    break;
555   case ROAR_VIO_DSTR_OBJT_ICY:
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_ICY, c->def) == -1 )
560      return -1;
561    break;
562   default:
563    return -1;
564  }
565
566  if ( next != NULL ) {
567   ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def=%p, next->def->type=%i", i,
568                    c->type & 0xFFFF, roar_vio_dstr_get_name(c->type),
569                    next->def, next->def == NULL ? -1 : next->def->type);
570   if ( next->def != NULL ) {
571    ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next->def->o_flags=%i", i,
572                     c->type & 0xFFFF, roar_vio_dstr_get_name(c->type),
573                     next->def->o_flags);
574   }
575  } else {
576   ROAR_DBG("roar_vio_dstr_set_defaults(*): i=%i, c->type=0x%.4x(%s): next=NULL", i,
577                    c->type & 0xFFFF, roar_vio_dstr_get_name(c->type));
578  }
579 }
580
581 ROAR_DBG("roar_vio_dstr_set_defaults(*) = 0");
582
583 return 0;
584}
585
586#define _ret(x) roar_vio_close(calls); ROAR_DBG("roar_vio_dstr_build_chain(*) = %i", (x)); return (x)
587
588int     roar_vio_dstr_build_chain(struct roar_vio_dstr_chain * chain, struct roar_vio_calls * calls,
589                                  struct roar_vio_calls * vio) {
590 struct roar_vio_dstr_chain * c;
591 struct roar_vio_defaults   * def;
592 struct roar_vio_calls      * tc, * prev;
593 int i;
594
595 ROAR_DBG("roar_vio_dstr_build_chain(*) = ?");
596
597 if ( chain == NULL || calls == NULL )
598  return -1;
599
600 if ( roar_vio_open_stack(calls) == -1 )
601  return -1;
602
603 ROAR_DBG("roar_vio_dstr_build_chain(*): chain=%p", chain);
604
605 if ( (def = chain->def) != NULL ) {
606  if ( (tc = malloc(sizeof(struct roar_vio_calls))) == NULL ) {
607   _ret(-1);
608  }
609
610  if ( roar_vio_init_calls(tc) == -1 ) {
611   free(tc);
612   _ret(-1);
613  }
614
615  if ( roar_vio_stack_add(calls, tc) == -1 ) {
616   _ret(-1);
617  }
618
619  if ( roar_vio_open_default(tc, def) == -1 ) {
620   _ret(-1);
621  }
622
623  prev = tc;
624 } else {
625  prev = vio;
626 }
627
628 for (i = 0; (c = &chain[i])->type != ROAR_VIO_DSTR_OBJT_EOL; i++) {
629  ROAR_DBG("roar_vio_dstr_build_chain(*): i=%i, c->type=0x%.4x(%s): need_vio=%i, def->o_flags=%i", i,
630                   c->type & 0xFFFF, roar_vio_dstr_get_name(c->type), c->need_vio, c->def->o_flags);
631
632  if ( c->need_vio ) {
633   if ( (tc = malloc(sizeof(struct roar_vio_calls))) == NULL ) {
634    _ret(-1);
635   }
636
637   if ( roar_vio_init_calls(tc) == -1 ) {
638    free(tc);
639    _ret(-1);
640   }
641
642   if ( roar_vio_stack_add(calls, tc) == -1 ) {
643    _ret(-1);
644   }
645
646
647   switch (c->type) {
648    case ROAR_VIO_DSTR_OBJT_PASS:
649      if ( roar_vio_open_pass(tc, prev) == -1 ) {
650       _ret(-1);
651      }
652     break;
653    case ROAR_VIO_DSTR_OBJT_RE:
654      if ( roar_vio_open_re(tc, prev) == -1 ) {
655       _ret(-1);
656      }
657     break;
658    case ROAR_VIO_DSTR_OBJT_GZIP:
659      if ( roar_vio_open_gzip(tc, prev, -1) == -1 ) {
660       _ret(-1);
661      }
662     break;
663    case ROAR_VIO_DSTR_OBJT_BZIP2:
664    case ROAR_VIO_DSTR_OBJT_PGP:
665      if ( roar_vio_open_pgp_decrypt(tc, prev, NULL) == -1 ) {
666       _ret(-1);
667      }
668     break;
669    case ROAR_VIO_DSTR_OBJT_HTTP09:
670    case ROAR_VIO_DSTR_OBJT_HTTP10:
671    case ROAR_VIO_DSTR_OBJT_HTTP11:
672      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_HTTP, c->def) == -1 ) {
673       _ret(-1);
674      }
675     break;
676    case ROAR_VIO_DSTR_OBJT_GOPHER:
677    case ROAR_VIO_DSTR_OBJT_GOPHER_PLUS:
678      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_GOPHER, c->def) == -1 ) {
679       _ret(-1);
680      }
681     break;
682    case ROAR_VIO_DSTR_OBJT_ICY:
683      if ( roar_vio_open_proto(tc, prev, c->dst, ROAR_VIO_PROTO_P_ICY, c->def) == -1 ) {
684       _ret(-1);
685      }
686     break;
687    case ROAR_VIO_DSTR_OBJT_PGP_ENC:
688    case ROAR_VIO_DSTR_OBJT_PGP_STORE:
689      if ( roar_vio_open_pgp_store(tc, prev, ROAR_VIO_PGP_OPTS_NONE) == -1 ) {
690       _ret(-1);
691      }
692     break;
693    case ROAR_VIO_DSTR_OBJT_SSL1:
694    case ROAR_VIO_DSTR_OBJT_SSL2:
695    case ROAR_VIO_DSTR_OBJT_SSL3:
696    case ROAR_VIO_DSTR_OBJT_TLS:
697    case ROAR_VIO_DSTR_OBJT_MAGIC:
698      _ret(-1);
699     break;
700    default:
701      _ret(-1);
702   }
703
704   prev = tc;
705  } // else we can skip to the next :)
706 }
707
708 ROAR_DBG("roar_vio_dstr_build_chain(*) = 0");
709 return 0;
710}
711
712#undef _ret
713#endif
714
715//ll
Note: See TracBrowser for help on using the repository browser.