source: roaraudio/roarclients/roarradio.c @ 5950:7fe8f5df7a83

Last change on this file since 5950:7fe8f5df7a83 was 5950:7fe8f5df7a83, checked in by phi, 11 years ago

code cleanup and again a patch for checking commandlion parameters

File size: 6.4 KB
RevLine 
[800]1//roarradio.c:
2
3/*
[5823]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2013
[800]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
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[800]23 *
24 */
25
26#include <roaraudio.h>
27
[2114]28#define P_UNKNOWN 0
29#define P_HTTP    1
30#define P_GOPHER  2
31
[800]32void usage (void) {
33 printf("roarradio [OPTIONS]... [FILE|URL]\n");
34
35 printf("\nOptions:\n\n");
36
[5533]37 printf("  --server SERVER      - Set server hostname\n"
38        "  --rate  -R RATE      - Set sample rate\n"
39        "  --bits  -B BITS      - Set bits per sample\n"
40        "  --chans -C CHANNELS  - Set number of channels\n"
41        "  --codec -E CODEC     - Set the codec\n"
42        "  --aiprofile PROFILE  - Set audio profile\n"
43        "  --help               - Show this help\n"
[800]44       );
45
46}
47
[4740]48static void die(const char * msg) {
49 fprintf(stderr, "Fatal error: %s\n", msg);
50 abort();
51}
52
[800]53int main (int argc, char * argv[]) {
[5533]54 struct roar_audio_info info;
[5534]55 const char * server   = NULL;
56 const char * k;
[800]57 int    i;
58 int    in = -1;
59 char * file = NULL;
60 char * host;
[2114]61 int    port;
[800]62 FILE * http;
63 struct roar_connection con[1];
64 struct roar_stream     stream[1];
65 char buf0[80], buf1[80];
[2114]66 int proto = P_UNKNOWN;
[4740]67 ssize_t slen;
[800]68
[5533]69 if ( roar_profile2info(&info, "default") == -1 )
70  return 1;
71
72 info.codec = ROAR_CODEC_OGG_VORBIS;
73
[800]74 for (i = 1; i < argc; i++) {
75  k = argv[i];
76
77  if ( strcmp(k, "--server") == 0 ) {
[5950]78   ROAR_CKHAVEARGS(1);
[800]79   server = argv[++i];
[5533]80  } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) {
[5950]81   ROAR_CKHAVEARGS(1);
[5533]82   info.rate = roar_str2rate(argv[++i]);
83  } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) {
[5950]84   ROAR_CKHAVEARGS(1);
[5533]85   info.bits = roar_str2bits(argv[++i]);
86  } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) {
[5950]87   ROAR_CKHAVEARGS(1);
[5533]88   info.channels = roar_str2channels(argv[++i]);
89  } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) {
[5950]90   ROAR_CKHAVEARGS(1);
[5533]91   info.codec = roar_str2codec(argv[++i]);
92  } else if ( !strcmp(k, "--aiprofile") ) {
[5950]93   ROAR_CKHAVEARGS(1);
[5533]94   if ( roar_profile2info(&info, argv[++i]) == -1 ) {
95    fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error));
96    return 1;
97   }
[800]98  } else if ( strcmp(k, "--help") == 0 ) {
99   usage();
100   return 0;
101  } else if ( file == NULL ) {
102   file = argv[i];
103  } else {
104   fprintf(stderr, "Error: unknown argument: %s\n", k);
105   usage();
106   return 1;
107  }
108 }
109
110 if ( file == NULL ) {
111  file = "/dev/stdin";
112  in   = ROAR_STDIN;
113 } else {
[2114]114  if ( strncmp(file, "http://", 7) == 0 ) {
115   proto = P_HTTP;
116   host  = file+7;
117   port  = 80;
118  } else if ( strncmp(file, "gopher://", 9) == 0 ) {
119   proto = P_GOPHER;
120   host  = file+9;
121   port  = 70;
[2222]122  } else {
123   fprintf(stderr, "Error: unknown protocol: %s\n", file);
124   return 20;
[2114]125  }
[800]126
[2114]127  if ( proto == P_HTTP || proto == P_GOPHER ) {
[800]128   for (i = 0; host[i] != 0; i++) {
129    if ( host[i] == ':' ) {
130     port    = atoi(host+i+1); // atoi() ignores the rest after '/'
131     host[i] = 0;
132    } else if ( host[i] == '/' ) {
133     file    = host+i;
134     break;
135    }
136   }
137
[1511]138   if ( !*file ) {
139    file = "/";
140
[5375]141    if ( (in = roar_socket_connect(ROAR_SOCKET_TYPE_UNKNOWN, host, port)) == -1 ) {
[1511]142     ROAR_ERR("can not connect to remote server %s (port %i): %s", host, port, strerror(errno));
143     return 0;
144    }
145   } else {
146    *file = 0;
147
[5375]148    if ( (in = roar_socket_connect(ROAR_SOCKET_TYPE_UNKNOWN, host, port)) == -1 ) {
[1511]149     ROAR_ERR("can not connect to remote server %s (port %i): %s", host, port, strerror(errno));
150     return 0;
151    }
152
153    *file = '/';
[800]154   }
155
[2114]156   switch (proto) {
157    case P_HTTP:
158      if ( (http = fdopen(in, "r+")) == NULL ) {
159       ROAR_ERR("can not create FILE* object: %s", strerror(errno));
160       return 0;
161      }
162
163      fprintf(http, "GET %s HTTP/1.1\r\n", file);
164      fprintf(http, "Host: %s\r\n", host);
165      fprintf(http, "User-Agent: roarradio $Revision$\r\n");
166      fprintf(http, "Connection: close\r\n");
167      fprintf(http, "\r\n");
168      fflush(http);
169
170      if ( fscanf(http, "%79s %i %79s\n", buf0, &port, buf1) != 3 ) {
[4012]171       ROAR_ERR("HTTP protocol error!, no initial HTTP/1.x-line!");
[2114]172       return 1;
173      }
174      if ( port != 200 ) { // 200 = HTTP OK
175       ROAR_ERR("HTTP Error: %i - %s", port, buf1);
176       return 1;
177      }
[800]178
[2114]179      *buf0 = 0;
180
181      while (*buf0 != '\r' && *buf0 != '\n') {
[4740]182       if ( fgets(buf0, 80, http) == NULL )
183        die("Can not read header lion");
[2114]184      }
[800]185
[2114]186      fflush(http);
187     break;
188    case P_GOPHER:
189      if ( file[0] == 0 ) {
190       file[0] = '/';
191       file[1] = 0;
192      } else if ( file[0] == '/' && file[1] != 0 && file[2] == '/' ) { // strip the type prefix
193       file += 2;
194      }
195      // TODO: do some error checks here
[4740]196      slen = strlen(file);
197      if ( write(in, file, slen) != slen )
198       die("Can not write selector");
199      if ( write(in, "\r\n", 2) != 2 )
200       die("Can not write selector terminator");
[2114]201      ROAR_SHUTDOWN(in, SHUT_WR);
202     break;
203   }
204  } else {
205   if ( (in = open(file, O_RDONLY, 0644)) == -1 ) {
206    ROAR_ERR("can not open file: %s: %s", file, strerror(errno));
[800]207    return 1;
208   }
209  }
210 }
211
212 if ( in == -1 ) {
213  ROAR_ERR("No open file, bad. This should not happen");
214  return 1;
215 }
216
217 if ( roar_simple_connect(con, server, "roarradio") == -1 ) {
218  ROAR_ERR("Can not connect to server");
[2225]219  return 1;
[800]220 }
221
[5536]222 if ( roar_stream_new_by_info(stream, &info) == -1 ) {
[800]223  roar_disconnect(con);
[2225]224  return 1;
[800]225 }
226
[5238]227 if ( roar_stream_connect(con, stream, ROAR_DIR_PLAY, -1) == -1 ) {
[800]228  roar_disconnect(con);
[2225]229  return 1;
[800]230 }
231
232 if ( roar_stream_passfh(con, stream, in) == -1 ) {
233  roar_disconnect(con);
[2225]234  return 1;
[800]235 }
236
237 close(in);
238
239 if ( roar_stream_attach_simple(con, stream, 0) == -1 ) {
240  ROAR_ERR("Can not attach stream to server");
241 }
242
243 roar_disconnect(con);
244
245 return 0;
246}
247
248//ll
Note: See TracBrowser for help on using the repository browser.