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

📄 cddb.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <ctype.h>char *server = "freedb.freedb.org";int debug;#define DPRINT if(debug)fprintint tflag;int Tflag;typedef struct Track Track;struct Track {	int n;	char *title;};enum {	MTRACK = 64,};typedef struct Toc Toc;struct Toc {	ulong diskid;	int ntrack;	char *title;	Track track[MTRACK];};void*emalloc(uint n){	void *p;	p = malloc(n);	if(p == nil)		sysfatal("can't malloc: %r");	memset(p, 0, n);	return p;}char*estrdup(char *s){	char *t;	t = emalloc(strlen(s)+1);	strcpy(t, s);	return t;}static voiddumpcddb(Toc *t){	int i, n, s;	print("title	%s\n", t->title);	for(i=0; i<t->ntrack; i++){		if(tflag){			n = t->track[i+1].n;			if(i == t->ntrack-1)				n *= 75;			s = (n - t->track[i].n)/75;			print("%d\t%s\t%d:%2.2d\n", i+1, t->track[i].title, s/60, s%60);		}		else			print("%d\t%s\n", i+1, t->track[i].title);	}	if(Tflag){		s = t->track[i].n;		print("Total time: %d:%2.2d\n", s/60, s%60);	}}char*append(char *a, char *b){	char *c;	c = emalloc(strlen(a)+strlen(b)+1);	strcpy(c, a);	strcat(c, b);	return c;}static intcddbfilltoc(Toc *t){	int fd;	int i;	char *p, *q;	Biobuf bin;	char *f[10];	int nf;	char *id, *categ;	fd = dial(netmkaddr(server, "tcp", "888"), 0, 0, 0);	if(fd < 0) {		fprint(2, "%s: %s: cannot dial: %r\n", argv0, server);		return -1;	}	Binit(&bin, fd, OREAD);	if((p=Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2) {	died:		close(fd);		Bterm(&bin);		fprint(2, "%s: error talking to cddb server %s\n",			argv0, server);		if(p) {			p[Blinelen(&bin)-1] = 0;			fprint(2, "%s: server says: %s\n", argv0, p);		}		return -1;	}	fprint(fd, "cddb hello gre plan9 9cd 1.0\r\n");	if((p = Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2)		goto died;	/*	 *	Protocol level 6 is the same as level 5 except that	 *	the character set is now UTF-8 instead of ISO-8859-1.  	 */	fprint(fd, "proto 6\r\n");	DPRINT(2, "proto 6\r\n");	if((p = Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2)		goto died;	p[Blinelen(&bin)-1] = 0;	DPRINT(2, "cddb: %s\n", p);	fprint(fd, "cddb query %8.8lux %d", t->diskid, t->ntrack);	DPRINT(2, "cddb query %8.8lux %d", t->diskid, t->ntrack);	for(i=0; i<t->ntrack; i++) {		fprint(fd, " %d", t->track[i].n);		DPRINT(2, " %d", t->track[i].n);	}	fprint(fd, " %d\r\n", t->track[t->ntrack].n);	DPRINT(2, " %d\r\n", t->track[t->ntrack].n);	if((p = Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2)		goto died;	p[Blinelen(&bin)-1] = 0;	DPRINT(2, "cddb: %s\n", p);	nf = tokenize(p, f, nelem(f));	if(nf < 1)		goto died;	switch(atoi(f[0])) {	case 200:	/* exact match */		if(nf < 3)			goto died;		categ = f[1];		id = f[2];		break;	case 211:	/* close matches */		if((p = Brdline(&bin, '\n')) == nil)			goto died;		if(p[0] == '.')	/* no close matches? */			goto died;		p[Blinelen(&bin)-1] = '\0';		/* accept first match */		nf = tokenize(p, f, nelem(f));		if(nf < 2)			goto died;		categ = f[0];		id = f[1];		/* snarf rest of buffer */		while(p[0] != '.') {			if((p = Brdline(&bin, '\n')) == nil)				goto died;			p[Blinelen(&bin)-1] = '\0';			DPRINT(2, "cddb: %s\n", p);		}		break;	case 202: /* no match */	default:		goto died;	}	t->title = "";	for(i=0; i<t->ntrack; i++)		t->track[i].title = "";	/* fetch results for this cd */	fprint(fd, "cddb read %s %s\r\n", categ, id);	do {		if((p = Brdline(&bin, '\n')) == nil)			goto died;		q = p+Blinelen(&bin)-1;		while(isspace(*q))			*q-- = 0;DPRINT(2, "cddb %s\n", p);		if(strncmp(p, "DTITLE=", 7) == 0)			t->title = append(t->title, p+7);		else if(strncmp(p, "TTITLE", 6) == 0 && isdigit(p[6])) {			i = atoi(p+6);			if(i < t->ntrack) {				p += 6;				while(isdigit(*p))					p++;				if(*p == '=')					p++;				t->track[i].title = append(t->track[i].title, estrdup(p));			}		} 	} while(*p != '.');	fprint(fd, "quit\r\n");	close(fd);	Bterm(&bin);	return 0;}voidusage(void){	fprint(2, "usage: aux/cddb [-DTt] [-s server] query diskid n ...\n");	exits("usage");}voidmain(int argc, char **argv){	int i;	Toc toc;	ARGBEGIN{	case 'D':		debug = 1;		break;	case 's':		server = EARGF(usage());		break;	case 'T':		Tflag = 1;		/*FALLTHROUGH*/	case 't':		tflag = 1;		break;	}ARGEND	if(argc < 3 || strcmp(argv[0], "query") != 0)		usage();	toc.diskid = strtoul(argv[1], 0, 16);	toc.ntrack = atoi(argv[2]);	if(argc != 3+toc.ntrack+1)		sysfatal("argument count does not match given ntrack");	for(i=0; i<=toc.ntrack; i++)		toc.track[i].n = atoi(argv[3+i]);	if(cddbfilltoc(&toc) < 0)		exits("whoops");	dumpcddb(&toc);	exits(nil);}

⌨️ 快捷键说明

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