Add copyright
[unix-history] / usr / src / usr.bin / f77 / libU77 / tapeio.c
CommitLineData
58ad378e 1/*
161423a6
RE
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.
58ad378e 5 *
161423a6
RE
6 * @(#)tapeio.c 5.1 %G%
7 */
8
9/*
58ad378e
DW
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>
ecbaeb66
DW
23#ifndef MTIOCGET /* 4.1+ defines this in ... */
24#include <sys/types.h>
25#include <sys/mtio.h>
26#endif
58ad378e
DW
27#include "../libI77/f_errno.h"
28
29#define TU_NAMESIZE 22
30#define TU_MAXTAPES 4
31
32struct 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
ecbaeb66
DW
49#ifdef MTWEOF /* this implies 4.1+ ... */
50struct mtget mtget; /* controller status */
51#endif
52
58ad378e
DW
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
67long
68topen_(tlu, name, labelled, len)
69long *tlu;
70char *name;
71long *labelled;
72long 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
114long
115tclose_(tlu)
116long *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
144long
145tread_(tlu, buffer, len)
146long *tlu;
147char *buffer;
148long 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
195long
196twrite_(tlu, buffer, len)
197long *tlu;
198char *buffer;
199long 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
240long
241trewin_(tlu)
242long *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
309long
310tskipf_(tlu, nfiles, nrecs)
311long *tlu;
312long *nfiles;
313long *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
394long
395tstate_(tlu, fileno, recno, err, eof, eot, tcsr)
396long *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);
ecbaeb66
DW
417#ifdef MTWEOF /* implies 4.1+ system */
418 ioctl(tu->tu_fd, MTIOCGET, &mtget);
419 *tcsr = (long)mtget.mt_dsreg & 0xffff;
420#else
58ad378e
DW
421 ioctl(tu->tu_fd, MTIOCGET, &csr);
422 *tcsr = (long)csr;
ecbaeb66 423#endif
58ad378e
DW
424 return(0L);
425}