source: roaraudio/roarclients/roarvio.c @ 5961:06e7fd9e4c25

Last change on this file since 5961:06e7fd9e4c25 was 5961:06e7fd9e4c25, checked in by phi, 10 years ago

Updates of copyright and license headers

File size: 6.6 KB
Line 
1//roarvio.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2014
5 *
6 *  This file is part of roarclients 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 *  RoarAudio 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 */
25
26int g_verbose = 0;
27#define ROAR_DBG_INFOVAR g_verbose
28
29#include <roaraudio.h>
30#include <errno.h>
31#include <string.h>
32#include <stdio.h>
33
34enum action {
35 READ,
36 WRITE,
37 PASS,
38 EXPLAIN
39};
40
41
42void usage (const char * progname) {
43 fprintf(stderr, "Usage: %s [OPTIONS]... FILE [FILE]\n", progname);
44
45 fprintf(stderr, "\nOptions:\n\n");
46
47 fprintf(stderr, " -h --help         - This help.\n"
48                 "    --verbose      - Be verbose. Can be used multiple times.\n"
49                 "    --read         - Reading mode (like 'cat file').\n"
50                 "    --write        - Writing mode (like 'cat > file').\n"
51                 "    --pass         - Passing mode (like 'cat infile > outfile').\n"
52                 "    --explain      - Explain VIO object.\n");
53}
54
55ssize_t do_explain (struct roar_vio_calls * cur) {
56 struct roar_sockname sockname;
57 int                  have_sockname;
58 int need_space, need_space2;
59 int level = 0;
60 int fh;
61 const char * name;
62 const char * codec;
63 const char * content_type;
64
65 while (cur != NULL) {
66  if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_NAME, &name) == -1 )
67   name = "UNKNOWN";
68
69  if ( g_verbose ) {
70   if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_MIMETYPE, &content_type) == -1 )
71    content_type = "UNKNOWN";
72
73   codec = roar_codec2str(roar_mime2codec(content_type));
74
75   if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_FH, &fh) == -1 )
76    fh = -1;
77
78   if ( g_verbose > 1 ) {
79    if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_PEERNAME, &sockname) == -1 ) {
80     have_sockname = 0;
81    } else {
82     have_sockname = 1;
83    }
84   } else {
85    have_sockname = 0;
86   }
87  } else {
88   content_type  = "UNKNOWN";
89   codec         = "UNKNOWN";
90   fh            = -1;
91   have_sockname = 0;
92  }
93
94  printf("%i: %s", level, name);
95  if ( fh != -1 || !!strcasecmp(codec, "UNKNOWN") || !!strcasecmp(content_type, "UNKNOWN") || have_sockname ) {
96   need_space = 0;
97   printf(" (");
98   if ( fh != -1 ) {
99    printf("fh=%i", fh);
100    need_space = 1;
101   }
102
103   if ( have_sockname ) {
104    need_space2 = 0;
105    printf("%ssocket={", need_space ? ", " : "");
106
107    need_space2 = 1;
108    switch (sockname.type) {
109     case ROAR_SOCKET_TYPE_UNIX:   printf("af=UNIX");   break;
110     case ROAR_SOCKET_TYPE_DECNET: printf("af=DECnet"); break;
111     case ROAR_SOCKET_TYPE_INET:   printf("af=INET");   break;
112     case ROAR_SOCKET_TYPE_INET6:  printf("af=INET6");  break;
113     default:
114       need_space2 = 0;
115      break;
116    }
117
118    if ( sockname.addr != NULL ) {
119     printf("%saddr=\"%s\"", need_space2 ? ", " : "", sockname.addr);
120     need_space2 = 1;
121    }
122
123    if ( sockname.port ) {
124     printf("%sport=%i", need_space2 ? ", " : "", sockname.port);
125     need_space2 = 1;
126    }
127
128    printf("}");
129    need_space = 1;
130   }
131
132   if ( !!strcasecmp(codec, "UNKNOWN") ) {
133    printf("%scodec=%s", need_space ? ", " : "", codec);
134    need_space = 1;
135   }
136
137   if ( !!strcmp(content_type, "UNKNOWN") ) {
138    printf("%scontent-type=\"%s\"", need_space ? ", " : "", content_type);
139    need_space = 1;
140   }
141   printf(")");
142  }
143  printf("\n");
144
145  level++;
146
147  if ( have_sockname )
148   if ( sockname.addr != NULL )
149    roar_mm_free(sockname.addr);
150
151  if ( roar_vio_ctl(cur, ROAR_VIO_CTL_GET_NEXT, &cur) == -1 )
152   cur = NULL;
153 }
154
155 roar_error = ROAR_ERROR_NONE;
156 return 0;
157}
158
159int main (int argc, char * argv[]) {
160 struct roar_vio_defaults def;
161 struct roar_vio_calls vio0, vio1;
162 enum action action = READ;
163 ssize_t written = -1;
164 int i;
165 const char * k;
166 const char * file0 = NULL;
167 const char * file1 = NULL;
168 int o_flags = -1;
169 int ret = 0;
170
171 for (i = 1; i < argc; i++) {
172  k = argv[i];
173
174  if ( !strcmp(k, "-h") || !strcmp(k, "--help") ) {
175   usage(argv[0]);
176   return 0;
177  } else if ( !strcmp(k, "--read") ) {
178   action = READ;
179  } else if ( !strcmp(k, "--write") ) {
180   action = WRITE;
181  } else if ( !strcmp(k, "--pass") ) {
182   action = PASS;
183  } else if ( !strcmp(k, "--explain") ) {
184   action = EXPLAIN;
185  } else if ( !strcmp(k, "--verbose") ) {
186   g_verbose++;
187  } else if ( file0 == NULL ) {
188   file0 = k;
189  } else if ( file1 == NULL ) {
190   file1 = k;
191  } else {
192   ROAR_ERR("Too many parameters or unknown parameter: %s", k);
193   usage(argv[0]);
194   return 1;
195  }
196 }
197
198 if ( file0 == NULL ) {
199  usage(argv[0]);
200  return 1;
201 }
202
203 if ( (file1 != NULL && action != PASS) || (action == PASS && file1 == NULL) ) {
204  usage(argv[0]);
205  return 1;
206 }
207
208 switch (action) {
209  case READ:
210  case PASS:
211  case EXPLAIN:
212    o_flags = O_RDONLY;
213   break;
214  case WRITE:
215    o_flags = O_WRONLY|O_CREAT|O_TRUNC;
216   break;
217 }
218
219 if ( o_flags == -1 ) {
220  ROAR_ERR("o_flags unset, very bad. This should never happen.");
221  return 1;
222 }
223
224 if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, o_flags, 0644) == -1 ) {
225  ROAR_ERR("Can not init DSTR defaults. Bad.");
226  return 1;
227 }
228
229 if ( roar_vio_open_dstr(&vio0, file0, &def, 1) == -1 ) {
230  ROAR_ERR("Can not open file: %s: %s", file0, roar_error2str(roar_error));
231  return 1;
232 }
233
234 if ( action == PASS ) {
235  if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_WRONLY|O_CREAT|O_TRUNC, 0644) == -1 ) {
236   ROAR_ERR("Can not init DSTR defaults. Bad.");
237   roar_vio_close(&vio0);
238   return 1;
239  }
240
241  if ( roar_vio_open_dstr(&vio1, file1, &def, 1) == -1 ) {
242   ROAR_ERR("Can not open file: %s: %s", file1, roar_error2str(roar_error));
243   roar_vio_close(&vio0);
244   return 1;
245  }
246 }
247
248 switch (action) {
249  case READ:
250    written = roar_vio_copy_data(roar_stdout, &vio0);
251   break;
252  case WRITE:
253    written = roar_vio_copy_data(&vio0, roar_stdin);
254   break;
255  case PASS:
256    written = roar_vio_copy_data(&vio1, &vio0);
257   break;
258  case EXPLAIN:
259    if ( (written = do_explain(&vio0)) == -1 )
260     ret = 4;
261   break;
262 }
263
264 if ( written == -1 ) {
265  ROAR_ERR("Can not push data: %s", roar_error2str(roar_error));
266 }
267
268 roar_vio_close(&vio0);
269 if ( file1 != NULL )
270  roar_vio_close(&vio1);
271
272 return ret;
273}
274
275//ll
Note: See TracBrowser for help on using the repository browser.