1 /*
2 * Mp3Splt -- Utility for mp3/ogg splitting without decoding
3 *
4 * Copyright (c) 2002-2005 M. Trotta - <mtrotta@users.sourceforge.net>
5 * Copyright (c) 2005-2014 Alexandru Munteanu - <m@ioalex.net>
6 *
7 * http://mp3splt.sourceforge.net
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program 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 program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 */
23
24 #include <unistd.h>
25
26 #ifdef __WIN32__
27 #include <conio.h>
28 #endif
29
30 #include "common.h"
31 #include "utils.h"
32 #include "print_utils.h"
33
34 #include "freedb.h"
35
36 static void handle_proxy(main_data *data);
37 static void query_for_proxy_and_write_configuration_file(main_data *data);
38 static void read_proxy_settings_from_configuration_file(main_data *data);
39 static char *get_configuration_filename();
40 static char *query_for_proxy_login();
41 static char *get_input_line(FILE *input_file, char *key);
42
43 extern FILE *console_out;
44
45 #if defined(__BEOS__) && !defined (HAS_GETPASS)
46 #warning Faking getpass() !!!
getpass(char * p)47 char *getpass(char *p)
48 {
49 char *ret = malloc(30);
50 if (!ret)
51 return NULL;
52 puts(p);
53 fgets(ret, 30, stdin);
54 return ret;
55 }
56 #endif
57
58 #ifdef __WIN32__
getpass(char * s)59 char *getpass(char *s)
60 {
61 char *pass, c;
62 int i=0;
63 fputs(s, stdout);
64 pass = malloc(100);
65 do {
66 c = _getch();
67 if (c!='\r') {
68 if (c=='\b') {
69 if (i>0) {
70 printf ("\b \b");
71 i--;
72 }
73 }
74 else {
75 printf ("*");
76 pass[i++] = c;
77 }
78 }
79 else break;
80 } while (i<100);
81
82 pass[i]='\0';
83
84 printf("\n");
85
86 return pass;
87 }
88 #endif
89
do_freedb_search(main_data * data)90 void do_freedb_search(main_data *data)
91 {
92 handle_proxy(data);
93
94 int err = SPLT_OK;
95 options *opt = data->opt;
96 splt_state *state = data->state;
97
98 char search_type[30] = "";
99 char get_type[30] = "";
100 if (opt->freedb_search_type == SPLT_FREEDB_SEARCH_TYPE_CDDB_CGI)
101 {
102 snprintf(search_type, 30, "%s", "cddb_cgi");
103 }
104 else
105 {
106 snprintf(search_type, 30 ,"%s", "web_search");
107 }
108 if (opt->freedb_get_type == SPLT_FREEDB_GET_FILE_TYPE_CDDB_CGI)
109 {
110 snprintf(get_type, 30, "%s", "cddb_cgi");
111 }
112 else
113 {
114 snprintf(get_type, 30, "%s", "cddb_protocol");
115 }
116
117 //print out infos about the servers
118 fprintf(console_out,_(" Freedb search type: %s , Site: %s , Port: %d\n"),
119 search_type,opt->freedb_search_server,opt->freedb_search_port);
120 fflush(console_out);
121 fprintf(console_out,_(" Freedb get type: %s , Site: %s , Port: %d\n"),
122 get_type,opt->freedb_get_server,opt->freedb_get_port);
123 fflush(console_out);
124
125 char *freedb_search_string = NULL;
126 char freedb_input[2048] = { '\0' };
127 //if we haven't chosen to search from the arguments, interactive search
128 if (opt->freedb_arg_search_string[0] == '\0')
129 {
130 print_message(_("CDDB QUERY. Insert album and artist informations to find cd."));
131
132 short first_time = SPLT_TRUE;
133 do {
134 if (!first_time)
135 {
136 print_message(_("\nPlease search something ..."));
137 }
138
139 memset(freedb_input, '\0', sizeof(freedb_input));
140
141 fprintf(console_out, "\n\t____________________________________________________________]");
142 fprintf(console_out, _("\r Search: ["));
143
144 fgets(freedb_input, 2046, stdin);
145
146 first_time = SPLT_FALSE;
147
148 freedb_input[strlen(freedb_input)-1] = '\0';
149 } while (strlen(freedb_input)==0);
150
151 freedb_search_string = freedb_input;
152 }
153 else
154 {
155 freedb_search_string = opt->freedb_arg_search_string;
156 }
157
158 fprintf(console_out, _("\n Search string: %s\n"),freedb_search_string);
159 fprintf(console_out, _("\nSearching from %s on port %d using %s ...\n"),
160 opt->freedb_search_server,opt->freedb_search_port, search_type);
161 fflush(console_out);
162
163 splt_freedb_results *f_results =
164 mp3splt_get_freedb_search(state, freedb_search_string,
165 &err, opt->freedb_search_type,
166 opt->freedb_search_server,
167 opt->freedb_search_port);
168
169 process_confirmation_error(err, data);
170 if (!f_results)
171 {
172 print_message_exit(_("No results found"), data);
173 }
174
175 //if we don't have an auto-select the result X from the arguments:
176 // (query{artist}(resultX)
177 //, then interactive user ask
178 int selected_cd = 0;
179 if (opt->freedb_arg_result_option < 0)
180 {
181 //print the searched informations
182 print_message(_("List of found cd:"));
183
184 int cd_number = 0;
185 short end = SPLT_FALSE;
186
187 mp3splt_freedb_init_iterator(f_results);
188 const splt_freedb_one_result *f_result = NULL;
189 while ((f_result = mp3splt_freedb_next(f_results))) {
190 int cd_id = mp3splt_freedb_get_id(f_result);
191
192 const char *cd_name = mp3splt_freedb_get_name(f_result);
193 fprintf(console_out,"%3d) %s\n", cd_id, cd_name);
194
195 int i = 0;
196 int number_of_revisions = mp3splt_freedb_get_number_of_revisions(f_result);
197 for(i = 0; i < number_of_revisions; i++)
198 {
199 fprintf(console_out, " |\\=>");
200 fprintf(console_out, "%3d) ", cd_id+i+1);
201 fprintf(console_out, _("Revision: %d\n"), i+2);
202
203 //break at 22
204 if (((cd_id+i+2) % 22) == 0)
205 {
206 //duplicate, see below
207 char junk[18];
208 fprintf(console_out, _("-- 'q' to select cd, Enter for more:"));
209 fflush(console_out);
210
211 fgets(junk, 16, stdin);
212 if (junk[0]=='q')
213 {
214 end = SPLT_TRUE;
215 goto end;
216 }
217 }
218 }
219
220 //we read result from the char, q tu select cd or
221 //enter to show more results
222 if (((cd_id + 1) % 22) == 0)
223 {
224 //duplicate, see ^^
225 char junk[18];
226 fprintf(console_out, _("-- 'q' to select cd, Enter for more: "));
227 fflush(console_out);
228
229 fgets(junk, 16, stdin);
230 if (junk[0]=='q')
231 {
232 end = SPLT_TRUE;
233 goto end;
234 }
235 }
236
237 end:
238 if (end)
239 {
240 end = SPLT_FALSE;
241 break;
242 }
243
244 cd_number++;
245 };
246
247 //select the CD
248 //input of the selected cd
249 char sel_cd_input[1024];
250 int tot = 0;
251 do {
252 selected_cd = 0;
253 fprintf(console_out, _("Select cd #: "));
254 fflush(console_out);
255 fgets(sel_cd_input, 254, stdin);
256 sel_cd_input[strlen(sel_cd_input)-1]='\0';
257 tot = 0;
258
259 if (sel_cd_input[tot] == '\0')
260 {
261 selected_cd = -1;
262 }
263
264 while(sel_cd_input[tot] != '\0')
265 {
266 if (isdigit(sel_cd_input[tot++])==0)
267 {
268 fprintf(console_out, _("Please "));
269 fflush(console_out);
270
271 selected_cd = -1;
272 break;
273 }
274 }
275
276 if (selected_cd != -1)
277 {
278 selected_cd = atoi(sel_cd_input);
279 }
280
281 } while ((selected_cd < 0) || (selected_cd >= cd_number));
282 }
283 else
284 {
285 selected_cd = opt->freedb_arg_result_option;
286 }
287
288 fprintf(console_out, _("\nGetting file from %s on port %d using %s ...\n"),
289 opt->freedb_get_server,opt->freedb_get_port, get_type);
290 fflush(console_out);
291
292 err = mp3splt_write_freedb_file_result(state, selected_cd,
293 MP3SPLT_CDDBFILE, opt->freedb_get_type,
294 opt->freedb_get_server, opt->freedb_get_port);
295 process_confirmation_error(err, data);
296
297 mp3splt_clear_proxy(data->state);
298 }
299
handle_proxy(main_data * data)300 static void handle_proxy(main_data *data)
301 {
302 mp3splt_clear_proxy(data->state);
303 query_for_proxy_and_write_configuration_file(data);
304 read_proxy_settings_from_configuration_file(data);
305 }
306
read_proxy_settings_from_configuration_file(main_data * data)307 static void read_proxy_settings_from_configuration_file(main_data *data)
308 {
309 char *config_file = get_configuration_filename();
310
311 FILE *input_file = fopen(config_file, "r");
312 if (!input_file)
313 {
314 free(config_file);
315 return;
316 }
317 free(config_file);
318
319 fseek(input_file, 0, SEEK_SET);
320
321 char *proxy_address = get_input_line(input_file, "PROXYADDR");
322 if (!proxy_address) { goto end; }
323
324 char *proxy_port = get_input_line(input_file, "PROXYPORT");
325 if (!proxy_port) { free(proxy_address); goto end; }
326 int port = atoi(proxy_port);
327
328 fprintf(stderr, " Using proxy %s on port %d\n", proxy_address, port);
329
330 mp3splt_use_proxy(data->state, proxy_address, port);
331
332 if (proxy_address != NULL)
333 {
334 free(proxy_address);
335 }
336 if (proxy_port != NULL)
337 {
338 free(proxy_port);
339 }
340
341 char *use_proxy_auth = get_input_line(input_file, "PROXYAUTH");
342 if (!use_proxy_auth) { goto end; }
343 if (use_proxy_auth[0] != '1')
344 {
345 free(use_proxy_auth);
346 goto end;
347 }
348 free(use_proxy_auth);
349
350 char *authentification = get_input_line(input_file, NULL);
351 if (authentification)
352 {
353 mp3splt_use_base64_authentification(data->state, authentification);
354 free(authentification);
355 }
356 else
357 {
358 splt_code error = SPLT_OK;
359
360 char *proxy_authentification = query_for_proxy_login();
361 char *authentification_as_base64 =
362 mp3splt_encode_in_base64(data->state, proxy_authentification, &error);
363 process_confirmation_error(error, data);
364
365 memset(proxy_authentification, 0x00, strlen(proxy_authentification));
366 free(proxy_authentification);
367
368 mp3splt_use_base64_authentification(data->state, authentification_as_base64);
369
370 memset(authentification_as_base64, 0x00, strlen(authentification_as_base64));
371 free(authentification_as_base64);
372 }
373
374 end:
375 fclose(input_file);
376 }
377
get_input_line(FILE * input_file,char * key)378 static char *get_input_line(FILE *input_file, char *key)
379 {
380 char *line = NULL;
381 size_t length = 0;
382
383 #ifndef HAVE_GETLINE
384 char junk[512];
385 fgets(junk, 511, input_file);
386 junk[strlen(junk)] = '\0';
387
388 length = strlen(junk) + 1;
389 line = my_malloc(sizeof(char) * length);
390 snprintf(line, length, junk);
391 #else
392 if (getline(&line, &length, input_file) == -1)
393 {
394 if (line) { free(line); }
395 return NULL;
396 }
397 #endif
398
399 if (!line) { return NULL; }
400
401 int line_length = strlen(line);
402 if (line_length < 3)
403 {
404 free(line);
405 return NULL;
406 }
407
408 line[line_length-1] = '\0';
409 if (line[line_length-2] == '\r')
410 {
411 line[line_length-2] = '\0';
412 }
413
414 if (key == NULL)
415 {
416 return line;
417 }
418
419 if (strstr(line, key) == NULL) {
420 free(line);
421 return NULL;
422 }
423
424 char *value_start = NULL;
425 if ((value_start = strchr(line, '=')) == NULL) {
426 print_warning(_("the configuration file is malformed !"));
427 free(line);
428 return NULL;
429 }
430
431 char *value = strdup(value_start + 1);
432 if (!value)
433 {
434 print_warning(_("cannot allocate memory !"));
435 }
436
437 free(line);
438
439 return value;
440 }
441
query_for_proxy_and_write_configuration_file(main_data * data)442 static void query_for_proxy_and_write_configuration_file(main_data *data)
443 {
444 char *config_file = get_configuration_filename();
445
446 FILE *output_file = NULL;
447 if ((output_file = fopen(config_file, "r")))
448 {
449 free(config_file);
450 fclose(output_file);
451 return;
452 }
453
454 if (data->opt->q_option)
455 {
456 return;
457 }
458
459 if (!(output_file = fopen(config_file, "w+")))
460 {
461 free(config_file);
462 print_warning(_("can't open the configuration file !"));
463 return;
464 }
465 free(config_file);
466
467 int user_input_length = 1024;
468 char user_input[1024] = { '\0' };
469
470 fprintf(stderr, _("Will you use a proxy ? (y/n): "));
471 fgets(user_input, user_input_length, stdin);
472 if (user_input[0] != 'y')
473 {
474 goto close_file;
475 }
476
477 fprintf(stderr, _("Proxy Address: "));
478 fgets(user_input, user_input_length, stdin);
479 fprintf(output_file, "PROXYADDR=%s", user_input);
480
481 fprintf(stderr, _("Proxy Port: "));
482 fgets(user_input, user_input_length, stdin);
483 fprintf(output_file, "PROXYPORT=%s", user_input);
484
485 fprintf(stderr, _("Need authentication ? (y/n): "));
486 fgets(user_input, user_input_length, stdin);
487 if (user_input[0] != 'y')
488 {
489 goto close_file;
490 }
491
492 fprintf(output_file, "PROXYAUTH=1\n");
493 fprintf(stderr, _("Would you like to save the password (insecure) ? (y/n): "));
494 fgets(user_input, user_input_length, stdin);
495 if (user_input[0] != 'y')
496 {
497 goto close_file;
498 }
499
500 char *authentification = query_for_proxy_login();
501
502 splt_code error = SPLT_OK;
503 char *authentification_as_base64 =
504 mp3splt_encode_in_base64(data->state, authentification, &error);
505 process_confirmation_error(error, data);
506
507 memset(authentification, 0x00, strlen(authentification));
508 free(authentification);
509
510 fprintf(output_file, "%s\n", authentification_as_base64);
511
512 memset(authentification_as_base64, 0x00, strlen(authentification_as_base64));
513 free(authentification_as_base64);
514
515 close_file:
516 fclose(output_file);
517 }
518
query_for_proxy_login()519 static char *query_for_proxy_login()
520 {
521 char user_input[130];
522 fprintf(console_out, _("Username: "));
523 fgets(user_input, 128, stdin);
524 user_input[strlen(user_input)-1] = '\0';
525
526 char *pass = getpass(_("Password: "));
527
528 size_t login_size = strlen(user_input) + strlen(pass) + 2;
529 char *login = my_malloc(sizeof(char) * login_size);
530 snprintf(login, login_size, "%s:%s", user_input, pass);
531
532 memset(pass, 0x00, strlen(pass));
533 free(pass);
534
535 return login;
536 }
537
get_configuration_filename()538 static char *get_configuration_filename()
539 {
540 char *home_directory = getenv("HOME");
541
542 size_t home_directory_length = 0;
543 if (home_directory)
544 {
545 home_directory_length = strlen(home_directory);
546 }
547
548 size_t maximum_length = home_directory_length + strlen(PROXY_CONFIG_FILE) + 2;
549 char *config_file = my_malloc(sizeof(char) * maximum_length);
550
551 if (home_directory != NULL)
552 {
553 snprintf(config_file, maximum_length, "%s%c"PROXY_CONFIG_FILE, home_directory, SPLT_DIRCHAR);
554 }
555 else
556 {
557 snprintf(config_file, maximum_length, PROXY_CONFIG_FILE);
558 }
559
560 return config_file;
561 }
562
563