static void
fsremove(Req *r)
{
switch((ulong)r->fid->qid.path){
case Qwa:
case Qwd:
if(drive->fixate(drive) < 0)
respond(r, geterrstr());
// let us see if it can figure this out: drive->writeok = No;
else
respond(r, nil);
checktoc(drive);
break;
default:
respond(r, "permission denied");
break;
}
}
/* result is one word, so it can be used as a uid in Dir structs */
char *
disctype(Drive *drive)
{
char *type, *rw;
switch (drive->mmctype) {
case Mmccd:
type = "cd-";
break;
case Mmcdvdminus:
case Mmcdvdplus:
type = drive->dvdtype;
break;
case Mmcbd:
type = "bd-";
break;
case Mmcnone:
type = "no-disc";
break;
default:
type = "**GOK**"; /* traditional */
break;
}
rw = "";
if (drive->mmctype != Mmcnone && drive->dvdtype == nil)
if (drive->erasable == Yes)
rw = drive->mmctype == Mmcbd? "re": "rw";
else if (drive->recordable == Yes)
rw = "r";
else
rw = "rom";
return smprint("%s%s", type, rw);
}
int
fillstat(ulong qid, Dir *d)
{
char *ty;
Track *t;
static char buf[32];
static ulong
cddb_sum(int n)
{
int ret;
ret = 0;
while(n > 0) {
ret += n%10;
n /= 10;
}
return ret;
}
static ulong
diskid(Drive *d)
{
int i, n;
ulong tmp;
Msf *ms, *me;
n = 0;
for(i=0; i < d->ntrack; i++)
n += cddb_sum(d->track[i].mbeg.m*60+d->track[i].mbeg.s);
ms = &d->track[0].mbeg;
me = &d->track[d->ntrack].mbeg;
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) | d->ntrack);
}
static void
readctl(Req *r)
{
int i, isaudio;
ulong nwa;
char *p, *e, *ty;
char s[1024];
Msf *m;
p = s;
e = s + sizeof s;
*p = '\0';
if(isaudio){
p = seprint(p, e, "aux/cddb query %8.8lux %d", diskid(drive),
drive->ntrack);
for(i=0; i<drive->ntrack; i++){
m = &drive->track[i].mbeg;
p = seprint(p, e, " %d", (m->m*60 + m->s)*75 + m->f);
}
m = &drive->track[drive->ntrack].mbeg;
p = seprint(p, e, " %d\n", m->m*60 + m->s);
}
if(drive->readspeed == drive->writespeed)
p = seprint(p, e, "speed %d\n", drive->readspeed);
else
p = seprint(p, e, "speed read %d write %d\n",
drive->readspeed, drive->writespeed);
p = seprint(p, e, "maxspeed read %d write %d\n",
drive->maxreadspeed, drive->maxwritespeed);
if (drive->Scsi.changetime != 0 && drive->ntrack != 0) { /* have disc? */
ty = disctype(drive);
p = seprint(p, e, "%s", ty);
free(ty);
if (drive->mmctype != Mmcnone) {
nwa = getnwa(drive);
p = seprint(p, e, " next writable sector ");
if (nwa == ~0ul)
p = seprint(p, e, "none; disc full");
else
p = seprint(p, e, "%lud", nwa);
}
seprint(p, e, "\n");
}
readstr(r, s);
}
static void
fsread(Req *r)
{
int j, n, m;
uchar *p, *ep;
Dir d;
Fid *fid;
Otrack *o;
vlong offset;
void *buf;
long count;
Aux *a;
switch((ulong)fid->qid.path){
case Qdir:
case Qwa:
case Qwd:
if(omode != OREAD) {
respond(r, "permission denied");
return;
}
break;
case Qctl:
if(omode & ~(OTRUNC|OREAD|OWRITE|ORDWR)) {
respond(r, "permission denied");
return;
}
break;
default:
if(fid->qid.path >= Qtrack+drive->ntrack) {
respond(r, "file no longer exists");
return;
}
/*
* allow the open with OWRITE or ORDWR if the
* drive and disc are both capable?
*/
if(omode != OREAD ||
(o = drive->openrd(drive, fid->qid.path-Qtrack)) == nil) {
respond(r, "permission denied");
return;
}