1 /*
2  *   cda - Command-line CD Audio Player/Ripper
3  *
4  *   Copyright (C) 1993-2004  Ti Kan
5  *   E-mail: xmcd@amb.org
6  *
7  *   This program is free software; you can redistribute it and/or modify
8  *   it under the terms of the GNU General Public License as published by
9  *   the Free Software Foundation; either version 2 of the License, or
10  *   (at your option) any later version.
11  *
12  *   This program is distributed in the hope that it will be useful,
13  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *   GNU General Public License for more details.
16  *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20  *
21  */
22 #ifndef lint
23 static char *_userreg_c_ident_ = "@(#)userreg.c	1.16 03/12/12";
24 #endif
25 
26 #include "common_d/appenv.h"
27 #include "common_d/util.h"
28 #include "libdi_d/libdi.h"
29 #include "cdinfo_d/cdinfo.h"
30 #include "cda_d/cda.h"
31 #include "cda_d/userreg.h"
32 
33 
34 extern appdata_t	app_data;
35 extern cdinfo_incore_t	*dbp;
36 extern FILE		*errfp;
37 
38 
39 /***********************
40  *  internal routines  *
41  ***********************/
42 
43 /*
44  * cda_get_cddbhandle
45  *	Prompt user for the CDDB user handle
46  *
47  * Args:
48  *	ttyfp - Opened file stream to the user's terminal
49  *
50  * Return:
51  *	TRUE - success
52  *	FALSE - failure
53  */
54 STATIC bool_t
55 cda_get_cddbhandle(FILE *ttyfp)
56 {
57 	char	input[64];
58 
59 	for (;;) {
60 		(void) fprintf(ttyfp,
61 		    "    Please enter your CDDB user handle%s%s%s: ",
62 		    dbp->userreg.handle == NULL ? "" : " [",
63 		    dbp->userreg.handle == NULL ? "" : dbp->userreg.handle,
64 		    dbp->userreg.handle == NULL ? "" : "]");
65 		(void) fflush(ttyfp);
66 
67 		if (fgets(input, 63, stdin) == NULL) {
68 			(void) fprintf(ttyfp, "\n");
69 			(void) fflush(ttyfp);
70 			return FALSE;
71 		}
72 		input[strlen(input)-1] = '\0';
73 		if (input[0] != '\0') {
74 			if (!util_newstr(&dbp->userreg.handle, input)) {
75 				(void) fflush(ttyfp);
76 				CDA_FATAL(app_data.str_nomemory);
77 				return FALSE;
78 			}
79 			break;
80 		}
81 		else if (dbp->userreg.handle != NULL)
82 			break;
83 	}
84 	(void) fflush(ttyfp);
85 	return TRUE;
86 }
87 
88 
89 /*
90  * cda_get_cddbpass
91  *	Prompt user for the CDDB password
92  *
93  * Args:
94  *	ttyfp - Opened file stream to the user's terminal
95  *
96  * Return:
97  *	TRUE - success
98  */
99 STATIC bool_t
100 cda_get_cddbpass(FILE *ttyfp)
101 {
102 	char	input[64],
103 		input2[64];
104 
105 	for (;;) {
106 		(void) fprintf(ttyfp,
107 			"    Please enter your CDDB password: ");
108 		(void) fflush(ttyfp);
109 		cda_echo(ttyfp, FALSE);
110 		if (fgets(input, 63, stdin) == NULL) {
111 			cda_echo(ttyfp, TRUE);
112 			(void) fprintf(ttyfp, "\n");
113 			(void) fflush(ttyfp);
114 			return FALSE;
115 		}
116 		cda_echo(ttyfp, TRUE);
117 		input[strlen(input)-1] = '\0';
118 		if (input[0] == '\0') {
119 			(void) fprintf(ttyfp, "\n");
120 			continue;
121 		}
122 
123 		(void) fprintf(ttyfp,
124 			"\n    Please re-type your CDDB password: ");
125 		(void) fflush(ttyfp);
126 		cda_echo(ttyfp, FALSE);
127 		if (fgets(input2, 63, stdin) == NULL) {
128 			cda_echo(ttyfp, TRUE);
129 			(void) fprintf(ttyfp, "\n");
130 			(void) fflush(ttyfp);
131 			return FALSE;
132 		}
133 		cda_echo(ttyfp, TRUE);
134 		input2[strlen(input2)-1] = '\0';
135 		if (input2[0] == '\0' || strcmp(input, input2) != 0) {
136 			(void) fprintf(ttyfp,
137 				"\nPasswords do not match.  Try again.\n");
138 			continue;
139 		}
140 
141 		if (!util_newstr(&dbp->userreg.passwd, input)) {
142 			(void) fprintf(ttyfp, "\n");
143 			(void) fprintf(ttyfp, "\n");
144 			(void) fflush(ttyfp);
145 			CDA_FATAL(app_data.str_nomemory);
146 			return FALSE;
147 		}
148 		if (!util_newstr(&dbp->userreg.vpasswd, input2)) {
149 			(void) fprintf(ttyfp, "\n");
150 			(void) fprintf(ttyfp, "\n");
151 			(void) fflush(ttyfp);
152 			CDA_FATAL(app_data.str_nomemory);
153 			return FALSE;
154 		}
155 		break;
156 	}
157 	(void) fprintf(ttyfp, "\n");
158 	(void) fflush(ttyfp);
159 	return TRUE;
160 }
161 
162 
163 /*
164  * cda_get_hint
165  *	Prompt user for the password hint
166  *
167  * Args:
168  *	ttyfp - Opened file stream to the user's terminal
169  *
170  * Return:
171  *	TRUE - success
172  */
173 STATIC bool_t
174 cda_get_hint(FILE *ttyfp)
175 {
176 	char	input[64];
177 
178 	(void) fprintf(ttyfp,
179 		"\nEntering a password hint allows CDDB to e-mail your\n"
180 		"password hint to you in case you forget it in the future.\n");
181 
182 	/* Password hint */
183 	(void) fprintf(ttyfp, "\n    Please enter a password hint: ");
184 	(void) fflush(ttyfp);
185 
186 	if (fgets(input, 63, stdin) == NULL) {
187 		(void) fprintf(ttyfp, "\n");
188 		(void) fflush(ttyfp);
189 		return TRUE;
190 	}
191 	input[strlen(input)-1] = '\0';
192 	if (!util_newstr(&dbp->userreg.hint, input)) {
193 		(void) fflush(ttyfp);
194 		CDA_FATAL(app_data.str_nomemory);
195 		return FALSE;
196 	}
197 	(void) fflush(ttyfp);
198 	return TRUE;
199 }
200 
201 
202 /*
203  * cda_get_email
204  *	Prompt user for the e-mail address
205  *
206  * Args:
207  *	ttyfp - Opened file stream to the user's terminal
208  *
209  * Return:
210  *	TRUE - success
211  */
212 STATIC bool_t
213 cda_get_email(FILE *ttyfp)
214 {
215 	char	input[64];
216 
217 	(void) fprintf(ttyfp,
218 		"\nProviding your e-mail address will allow CDDB to send you\n"
219 		"your password hint if you forget your password.\n");
220 
221 	/* E-mail address */
222 	(void) fprintf(ttyfp,
223 		"\n    Please enter your e-mail address: ");
224 	(void) fflush(ttyfp);
225 
226 	if (fgets(input, 63, stdin) == NULL) {
227 		(void) fprintf(ttyfp, "\n");
228 		(void) fflush(ttyfp);
229 		return TRUE;
230 	}
231 	input[strlen(input)-1] = '\0';
232 	if (!util_newstr(&dbp->userreg.email, input)) {
233 		(void) fflush(ttyfp);
234 		CDA_FATAL(app_data.str_nomemory);
235 		return FALSE;
236 	}
237 	(void) fflush(ttyfp);
238 	return TRUE;
239 }
240 
241 
242 /*
243  * cda_get_age
244  *	Prompt user for the age
245  *
246  * Args:
247  *	ttyfp - Opened file stream to the user's terminal
248  *
249  * Return:
250  *	TRUE - success
251  */
252 STATIC bool_t
253 cda_get_age(FILE *ttyfp)
254 {
255 	char	input[64];
256 
257 	(void) fprintf(ttyfp,
258 		"\n    Please enter your age: ");
259 	(void) fflush(ttyfp);
260 
261 	if (fgets(input, 63, stdin) == NULL) {
262 		(void) fprintf(ttyfp, "\n");
263 		(void) fflush(ttyfp);
264 		return TRUE;
265 	}
266 	input[strlen(input)-1] = '\0';
267 	if (!util_newstr(&dbp->userreg.age, input)) {
268 		(void) fflush(ttyfp);
269 		CDA_FATAL(app_data.str_nomemory);
270 		return FALSE;
271 	}
272 	(void) fflush(ttyfp);
273 	return TRUE;
274 }
275 
276 
277 /*
278  * cda_get_gender
279  *	Prompt user for the gender
280  *
281  * Args:
282  *	ttyfp - Opened file stream to the user's terminal
283  *
284  * Return:
285  *	TRUE - success
286  */
287 STATIC bool_t
288 cda_get_gender(FILE *ttyfp)
289 {
290 	char	input[64];
291 	bool_t	again;
292 
293 	do {
294 		again = FALSE;
295 
296 		(void) fprintf(ttyfp,
297 			"\n    Please enter your gender.\n"
298 			"\t1. Male\n"
299 			"\t2. Female\n"
300 			"\t3. Unspecified\n"
301 			"    Select [1-3]: ");
302 		(void) fflush(ttyfp);
303 
304 		if (fgets(input, 63, stdin) == NULL) {
305 			(void) fprintf(ttyfp, "\n");
306 			(void) fflush(ttyfp);
307 			return TRUE;
308 		}
309 		input[strlen(input)-1] = '\0';
310 
311 		if (input[0] != '\0') {
312 			switch (input[0]) {
313 			case '1':
314 				(void) strcpy(input, "m");
315 				break;
316 			case '2':
317 				(void) strcpy(input, "f");
318 				break;
319 			case '3':
320 				input[0] = '\0';
321 				break;
322 			default:
323 				(void) fprintf(ttyfp, "Invalid selection.\n");
324 				again = TRUE;
325 				break;
326 			}
327 		}
328 	} while (again);
329 
330 	if (!util_newstr(&dbp->userreg.gender, input)) {
331 		(void) fflush(ttyfp);
332 		CDA_FATAL(app_data.str_nomemory);
333 		return FALSE;
334 	}
335 	(void) fflush(ttyfp);
336 	return TRUE;
337 }
338 
339 
340 /*
341  * cda_get_allowemail
342  *	Prompt user whether to allow CDDB email info/promotions
343  *
344  * Args:
345  *	ttyfp - Opened file stream to the user's terminal
346  *
347  * Return:
348  *	TRUE - success
349  */
350 STATIC bool_t
351 cda_get_allowemail(FILE *ttyfp)
352 {
353 	char	input[64];
354 
355 	if (dbp->userreg.email == NULL)
356 		return TRUE;
357 
358 	(void) fprintf(ttyfp,
359 		"\n    Would you like CDDB to send you information and\n"
360 		"    promotions via e-mail? [yn] ");
361 	(void) fflush(ttyfp);
362 
363 	if (fgets(input, 63, stdin) == NULL) {
364 		(void) fprintf(ttyfp, "\n");
365 		(void) fflush(ttyfp);
366 		return TRUE;
367 	}
368 	input[strlen(input)-1] = '\0';
369 	if (input[0] == 'y' || input[0] == 'Y')
370 		dbp->userreg.allowemail = TRUE;
371 	else
372 		dbp->userreg.allowemail = FALSE;
373 
374 	(void) fflush(ttyfp);
375 	return TRUE;
376 }
377 
378 
379 /*
380  * cda_get_allowstats
381  *	Prompt user whether to allow playback stats to customize content
382  *
383  * Args:
384  *	ttyfp - Opened file stream to the user's terminal
385  *
386  * Return:
387  *	TRUE - success
388  */
389 STATIC bool_t
390 cda_get_allowstats(FILE *ttyfp)
391 {
392 	char	input[64];
393 
394 	(void) fprintf(ttyfp,
395 	    "\n    Would you allow CDDB to use your playback statistics\n"
396 	    "    to customize the information delivered "
397 	    "(such as URLs)? [yn] ");
398 	(void) fflush(ttyfp);
399 
400 	if (fgets(input, 63, stdin) == NULL) {
401 		(void) fprintf(ttyfp, "\n");
402 		(void) fflush(ttyfp);
403 		return TRUE;
404 	}
405 	input[strlen(input)-1] = '\0';
406 	if (input[0] == 'y' || input[0] == 'Y')
407 		dbp->userreg.allowstats = TRUE;
408 	else
409 		dbp->userreg.allowstats = FALSE;
410 
411 	(void) fflush(ttyfp);
412 	return TRUE;
413 }
414 
415 
416 /***********************
417  *   public routines   *
418  ***********************/
419 
420 /*
421  * cda_cddbhint
422  *	Have CDDB e-mail the password.
423  *
424  * Args:
425  *	ttyfp - Opened file stream to the user's terminal.
426  *
427  * Return:
428  *	TRUE for success
429  *	FALSE for failure
430  */
431 bool_t
432 cda_cddbhint(FILE *ttyfp)
433 {
434 	curstat_t	*s = curstat_addr();
435 	cdinfo_ret_t	ret;
436 
437 	if (cdinfo_cddb_ver() != 2) {
438 		(void) fprintf(ttyfp, "%s\n%s\n",
439 		    "This copy of cda uses the \"classic\" CDDB service.",
440 		    "No user registration is required."
441 		);
442 		(void) fflush(ttyfp);
443 		return TRUE;
444 	}
445 
446 	(void) fprintf(ttyfp,
447 		"\nIf you had forgotten your CDDB2 user registration\n"
448 		"password, Enter your user handle and have CDDB e-mail\n"
449 		"your password hint to you.\n\n");
450 
451 	if (!cda_get_cddbhandle(ttyfp))
452 		return FALSE;
453 
454 	(void) fprintf(ttyfp, "\nContacting CDDB... ");
455 
456 	if ((ret = cdinfo_getpasshint(s)) != 0) {
457 		DBGPRN(DBG_CDI)(errfp,
458 			"cdinfo_getpasshint: status=%d arg=%d\n",
459 			CDINFO_GET_STAT(ret), CDINFO_GET_ARG(ret));
460 	}
461 
462 	switch (CDINFO_GET_STAT(ret)) {
463 	case 0:	/* Success */
464 		(void) fprintf(ttyfp, " Success.\n"
465 		    "Your password hint is being e-mailed to you.\n");
466 		break;
467 
468 	case NAME_ERR:
469 		(void) fprintf(ttyfp, " Failed.\n"
470 		    "Invalid user handle.  Please try again.\n");
471 		break;
472 
473 	case HINT_ERR:
474 		(void) fprintf(ttyfp, " Failed.\n"
475 		    "You did not specify a hint when you first registered.\n"
476 		    "There is nothing to e-mail to you.\n");
477 		break;
478 
479 	case MAIL_ERR:
480 		(void) fprintf(ttyfp, " Failed.\n"
481 		    "You did not specify a e-mail address when you first\n"
482 		    "registered.  There is nothing to e-mail to you.\n");
483 		break;
484 
485 	default:
486 		(void) fprintf(ttyfp, " Failed.");
487 		break;
488 	}
489 
490 	(void) fflush(ttyfp);
491 	return TRUE;
492 }
493 
494 
495 /*
496  * cda_userreg
497  *	Ask the user to register with CDDB
498  *
499  * Args:
500  *	ttyfp - Opened file stream to the user's terminal.
501  *
502  * Return:
503  *	TRUE for success
504  *	FALSE for failure
505  */
506 bool_t
507 cda_userreg(FILE *ttyfp)
508 {
509 	curstat_t	*s = curstat_addr();
510 	cdinfo_ret_t	ret;
511 
512 	if (cdinfo_cddb_ver() != 2) {
513 		(void) fprintf(ttyfp, "%s\n%s\n",
514 		    "This copy of cda uses the \"classic\" CDDB service.",
515 		    "No user registration is required."
516 		);
517 		(void) fflush(ttyfp);
518 		return TRUE;
519 	}
520 
521 	(void) fprintf(ttyfp, "\n\tGracenote(R) CDDB2 User Registration\n"
522 		"\nYou must register in order to access the CDDB2 service.\n"
523 		"The user handle and password are required, all other\n"
524 		"answers are optional, and will help CDDB provide more\n"
525 		"personalized service.  See the PRIVACY file that comes\n"
526 		"with the xmcd/cda distribution for CDDB's user information\n"
527 		"privacy statement.\n\n");
528 	(void) fprintf(ttyfp,
529 		"You may also use this form to change or update your CDDB2\n"
530 		"user registration information.\n\n");
531 
532 	if (!cda_get_cddbhandle(ttyfp))
533 		return FALSE;
534 
535 	if (!cda_get_cddbpass(ttyfp))
536 		return FALSE;
537 
538 	(void) fprintf(ttyfp,
539 		"\nAll answers below are optional.  If you wish to skip,\n"
540 		"Just press the <Enter> key.\n");
541 
542 	if (!cda_get_hint(ttyfp))
543 		return FALSE;
544 
545 	if (!cda_get_email(ttyfp))
546 		return FALSE;
547 
548 	/*
549 	 * Region and postal code not implemented -- too clumsy with
550 	 * character interface
551 	 */
552 
553 	if (!cda_get_age(ttyfp))
554 		return FALSE;
555 
556 	if (!cda_get_gender(ttyfp))
557 		return FALSE;
558 
559 	if (!cda_get_allowemail(ttyfp))
560 		return FALSE;
561 
562 	if (!cda_get_allowstats(ttyfp))
563 		return FALSE;
564 
565 	(void) fprintf(ttyfp, "\nRegistering with CDDB...");
566 	(void) fflush(ttyfp);
567 	if ((ret = cdinfo_reguser(s)) != 0) {
568 		DBGPRN(DBG_CDI)(errfp, "cdinfo_reguser: status=%d arg=%d\n",
569 			CDINFO_GET_STAT(ret), CDINFO_GET_ARG(ret));
570 	}
571 
572 	switch (CDINFO_GET_STAT(ret)) {
573 	case 0:
574 		/* Success */
575 		(void) fprintf(ttyfp, " Succeeded.\n");
576 		break;
577 
578 	case NAME_ERR:
579 		(void) fprintf(ttyfp, " Failed.\n");
580 		(void) fprintf(ttyfp,
581 		    "Either you got your password wrong, or someone else.\n"
582 		    "is already using this handle.\n"
583 		    "Please try again, or use the \"cda cddbhint\" command\n"
584 		    "to have your password hint sent to you via e-mail.\n");
585 		break;
586 	default:
587 		(void) fprintf(ttyfp, " Failed.\n");
588 		break;
589 	}
590 
591 	(void) fflush(ttyfp);
592 	return TRUE;
593 }
594 
595 
596