From: rog@vitanuova.com
To: 9fans@cse.psu.edu
Subject: [9fans] tiny patch to acd
Date: Wed, 19 Dec 2001 16:37:10 +0000 [thread overview]
Message-ID: <20011219162228.6EDEB19A10@mail.cse.psu.edu> (raw)
[-- Attachment #1: Type: text/plain, Size: 895 bytes --]
if the track names are long, cddb splits its track/title lines;
e.g.
cddb DTITLE=Buddy MacMaster, fiddle, and 14 accompanists on piano / The Judique Fly
cddb DTITLE=er
cddb TTITLE0=Donald Angus Beaton Set (Joey Beaton, acc): Dan R's Fav, Willie Frase
cddb TTITLE0=r's, Francis Beaton's, Derrick Beaton's
this caused some very odd looking track listings, not surprisingly.
the attached cddb.c fixes that (but i didn't want to delve too deeply
into how/when track title strings were allocated, so you might find
the way i've done it a little conservative and/or restrictive.
while on the subject, i've been thinking of adding the ability to edit
the track titles in acme and do a Put which would either automatically
submit to cddb (if possible) or store them locally to be retrieved the
next time. the reason: i've got lots of CDs which cddb has never heard of.
rog.
[-- Attachment #2: Type: message/rfc822, Size: 3865 bytes --]
/* see CDDBPROTO */
static ulong
cddb_sum(int n)
{
int ret;
ret = 0;
while(n > 0) {
ret += n%10;
n /= 10;
}
return ret;
}
static ulong
diskid(Toc *t)
{
int i, n, tmp;
Msf *ms, *me;
n = 0;
for(i=0; i < t->ntrack; i++)
n += cddb_sum(t->track[i].start.m*60+t->track[i].start.s);
ms = &t->track[0].start;
me = &t->track[t->ntrack].start;
tmp = (me->m*60+me->s) - (ms->m*60+ms->s);
/*
* the spec says n%0xFF rather than n&0xFF. it's unclear which is correct.
* most CDs are in the database under both entries.
*/
return ((n & 0xFF) << 24 | (tmp << 8) | t->ntrack);
}
static void
append(char **d, char *s)
{
char *r;
if (*d == nil)
*d = estrdup(s);
else {
r = emalloc(strlen(*d) + strlen(s) + 1);
strcpy(r, *d);
strcat(r, s);
free(*d);
*d = r;
}
}
static int
cddbfilltoc(Toc *t)
{
int fd;
int i;
char *p, *q;
Biobuf bin;
Msf *m;
char *f[10];
int nf;
char *id, *categ;
char gottrack[MTRACK];
int gottitle;
fd = dial("tcp!freedb.freedb.org!888", 0, 0, 0);
if(fd < 0) {
fprint(2, "cannot dial: %r\n");
return -1;
}
Binit(&bin, fd, OREAD);
if((p=Brdline(&bin, '\n')) == nil || atoi(p)/100 != 2) {
died:
close(fd);
Bterm(&bin);
fprint(2, "error talking to server\n");
if(p) {
p[Blinelen(&bin)-1] = 0;
fprint(2, "server says: %s\n", 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;
fprint(fd, "cddb query %8.8lux %d", diskid(t), t->ntrack);
DPRINT(2, "cddb query %8.8lux %d", diskid(t), t->ntrack);
for(i=0; i<t->ntrack; i++) {
m = &t->track[i].start;
fprint(fd, " %d", (m->m*60+m->s)*75+m->f);
DPRINT(2, " %d", (m->m*60+m->s)*75+m->f);
}
m = &t->track[t->ntrack-1].end;
fprint(fd, " %d\r\n", m->m*60+m->s);
DPRINT(2, " %d\r\n", m->m*60+m->s);
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;
}
/* fetch results for this cd */
fprint(fd, "cddb read %s %s\r\n", categ, id);
memset(gottrack, 0, sizeof(gottrack));
gottitle = 0;
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) {
if (gottitle)
append(&t->title, p + 7);
else
t->title = estrdup(p+7);
gottitle = 1;
} 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++;
if (gottrack[i])
append(&t->track[i].title, p);
else
t->track[i].title = estrdup(p);
gottrack[i] = 1;
}
}
} while(*p != '.');
fprint(fd, "quit\r\n");
close(fd);
Bterm(&bin);
return 0;
}
void
cddbproc(void *v)
{
Drive *d;
Toc t;
threadsetname("cddbproc");
d = v;
while(recv(d->cdbreq, &t))
if(cddbfilltoc(&t) == 0)
send(d->cdbreply, &t);
}
next reply other threads:[~2001-12-19 16:37 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2001-12-19 16:37 rog [this message]
2001-12-19 17:34 rog
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20011219162228.6EDEB19A10@mail.cse.psu.edu \
--to=rog@vitanuova.com \
--cc=9fans@cse.psu.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).