source: roaraudio/roarclients/roarshout.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: 8.5 KB
Line 
1//roarshout.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-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
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   ROAR_CKHAVEARGS(1);
124   server = argv[++i];
125  } else if ( strcmp(k, "--rate") == 0 || strcmp(k, "-R") == 0 ) {
126   ROAR_CKHAVEARGS(1);
127   info.rate = roar_str2rate(argv[++i]);
128  } else if ( strcmp(k, "--bits") == 0 || strcmp(k, "-B") == 0 ) {
129   ROAR_CKHAVEARGS(1);
130   info.bits = roar_str2bits(argv[++i]);
131  } else if ( strcmp(k, "--channels") == 0 || strcmp(k, "--chans") == 0 || strcmp(k, "-C") == 0 ) {
132   ROAR_CKHAVEARGS(1);
133   info.channels = roar_str2channels(argv[++i]);
134  } else if ( strcmp(k, "--codec") == 0 || strcmp(k, "-E") == 0 ) {
135   ROAR_CKHAVEARGS(1);
136   info.codec = roar_str2codec(argv[++i]);
137  } else if ( !strcmp(k, "--aiprofile") ) {
138   ROAR_CKHAVEARGS(1);
139   if ( roar_profile2info(&info, argv[++i]) == -1 ) {
140    fprintf(stderr, "Error: Can not load audio profile: %s: %s\n", argv[i], roar_error2str(roar_error));
141    return 1;
142   }
143  } else if ( strcmp(k, "--pw-arg") == 0 ) {
144   pw_source = ARG;
145  } else if ( strcmp(k, "--pw-ask") == 0 ) {
146   pw_source = ASK;
147  } else if ( strcmp(k, "--pw-dstr") == 0 ) {
148   pw_source = DSTR;
149  } else if ( strcmp(k, "-p") == 0 || strcmp(k, "--public") == 0 ) {
150   s_public = 1;
151  } else if ( strcmp(k, "-d") == 0 ) {
152   ROAR_CKHAVEARGS(1);
153   s_desc   = argv[++i];
154  } else if ( strcmp(k, "-g") == 0 ) {
155   ROAR_CKHAVEARGS(1);
156   s_genre  = argv[++i];
157  } else if ( strcmp(k, "-n") == 0 ) {
158   ROAR_CKHAVEARGS(1);
159   s_name   = argv[++i];
160  } else if ( strcmp(k, "-u") == 0 ) {
161   ROAR_CKHAVEARGS(1);
162   s_url    = argv[++i];
163  } else if ( strcmp(k, "-h") == 0 || strcmp(k, "--help") == 0 ) {
164   usage();
165   return 0;
166  } else if ( s_server == NULL ) {
167   ROAR_CKHAVEARGS(1);
168   s_server = k;
169  } else if ( s_port   == -1 ) {
170   ROAR_CKHAVEARGS(1);
171   s_port   = atoi(k);
172  } else if ( s_pw     == NULL ) {
173   ROAR_CKHAVEARGS(1);
174   s_pw     = argv[i]; // do not use k here so k can be const.
175  } else if ( s_mount  == NULL ) {
176   ROAR_CKHAVEARGS(1);
177   s_mount  = k;
178  } else {
179   fprintf(stderr, "Error: unknown argument: %s\n", k);
180   usage();
181   return 1;
182  }
183 }
184
185 switch (pw_source) {
186  case ARG:
187    // nothing to do
188   break;
189  case ASK:
190    if ( roar_passwd_simple_ask_pw(&s_pw, "Password for icecast server?", NULL) == -1 ) {
191     fprintf(stderr, "Error: unabled to read password from user.\n");
192     return 1;
193    }
194    strncpy(password_buf, s_pw, sizeof(password_buf)-1);
195    roar_mm_free(s_pw);
196    password_buf[sizeof(password_buf)-2] = 0;
197    s_pw = password_buf;
198   break;
199  case DSTR:
200    if ( (s_pw = read_pw_from_file(s_pw, password_buf, sizeof(password_buf))) == NULL ) {
201     fprintf(stderr, "Error: unabled to read password from file.\n");
202     return 1;
203    }
204   break;
205 }
206
207 if ( s_server == NULL )
208  s_server = "localhost";
209
210 if ( s_mount == NULL )
211  s_mount  = "/roar.ogg";
212
213 if ( s_pw == NULL )
214  s_pw     = "hackme";
215
216 if ( s_port == -1 )
217  s_port   = 8000;
218
219 if ( !strcasecmp(s_pw, "hackme") ) {
220  fprintf(stderr, "Warning: Your password is very weak. Change it!\n");
221 }
222
223 shout_init();
224
225 if (!(shout = shout_new())) {
226  ROAR_ERR("Can not create shout object");
227  return 1;
228 }
229
230 if (shout_set_host(shout, s_server) != SHOUTERR_SUCCESS) {
231  ROAR_ERR("Error setting hostname: %s", shout_get_error(shout));
232  return 1;
233 }
234
235 if (shout_set_protocol(shout, SHOUT_PROTOCOL_HTTP) != SHOUTERR_SUCCESS) {
236  ROAR_ERR("Error setting protocol: %s", shout_get_error(shout));
237  return 1;
238 }
239
240 if (shout_set_port(shout, s_port) != SHOUTERR_SUCCESS) {
241  ROAR_ERR("Error setting port: %s", shout_get_error(shout));
242  return 1;
243 }
244
245 if (shout_set_password(shout, s_pw) != SHOUTERR_SUCCESS) {
246  ROAR_ERR("Error setting password: %s", shout_get_error(shout));
247  return 1;
248 }
249
250 if (shout_set_mount(shout, s_mount) != SHOUTERR_SUCCESS) {
251  ROAR_ERR("Error setting mount: %s", shout_get_error(shout));
252  return 1;
253 }
254
255 if (shout_set_user(shout, "source") != SHOUTERR_SUCCESS) {
256  ROAR_ERR("Error setting user: %s", shout_get_error(shout));
257  return 1;
258 }
259
260 if (shout_set_format(shout, SHOUT_FORMAT_OGG) != SHOUTERR_SUCCESS) {
261  ROAR_ERR("Error setting format: %s", shout_get_error(shout));
262  return 1;
263 }
264
265 shout_set_public(shout, s_public);
266
267 if (s_desc  != NULL)
268  shout_set_description(shout, s_desc);
269
270 if (s_genre != NULL)
271  shout_set_genre(shout, s_genre);
272
273 if (s_name  != NULL)
274  shout_set_name(shout, s_name);
275
276 if (s_url   != NULL)
277  shout_set_url(shout, s_url);
278
279 if ( (vss = roar_vs_new_simple(server, "roarshout",
280                                info.rate, info.channels, info.codec, info.bits,
281                                ROAR_DIR_MONITOR, &err)) == NULL ) {
282  fprintf(stderr, "Error: can not start monitoring: %s\n", roar_vs_strerr(err));
283  return 1;
284 }
285
286 if (shout_open(shout) != SHOUTERR_SUCCESS) {
287  ROAR_ERR("Can not open connection via libshout!");
288  return -1;
289 }
290
291 while((ret = roar_vs_read(vss, buf, BUFSIZE, NULL)))
292  if (shout_send(shout, (unsigned char*)buf, i) != SHOUTERR_SUCCESS)
293   break;
294
295 roar_vs_close(vss, ROAR_VS_TRUE, NULL);
296
297 shout_sync(shout);
298
299 shout_close(shout);
300
301 shout_shutdown();
302
303 return 0;
304}
305
306#else
307int main (void) {
308 fprintf(stderr, "No libshout support compiled in!\n");
309 return 1;
310}
311#endif
312//ll
Note: See TracBrowser for help on using the repository browser.