⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cddbtool.c

📁 -一个LINUX下的使用方&#63845 的CD-ROM刻录软件,开放源码
💻 C
字号:
/*	cddb.c	31.5.99 tn	stuff to access the cddb-database via the cddbp-protocol	standalone version*/#include <stdio.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#if defined(linux) || defined(__CYGWIN32__)#include <getopt.h>#endif#include <sys/time.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <gtk/gtk.h>#include <gdk/gdk.h>#include "xcdroast.h"#include "main.h"#ifndef INADDR_NONE#define INADDR_NONE 0xFFFFFFFF#endifgchar hostname[MAXLINE];gchar username[MAXLINE];cddb_match_t **cddbmatch;gint matchnr;gint oldtnr;/* extract the 3 digit code from a cddb-answer */gint get_cddb_code(gchar *line) {gchar tmp[MAXLINE];	if (line == NULL || strlen(line) < 3) {		return 0;	}	strncpy(tmp,line,3);	tmp[3] = '\0';		return(atoi(tmp));}/* connect to the cddb-server and return socket-fd:    return -1 on "hostname lookup failure"           -2 on "cant open stream socket"	  -3 on "connection refused"	  -4 on "no response from server"	  -5 on "timeout while connect"*/gint connect_cddb_server(gchar *server, gint port) {struct sockaddr_in serv_addr;struct hostent *myhost;gchar tmp[MAXLINE];gint sockfd,n;	/* resolv ipnumber from hostname if neccessary */	if ((serv_addr.sin_addr.s_addr = inet_addr(server)) == INADDR_NONE) {		/* no valid ip-nummer, look up name */		if ((myhost = gethostbyname(server)) == NULL) {			return -1;		}		memcpy(&serv_addr.sin_addr, myhost->h_addr, myhost->h_length);	}	/* fill structure serv_addr */	serv_addr.sin_family      = AF_INET;	serv_addr.sin_port        = htons(port);	/* open tcp socket (internet stream socket) */	if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {		return -2;	}	/* connect */	if (connect(sockfd, (struct sockaddr *) &serv_addr,		sizeof(serv_addr)) < 0) {		close(sockfd);		return -3;	}	/* read connect response */	n = read_line2(sockfd, tmp, MAXLINE, 1);	if (n == -2) {		/* timeout */		close(sockfd);		return -5;	}	if (n < 0) {		g_print("-11: Error: read error on socket when connecting\n");		fflush(stdout);		close(sockfd);		return -4;	}	return sockfd;}/* perform cddbp-handshaking *//* return 0 on success, 1 on error */gint cddb_handshake(gint sockfd) {gchar tmp[MAXLINE];gint n, code;	g_snprintf(tmp,MAXLINE,"cddb hello %s %s xcdroast %s",		username,hostname,XCDROAST_VERSION);	/* now send string */	if (writen(sockfd,tmp,strlen(tmp), 1) != strlen(tmp)) {		g_print("-10: Error: write error on socket when cddb handshaking\n");		fflush(stdout);		return 1;	}	/* read response */	n = read_line2(sockfd, tmp, MAXLINE, 1);	if (n < 0) {		g_print("-11: Error: read error on socket when cddb handshaking\n");		fflush(stdout);		return 1;	}	code = get_cddb_code(tmp);	switch(code) {		/* all ok */		case 200:			return 0;		/* handshake failed */		case 431:			return 1;		/* alread shook hands */		case 402:			return 0;			default:			return 1;	}}/* extract a match of the cddb-query command */void extract_cddb_match(gchar *match, gint exact) {gchar *p1;	/* allocate memory and free old */	if (cddbmatch[matchnr] != NULL) {		g_free(cddbmatch[matchnr]->categ);		g_free(cddbmatch[matchnr]->discid);		g_free(cddbmatch[matchnr]->dtitle);		g_free(cddbmatch[matchnr]);	}	cddbmatch[matchnr] = g_new0(cddb_match_t,1);	cddbmatch[matchnr]->exact = exact;	p1 = strtok(match," ");	cddbmatch[matchnr]->categ = g_strdup(p1);	p1 = strtok(NULL," ");	cddbmatch[matchnr]->discid = g_strdup(p1);	p1 = strtok(NULL,"");	cddbmatch[matchnr]->dtitle = g_strdup(p1);		matchnr++;}/* perform cddbp-query *//* return 0 on success, 1 on error */gint cddb_query(gint sockfd, gchar *querystring) {gchar tmp[MAXLINE];gint n, code;	matchnr = 0;	oldtnr = -1;	/* construct query */	strcpy(tmp,querystring);	/* now send string */	if (writen(sockfd,tmp,strlen(tmp), 1) != strlen(tmp)) {		g_print("-10: Error: write error on socket when cddb query\n");		fflush(stdout);		return 1;	}	/* read response */	n = read_line2(sockfd, tmp, MAXLINE, 1);	if (n < 0) {		g_print("-11: Error: read error on socket when cddb query\n");		fflush(stdout);		return 1;	}	code = get_cddb_code(tmp);	switch(code) {		/* exact match */		case 200:			extract_cddb_match(tmp+4,1);			return 0;		/* no match found */		case 202:			return 0; 		/* Database entry is corrupt */		case 403:			return 0;		/* No handshake */		case 409:			return 1;		/* list of matches found */		case 210:		case 211: {			while (matchnr < MAXCDDB) {				n = read_line2(sockfd, tmp, MAXLINE, 1);				if (n < 0) {					g_print("-11: Error: read error on socket when cddb query\n");					fflush(stdout);					return 1;				}				if (tmp[0] == '.') {					/* done with list */					return 0;				}				if (code == 210) {					extract_cddb_match(tmp,1);				} else {					extract_cddb_match(tmp,0);				}						}			}		default: 			return 1;	}}/* parse the received cddb-entry into info-structures *//* return 0 on success, 1 on error */gint parse_cddb_entry(gint sockfd) {gchar tmp[MAXLINE];gchar tmp2[MAXLINE];gchar *p1;gint n, tnr;	while (1) {		n = read_line2(sockfd, tmp, MAXLINE, 1);		if (n < 0) {			g_print("-11: Error: read error on socket when cddb read\n");			fflush(stdout);			return 1;		}				/* end marker found */		if (tmp[0] == '.') {			/* no more tracks, close old track */			g_print("\"\n");			fflush(stdout);			return 0;		}		if (strncmp(tmp,"DTITLE",6) == 0) {			p1 = strtok(tmp,"=");			p1 = strtok(NULL,"");			strcpy(tmp2,p1);			strip_string(tmp2);			g_print("07: \"%s\"\n", convert_escape(tmp2));			fflush(stdout);			continue;		}		if (strncmp(tmp,"TTITLE",6) == 0) {			strcpy(tmp2,tmp+6);			p1 = strtok(tmp2,"=");			tnr = atoi(p1);			/* got a new track? close line of previous one */			if (oldtnr != -1 && oldtnr != tnr) {				g_print("\"\n");				fflush(stdout);			}			p1 = strtok(NULL,"");			strcpy(tmp,p1);			strip_string(tmp);			if (oldtnr != -1 && oldtnr == tnr) {				/* continue old line */				g_print("%s", convert_escape(tmp));			} else {				/* new track line (to be continue) */				g_print("08: \"%s", convert_escape(tmp));			}				oldtnr = tnr;			continue;		}	}}/* perform cddbp-read *//* return 0 on success, 1 on error */gint cddb_read(gint sockfd, gint nr) {gchar tmp[MAXLINE];gint n, code;	if (cddbmatch[nr] == 0) {		/* no such match */		return 1;	}	/* construct query */	g_snprintf(tmp,MAXLINE,"cddb read %s %s",cddbmatch[nr]->categ,		cddbmatch[nr]->discid);	/* now send string */	if (writen(sockfd,tmp,strlen(tmp), 1) != strlen(tmp)) {		g_print("-10: Error: write error on socket when cddb read\n");		fflush(stdout);		return 1;	}	/* read response */	n = read_line2(sockfd, tmp, MAXLINE, 1);	if (n < 0) {		g_print("-11: Error: read error on socket when cddb read\n");		fflush(stdout);		return 1;	}	code = get_cddb_code(tmp);	switch(code) {		/* database entry follow */		case 210:			parse_cddb_entry(sockfd);			return 0;		/* no entry found */		case 401:			return 1;		/* server error */		case 402:			return 1;		/* Database entry is corrupt */		case 403:			return 1;		/* No handshake */		case 409:			return 1;		/* Access limit exceeded, explanation follows */		case 417: {			while (1) {				n = read_line2(sockfd, tmp, MAXLINE, 1);				if (n < 0) {					g_print("-11: Error: read error on socket when cddb query\n");					fflush(stdout);					return 1;				}				if (tmp[0] == '.') {					/* done with list */					return 1;				}				/* output error-message line of server */				g_print("-12: Server: %s\n",tmp);					fflush(stdout);			}		}		default: 			return 1;	}}/* perform cddbp-quit *//* return 0 on success, 1 on error */gint cddb_quit(gint sockfd) {gchar tmp[MAXLINE];	/* construct query */	strcpy(tmp,"quit");	/* now send string */	if (writen(sockfd,tmp,strlen(tmp), 1) != strlen(tmp)) {		g_print("-10: Error: write error on socket when cddb quit\n");		fflush(stdout);		return 1;	}	return 0;}/* close the socket when user canceled-out */void close_cddb(sock) {	if (sock > 0) {		close(sock);	}}/* do the cddb-work and output info to keep user informed *//* return 1 on trouble, 0 if all ok */gint start_cddb_query(gint *sockpnt, gchar *host, gint port, gchar *querystring) {gint i;gint sock;gchar tmptmp[MAXLINE];	/* connect */	g_print("00: Connecting to %s:%d\n",host,port);	fflush(stdout);	sock = connect_cddb_server(host,port);	*sockpnt = sock;	if (sock < 0) {		switch (sock) {		case -1: 			/* lookup error */			g_print("-1: Error: Hostname lookup failure\n");			break;		case -2:			/* socket error */			g_print("-2: Error: Can't open stream socket\n");			break;		case -3:			/* connection refused */			g_print("-3: Error: Connection refused\n");			break;		case -4: 			/* no response from server */			g_print("-4: Error: No response from server\n");			break;		case -5:			/* timeout */			g_print("-5: Error: No answer within timeout\n");			break;		}		fflush(stdout);		return 1;	}		/* connect was ok, now send handshake */	g_print("01: Connect ok: Sending handshake\n");	fflush(stdout);	if (cddb_handshake(sock) != 0) {		g_print("-6: Handshake failed - No valid CDDB-server?\n");		fflush(stdout);		return 1;	}	/* start query */	g_print("02: Sending CDDB-query\n");	fflush(stdout);	if (cddb_query(sock, querystring) != 0) {		g_print("-7: Error: CDDB-query failed\n");		fflush(stdout);		return 1;	}	/* now the global match-structure contains all hits */	if (matchnr == 0) {		/* no matches found */		g_print("03: No matches found - unknown CD\n");		fflush(stdout);		/* all the user can do now is to cancel */		return 1;	} else {		/* output number of matches */		g_print("%% %d\n",matchnr);		fflush(stdout);		/* what type of matches */		if (cddbmatch[0]->exact == 0) {			/* close */			g_print("04: Found %d close matches - Please select (enter number and press enter)\n", matchnr);			fflush(stdout);		} else {			/* exact */			g_print("05: Found %d exact matches - Please select (enter number and press enter)\n", matchnr);			fflush(stdout);		}			/* now add all matches to clist */		for (i = 0; i < matchnr; i++) {			strcpy(tmptmp,cddbmatch[i]->dtitle);			g_print("#%02d: \"%s\"\n", i, 				convert_escape(tmptmp));		}			g_print("#--\n");		fflush(stdout);	}	/* so..now wait until the user select a match */	return 0;}/* user selected a match - fetch the corresponding data *//* return 1 on trouble, 0 if all ok */gint continue_cddb_query(gint sock, gint match) {	/* get data only when user manually not forbid it */	if (match != -1) {		g_print("06: Requesting data - Please wait\n");		fflush(stdout);		/* get the data */		if (cddb_read(sock, match) != 0) {			g_print("-8: Error: CDDB-read failed\n");			fflush(stdout);			return 1;		}	}	if (cddb_quit(sock) != 0) {		g_print("-9: Warning: CDDB-logout failed\n");		fflush(stdout);		return 1;	}	close_cddb(sock);	return 0;}void usage(gchar *cmd) {	g_print("Usage: %s [options] (Version: %s)\n",cmd, XCDROAST_VERSION);	g_print("Options:\n");	g_print("\t-s <cddb-server>\n");	g_print("\t-p <cddb-port>\n");	g_print("\t-u <id username>\n");	g_print("\t-h <id hostname>\n");	g_print("\t-m <match nr> get info for this match number\n\t   (Do not wait for user input - set to -1 for match list only)\n");	g_print("\t-q <cddb-query-string>\n");}gint main(gint argc, gchar **argv) {gint c;gchar server[MAXLINE];gchar selectbuffer[MAXLINE];gchar querystring[MAXLINE];gint port;gint ret, match;gint sock;gint automatch;	/* do some defaults */	strcpy(server,"freedb.freedb.org");	port = 888;	strcpy(username,"undef");	strcpy(hostname,"localhost");	strcpy(querystring, "");	automatch = -2;	cddbmatch = g_new0(cddb_match_t *,MAXCDDB);	while ((c = getopt(argc,argv,"s:p:u:h:q:m:")) != EOF) 	switch((gchar)c) {	case 's':			strncpy(server,optarg,MAXLINE);		break;	case 'u':			strncpy(username,optarg,MAXLINE);		break;	case 'h':			strncpy(hostname,optarg,MAXLINE);		break;	case 'q':			strncpy(querystring,optarg,MAXLINE);		break;	case 'p':		port = atoi(optarg);		break;	case 'm':		automatch = atoi(optarg);		break;	default:		usage(argv[0]);		exit(-1);	}	/* any parameters at all given? */	if (strcmp(querystring,"") == 0) {		usage(argv[0]);		exit(-1);	}	ret = start_cddb_query(&sock, server, port, querystring);	if (ret == 0) {		/* ok, now let the user select an match */		if (automatch == -2) {			read_line2(STDIN_FILENO, selectbuffer, MAXLINE, 0);			match = atoi(selectbuffer);		} else {			match = automatch;		} 		ret = continue_cddb_query(sock, match);		if (ret != 0) {			/* some error */			exit(1);		}	}	return 0;} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -