1 #ifndef lint 2 static char *sccsid = "@(#)dumplab.c 1.3 (UKC) 08/11/87"; 3 #endif not lint 4 /* 5 * This file included by Peter Collinson 6 * to handle tape labelling 7 * There are two dump parameters which are used to specify labels 8 * -l Give the basic label format string - this may contain 9 * a single %s to insert the volume number string 10 * -m Map string - used to map volume numbers into a string 11 * 12 * Routines are: 13 * storelabel(arg) - called from main() to store a label format 14 * 15 * storelabelmap(arg) - called from main() to process a map argument 16 * - which is 17 * string simple string 18 * string-string expanded by incrementing 19 * string,string,..list of the above 20 * char * 21 * createlabel(volno) - returns a label appropriate for the volume 22 * 23 * initialtape() - called to print an operator message asking for 24 * - the 1st tape 25 * 26 * labelest(etapes) - checks if there are enough tape labels 27 * - specified for a given dump 28 * 29 * labelcheck() - reads one record from tape 30 * - checks that the labels match 31 * - backspace one record back 32 * - so that multi-volume dumps work 33 * 34 * log_volume() - write a logfile entry for the volume 35 * 36 */ 37 38 #include "dump.h" 39 #include <math.h> 40 41 42 #define LABMAX 100 /* get space for 100 */ 43 44 char *labfmt; /* Basic tape format */ 45 46 char *labarg[LABMAX]; /* Pointer to argument list */ 47 48 int labct; /* number of entries */ 49 /* if zero then no labels used */ 50 51 int userlabel; /* set if user has given a label */ 52 53 int labchk; /* check labels - set by t(est) flag */ 54 55 /* 56 * The file /etc/dumpvolumes is used to maintain a log of 57 * tapes which are/have been used for tape dumping 58 * The format is: 59 * label: date dev=<devname> level=<dump level> reel=<volume number> inode=<start inode> 60 */ 61 char dumpvolumes[] = "/etc/dumpvolumes"; 62 63 #ifdef RDUMP 64 extern char *host; 65 #endif RDUMP 66 67 /* 68 * Called from argument decoding to store the 69 * basic label format 70 * This is the parameter to the -l parameter 71 */ 72 storelabel(arg) 73 char *arg; 74 { 75 labfmt = arg; 76 userlabel = 1; 77 } 78 79 /* 80 * Store map list 81 * The map list 82 * allows a simple way to specify a range of tapes 83 * This generates a string which is inserted into the label format 84 * by use of an sprint operation 85 * 86 * The basic form here is: 87 * <string> a single string 88 * <string>,<string>,...... a list of strings 89 * <string>-<string> a range of strings 90 * where the string is `incremented' 91 * to generate a list 92 */ 93 storelabelmap(arg) 94 char *arg; 95 { 96 register char *ss, *es; 97 register char *incbase, *incr; 98 register lastc; 99 char *labskip(); 100 char *strstore(); 101 102 userlabel = 1; 103 104 /* 105 * Parse the argument looking for a single string 106 */ 107 for (ss = arg; *ss; ss = es) { 108 es = labskip(ss); 109 lastc = *es; /* save last character */ 110 *es++ = '\0'; /* make the first label into a string */ 111 if (labct > LABMAX) 112 labfatal("Too many (> %d) tape labels specified\n", LABMAX); 113 if (*ss == '\0') 114 labfatal("Zero length tape label found\n"); 115 labarg[labct++] = strstore(ss); 116 117 if (lastc == 0) 118 break; /* end of list */ 119 120 if (lastc == '-') { 121 /* 122 * this gives a tape range 123 * increment the source number until it equals the final 124 * value 125 */ 126 incbase = ss; 127 ss = es; 128 es = labskip(ss); 129 if (*es == '-') 130 labfatal("Range has the format <string>-<string>\n"); 131 lastc = *es; 132 if (lastc) 133 *es++ = '\0'; 134 /* 135 * basic test the source string length must be equal to the 136 * end string length 137 */ 138 if (strlen(incbase) != strlen(ss)) 139 labfatal("strlen(\"%s\") != strlen(\"%s\")\n", incbase, ss); 140 labelrange(incbase, ss); 141 } 142 } 143 } 144 145 /* 146 * Expand a label range 147 */ 148 /* static */ 149 labelrange(startrange, endrange) 150 char *startrange, *endrange; 151 { 152 register char *incr; 153 register int carry; 154 155 156 for (incr = startrange + strlen(startrange) - 1; 157 strcmp(startrange, endrange) != 0; ) { 158 /* start incrementing */ 159 carry = 0; 160 do { 161 if (isdigit(*incr)) { 162 if (*incr == '9') { 163 *incr = '0'; 164 carry = 1; 165 } else 166 (*incr)++; 167 } else 168 if (isupper(*incr)) { 169 if (*incr == 'Z') { 170 *incr = 'A'; 171 carry = 1; 172 } else 173 (*incr)++; 174 } else 175 if (islower(*incr)) { 176 if (*incr == 'z') { 177 *incr = 'a'; 178 carry = 1; 179 } else 180 (*incr)++; 181 } else 182 labfatal("Problem with label map range spec - can only increment alphanumeric values\n"); 183 if (carry) { 184 incr--; 185 if (incr < startrange) 186 labfatal("Problem with label map range spec - end of range reached\n"); 187 } 188 } while (carry); 189 190 if (labct > LABMAX) 191 labfatal("Too many (> %d) tape labels specified\n", LABMAX); 192 labarg[labct++] = strstore(startrange); 193 194 } 195 } 196 197 /* 198 * Store a string using malloc 199 */ 200 /* static */ 201 char * 202 strstore(arg) 203 char *arg; 204 { 205 register len = strlen(arg)+1; 206 register char *dest; 207 char *malloc(); 208 209 dest = malloc(len); 210 if (dest == NULL) 211 labfatal("No memory for string storage\n"); 212 bcopy(arg, dest, len); 213 return(dest); 214 } 215 216 /* 217 * Create a tape label from a volume number 218 */ 219 char * 220 createlabel(volno) 221 int volno; 222 { 223 static char buf[LBLSIZE+LBLSIZE]; 224 static int lastvol; 225 char volbuf[8]; 226 register char *arg; 227 228 if (userlabel == 0) 229 return ("none"); /* previous behaviour */ 230 231 if (volno == lastvol) /* cache */ 232 return(buf); 233 lastvol = volno; 234 235 if (labfmt == NULL) 236 labfmt = "%s"; 237 238 if (labct == 0) 239 { (void) sprintf(volbuf, "%d", volno); 240 arg = volbuf; 241 } 242 else 243 arg = labarg[volno-1]; /* volumes run 1-> */ 244 (void) sprintf(buf, labfmt, arg); 245 buf[LBLSIZE-1] = '\0'; /* Truncate to correct size */ 246 return(buf); 247 } 248 249 initialtape() 250 { static firstpr; 251 252 if (labchk == 0) 253 return; 254 if (firstpr == 0) 255 msg("Mount tape %s for reel 1 of the dump\n", createlabel(1)); 256 firstpr = 1; 257 } 258 259 /* 260 * given an estimated number of tapes, check that 261 * there are enough tapes on the label list 262 */ 263 labelest(etapes) 264 double etapes; 265 { int et; 266 267 if (labct) { 268 et = ceil(etapes); 269 if (et > labct) 270 labfatal("Only %d labe%s given, estimated need %d\n", 271 labct, labct == 1 ? "l" : "ls", et); 272 } 273 } 274 275 /* 276 * labelcheck 277 * read a dump header and check that the tape header contains 278 * the label we expected 279 * close the tape after use 280 */ 281 labelcheck(tno) 282 int tno; 283 { 284 register fd; 285 union u_spcl uin; 286 register char *label; 287 register char *ontape = uin.s_spcl.c_label; 288 289 if (labchk == 0 || pipeout) 290 return(0); 291 label = createlabel(tno); 292 293 #ifdef RDUMP 294 /* doing it this way to make it easier to read */ 295 if (host) { 296 while (rmtopen(tape, 0) < 0) 297 if (!query("Cannot open tape. Do you want to retry the open?")) 298 dumpabort(); 299 if (rmtread((char *)&uin, sizeof uin) != sizeof uin) { 300 msg("Tape does not start with the correctly sized record\n"); 301 (void)rmtclose(); 302 return(-1); 303 } 304 if (ontape[0] == '\0' || 305 strcmp(ontape, "none") == 0 || 306 strcmp(ontape, label) == 0) { 307 (void)rmtclose(); 308 return(0); 309 } 310 msg("Tape labels do not match should be `%s' is `%s'\n", label, ontape); 311 (void)rmtclose(); 312 return(-1); 313 } 314 #endif RDUMP 315 while ((fd = open(tape, 0)) < 0) 316 if (!query("Cannot open tape. Do you want to retry the open?")) 317 dumpabort(); 318 if (read(fd, (char *)&uin, sizeof uin) != sizeof uin) { 319 msg("Tape does not start with the correctly sized record\n"); 320 (void)close(fd); 321 return(-1); 322 } 323 if (ontape[0] == '\0' || 324 strcmp(ontape, "none") == 0 || 325 strcmp(ontape, label) == 0) { 326 (void)close(fd); 327 return(0); 328 } 329 msg("Tape labels do not match should be `%s' is `%s'\n", label, ontape); 330 (void)close(fd); 331 return(-1); 332 } 333 334 /* 335 * write a log entry for the volume into the log file 336 */ 337 log_volume(tlabel) 338 char *tlabel; 339 { 340 char *ctime(); 341 FILE *logfd; 342 343 if (uflag == 0 || labchk == 0) 344 return; 345 if ((logfd = fopen(dumpvolumes, "a")) == NULL) 346 return; 347 fprintf(logfd, "%s: date=%20.20s dev=%s level=%c reel=%d ino=%d\n", 348 tlabel, ctime(&spcl.c_date)+4, disk, incno, tapeno, 349 tapeno == 1 ? ROOTINO : ino); 350 fclose(logfd); 351 } 352 353 /* 354 * skip forward looking for valid end of label characters 355 */ 356 /* static */ 357 char * 358 labskip(str) 359 register char *str; 360 { 361 while (*str != ',' && *str != '-' && *str) 362 str++; 363 return (str); 364 } 365 366 /* 367 * generate a fatal error message 368 */ 369 /* VARARGS1 */ 370 /* ARGSUSED */ 371 labfatal(fmt, a1, a2, a3, a4, a5) 372 char *fmt; 373 int a1, a2, a3, a4, a5; 374 { 375 msg(fmt, a1, a2, a3, a4, a5); 376 dumpabort(); 377 } 378 379