|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)tapeio.c 5.1 6/7/85 ! 7: */ ! 8: ! 9: /* ! 10: * tapeio - tape device specific I/O routines ! 11: * ! 12: * ierr = topen (tlu, name, labelled) ! 13: * ierr = tclose (tlu) ! 14: * nbytes = tread (tlu, buffer) ! 15: * nbytes = twrite (tlu, buffer) ! 16: * ierr = trewin (tlu) ! 17: * ierr = tskipf (tlu, nfiles, nrecs) ! 18: * ierr = tstate (tlu, fileno, recno, err, eof, eot, tcsr) ! 19: */ ! 20: ! 21: #include <ctype.h> ! 22: #include <sys/ioctl.h> ! 23: #ifndef MTIOCGET /* 4.1+ defines this in ... */ ! 24: #include <sys/types.h> ! 25: #include <sys/mtio.h> ! 26: #endif ! 27: #include "../libI77/f_errno.h" ! 28: ! 29: #define TU_NAMESIZE 22 ! 30: #define TU_MAXTAPES 4 ! 31: ! 32: struct tunits { ! 33: char tu_name[TU_NAMESIZE]; /* device name */ ! 34: int tu_fd; /* file descriptor */ ! 35: int tu_flags; /* state flags */ ! 36: int tu_file; /* current tape file number */ ! 37: int tu_rec; /* current record number in file */ ! 38: } tunits[TU_MAXTAPES]; ! 39: ! 40: #define TU_OPEN 0x1 ! 41: #define TU_EOF 0x2 ! 42: #define TU_ERR 0x4 ! 43: #define TU_READONLY 0x8 ! 44: #define TU_LABELLED 0x10 ! 45: #define TU_WRITING 0x20 ! 46: #define TU_EOT 0x40 ! 47: #define TU_RDATA 0x80 ! 48: ! 49: #ifdef MTWEOF /* this implies 4.1+ ... */ ! 50: struct mtget mtget; /* controller status */ ! 51: #endif ! 52: ! 53: /* ! 54: * Open a tape unit for I/O ! 55: * ! 56: * calling format: ! 57: * integer topen, tlu ! 58: * character*(*) devnam ! 59: * logical labled ! 60: * ierror = topen(tlu, devnam, labled) ! 61: * where: ! 62: * ierror will be 0 for successful open; an error number otherwise. ! 63: * devnam is a character string ! 64: * labled should be .true. if the tape is labelled. ! 65: */ ! 66: ! 67: long ! 68: topen_(tlu, name, labelled, len) ! 69: long *tlu; ! 70: char *name; ! 71: long *labelled; ! 72: long len; ! 73: { ! 74: struct tunits *tu; ! 75: ! 76: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 77: errno = F_ERUNIT; ! 78: return(-1L); ! 79: } ! 80: ! 81: tu = &tunits[*tlu]; ! 82: if (tu->tu_flags & TU_OPEN) ! 83: tclose_(tlu); ! 84: ! 85: if (len >= TU_NAMESIZE) { ! 86: errno = F_ERARG; ! 87: return(-1L); ! 88: } ! 89: ! 90: g_char(name, len, tu->tu_name); ! 91: ! 92: if ((tu->tu_fd = open(tu->tu_name, 2)) < 0) { ! 93: if ((tu->tu_fd = open(tu->tu_name, 0)) < 0) ! 94: return(-1L); ! 95: tu->tu_flags |= TU_READONLY; ! 96: } ! 97: tu->tu_flags |= TU_OPEN; ! 98: tu->tu_file = tu->tu_rec = 0; ! 99: if (*labelled) ! 100: tu->tu_flags |= TU_LABELLED; ! 101: return(0L); ! 102: } ! 103: ! 104: /* ! 105: * Close a tape unit previously opened by topen_() ! 106: * ! 107: * calling sequence: ! 108: * integer tlu, tclose ! 109: * ierrno = tclose(tlu) ! 110: * where: ! 111: * tlu is a previously topened tape logical unit. ! 112: */ ! 113: ! 114: long ! 115: tclose_(tlu) ! 116: long *tlu; ! 117: { ! 118: struct tunits *tu; ! 119: ! 120: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 121: errno = F_ERUNIT; ! 122: return(-1L); ! 123: } ! 124: ! 125: tu = &tunits[*tlu]; ! 126: if (!(tu->tu_flags & TU_OPEN)) ! 127: return(0L); ! 128: ! 129: tu->tu_flags = 0; ! 130: if (close(tu->tu_fd) < 0) ! 131: return(-1L); ! 132: return(0L); ! 133: } ! 134: ! 135: /* ! 136: * Read from a tape logical unit ! 137: * ! 138: * calling sequence: ! 139: * integer tread, tlu ! 140: * character*(*) buffer ! 141: * ierr = tread(tlu, buffer) ! 142: */ ! 143: ! 144: long ! 145: tread_(tlu, buffer, len) ! 146: long *tlu; ! 147: char *buffer; ! 148: long len; ! 149: { ! 150: struct tunits *tu; ! 151: int nbytes; ! 152: ! 153: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 154: errno = F_ERUNIT; ! 155: return(-1L); ! 156: } ! 157: ! 158: tu = &tunits[*tlu]; ! 159: if (!(tu->tu_flags & TU_OPEN)) { ! 160: errno = F_ERNOPEN; ! 161: return(-1L); ! 162: } ! 163: if (tu->tu_flags & TU_WRITING) { ! 164: errno = F_ERILLOP; ! 165: return(-1L); ! 166: } ! 167: if (tu->tu_flags & (TU_EOF|TU_EOT)) ! 168: return(0L); ! 169: ! 170: if ((nbytes = read(tu->tu_fd, buffer, (int)len)) > 0) ! 171: tu->tu_flags |= TU_RDATA; ! 172: ! 173: if (nbytes == 0 && len != 0) { ! 174: tu->tu_flags |= TU_EOF; ! 175: if (tu->tu_rec == 0) ! 176: tu->tu_flags |= TU_EOT; ! 177: } ! 178: if (nbytes < 0) ! 179: tu->tu_flags |= TU_ERR; ! 180: else ! 181: tu->tu_rec++; ! 182: ! 183: return((long)nbytes); ! 184: } ! 185: ! 186: /* ! 187: * Write to a tape logical unit ! 188: * ! 189: * calling sequence: ! 190: * integer twrite, tlu ! 191: * character*(*) buffer ! 192: * ierr = twrite(tlu, buffer) ! 193: */ ! 194: ! 195: long ! 196: twrite_(tlu, buffer, len) ! 197: long *tlu; ! 198: char *buffer; ! 199: long len; ! 200: { ! 201: struct tunits *tu; ! 202: int nbytes; ! 203: long nf; ! 204: long zero = 0L; ! 205: ! 206: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 207: errno = F_ERUNIT; ! 208: return(-1L); ! 209: } ! 210: ! 211: tu = &tunits[*tlu]; ! 212: if (!(tu->tu_flags & TU_OPEN)) { ! 213: errno = F_ERNOPEN; ! 214: return(-1L); ! 215: } ! 216: if (tu->tu_flags & TU_READONLY) { ! 217: errno = F_ERILLOP; ! 218: return(-1L); ! 219: } ! 220: ! 221: if (tu->tu_flags & TU_EOT) { /* must backspace over last EOF */ ! 222: nf = (long)tu->tu_file; /* should be number to skip */ ! 223: trewin_(tlu); /* KLUDGE!! */ ! 224: tskipf_(tlu, &nf, &zero); ! 225: } ! 226: ! 227: nbytes = write(tu->tu_fd, buffer, (int)len); ! 228: if (nbytes <= 0) ! 229: tu->tu_flags |= TU_ERR; ! 230: tu->tu_rec++; ! 231: tu->tu_flags |= TU_WRITING; ! 232: tu->tu_flags &= ~(TU_EOF|TU_EOT|TU_RDATA); ! 233: return((long)nbytes); ! 234: } ! 235: ! 236: /* ! 237: * rewind a tape device ! 238: */ ! 239: ! 240: long ! 241: trewin_(tlu) ! 242: long *tlu; ! 243: { ! 244: struct tunits *tu; ! 245: char namebuf[TU_NAMESIZE]; ! 246: register char *p, *q; ! 247: int munit; ! 248: int rfd; ! 249: long labelled; ! 250: long one = 1L; ! 251: long zero = 0L; ! 252: int save_errno; ! 253: ! 254: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 255: errno = F_ERUNIT; ! 256: return(-1L); ! 257: } ! 258: ! 259: tu = &tunits[*tlu]; ! 260: if (!(tu->tu_flags & TU_OPEN)) { ! 261: errno = F_ERNOPEN; ! 262: return(-1L); ! 263: } ! 264: labelled = (tu->tu_flags & TU_LABELLED); ! 265: tclose_(tlu); ! 266: ! 267: for (p = tu->tu_name, q = namebuf; *p; p++) { ! 268: if (*p == 'n') /* norewind name */ ! 269: continue; ! 270: if (isdigit(*p)) { /* might be norewind minor dev */ ! 271: munit = 0; ! 272: while (isdigit(*p)) ! 273: munit = (10 * munit) + (*p++ - '0'); ! 274: *q++ = (munit & 03) + '0'; ! 275: while (*p) ! 276: *q++ = *p++; ! 277: break; ! 278: } ! 279: *q++ = *p; ! 280: } ! 281: *q = '\0'; ! 282: /* debug printf("rewinding [%s]\n", namebuf); /* */ ! 283: ! 284: if ((rfd = open(namebuf, 0)) < 0) ! 285: save_errno = errno; ! 286: else { ! 287: save_errno = 0; ! 288: close(rfd); ! 289: } ! 290: ! 291: topen_(tlu, tu->tu_name, &labelled, (long)strlen(tu->tu_name)); ! 292: if (labelled) { ! 293: tskipf_(tlu, &one, &zero); ! 294: tu->tu_file = 0; ! 295: } ! 296: if (save_errno) { ! 297: errno = save_errno; ! 298: return(-1L); ! 299: } ! 300: return(0L); ! 301: } ! 302: ! 303: /* ! 304: * Skip forward files ! 305: * ! 306: * NOTE: This is a kludge, to be fixed after 4.1a ! 307: */ ! 308: ! 309: long ! 310: tskipf_(tlu, nfiles, nrecs) ! 311: long *tlu; ! 312: long *nfiles; ! 313: long *nrecs; ! 314: { ! 315: struct tunits *tu; ! 316: char dummybuf[20]; ! 317: int nf; ! 318: int nr; ! 319: int nb; ! 320: int empty; ! 321: ! 322: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 323: errno = F_ERUNIT; ! 324: return(-1L); ! 325: } ! 326: ! 327: tu = &tunits[*tlu]; ! 328: if (!(tu->tu_flags & TU_OPEN)) { ! 329: errno = F_ERNOPEN; ! 330: return(-1L); ! 331: } ! 332: if (tu->tu_flags & TU_WRITING) { ! 333: errno = F_ERILLOP; ! 334: return(-1L); ! 335: } ! 336: ! 337: nf = (int)*nfiles; ! 338: while (nf > 0) { ! 339: if (tu->tu_flags & TU_EOT) { ! 340: errno = F_ERILLOP; ! 341: return(-1L); ! 342: } ! 343: if (tu->tu_flags & TU_EOF) ! 344: tu->tu_flags &= ~TU_EOF; ! 345: else { ! 346: empty = ((tu->tu_flags & TU_RDATA) == 0); ! 347: while ((nb = read(tu->tu_fd, dummybuf, sizeof dummybuf)) > 0) ! 348: empty = 0; ! 349: ! 350: if (nb < 0) { ! 351: tu->tu_flags |= TU_ERR; ! 352: return(-1L); ! 353: } ! 354: if (empty) ! 355: tu->tu_flags |= TU_EOT; ! 356: } ! 357: nf--; ! 358: tu->tu_rec = 0; ! 359: tu->tu_flags &= ~TU_RDATA; ! 360: if (tu->tu_flags & TU_EOT) ! 361: return(-1L); ! 362: else ! 363: tu->tu_file++; ! 364: } ! 365: ! 366: nr = (int)*nrecs; ! 367: while (nr > 0) { ! 368: if (tu->tu_flags & (TU_EOT|TU_EOF)) { ! 369: errno = F_ERILLOP; ! 370: return(-1L); ! 371: } ! 372: ! 373: empty = ((nb = read(tu->tu_fd, dummybuf, sizeof dummybuf)) <= 0); ! 374: if (nb < 0) { ! 375: tu->tu_flags |= TU_ERR; ! 376: return(-1L); ! 377: } ! 378: if (empty) { ! 379: tu->tu_flags |= TU_EOF; ! 380: if (!(tu->tu_flags & TU_RDATA)) ! 381: tu->tu_flags |= TU_EOT; ! 382: } else ! 383: tu->tu_flags |= TU_RDATA; ! 384: nr--; ! 385: tu->tu_rec++; ! 386: } ! 387: return(0L); ! 388: } ! 389: ! 390: /* ! 391: * Return status of tape channel ! 392: */ ! 393: ! 394: long ! 395: tstate_(tlu, fileno, recno, err, eof, eot, tcsr) ! 396: long *tlu, *fileno, *recno, *err, *eof, *eot, *tcsr; ! 397: { ! 398: struct tunits *tu; ! 399: int csr; ! 400: ! 401: if (*tlu < 0 || *tlu >= TU_MAXTAPES) { ! 402: errno = F_ERUNIT; ! 403: return(-1L); ! 404: } ! 405: ! 406: tu = &tunits[*tlu]; ! 407: if (!(tu->tu_flags & TU_OPEN)) { ! 408: errno = F_ERNOPEN; ! 409: return(-1L); ! 410: } ! 411: ! 412: *fileno = (long)tu->tu_file; ! 413: *recno = (long)tu->tu_rec; ! 414: *err = (long)((tu->tu_flags & TU_ERR) != 0); ! 415: *eof = (long)((tu->tu_flags & TU_EOF) != 0); ! 416: *eot = (long)((tu->tu_flags & TU_EOT) != 0); ! 417: #ifdef MTWEOF /* implies 4.1+ system */ ! 418: ioctl(tu->tu_fd, MTIOCGET, &mtget); ! 419: *tcsr = (long)mtget.mt_dsreg & 0xffff; ! 420: #else ! 421: ioctl(tu->tu_fd, MTIOCGET, &csr); ! 422: *tcsr = (long)csr; ! 423: #endif ! 424: return(0L); ! 425: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.