1 #ifndef lint 2 static char sccsid[] = "@(#)tp3.c 4.1 12/18/82"; 3 #endif 4 5 #include "tp.h" 6 7 gettape(how) 8 int (*how)(); 9 { 10 register char *ptr0, *ptr1; 11 register struct dent *d; 12 int count; 13 14 do { 15 d = &dir[0]; 16 count = 0; 17 do { 18 if (d->d_namep == 0) continue; 19 decode(name,d); 20 if (rnarg > 2) { 21 ptr0 = name; 22 ptr1 = *parg; 23 while (*ptr1) 24 if (*ptr0++ != *ptr1++) goto cont; 25 if (*ptr0 && *ptr0 != '/') goto cont; 26 } 27 (*how)(d); /* delete, extract, or taboc */ 28 ++count; 29 cont: continue; 30 } while (++d <= lastd); 31 if (count == 0 && rnarg > 2) 32 printf("%s not found\n", *parg); 33 ++parg; 34 } while (--narg > 2); 35 } 36 37 delete(dd) 38 struct dent *dd; 39 { 40 if (verify('d') >= 0) 41 clrent(dd); 42 } 43 44 45 update() 46 { 47 register struct dent *d; 48 register b, last; 49 int first, size; 50 51 52 bitmap(); 53 d = &dir[0]; 54 do { 55 if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue; 56 if (d->d_size == 0) continue; 57 /* find a place on the tape for this file */ 58 size = (d->d_size+BSIZE-1)/BSIZE; 59 first = ndentb; 60 toosmall: ++first; 61 if ((last = first + size) >= tapsiz) maperr(); 62 for (b = first; b < last; ++b) 63 if (map[(b>>3) & MAPMASK] & (1<<(b&7))) { 64 first = b; 65 goto toosmall; 66 }; 67 d->d_tapea = first; 68 setmap(d); 69 } while (++d <= lastd); 70 wrdir(); 71 update1(); 72 } 73 74 75 update1() 76 { 77 register struct dent *d, *id; 78 register index; 79 int f; 80 81 for (;;) { 82 d = &dir[0]; 83 index = MTSIZ; 84 id = 0; 85 do { /* find new dent with lowest tape address */ 86 if(d->d_namep == 0 || (d->d_mode&OK) == 0) continue; 87 if (d->d_tapea < index) { 88 index = d->d_tapea; 89 id = d; 90 } 91 } while (++d <= lastd); 92 if ((d = id) == 0) return; 93 d->d_mode &= ~OK; /* change from new to old */ 94 if (d->d_size == 0) continue; 95 decode(name,d); 96 wseek(index); 97 if ((f = open(name,0)) < 0) { 98 printf("Can't open %s\n", name); 99 continue; 100 } 101 for (index = d->d_size/BSIZE; index != 0; --index) { 102 if (read(f,(char *)tapeb,BSIZE) != BSIZE) phserr(); 103 twrite(); 104 } 105 if (index = d->d_size % BSIZE) { 106 if (read(f,(char *)tapeb,index) != index) phserr(); 107 twrite(); 108 } 109 if (read(f,(char *)tapeb,1) != 0) phserr(); 110 close(f); 111 } 112 } 113 114 phserr() 115 { printf("%s -- Phase error \n", name); } 116 117 118 bitmap() /* place old files in the map */ 119 { 120 register char *m; 121 register count; 122 register struct dent *d; 123 124 for(m=map;m<&map[MAPSIZE];) *m++ = 0; 125 count = ndirent; 126 d = dir; 127 do { 128 if(d->d_namep != 0 && (d->d_mode&OK) == 0 129 && d->d_size != 0) setmap(d); 130 d++; 131 } while (--count); 132 } 133 134 setmap(d) 135 register struct dent *d; 136 { 137 unsigned c, block; 138 char bit; 139 int i; 140 141 c = d->d_size/BSIZE; 142 if (d->d_size % BSIZE) c++; 143 block = d->d_tapea; 144 if ((c += block) >= tapsiz) maperr(); 145 do { 146 bit = 1 << (block & 7); 147 i = (block>>3) & MAPMASK; 148 if (bit & map[i]) maperr(); 149 map[i] |= bit; 150 } while (++block < c); 151 } 152 153 maperr() 154 { 155 printf("Tape overflow\n"); 156 done(); 157 } 158 159 160 usage() 161 { 162 register reg,count; 163 int nused, nentr, nfree; 164 static lused; 165 166 bitmap(); 167 for(count=0,nentr=0;count<ndirent;count++) 168 if(dir[count].d_namep != 0) nentr++; 169 nused = nfree = 0; 170 reg = ndentb; 171 ++reg; /* address of first non-directory tape block */ 172 count = tapsiz - reg; 173 do { 174 if (reg >= tapsiz) { 175 printf("Tape overflow\n"); 176 done(); 177 } 178 if (map[(reg>>3) & MAPMASK] & (1 << (reg&7))) { 179 nused++; 180 lused = reg; 181 } else { 182 if (flags & flm) break; 183 nfree++; 184 } 185 reg++; 186 } while (--count); 187 printf("%4d entries\n%4d used\n", nentr, nused); 188 if ((flags & flm)==0) 189 printf("%4d free\n", nfree); 190 printf("%4d last\n", lused); 191 } 192 193 194 taboc(dd) 195 struct dent *dd; 196 { 197 register mode; 198 register *m; 199 register char *s; 200 int count, *localtime(); 201 char work[20]; 202 203 if (flags & flv) { 204 mode = dd->d_mode; 205 s = &work[19]; 206 *s = 0; 207 for (count = 3; count; --count) { 208 if (mode&1) *--s = 'x'; 209 else *--s = '-'; 210 if (mode&2) *--s = 'w'; 211 else *--s = '-'; 212 if (mode&4) *--s = 'r'; 213 else *--s = '-'; 214 mode >>= 3; 215 } 216 if (mode&4) s[2] = 's'; 217 if (mode&2) s[5] = 's'; 218 printf("%s%4d%4d%5d%9D ",s,dd->d_uid, dd->d_gid,dd->d_tapea,dd->d_size); 219 m = localtime(&dd->d_time); 220 printf("%2d/%2d/%2d %2d:%2d ",m[5],m[4]+1,m[3],m[2],m[1]); 221 } 222 printf("%s\n", name); 223 } 224 225 226 extract(d) 227 register struct dent *d; 228 { 229 register count, id; 230 231 if (d->d_size==0) return; 232 if (verify('x') < 0) return; 233 rseek(d->d_tapea); 234 unlink(name); 235 if ((id = creat(name,d->d_mode)) < 0) 236 printf("%s -- create error\n", name); 237 count = d->d_size/BSIZE; 238 while (count--) { 239 tread(); 240 if (write(id, (char *)tapeb, BSIZE) != BSIZE) goto ng; 241 } 242 if (count = d->d_size % BSIZE) { 243 tread(); 244 if (write(id, (char *)tapeb, count) != count) { 245 ng: printf("%s -- write error\n", name); 246 close(id); 247 return; 248 } 249 } 250 close(id); 251 chown(name,d->d_uid & 0377, d->d_gid&0377); 252 } 253