source: roaraudio/roarclients/roarradio.c @ 5381:430b1d26e12d

Last change on this file since 5381:430b1d26e12d was 5381:430b1d26e12d, checked in by phi, 12 years ago

updated copyright years

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