📄 9660srv.c
字号:
if(d->reclen == 0) return 0; fprint(fd, "%d %d %ld %ld ", d->reclen, d->attrlen, l32(d->addr), l32(d->size)); fprint(fd, "%s 0x%2.2x %d %d %ld ", rdate(d->date, fmt), (fmt=='z' ? d->flags : d->r_flags), d->unitsize, d->gapsize, l16(d->vseqno)); fprint(fd, "%d %s", d->namelen, nstr(d->name, d->namelen)); if(fmt != 'J'){ namelen = d->namelen + (1-(d->namelen&1)); syslen = d->reclen - 33 - namelen; if(syslen != 0) fprint(fd, " %s", nstr(&d->name[namelen], syslen)); } fprint(fd, "\n"); return d->reclen + (d->reclen&1);}static voidnewdrec(Xfile *f, Drec *dp){ Isofile *x = f->ptr; Isofile *n; int len; len = sizeof(Isofile) - sizeof(Drec) + dp->reclen; n = ealloc(len); n->fmt = x->fmt; n->blksize = x->blksize; n->offset = 0; n->doffset = 0; memmove(&n->d, dp, dp->reclen); free(x); f->ptr = n; f->len = len;}static voidungetdrec(Xfile *f){ Isofile *ip = f->ptr; if(ip->offset >= ip->odelta){ ip->offset -= ip->odelta; ip->odelta = 0; }}static intgetdrec(Xfile *f, void *buf){ Isofile *ip = f->ptr; int len = 0, boff = 0; long size, addr; Iobuf *p = 0; if(!ip) return -1; size = l32(ip->d.size); while(ip->offset<size){ addr = (l32(ip->d.addr)+ip->d.attrlen)*ip->blksize + ip->offset; boff = (ulong)addr % Sectorsize; if(boff > Sectorsize-34){ ip->offset += Sectorsize-boff; continue; } p = getbuf(f->xf->d, (ulong)addr/Sectorsize); len = p->iobuf[boff]; if(len >= 34) break; putbuf(p); p = 0; ip->offset += Sectorsize-boff; } if(p) { memmove(buf, &p->iobuf[boff], len); putbuf(p); ip->odelta = len + (len&1); ip->offset += ip->odelta; } if(p) return 0; return -1;}static intopendotdot(Xfile *f, Xfile *pf){ uchar dbuf[256]; Drec *d = (Drec *)dbuf; Isofile *ip = f->ptr, *pip = pf->ptr; ip->offset = 0; if(getdrec(f, d) < 0){ chat("opendotdot: getdrec(.) failed..."); return -1; } if(d->namelen != 1 || d->name[0] != 0){ chat("opendotdot: no . entry..."); return -1; } if(l32(d->addr) != l32(ip->d.addr)){ chat("opendotdot: bad . address..."); return -1; } if(getdrec(f, d) < 0){ chat("opendotdot: getdrec(..) failed..."); return -1; } if(d->namelen != 1 || d->name[0] != 1){ chat("opendotdot: no .. entry..."); return -1; } pf->xf = f->xf; pip->fmt = ip->fmt; pip->blksize = ip->blksize; pip->offset = 0; pip->doffset = 0; pip->d = *d; return 0;}enum { Hname = 1, Hmode = 2,};static intrzdir(Xfs *fs, Dir *d, int fmt, Drec *dp){ int n, flags, i, j, lj, nl, vers, sysl, mode, l, have; uchar *s; char *p; char buf[Maxname+UTFmax+1]; uchar *q; Rune r; enum { ONAMELEN = 28 }; /* old Plan 9 directory name length */ have = 0; flags = 0; vers = -1; d->qid.path = l32(dp->addr); d->qid.type = 0; d->qid.vers = 0; n = dp->namelen; memset(d->name, 0, Maxname); if(n == 1) { switch(dp->name[0]){ case 1: d->name[1] = '.'; /* fall through */ case 0: d->name[0] = '.'; have = Hname; break; default: d->name[0] = tolower(dp->name[0]); } } else { if(fmt == 'J'){ /* Joliet, 16-bit Unicode */ q = (uchar*)dp->name; for(i=j=lj=0; i<n && j<Maxname; i+=2){ lj = j; r = (q[i]<<8)|q[i+1]; j += runetochar(buf+j, &r); } if(j >= Maxname) j = lj; memmove(d->name, buf, j); }else{ if(n >= Maxname) n = Maxname-1; for(i=0; i<n; i++) d->name[i] = tolower(dp->name[i]); } } sysl = dp->reclen-(34+dp->namelen); s = (uchar*)dp->name + dp->namelen; if(((uintptr)s) & 1) { s++; sysl--; } if(fs->isplan9 && sysl > 0) { /* * get gid, uid, mode and possibly name * from plan9 directory extension */ nl = *s; if(nl >= ONAMELEN) nl = ONAMELEN-1; if(nl) { memset(d->name, 0, ONAMELEN); memmove(d->name, s+1, nl); } s += 1 + *s; nl = *s; if(nl >= ONAMELEN) nl = ONAMELEN-1; memset(d->uid, 0, ONAMELEN); memmove(d->uid, s+1, nl); s += 1 + *s; nl = *s; if(nl >= ONAMELEN) nl = ONAMELEN-1; memset(d->gid, 0, ONAMELEN); memmove(d->gid, s+1, nl); s += 1 + *s; if(((uintptr)s) & 1) s++; d->mode = l32(s); if(d->mode & DMDIR) d->qid.type |= QTDIR; } else { d->mode = 0444; switch(fmt) { case 'z': if(fs->isrock) strcpy(d->gid, "ridge"); else strcpy(d->gid, "iso9660"); flags = dp->flags; break; case 'r': strcpy(d->gid, "sierra"); flags = dp->r_flags; break; case 'J': strcpy(d->gid, "joliet"); flags = dp->flags; break; case '9': strcpy(d->gid, "plan9"); flags = dp->flags; break; } if(flags & 0x02){ d->qid.type |= QTDIR; d->mode |= DMDIR|0111; } strcpy(d->uid, "cdrom"); if(fmt!='9' && !(d->mode&DMDIR)){ /* * ISO 9660 actually requires that you always have a . and a ;, * even if there is no version and no extension. Very few writers * do this. If the version is present, we use it for qid.vers. * If there is no extension but there is a dot, we strip it off. * (VMS heads couldn't comprehend the dot as a file name character * rather than as just a separator between name and extension.) * * We don't do this for directory names because directories are * not allowed to have extensions and versions. */ if((p=strchr(d->name, ';')) != nil){ vers = strtoul(p+1, 0, 0); d->qid.vers = vers; *p = '\0'; } if((p=strchr(d->name, '.')) != nil && *(p+1)=='\0') *p = '\0'; } if(fs->issusp){ nl = 0; s += fs->suspoff; sysl -= fs->suspoff; for(; sysl >= 4 && have != (Hname|Hmode); sysl -= l, s += l){ if(s[0] == 0 && ((uintptr)s & 1)){ /* MacOS pads individual entries, contrary to spec */ s++; sysl--; } l = s[2]; if(s[0] == 'P' && s[1] == 'X' && s[3] == 1){ /* posix file attributes */ mode = l32(s+4); d->mode = mode & 0777; if((mode & 0170000) == 040000){ d->mode |= DMDIR; d->qid.type |= QTDIR; } have |= Hmode; } else if(s[0] == 'N' && s[1] == 'M' && s[3] == 1){ /* alternative name */ if((s[4] & ~1) == 0){ i = nl+l-5; if(i >= Maxname) i = Maxname-1; if((i -= nl) > 0){ memmove(d->name+nl, s+5, i); nl += i; } if(s[4] == 0) have |= Hname; } } else if(s[0] == 'C' && s[1] == 'E' && s[2] >= 28){ sysl = getcontin(fs->d, s, &s); continue; } else if(s[0] == 'S' && s[1] == 'T') break; } } } d->length = 0; if((d->mode & DMDIR) == 0) d->length = l32(dp->size); d->type = 0; d->dev = 0; d->atime = gtime(dp->date); d->mtime = d->atime; return vers;}static intgetcontin(Xdata *dev, uchar *p, uchar **s){ long bn, off, len; Iobuf *b; bn = l32(p+4); off = l32(p+12); len = l32(p+20); chat("getcontin %d...", bn); b = getbuf(dev, bn); if(b == 0){ *s = 0; return 0; } *s = b->iobuf+off; putbuf(b); return len;}static char *nstr(uchar *p, int n){ static char buf[132]; char *q = buf; while(--n >= 0){ if(*p == '\\') *q++ = '\\'; if(' ' <= *p && *p <= '~') *q++ = *p++; else q += sprint(q, "\\%2.2ux", *p++); } *q = 0; return buf;}static char *rdate(uchar *p, int fmt){ static char buf[64]; int htz, s, n; n = sprint(buf, "%2.2d.%2.2d.%2.2d %2.2d:%2.2d:%2.2d", p[0], p[1], p[2], p[3], p[4], p[5]); if(fmt == 'z'){ htz = p[6]; if(htz >= 128){ htz = 256-htz; s = '-'; }else s = '+'; sprint(&buf[n], " (%c%.1f)", s, (float)htz/2); } return buf;}static chardmsize[12] ={ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31,};static intdysize(int y){ if((y%4) == 0) return 366; return 365;}static longgtime(uchar *p) /* yMdhmsz */{ long t; int i, y, M, d, h, m, s, tz; y=p[0]; M=p[1]; d=p[2]; h=p[3]; m=p[4]; s=p[5]; tz=p[6]; USED(tz); if (y < 70) return 0; if (M < 1 || M > 12) return 0; if (d < 1 || d > dmsize[M-1]) return 0; if (h > 23) return 0; if (m > 59) return 0; if (s > 59) return 0; y += 1900; t = 0; for(i=1970; i<y; i++) t += dysize(i); if (dysize(y)==366 && M >= 3) t++; while(--M) t += dmsize[M-1]; t += d-1; t = 24*t + h; t = 60*t + m; t = 60*t + s; return t;}#define p ((uchar*)arg)static longl16(void *arg){ long v; v = ((long)p[1]<<8)|p[0]; if (v >= 0x8000L) v -= 0x10000L; return v;}static longl32(void *arg){ return ((((((long)p[3]<<8)|p[2])<<8)|p[1])<<8)|p[0];}#undef p
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -