Here are the details on Dennis Ritchie's Plan 9 plug-in to read the s2-bits tape, as sent in by e-mail. From: dmr@plan9.bell-labs.com Subject: Re: Happy New Year + 1stEd binaries run again Date: Tue, 4 Jan 2000 22:19:01 -0500 To: wkt@cs.adfa.edu.au MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Status: RO Attached below is the "plugin" for tapfs (part of the plan 9 things that mount things as file systems). It's the only part that's tap-specific. Just got your latest mail--as I said, I don't recognize the format of s1 either. My headers for s2 are consistent with yours, I think, modulo date understanding. (And mapping of permissions etc into Plan 9). For example: --r---wxrw- M 10745 79524 28 1912 Jan 3 1973 bin/form The M 10745 79524 28 part is just Plan 9; there's a possible year ambiguity; the day difference is probably US vs AU. --- #include #include #include "tapefs.h" /* * File system for old tap tapes. */ struct tap { unsigned char name[32]; unsigned char mode[1]; unsigned char uid[1]; unsigned char size[2]; unsigned char tmod[4]; unsigned char taddress[2]; unsigned char unused[20]; unsigned char checksum[2]; } dir[192]; int tapefile; char buffer[8192]; long cvtime(unsigned char *); void populate(char *name) { int i, isabs; struct tap *tpp; Fileinf f; replete = 1; tapefile = open(name, OREAD); if (tapefile<0) error("Can't open argument file"); read(tapefile, dir, sizeof dir); for (i=0, tpp=&dir[8]; i<192; i++, tpp++) { unsigned char *sp = (unsigned char *)tpp; int j, cksum = 0; for (j=0; j<32; j++, sp+=2) cksum += sp[0] + (sp[1]<<8); cksum &= 0xFFFF; if (cksum!=0) { print("cksum failure\n"); continue; } if (tpp->name[0]=='\0') continue; f.addr = (void *)(tpp->taddress[0] + (tpp->taddress[1]<<8)); if (f.addr==0) continue; f.size = tpp->size[0] + (tpp->size[1]<<8); f.mdate = cvtime(tpp->tmod); f.mode = tpp->mode[0]&0777; isabs = tpp->name[0]=='/'; f.name = (char *)tpp->name+isabs; poppath(f, 1); } } long cvtime(unsigned char *tp) { unsigned long t = (tp[1]<<24)+(tp[0]<<16)+(tp[3]<<8)+(tp[2]<<0); t /= 60; t += 3*365*24*3600; return t; } void popdir(Ram *r) { USED(r); } void dotrunc(Ram *r) { USED(r); } void docreate(Ram *r) { USED(r); } char * doread(Ram *r, long off, long cnt) { if (cnt>sizeof(buffer)) print("count too big\n"); seek(tapefile, 512*(int)r->data+off, 0); read(tapefile, buffer, cnt); return buffer; } void dowrite(Ram *r, char *buf, long off, long cnt) { USED(r); USED(buf); USED(off); USED(cnt); } int dopermw(Ram *r) { USED(r); return 0; }