1 /*
2  *   libcddb - CDDB Interface Library for xmcd/cda
3  *
4  *	This library implements an interface to access the "classic"
5  *	CDDB1 services.
6  *
7  *   Copyright (C) 1993-2004  Ti Kan
8  *   E-mail: xmcd@amb.org
9  *
10  *   This program is free software; you can redistribute it and/or modify
11  *   it under the terms of the GNU General Public License as published by
12  *   the Free Software Foundation; either version 2 of the License, or
13  *   (at your option) any later version.
14  *
15  *   This program is distributed in the hope that it will be useful,
16  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *   GNU General Public License for more details.
19  *
20  *   You should have received a copy of the GNU General Public License
21  *   along with this program; if not, write to the Free Software
22  *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  *
24  */
25 #ifndef lint
26 static char	*_control_c_ident_ = "@(#)control.c	1.39 04/03/11";
27 #endif
28 
29 #include "fcddb.h"
30 #include "common_d/version.h"
31 
32 
33 extern bool_t		fcddb_debug;
34 extern FILE		*fcddb_errfp;
35 
36 
37 /* Scratch array for the starting frame offset of each track */
38 STATIC unsigned int	trkframes[MAXTRACK];
39 
40 
41 /*
42  * CddbControl_Initialize
43  *	Initialize CDDB control
44  */
45 /*ARGSUSED*/
46 CddbResult
CddbControl_Initialize(CddbControlPtr ctrlp,long unused,CDDBCacheFlags flags)47 CddbControl_Initialize(CddbControlPtr ctrlp, long unused, CDDBCacheFlags flags)
48 {
49 	int		i;
50 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
51 	char		cacheroot[FILE_PATH_SZ];
52 
53 	if (cp->magic != CDDB1_MAGIC)
54 		return Cddb_E_INVALIDARG;
55 	if (cp->clientid == NULL)
56 		return CDDBTRNNoUserInfo;
57 
58 	/* Initialize structures */
59 	(void) strcpy(cp->options.objtype, "CddbOptions");
60 	(void) strcpy(cp->userinfo.objtype, "CddbUserInfo");
61 	(void) strcpy(cp->regionlist.objtype, "CddbRegionList");
62 	(void) strcpy(cp->languagelist.objtype, "CddbLanguageList");
63 	(void) strcpy(cp->genretree.objtype, "CddbGenreTree");
64 	(void) strcpy(cp->roletree.objtype, "CddbRoleTree");
65 	(void) strcpy(cp->urllist.objtype, "CddbURLList");
66 	(void) strcpy(cp->discs.objtype, "CddbDiscs");
67 	(void) strcpy(cp->disc.objtype, "CddbDisc");
68 	(void) strcpy(cp->disc.fullname.objtype, "CddbFullName");
69 	(void) strcpy(cp->disc.tracks.objtype, "CddbTracks");
70 
71 	/* Set up back pointers */
72 	cp->disc.control = (void *) cp;
73 	for (i = 0; i < MAXTRACK; i++)
74 		cp->disc.tracks.track[i].control = (void *) cp;
75 
76 	/* Set up some defaults */
77 	cp->options.proxyport = 80;
78 	cp->options.servertimeout = 60000;
79 #ifdef __VMS
80 	(void) sprintf(cacheroot, "%s.cddb2.%s",
81 		       fcddb_homedir(), cp->clientid);
82 #else
83 	(void) sprintf(cacheroot, "%s/.cddb2/%s",
84 		       fcddb_homedir(), cp->clientid);
85 #endif
86 	cp->options.localcachepath = (CddbStr) fcddb_strdup(cacheroot);
87 	cp->options.localcachetimeout = 7;
88 	cp->options.localcacheflags = (long) flags;
89 
90 	/* Get user name and host name */
91 	cp->userinfo.userhandle = (CddbStr) fcddb_strdup(fcddb_username());
92 	cp->hostname = (CddbStr) fcddb_strdup(fcddb_hostname());
93 
94 	/* General library initializations */
95 	return (fcddb_init(cp));
96 }
97 
98 
99 /*
100  * CddbControl_Shutdown
101  *	Shutdown CDDB control
102  */
103 CddbResult
CddbControl_Shutdown(CddbControlPtr ctrlp)104 CddbControl_Shutdown(CddbControlPtr ctrlp)
105 {
106 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
107 
108 	/* General library shutdown */
109 	return (fcddb_halt(cp));
110 }
111 
112 
113 /*
114  * CddbControl_FlushLocalCache
115  *	Flush local cache
116  */
117 CddbResult
CddbControl_FlushLocalCache(CddbControlPtr ctrlp,CDDBFlushFlags flags)118 CddbControl_FlushLocalCache(CddbControlPtr ctrlp, CDDBFlushFlags flags)
119 {
120 	return fcddb_flush_cddb((cddb_control_t *) ctrlp, flags);
121 }
122 
123 
124 /*
125  * CddbControl_GetDiscInfo
126  *	Return disc object given the mediaid and muiid
127  */
128 /*ARGSUSED*/
129 CddbResult
CddbControl_GetDiscInfo(CddbControlPtr ctrlp,CddbConstStr mediaid,CddbConstStr muiid,CddbConstStr revid,CddbConstStr revtag,CddbBoolean unused,CddbDiscPtr * disc,CddbDiscsPtr * discs)130 CddbControl_GetDiscInfo(
131 	CddbControlPtr	ctrlp,
132 	CddbConstStr	mediaid,
133 	CddbConstStr	muiid,
134 	CddbConstStr	revid,
135 	CddbConstStr	revtag,
136 	CddbBoolean	unused,
137 	CddbDiscPtr	*disc,
138 	CddbDiscsPtr	*discs
139 )
140 {
141 	*disc = NULL;
142 	*discs = NULL;
143 	return Cddb_E_NOTIMPL;
144 }
145 
146 
147 /*
148  * CddbControl_GetFullDiscInfo
149  *	Return fully populated disc object after a fuzzy match selection
150  */
151 /*ARGSUSED*/
152 CddbResult
CddbControl_GetFullDiscInfo(CddbControlPtr ctrlp,CddbDiscPtr discp,CddbBoolean unused,CddbDiscPtr * pval)153 CddbControl_GetFullDiscInfo(
154 	CddbControlPtr	ctrlp,
155 	CddbDiscPtr	discp,
156 	CddbBoolean	unused,
157         CddbDiscPtr	*pval
158 )
159 {
160 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
161 	cddb_disc_t	*dp1 = (cddb_disc_t *) discp,
162 			*dp2 = &cp->disc;
163 	char		*conhost;
164 	unsigned int	oa;
165 	unsigned short	conport;
166 	CddbResult	ret;
167 	bool_t		isproxy;
168 	void		(*oh)(int);
169 
170 	if (dp1 == NULL || pval == NULL || dp1->discid == NULL ||
171 	    dp1->category == NULL || dp1->genre == NULL || dp1->toc == NULL) {
172 		*pval = NULL;
173 		return Cddb_E_INVALIDARG;
174 	}
175 
176 	if (cp->options.proxyserver == NULL) {
177 		conhost = CDDB_SERVER_HOST;
178 		conport = HTTP_PORT;
179 		isproxy = FALSE;
180 	}
181 	else {
182 		conhost = cp->options.proxyserver;
183 		conport = (unsigned short) cp->options.proxyport;
184 		isproxy = TRUE;
185 	}
186 
187 	/* Set timeout alarm */
188 	oh = fcddb_signal(SIGALRM, fcddb_onsig);
189 	oa = alarm(cp->options.servertimeout / 1000);
190 
191 	ret = fcddb_read_cddb(cp, dp1->discid, dp1->toc, dp1->category,
192 			       conhost, conport, isproxy);
193 
194 	(void) alarm(oa);
195 	(void) fcddb_signal(SIGALRM, oh);
196 
197 	if (ret == Cddb_OK)
198 		*pval = (CddbDiscPtr) dp2;
199 	else
200 		*pval = NULL;
201 
202 	return (ret);
203 }
204 
205 
206 /*
207  * CddbControl_GetGenreTree
208  *	Return genre tree
209  */
210 /*ARGSUSED*/
211 CddbResult
CddbControl_GetGenreTree(CddbControlPtr ctrlp,CddbBoolean unused,CddbGenreTreePtr * pval)212 CddbControl_GetGenreTree(
213 	CddbControlPtr	ctrlp,
214 	CddbBoolean	unused,
215 	CddbGenreTreePtr *pval
216 )
217 {
218 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
219 
220 	*pval = (CddbGenreTreePtr) &cp->genretree;
221 	return Cddb_OK;
222 }
223 
224 
225 /*
226  * CddbControl_GetMatchedDisc
227  *	Return disc object after exact match
228  */
229 CddbResult
CddbControl_GetMatchedDisc(CddbControlPtr ctrlp,CddbDiscPtr * disc)230 CddbControl_GetMatchedDisc(CddbControlPtr ctrlp, CddbDiscPtr *disc)
231 {
232 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
233 
234 	*disc = (CddbDiscPtr) &cp->disc;
235 	return Cddb_OK;
236 }
237 
238 
239 /*
240  * CddbControl_GetMatchedDiscs
241  *	Return discs object after fuzzy match
242  */
243 CddbResult
CddbControl_GetMatchedDiscs(CddbControlPtr ctrlp,CddbDiscsPtr * discs)244 CddbControl_GetMatchedDiscs(CddbControlPtr ctrlp, CddbDiscsPtr *discs)
245 {
246 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
247 
248 	*discs = (CddbDiscsPtr) &cp->discs;
249 	return Cddb_OK;
250 }
251 
252 
253 /*
254  * CddbControl_GetOptions
255  *	Return options object
256  */
257 CddbResult
CddbControl_GetOptions(CddbControlPtr ctrlp,CddbOptionsPtr * pval)258 CddbControl_GetOptions(CddbControlPtr ctrlp, CddbOptionsPtr *pval)
259 {
260 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
261 	cddb_options_t	*op;
262 
263 	op = (cddb_options_t *) fcddb_obj_alloc(
264 		"CddbOptions", sizeof(cddb_options_t)
265 	);
266 	if (op == NULL)
267 		return CDDBTRNOutOfMemory;
268 
269 	if (cp->options.proxyserver != NULL) {
270 		op->proxyserver =
271 		    (CddbStr) fcddb_strdup((char *) cp->options.proxyserver);
272 	}
273 	if (cp->options.proxyusername != NULL) {
274 		op->proxyusername =
275 		    (CddbStr) fcddb_strdup((char *) cp->options.proxyusername);
276 	}
277 	if (cp->options.proxypassword != NULL) {
278 		op->proxypassword =
279 		    (CddbStr) fcddb_strdup((char *) cp->options.proxypassword);
280 	}
281 	op->proxyport = cp->options.proxyport;
282 	op->servertimeout = cp->options.servertimeout;
283 	op->testsubmitmode = cp->options.testsubmitmode;
284 
285 	*pval = (CddbOptionsPtr) op;
286 	return Cddb_OK;
287 }
288 
289 
290 /*
291  * CddbControl_GetRegionList
292  *	Return region list object
293  */
294 /*ARGSUSED*/
295 CddbResult
CddbControl_GetRegionList(CddbControlPtr ctrlp,CddbBoolean unused,CddbRegionListPtr * pval)296 CddbControl_GetRegionList(
297 	CddbControlPtr	ctrlp,
298 	CddbBoolean	unused,
299 	CddbRegionListPtr *pval
300 )
301 {
302 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
303 
304 	*pval = (CddbRegionListPtr) &cp->regionlist;
305 	return Cddb_OK;
306 }
307 
308 
309 /*
310  * CddbControl_GetLanguageList
311  *	Return language list object
312  */
313 /*ARGSUSED*/
314 CddbResult
CddbControl_GetLanguageList(CddbControlPtr ctrlp,CddbBoolean unused,CddbLanguageListPtr * pval)315 CddbControl_GetLanguageList(
316 	CddbControlPtr	ctrlp,
317 	CddbBoolean	unused,
318 	CddbLanguageListPtr *pval
319 )
320 {
321 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
322 
323 	*pval = (CddbLanguageListPtr) &cp->languagelist;
324 	return Cddb_OK;
325 }
326 
327 
328 /*
329  * CddbControl_GetRoleTree
330  *	Return role tree object
331  */
332 /*ARGSUSED*/
333 CddbResult
CddbControl_GetRoleTree(CddbControlPtr ctrlp,CddbBoolean unused,CddbRoleTreePtr * pval)334 CddbControl_GetRoleTree(
335 	CddbControlPtr	ctrlp,
336 	CddbBoolean 	unused,
337 	CddbRoleTreePtr	*pval
338 )
339 {
340 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
341 
342 	*pval = (CddbRoleTreePtr) &cp->roletree;
343 	return Cddb_OK;
344 }
345 
346 
347 /*
348  * CddbControl_GetServiceStatus
349  *	Return CDDB service status string
350  */
351 /*ARGSUSED*/
352 CddbResult
CddbControl_GetServiceStatus(CddbControlPtr ctrlp,CddbStr * pval)353 CddbControl_GetServiceStatus(CddbControlPtr ctrlp, CddbStr *pval)
354 {
355 	*pval = "GetServiceStatus not implemented.";
356 	return Cddb_OK;
357 }
358 
359 
360 /*
361  * CddbControl_GetSubmitDisc
362  *	Return a skeleton disc object to be filled for submission
363  */
364 /*ARGSUSED*/
365 CddbResult
CddbControl_GetSubmitDisc(CddbControlPtr ctrlp,CddbConstStr toc,CddbConstStr mediaid,CddbConstStr muiid,CddbDiscPtr * pval)366 CddbControl_GetSubmitDisc(
367 	CddbControlPtr	ctrlp,
368 	CddbConstStr	toc,
369 	CddbConstStr	mediaid,
370 	CddbConstStr	muiid,
371 	CddbDiscPtr	*pval
372 )
373 {
374 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
375 	cddb_disc_t	*dp;
376 
377 	if (toc == NULL) {
378 		*pval = NULL;
379 		return Cddb_E_INVALIDARG;
380 	}
381 
382 	dp = (cddb_disc_t *) fcddb_obj_alloc(
383 		"CddbDisc",
384 		sizeof(cddb_disc_t)
385 	);
386 	if (dp == NULL) {
387 		*pval = NULL;
388 		return CDDBTRNOutOfMemory;
389 	}
390 
391 	dp->tracks.count = fcddb_parse_toc((char *) toc, trkframes);
392 	if (dp->tracks.count == 0) {
393 		*pval = NULL;
394 		return Cddb_E_INVALIDARG;
395 	}
396 
397 	dp->discid = fcddb_discid(dp->tracks.count, trkframes);
398 
399 	if (mediaid != NULL && strcmp(dp->discid, mediaid) != 0) {
400 		/* Sanity check */
401 		*pval = NULL;
402 		return Cddb_E_INVALIDARG;
403 	}
404 
405 	if (muiid != NULL)
406 		dp->category = fcddb_strdup((char *) muiid);
407 	else
408 		dp->category = NULL;
409 
410 	dp->toc = (CddbStr) fcddb_strdup((char *) toc);
411 	dp->control = cp;
412 
413 	*pval = (CddbDiscPtr) dp;
414 	return Cddb_OK;
415 }
416 
417 
418 /*
419  * CddbControl_GetURLList
420  *	Return URL list object
421  */
422 /*ARGSUSED*/
423 CddbResult
CddbControl_GetURLList(CddbControlPtr ctrlp,CddbDiscPtr discp,CddbBoolean unused,CddbURLListPtr * pval)424 CddbControl_GetURLList(
425 	CddbControlPtr	ctrlp,
426 	CddbDiscPtr	discp,
427 	CddbBoolean	unused,
428 	CddbURLListPtr	*pval
429 )
430 {
431 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
432 	cddb_disc_t	*dp = (cddb_disc_t *) discp;
433 
434 	if (discp == NULL)
435 		*pval = (CddbURLListPtr) &cp->urllist;
436 	else
437 		*pval = (CddbURLListPtr) &dp->urllist;
438 
439 	return Cddb_OK;
440 }
441 
442 
443 /*
444  * CddbControl_GetURLManager
445  *	Return URL manager object
446  */
447 /*ARGSUSED*/
448 CddbResult
CddbControl_GetURLManager(CddbControlPtr ctrlp,CddbURLManagerPtr * pval)449 CddbControl_GetURLManager(CddbControlPtr ctrlp, CddbURLManagerPtr *pval)
450 {
451 	cddb_control_t		*cp = (cddb_control_t *) ctrlp;
452 	cddb_urlmanager_t	*mp;
453 
454 	mp = (cddb_urlmanager_t *) fcddb_obj_alloc(
455 		"CddbURLManager",
456 		sizeof(cddb_urlmanager_t)
457 	);
458 	if (mp == NULL) {
459 		*pval = NULL;
460 		return CDDBTRNOutOfMemory;
461 	}
462 
463 	mp->control = cp;
464 
465 	*pval = (CddbURLManagerPtr) mp;
466 	return Cddb_OK;
467 }
468 
469 
470 /*
471  * CddbControl_GetUserInfo
472  *	Return user info object
473  */
474 CddbResult
CddbControl_GetUserInfo(CddbControlPtr ctrlp,CddbUserInfoPtr * pval)475 CddbControl_GetUserInfo(CddbControlPtr ctrlp, CddbUserInfoPtr *pval)
476 {
477 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
478 
479 	*pval = (CddbUserInfoPtr) &cp->userinfo;
480 	return Cddb_OK;
481 }
482 
483 
484 /*
485  * CddbControl_GetVersion
486  *	Return CDDB control version string
487  */
488 /*ARGSUSED*/
489 CddbResult
CddbControl_GetVersion(CddbControlPtr ctrlp,CddbStr * pval)490 CddbControl_GetVersion(CddbControlPtr ctrlp, CddbStr *pval)
491 {
492 	static char	buf[STR_BUF_SZ];
493 
494 	(void) sprintf(buf, "CDDBControl xmcd %s.%s.%s",
495 		       VERSION_MAJ, VERSION_MIN, VERSION_TEENY);
496 	*pval = buf;
497 	return Cddb_OK;
498 }
499 
500 
501 /*
502  * CddbControl_InvokeInfoBrowser
503  *	Spawn CDDB Music Browser
504  */
505 /*ARGSUSED*/
506 CddbResult
CddbControl_InvokeInfoBrowser(CddbControlPtr ctrlp,CddbDiscPtr discp,CddbURLPtr urlp,CDDBUIFlags flags)507 CddbControl_InvokeInfoBrowser(
508 	CddbControlPtr	ctrlp,
509 	CddbDiscPtr	discp,
510 	CddbURLPtr	urlp,
511 	CDDBUIFlags	flags
512 )
513 {
514 	/* Not supported in CDDB1 */
515 	return Cddb_OK;
516 }
517 
518 
519 /*
520  * CddbControl_IsRegistered
521  *	Check user registration status
522  */
523 /*ARGSUSED*/
524 CddbResult
CddbControl_IsRegistered(CddbControlPtr ctrlp,CddbBoolean unused,CddbBoolean * ret)525 CddbControl_IsRegistered(
526 	CddbControlPtr	ctrlp,
527 	CddbBoolean	unused,
528 	CddbBoolean	*ret
529 )
530 {
531 	*ret = 1;		/* Hard code to TRUE */
532 	return Cddb_OK;
533 }
534 
535 
536 /*
537  * CddbControl_LookupMediaByToc
538  *	Do CDDB query based on a CD's TOC
539  */
540 /*ARGSUSED*/
541 CddbResult
CddbControl_LookupMediaByToc(CddbControlPtr ctrlp,CddbConstStr toc,CddbBoolean unused,CDDBMatchCode * matchcode)542 CddbControl_LookupMediaByToc(
543 	CddbControlPtr	ctrlp,
544 	CddbConstStr	toc,
545 	CddbBoolean	unused,
546 	CDDBMatchCode	*matchcode
547 )
548 {
549 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
550 	char		*conhost,
551 			*discid;
552 	int		ntrks;
553 	unsigned int	oa;
554 	CddbResult	ret;
555 	unsigned short	conport;
556 	bool_t		isproxy;
557 	void		(*oh)(int);
558 
559 	if ((ntrks = fcddb_parse_toc((char *) toc, trkframes)) == 0) {
560 		*matchcode = 0;
561 		return Cddb_E_INVALIDARG;
562 	}
563 
564 	discid = fcddb_discid(ntrks, trkframes);
565 
566 	if (cp->options.proxyserver == NULL) {
567 		conhost = CDDB_SERVER_HOST;
568 		conport = HTTP_PORT;
569 		isproxy = FALSE;
570 	}
571 	else {
572 		conhost = cp->options.proxyserver;
573 		conport = (unsigned short) cp->options.proxyport;
574 		isproxy = TRUE;
575 	}
576 
577 	/* Set timeout alarm */
578 	oh = fcddb_signal(SIGALRM, fcddb_onsig);
579 	oa = alarm(cp->options.servertimeout / 1000);
580 
581 	ret = fcddb_lookup_cddb(cp, discid, trkframes, (char *) toc,
582 				 conhost, conport, isproxy,
583 				 (int *) matchcode);
584 
585 	(void) alarm(oa);
586 	(void) fcddb_signal(SIGALRM, oh);
587 
588 	MEM_FREE(discid);
589 	return (ret);
590 }
591 
592 
593 /*
594  * CddbControl_ServerNoop
595  *	Contact the CDDB service and perform a non-operation
596  */
597 /*ARGSUSED*/
598 CddbResult
CddbControl_ServerNoop(CddbControlPtr ctrlp,CddbBoolean unused)599 CddbControl_ServerNoop(CddbControlPtr ctrlp, CddbBoolean unused)
600 {
601 	/* Not supported in CDDB1 */
602 	return Cddb_OK;
603 }
604 
605 
606 /*
607  * CddbControl_SetClientInfo
608  *	Set CDDB client information
609  */
610 CddbResult
CddbControl_SetClientInfo(CddbControlPtr ctrlp,CddbConstStr clid,CddbConstStr cltag,CddbConstStr clver,CddbConstStr clregstr)611 CddbControl_SetClientInfo(
612 	CddbControlPtr	ctrlp,
613 	CddbConstStr	clid,
614 	CddbConstStr	cltag,
615 	CddbConstStr	clver,
616 	CddbConstStr	clregstr
617 )
618 {
619 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
620 
621 	if (ctrlp == NULL || clid == NULL || cltag == NULL || clver == NULL ||
622 	    clregstr == NULL)
623 		return Cddb_E_INVALIDARG;
624 
625 	cp->clientname = (CddbStr) fcddb_strdup((char *) clregstr);
626 	cp->clientid = (CddbStr) fcddb_strdup((char *) clid);
627 	cp->clientver = (CddbStr) fcddb_strdup((char *) clver);
628 
629 	if (strcmp((char *) cltag, "debug") == 0)
630 		fcddb_debug = TRUE;
631 
632 	return Cddb_OK;
633 }
634 
635 
636 /*
637  * CddbControl_SetOptions
638  *	Set options information
639  */
640 CddbResult
CddbControl_SetOptions(CddbControlPtr ctrlp,CddbOptionsPtr optionsp)641 CddbControl_SetOptions(CddbControlPtr ctrlp, CddbOptionsPtr optionsp)
642 {
643 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
644 	cddb_options_t	*op = (cddb_options_t *) optionsp;
645 	CddbResult	ret;
646 
647 	ret = Cddb_OK;
648 
649 	if (cp->options.proxyserver != NULL)
650 		MEM_FREE(cp->options.proxyserver);
651 	if (cp->options.proxyusername != NULL)
652 		MEM_FREE(cp->options.proxyusername);
653 	if (cp->options.proxypassword != NULL)
654 		MEM_FREE(cp->options.proxypassword);
655 
656 	if (op->proxyserver == NULL || op->proxyserver[0] == '\0')
657 		cp->options.proxyserver = NULL;
658 	else
659 		cp->options.proxyserver =
660 		    (CddbStr) fcddb_strdup((char *) op->proxyserver);
661 
662 	if (op->proxyusername == NULL || op->proxyusername[0] == '\0')
663 		cp->options.proxyusername = NULL;
664 	else
665 		cp->options.proxyusername =
666 		    (CddbStr) fcddb_strdup((char *) op->proxyusername);
667 
668 	if (op->proxypassword == NULL || op->proxypassword[0] == '\0')
669 		cp->options.proxypassword = NULL;
670 	else
671 		cp->options.proxypassword =
672 		    (CddbStr) fcddb_strdup((char *) op->proxypassword);
673 
674 	cp->options.proxyport = op->proxyport;
675 	cp->options.servertimeout = op->servertimeout;
676 	cp->options.testsubmitmode = op->testsubmitmode;
677 
678 	if (cp->options.proxyusername != NULL &&
679 	    cp->options.proxypassword != NULL) {
680 		ret = fcddb_set_auth(cp->options.proxyusername,
681 				      cp->options.proxypassword);
682 	}
683 
684 	return (ret);
685 }
686 
687 
688 /*
689  * CddbControl_SetUserInfo
690  *	Set user information
691  */
692 /*ARGSUSED*/
693 CddbResult
CddbControl_SetUserInfo(CddbControlPtr ctrlp,CddbUserInfoPtr uinfop)694 CddbControl_SetUserInfo(CddbControlPtr ctrlp, CddbUserInfoPtr uinfop)
695 {
696 	/* Do nothing */
697 	return Cddb_OK;
698 }
699 
700 
701 /*
702  * CddbControl_SubmitDisc
703  *	Submit disc information to CDDB
704  */
705 /*ARGSUSED*/
706 CddbResult
CddbControl_SubmitDisc(CddbControlPtr ctrlp,CddbDiscPtr discp,CddbBoolean unused,long * pval)707 CddbControl_SubmitDisc(
708 	CddbControlPtr	ctrlp,
709 	CddbDiscPtr	discp,
710 	CddbBoolean	unused,
711 	long		*pval
712 )
713 {
714 	cddb_control_t	*cp = (cddb_control_t *) ctrlp;
715 	cddb_disc_t	*dp = (cddb_disc_t *) discp;
716 	char		*conhost;
717 	int		i,
718 			ntrks;
719 	unsigned int	discid_val = 0,
720 			oa;
721 	CddbResult	ret;
722 	unsigned short	conport;
723 	bool_t		isproxy;
724 	void		(*oh)(int);
725 
726 	if (ctrlp == NULL || discp == NULL || pval == NULL)
727 		return Cddb_E_INVALIDARG;
728 
729 	*pval = 0;
730 
731 	/* Do some sanity checking */
732 	if (dp->title == NULL || dp->genre == NULL)
733 		return CDDBCTLMissingField;
734 
735 	if (dp->discid == NULL)
736 		return Cddb_E_INVALIDARG;
737 
738 	(void) sscanf(dp->discid, "%x", (unsigned int *) &discid_val);
739 
740 	ntrks = (discid_val & 0xff);
741 	if (ntrks == 0)
742 		return Cddb_E_INVALIDARG;
743 
744 	for (i = 0; i < ntrks; i++) {
745 		if (dp->tracks.track[i].title == NULL)
746 			return CDDBCTLMissingField;
747 	}
748 
749 	if (cp->options.proxyserver == NULL) {
750 		conhost = CDDB_SUBMIT_HOST;
751 		conport = HTTP_PORT;
752 		isproxy = FALSE;
753 	}
754 	else {
755 		conhost = cp->options.proxyserver;
756 		conport = (unsigned short) cp->options.proxyport;
757 		isproxy = TRUE;
758 	}
759 
760 	/* Set timeout alarm */
761 	oh = fcddb_signal(SIGALRM, fcddb_onsig);
762 	oa = alarm(cp->options.servertimeout / 1000);
763 
764 	ret = fcddb_submit_cddb(cp, dp, conhost, conport, isproxy);
765 
766 	(void) alarm(oa);
767 	(void) fcddb_signal(SIGALRM, oh);
768 
769 	return (ret);
770 }
771 
772 
773