home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume22
/
ftape
/
part01
/
ftapewrite.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-09-04
|
6KB
|
216 lines
#ifndef lint
static char sccs_id[] = "@(#)2.4 ftapewrite.c 91/09/03 FAST TAPE WRITE";
#endif
/*
* Original author: Kari Yli-Kuha, SQ Consulting Ltd.
* Address: Kanslerinkatu 8, 33720 Tampere, Finland
* Phone: (358) 31 165200
*
* Reads from shared memory buffers and writes to tape.
*
* Handles tape changing if we're attached to terminal, otherwise exits
*
* There seems to be no reliable way to determine tape ending with
* ISC 386/ix Wangtek tape driver other then counting the bytes written
* to the tape - and even that ain't reliable. We're doing the counting here.
* DON'T use cheap tapes - I've had all sorts of trouble with them.
*
* The last buffer which didn't fit in the tape is rewritten to the new tape.
*/
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <ctype.h>
#include "ftape.h"
extern void perror(), exit();
extern char *strrchr();
extern int errno;
extern struct SHBUF *shbuf; /* shared memory */
void quit(); /* signal catching */
static char *progname; /* name of this program */
/*
* main
*/
main(argc, argv)
int argc;
char *argv[];
{
extern int optind; /* option index */
extern char *optarg; /* option's argument */
int opt; /* current option */
char *tape_device = TAPE; /* default tape device */
int shbufs = SHBUFS; /* default # of buffers */
int fdtape; /* tape device file descriptor */
unsigned written = 0; /* # of bytes written to tape */
int nread = 0; /* # of bytes in shared memory buffer */
int nbuf = 0; /* # of buffer we currently use */
struct SHBUF *buf; /* ptr to current buffer */
FILE * ttyin, *ttyout; /* terminal (if any) */
int debug = 0; /* default: nodebug */
int n; /* local */
char *cp; /* local */
progname = ((cp = strrchr (argv[0], '/')) ? cp+1 : argv[0]);
/* options */
while ( (opt = getopt(argc, argv, "dn:f:")) != EOF ) {
switch (opt) {
case 'n': /* # of buffers */
shbufs = atoi(optarg);
if (shbufs <= 0) {
(void) fprintf (stderr, "%s: too few buffers: %d\n", progname, shbufs);
exit(1);
}
break;
case 'f':
tape_device = optarg;
break;
case 'd':
debug++;
break;
default: /* unknown option */
(void) fprintf (stderr, "%s: unknown option -- %c\n", progname, opt);
exit(1);
break;
}
}
/* catch signals */
for (n = 0; n < NSIG; n++)
(void) signal (n, quit);
/*
* Try to attach to terminal if possible.
* It may not be possible if we're running in background
* or started by 'cron'.
*/
ttyin = fopen ("/dev/tty", "r");
ttyout = fopen ("/dev/tty", "w");
/* attach to shared memory */
if (attach_shared(tape_device) == -1)
exit (1);
/* open tape */
if ((fdtape = open(tape_device, O_WRONLY, 0777)) == -1) {
(void) fprintf (stderr, "\n Could not open tape\n");
exit (1);
}
/*
* loop until all data is written to the tape
*/
nbuf = 0;
buf = shbuf;
while (1) {
semdown (BUFFERS_AVAIL, 1);
if (buf->nread == 0) /* end of data */
break;
nread = buf->nread;
if (!nread) /* empty buffer */
break;
DEBUG fprintf (ttyout, "%s: READ %-6d", progname, nread), fflush(ttyout);
errno = 0; /* clear errno, write doesn't do it */
written = write (fdtape, (char *)buf->buf, nread);
if (errno == EINTR) {
(void) fprintf (stderr, "Write to tape failed\n");
perror ("write");
exit (1);
}
DEBUG fprintf (ttyout, "%s: WRITTEN %d bytes, errno %d \r",
progname, written, errno), fflush(ttyout);
if ( written != nread) {
/*
* We obviously ran to EOM - close the tape, reopen after changing
* the tape and rewrite rest of the buffer.
*/
(void) close(fdtape);
if (ttyin && ttyout)
fdtape = change_tape(ttyin, ttyout, tape_device);
else {
(void) fprintf (stderr, "Reached end of medium.\n");
(void) fprintf (stderr, "No controlling terminal. Exit.\n");
exit(1);
}
/*
* write the rest of the buffer and continue.
*/
(void) write (fdtape, (char *)buf->buf+written, nread-written);
DEBUG fprintf (ttyout, "\n%s: WRITTEN %d bytes, errno %d\n",
progname, written, errno);
}
semup (BUFFERS_FREE, 1);
nbuf++; buf++;
if (nbuf >= shbufs) {
nbuf = 0;
buf = shbuf;
}
}
(void) close (fdtape);
exit (0);
/*NOTREACHED*/
return (0);
}
/*
* Signal interrupt is written to stderr
* exit() called with sig as parameter
*/
void quit(sig)
int sig;
{
if (sig > 0)
fprintf (stderr, "%s: exit signal %d\n", progname, sig);
exit (sig);
}
/*
* change_tape
*/
change_tape(ttyin, ttyout, device)
FILE *ttyin, *ttyout;
char *device;
{
static char inbuf[BUFSIZ];
int (fdtape);
(void) fprintf (ttyout, "\nReached end of medium.\n");
(void) fprintf (ttyout, "Change tape after the light is off.\n");
while (1) {
(void) fprintf (ttyout, "Press 'y' <RETURN> to continue: ");
fgets (inbuf, sizeof(inbuf), ttyin);
if (tolower(inbuf[0]) != 'y') {
(void) fprintf (ttyout, "\007"); /* BEEP - illegal reply */
continue;
}
if ((fdtape = open(device, O_WRONLY, 0777)) != -1)
break;
(void) fprintf (ttyout, "\007Could not open tape for writing.\n");
(void) fprintf (ttyout, "Check if it's write protected.\n");
}
return fdtape;
}