source: roaraudio/roarclients/roarshout.c @ 5823:f9f70dbaa376

Last change on this file since 5823:f9f70dbaa376 was 5823:f9f70dbaa376, checked in by phi, 11 years ago

updated copyright

File size: 8.2 KB
Line 
1//roarshout.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2013
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#ifdef ROAR_HAVE_LIBSHOUT
29#include <shout/shout.h>
30
31#define BUFSIZE 2048
32
33void usage (void) {
34 printf("roarshout [OPTIONS]... [address [port [password [mountpoint]]]\n");
35
36 printf("\nRoarAudio Options:\n\n");
37
38 printf("    --server SERVER    - Set server hostname\n"
39        " -R --rate   RATE      - Set sample rate\n"
40        " -B --bits   BITS      - Set bits per sample\n"
41        " -C --chans  CHANNELS  - Set number of channels\n"
42        " -E --codec  CODEC     - Set the codec\n"
43        "    --aiprofile PROFILE\n"
44        "                       - Set audio profile\n"
45        " -h --help             - Show this help\n"
46        "    --pw-arg           - Password is supplied as argument (default).\n"
47        "    --pw-ask           - Ask user for password interactively.\n"
48        "    --pw-dstr          - Read password from file. Filename is supplied\n"
49        "                         as normal password argument.\n"
50       );
51
52 printf("\nlibshout Options:\n\n");
53
54 printf(" -p --public           - Allow listing in stream directory\n"
55        " -d          DESC      - Set stream description\n"
56        " -g          GENRE     - Set stream genre\n"
57        " -n          NAME      - Set stream name\n"
58        " -u          URL       - Set stream URL/homepage\n"
59       );
60
61}
62
63char * read_pw_from_file(char * filename, char * buffer, size_t bufferlen) {
64 struct roar_vio_defaults def;
65 struct roar_vio_calls file;
66 ssize_t len;
67
68 if (filename == NULL || buffer == NULL)
69  return NULL;
70
71 if ( roar_vio_dstr_init_defaults(&def, ROAR_VIO_DEF_TYPE_NONE, O_RDONLY, 0644) == -1 )
72  return NULL;
73
74 if ( roar_vio_open_dstr(&file, filename, &def, 1) == -1 )
75  return NULL;
76
77 len = roar_vio_read(&file, buffer, bufferlen - 1);
78
79 if ( len == -1 )
80  return NULL;
81
82 // strip newlions.
83 for (; buffer[len-1] == '\r' || buffer[len-1] == '\n'; len--);
84
85 buffer[len] = 0;
86
87 roar_vio_close(&file);
88
89 return buffer;
90}
91
92int main (int argc, char * argv[]) {
93 enum { ARG, ASK, DSTR } pw_source = ARG;
94 struct roar_audio_info info;
95 const char * server   = NULL;
96 const char * k;
97 const char * s_server = NULL;
98 const char * s_mount  = NULL;
99 char * s_pw     = NULL;
100 int    s_port   = -1;
101 const char * s_desc   = NULL;
102 const char * s_genre  = NULL;
103 const char * s_name   = NULL;
104 const char * s_url    = NULL;
105 int    s_public = 0;
106 roar_vs_t * vss;
107 int    err;
108 ssize_t ret;
109 int    i;
110 char buf[BUFSIZE];
111 shout_t * shout;
112 char password_buf[128];
113
114 if ( roar_profile2info(&info, "default") == -1 )
115  return 1;
116
117 info.codec = ROAR_CODEC_OGG_VORBIS;
118
119 for (i = 1; i < argc; i++) {
120  k = argv[i];
121
122  if ( strcmp(k, "--server") == 0 ) {
123   server = argv[++i];
124  } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) {
125   info.rate = roar_str2rate(argv[++i]);
126  } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) {
127   info.bits = roar_str2bits(argv[++i]);
128  } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) {
129   info.channels = roar_str2channels(argv[++i]);
130  } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) {
131   info.codec = roar_str2codec(argv[++i]);
132  } else if ( !strcmp(k, "--aiprofile") ) {
133   if ( roar_profile2info(&info, argv[++i]) == -1 ) {
134    fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error));
135    return 1;
136   }
137  } else if ( strcmp(k, "--pw-arg") == 0 ) {
138   pw_source = ARG;
139  } else if ( strcmp(k, "--pw-ask") == 0 ) {
140   pw_source = ASK;
141  } else if ( strcmp(k, "--pw-dstr") == 0 ) {
142   pw_source = DSTR;
143  } else if ( strcmp(k, "-p") == 0 || strcmp(k, "--public") == 0 ) {
144   s_public = 1;
145  } else if ( strcmp(k, "-d") == 0 ) {
146   s_desc   = argv[++i];
147  } else if ( strcmp(k, "-g") == 0 ) {
148   s_genre  = argv[++i];
149  } else if ( strcmp(k, "-n") == 0 ) {
150   s_name   = argv[++i];
151  } else if ( strcmp(k, "-u") == 0 ) {
152   s_url    = argv[++i];
153  } else if ( strcmp(k, "-h") == 0 || strcmp(k, "--help") == 0 ) {
154   usage();
155   return 0;
156  } else if ( s_server == NULL ) {
157   s_server = k;
158  } else if ( s_port   == -1 ) {
159   s_port   = atoi(k);
160  } else if ( s_pw     == NULL ) {
161   s_pw     = argv[i]; // do not use k here so k can be const.
162  } else if ( s_mount  == NULL ) {
163   s_mount  = k;
164  } else {
165   fprintf(stderr, "Error: unknown argument: %s\n", k);
166   usage();
167   return 1;
168  }
169 }
170
171 switch (pw_source) {
172  case ARG:
173    // nothing to do
174   break;
175  case ASK:
176    if ( roar_passwd_simple_ask_pw(&s_pw, "Password for icecast server?", NULL) == -1 ) {
177     fprintf(stderr, "Error: unabled to read password from user.\n");
178     return 1;
179    }
180    strncpy(password_buf, s_pw, sizeof(password_buf)-1);
181    roar_mm_free(s_pw);
182    password_buf[sizeof(password_buf)-2] = 0;
183    s_pw = password_buf;
184   break;
185  case DSTR:
186    if ( (s_pw = read_pw_from_file(s_pw, password_buf, sizeof(password_buf))) == NULL ) {
187     fprintf(stderr, "Error: unabled to read password from file.\n");
188     return 1;
189    }
190   break;
191 }
192
193 if ( s_server == NULL )
194  s_server = "localhost";
195
196 if ( s_mount == NULL )
197  s_mount  = "/roar.ogg";
198
199 if ( s_pw == NULL )
200  s_pw     = "hackme";
201
202 if ( s_port == -1 )
203  s_port   = 8000;
204
205 if ( !strcasecmp(s_pw, "hackme") ) {
206  fprintf(stderr, "Warning: Your password is very weak. Change it!\n");
207 }
208
209 shout_init();
210
211 if (!(shout = shout_new())) {
212  ROAR_ERR("Can not create shout object");
213  return 1;
214 }
215
216 if (shout_set_host(shout, s_server) != SHOUTERR_SUCCESS) {
217  ROAR_ERR("Error setting hostname: %s", shout_get_error(shout));
218  return 1;
219 }
220
221 if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) {
222  ROAR_ERR("Error setting protocol: %s", shout_get_error(shout));
223  return 1;
224 }
225
226 if (shout_set_port(shout, s_port) != SHOUTERR_SUCCESS) {
227  ROAR_ERR("Error setting port: %s", shout_get_error(shout));
228  return 1;
229 }
230
231 if (shout_set_password(shout, s_pw) != SHOUTERR_SUCCESS) {
232  ROAR_ERR("Error setting password: %s", shout_get_error(shout));
233  return 1;
234 }
235
236 if (shout_set_mount(shout, s_mount) != SHOUTERR_SUCCESS) {
237  ROAR_ERR("Error setting mount: %s", shout_get_error(shout));
238  return 1;
239 }
240
241 if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) {
242  ROAR_ERR("Error setting user: %s", shout_get_error(shout));
243  return 1;
244 }
245
246 if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) {
247  ROAR_ERR("Error setting format: %s", shout_get_error(shout));
248  return 1;
249 }
250
251 shout_set_public(shout, s_public);
252
253 if (s_desc  != NULL)
254  shout_set_description(shout, s_desc);
255
256 if (s_genre != NULL)
257  shout_set_genre(shout, s_genre);
258
259 if (s_name  != NULL)
260  shout_set_name(shout, s_name);
261
262 if (s_url   != NULL)
263  shout_set_url(shout, s_url);
264
265 if ( (vss = roar_vs_new_simple(server, "roarshout",
266                                info.rate, info.channels, info.codec, info.bits,
267                                ROAR_DIR_MONITOR, &err)) == NULL ) {
268  fprintf(stderr, "Error: can not start monitoring: %s\n", roar_vs_strerr(err));
269  return 1;
270 }
271
272 if (shout_open(shout) != SHOUTERR_SUCCESS) {
273  ROAR_ERR("Can not open connection via libshout!");
274  return -1;
275 }
276
277 while((ret = roar_vs_read(vss, buf, BUFSIZE, NULL)))
278  if (shout_send(shout, (unsigned char*)buf, i) != SHOUTERR_SUCCESS)
279   break;
280
281 roar_vs_close(vss, ROAR_VS_TRUE, NULL);
282
283 shout_sync(shout);
284
285 shout_close(shout);
286
287 shout_shutdown();
288
289 return 0;
290}
291
292#else
293int main (void) {
294 fprintf(stderr, "No libshout support compiled in!\n");
295 return 1;
296}
297#endif
298//ll
Note: See TracBrowser for help on using the repository browser.