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: }

Defined functions

tclose_ defined in line 114; used 2 times
topen_ defined in line 67; used 1 times
tread_ defined in line 144; never used
trewin_ defined in line 240; used 1 times
tskipf_ defined in line 309; used 2 times
tstate_ defined in line 394; never used
twrite_ defined in line 195; never used

Defined variables

mtget defined in line 50; used 2 times
tunits defined in line 38; used 7 times

Defined struct's

tunits defined in line 32; used 14 times

Defined macros

TU_EOF defined in line 41; used 8 times
TU_EOT defined in line 46; used 10 times
TU_ERR defined in line 42; used 5 times
TU_LABELLED defined in line 44; used 2 times
TU_MAXTAPES defined in line 30; used 8 times
TU_NAMESIZE defined in line 29; used 3 times
TU_OPEN defined in line 40; used 8 times
TU_RDATA defined in line 47; used 6 times
TU_READONLY defined in line 43; used 2 times
TU_WRITING defined in line 45; used 3 times
Last modified: 1987-02-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3154
Valid CSS Valid XHTML 1.0 Strict