ftp.nice.ch/pub/next/unix/audio/Cmix.N.s.tar.gz#/cmix/tape.backup/sfbackup.c

This is sfbackup.c in view mode; [Download] [Up]

/* Program to backup one or more soundfiles onto a magtape */
/* confusion about skipfile, tapefile, now that label is there */
/* do I want to specify the file to start with, or the files to skip ? */
#include "../H/sfheader.h"
#include <stdio.h>
#include <strings.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/mtio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <signal.h>
#include <errno.h>
#include <pwd.h>
#include "label.h"
#define  BUFSIZE 32768 

char tapename[16] = "/dev/rxt0";
char *usefile;

main(argc,argv)

int argc;
char *argv[];

{
	SFHEADER sfh1;
	struct stat sfst1;
	struct mtget mtget ;
	struct mtop mtop ;
	struct passwd *pwst,*getpwuid();
	struct label label;

	char *cp,*sfin,*getsfcode();
	char buffer[BUFSIZE];
	int grandtotal,totalbytes,allbytes,allt,i,j,result,temp,inbytes;
	int sf1,tapeunit,tapefile,skipfile,tapenumber,headersize;
	float duration;

	char *catname,catholder[128],*chbptr,charbuff[500];
	char *tmpname,tmpholder[14];
	char *getenv(),*ctime();
	FILE *fdcat,*fdtmp;
	struct tm *tmm,*localtime();

	if(argc == 1) { 
usage:	printf("Usage: -l [tapenumber] -s [number tape files to skip first] -f [device to use] sf1 .... sfn\nDefaults: skip over label only, use /dev/rmt0\n");
		exit(1);
	}

	chbptr = charbuff;
	chbptr = strcpy(chbptr,"test -d ");
	chbptr = strcat(chbptr,getenv("HOME"));
	chbptr = strcat(chbptr,"/catalogs");
	if (system(chbptr) != 0) {
		fprintf(stderr,
	"\n\nShame on you! You need a directory called 'catalogs' in\n");
		fprintf(stderr,
	"your home directory to run this program! Sorry.....\n\n\n");
		exit(-3);
		}

	catname = catholder;
	tmpname = tmpholder;
	tmpname = getenv("HOME");
	catname = strcpy(catname,tmpname);
	catname = strcat(catname,"/catalogs/");
	tmpname = strcpy(tmpname,"/tmp/");

	tapenumber = 0;
	usefile = tapename;
	grandtotal = skipfile = allbytes = 0;
	tapefile = 0;
	system("date");

	while((*++argv)[0] == '-') {
		argc -= 2; /* Take away two args */
		for(cp = argv[0]+1; *cp; cp++) {
			switch(*cp) { /* Grap options */
			case 'f': 
				usefile = *++argv;
				break;
			case 's':
				tapefile = atoi(*++argv)-1;
				/* now specifies files to skip -1 since 
				   label is always read */
				skipfile = tapefile ? 1 : 0;
				break;
			case 'l':
				tapenumber = atoi(*++argv);
				catname = strcat(catname,*argv);
				catname = strcat(catname,".catlg");
				tmpname = strcat(tmpname,*argv);
				break;
			default :
				printf("unknown option\n");
				goto usage;
			}
		}
	}
	if(!tapenumber) {
		printf("You didn't specify a tape number with -l flag\n");
		exit(-1);
	}

	if((tapeunit = open(usefile,2)) < 0) {
		printf("trouble opening tape unit\n");
		exit(tapeunit);
	}
	if(read(tapeunit,&label,SIZEOFLABEL) != SIZEOFLABEL) {
		printf("Can't seem to read the label on this tape\n");
		exit(tapeunit);
	}

	if(label.tapenumber != tapenumber) {
		printf
		("this is tape number %d, you are asking for tape number %d\n"
		,label.tapenumber,tapenumber);
		exit(tapeunit);
	}

	if(getuid() != 0) {  /* allow root access */
		if(label.owner_uid != getuid()) {
			printf("This tape doesn't belong to you!\n");
			exit(tapeunit);
		}
	}

	mtop.mt_op = MTFSF;
	mtop.mt_count = 1;
	if((ioctl(tapeunit,MTIOCTOP,&mtop)) == -1) {
		printf("error forward spacing tape past label eof\n");
		exit(-2);
	}

	printf("Comment on tape %d: %s\n",label.tapenumber,label.comment);

	if ((fdtmp = fopen(tmpname,"w")) == NULL) {
		fprintf(stderr,"uh-oh, can't make the temp catalog!\n");
		exit(-3);
		}

	pwst = getpwuid(label.owner_uid);
	fprintf(fdtmp,
	"TAPE NUMBER: %d\t\tOwner: %s\n",label.tapenumber,pwst->pw_name);
	fprintf(fdtmp,
"Initialization date: %sComment: %s\n\n",ctime(&label.date),label.comment);

	fputs("file# dur\t chans class   nbytes\t  creation date     name\n",fdtmp);

	for(i=0; i<argc-1; i++) {
		sfin = argv[i];
		drwopensf(sfin,sf1,sfh1,sfst1,"sfbackup",result,0)
		headersize = getheadersize(&sfh1);
		printf("headersize = %d\n",headersize);
		if(result<0) exit(-99);
		printf("name: %s   sr: %f   nchans: %d  class: %d\n",sfin,
		sfsrate(&sfh1),sfchans(&sfh1),sfclass(&sfh1));
		if(headersize == SIZEOF_NeXT_HEADER) 
			  printf("This is a native NeXT soundfile\n");

/*****************
		readopensf(sfin,sf1,sfh1,sfst1,"sfbackup",result);
		if(result < 0) {
			close(sf1);
			fprintf(stderr,
			"Yo! There ain't no file called %s!\n",sfin);
			exit(-3);
		}
*********************/
		printf("-------------------------------------------------\n");
		printf(":::::::::::::Backup file %s\n",sfin);
		totalbytes = 0;

		printsf(&sfh1);

		if(skipfile) {
			mtop.mt_op = MTFSF;
			mtop.mt_count = tapefile;
			if((ioctl(tapeunit,MTIOCTOP,&mtop)) == -1) {
				printf("error forward spacing tape\n");
				exit(-2);
			}
			if ((fdcat = fopen(catname,"r")) != NULL) {
				for (j = 0; j < 5; j++) /* get past old hdr */
					fgets(chbptr,500,fdcat); 
				for (j = 0; j < tapefile; j++) {
					fgets(chbptr,128,fdcat);
					sscanf(chbptr, 
						"%*d %*f %*d %*d %d",&allt);
					allbytes += allt;
					fputs(chbptr,fdtmp);
					}
				fclose(fdcat);
				}
			else {
				fprintf(stderr,
					"Can't open the old catalog!\n");
				exit(-3);
				}
		}
		skipfile = 0;

		if(lseek(sf1,0,0) < 0) {
			printf("bad lseek on soundfile\n");
			exit(-1);
		}

		while(1) {
			if((inbytes = read(sf1,(char *)buffer,BUFSIZE)) <= 0) {
				printf("reached eof on input\n");
				close(sf1);
				break;
			}
			if((temp=write(tapeunit,(char *)buffer,inbytes)) != inbytes) {
				printf("Bad write on tape file, bytes=%d\n",temp);
				close(sf1);
				closetape(tapeunit);
				exit(0);
			}
			totalbytes += inbytes;
		}
		duration = 
			(float)totalbytes/(float)sfclass(&sfh1)/
				(float)sfchans(&sfh1)/sfsrate(&sfh1);
		tapefile++;
		printf("Bytes dumped = %d, duration = %f, tapefile = %d\n",
				totalbytes,duration,tapefile+1);

		tmm = localtime(&sfst1.st_mtime);
		fprintf(fdtmp,
"%3d   %.4f\t   %d     %d   %9d\t%02d:%02d:%02d %2d/%02d/%2d  %s\n",tapefile+1,duration,sfchans(&sfh1),sfclass(&sfh1),totalbytes,tmm->tm_hour,tmm->tm_min,tmm->tm_sec,(tmm->tm_mon)+1,tmm->tm_mday,tmm->tm_year,sfin);

		grandtotal += totalbytes;
		fflush(stdout);
		close(sf1);
		closetape(tapeunit);

		if (i < argc-2) {
			fclose(fdtmp);
			chbptr = strcpy(chbptr,"cp ");
			chbptr = strcat(chbptr,tmpname);
			chbptr = strcat(chbptr," ");
			chbptr = strcat(chbptr,catname);
			system(chbptr);
			if ((fdtmp = fopen(tmpname,"a")) == NULL) {
				fprintf(stderr,"Can't reopen tmp catalog!\n");
				exit(-3);
				}
			}
	}

	fprintf(fdtmp,
		"Total bytes used on this tape: %d\n",allbytes+grandtotal);
	fclose(fdtmp);
	chbptr = strcpy(chbptr,"cp ");
	chbptr = strcat(chbptr,tmpname);
	chbptr = strcat(chbptr," ");
	chbptr = strcat(chbptr,catname);
	system(chbptr);

	close(tapeunit); /* I believe that there will now be three eofs */
	printf("Total bytes dumped this run = %d\n",grandtotal);
}
closetape(unit)
{
	struct mtop mtop ;
	/* write two eofs and backspace inbetween them.
	   this will allow /dev/rmt0 to be used, which will
	   automatically rewind on close */

	mtop.mt_op = MTWEOF;
	mtop.mt_count = 2;
	if((ioctl(unit,MTIOCTOP,&mtop)) == -1) {
		printf("error writing eofs\n");
		exit(-2);
	}
	mtop.mt_op = MTBSF;
	mtop.mt_count = 1;
	if((ioctl(unit,MTIOCTOP,&mtop)) == -1) {
		printf("error spacing past eof\n");
		exit(-2);
	}
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.