#!/usr/local/bin/icmake -qi

/* Here are some things you might like to change: */
/* remote tape device and the host where tape device is */
#define TAPEDEV		"/dev/rst0"
#define TAPEHOST	"beatrix"
/* local tape device */
#define PIPE		"/tmp/tape"		
/* username by which tar backup gets sent */
#define USERNAME	"karel"
/* blocksize to be used in remote dd command */
#define BLOCKSIZE	"10k"
/* remote command: rsh for linux/BSD, rcmd for SYSV */
#define REMOTECMD 	"rsh"
/* compression: " -z" for gzip, " -Z" for compress, "" for none */
/* note the leading space in the string */
#define COMPRESS " -z"

/* Don't change the remainder of this file. */
#define VER 		"1.02"
#define TOTAPE		0
#define FROMTAPE	1

int
    verbose;					/* 0: not verbose, 1: ver */
    
list remove_element (list l, int index)		/* remove element #index */
{						/* from list l */
    int
    	i;					/* counter */
    list
    	ret;					/* returned list */
    	
    for (i = 0; i < sizeof (l); i++)		/* loop thru source list */
    	if (i != index)				/* add elements to dest */
    	   ret += (list) element (i, l);	/* except for #index */
    	   
    return (ret);				/* return dest list */
}
    
void run_system (string sys, int dir)		/* execute tar string, print */
{						/* string if verbose */
    string
    	redir,					/* local redirection for tar */
    	dddir;					/* remote redirection for dd */
    	
    if (dir == TOTAPE)				/* set redir string */
    {
    	dddir = "obs=" + BLOCKSIZE + " of";	/* for remote command */
    	redir = "<";				/* for local command */
    }
    else
    {
    	dddir = "ibs=" + BLOCKSIZE + " if";	/* for remote command */
    	redir = ">";
    }
    	
    if (verbose)				/* show cmds if verbose */
    	printf ("backup: establishing remote drive interface\n");
    
    exec ("su", "-", USERNAME, "-c", 		/* run a command as USERNM */
          "\"",	
	      REMOTECMD, TAPEHOST, 		/* cmd to run is rsh */
	          "dd", dddir + "=" + TAPEDEV, 	/* rsh should do a dd */
	   	        "conv=sync",
	  "\"", redir, PIPE, "&");		/* cmd should read PIPE */
						/* and must run in backgr */
						
    if (verbose)				/* verbose msg */
    	printf ("backup: starting ", sys, "\n");
    		  			
    system (sys);				/* run local tar cmd */
}

string makecmd (string opt, list files, 	/* make tar system */
		int needverbose)		/* command */
{
    string
    	sys;					/* the system string */
    int 
    	i;					/* loop cntr */
    	
    sys = "tar --" + opt;			/* first tar option */
    if (needverbose)
    	sys += " --verbose";			/* verbose if requested */
    	
    sys += COMPRESS;				/* compression, if needed */
    	
    sys += " --file " + PIPE;			/* local tape pipe */
    
    for (i = 0; i < sizeof (files); i++)	/* files to process */
    	sys += " " + element (i, files);
    	
    return (sys);				/* system string is */
}						/* returned */

void backup (list dirs)				/* writes files/dirs to */
{						/* tape device */
    string
    	sys;					/* tar cmd */
    	
    if (! dirs)					/* check if argument */
    {						/* present */
    	printf ("backup: store needs directory or file argument(s)\n");
    	exit (1);
    }
    
    sys = makecmd ("create", dirs, 1);		/* the system string */
    run_system (sys, TOTAPE);			/* here goes.. */
}

void listtape (list files)
{
    string
    	sys;					/* system() string */
    	
    sys = makecmd ("list", files, verbose);	/* the system command */
    run_system (sys, FROMTAPE);
}

void extract (list files)
{
    string
    	sys;
    	
    sys = makecmd ("extract", files, verbose);	/* system() string */
    run_system (sys, FROMTAPE);
}

void usage ()
{
    printf ("\n"
    	    "ICCE Tar/Tape Backup Facility  V", VER, "\n"
    	    "Copyright (c) ICCE 1993. All rights reserved.\n"
    	    "\n"
    	    "Backup by Karel Kubat.\n"
    	    "\n"
    	    "Usage: backup [-v] operation [arguments]\n"
    	    "where:\n"
    	    "    -v flag                     : verbose operation\n"
    	    "    operation and arguments     : specify what to do, one of:\n"
    	    "        store file(s) or dir(s) : to backup to tape\n"
    	    "        list [file(s)]          : to list contents of the tape\n"
    	    "        restore [file(s)]       : to extract file(s) from tape\n"
    	    "\n"
    	    "Currently active defaults:\n"
    	    "\n"
    	    "Remote tape device: ", TAPEDEV, "\n"
    	    "Remote tape host  : ", TAPEHOST, "\n"
    	    "Used username     : ", USERNAME, "\n"
    	    "Piping device     : ", PIPE, "\n"
    	    "\n");
}

void prepare_tape ()
{
    if (! exists (PIPE))
    	exec ("su", USERNAME, "-c", "\"mknod " + PIPE + " p\"");
}

void terminate_tape ()
{
    if (exists (PIPE))
    	exec ("su", USERNAME, "-c", "\"rm -f " + PIPE + "\"");
}

void main (int argc, list argv, list envp)
{
    string
    	selector;				/* option of program */
    	
    echo (0);					/* no cmds re-echoing */
    	
    argv = remove_element (argv, 0);		/* remove makefile name */
    selector = element (0, argv);		/* get selector */
    
    if (selector == "-v")			/* if this is the -v flag: */
    {
    	verbose++;				/* verbose requested */
    	argv = remove_element (argv, 0);	/* remove it */
    	selector = element (0, argv);		/* get new selector */
    }
    
    argv = remove_element (argv, 0);		/* remove selector */

    if (selector == "store")			/* take action according */
    {						/* to selector */
    	prepare_tape ();
    	backup (argv);				
    	terminate_tape ();
    }
    else if (selector == "list")
    {
    	prepare_tape ();
    	listtape (argv);
    	terminate_tape ();
    }
    else if (selector == "restore")
    {
    	prepare_tape ();
    	extract (argv);
    	terminate_tape ();
    }
    else
    	usage ();
    	
    exit (0);					/* done. */
}
