Xinu7/src/cmd/download/cmd/download.c

Compare this file to the similar file:
Show the results in this format:

/* download.c -- download */

#include "/usr/include/stdio.h"
#include "/usr/include/sgtty.h"
#include "/usr/include/ctype.h"
#include <baud.h>
#include <getdev.h>
#include "/usr/include/sys/file.h"
#include <download.h>

static	struct arglist A;
static	char execfile[MAXBIN] = {LIBPATH};

/*==============================================
 * download -- outer level of generic downloader
 *==============================================
*/
main(argc, argv)
int	argc;
char	*argv[];
{
	DevDesc	*Dev;
	int	aout_fd, ndbargs, i, j;
	char	*argvec[MAXARGS];

	initargs();		/* initialize A argument structure */
	procargs(argv, argc);	/* process arguments into struct A */
	Dev = getdev(A.class, A.machnum, A.devflags);
	if ((char *)Dev == NULL)
		exit(1);
	ndbargs = getdbargs(Dev, argvec); /* get argument field from db */
	argvec[0] = "db";		/* in case error in argument */
	procargs(argvec, ndbargs);
	using_msg(Dev, argv[0]);
	linemode(Dev->fd, A.baudrate, RAW, Dev);
	aout_fd = openfile(A.filename, O_RDONLY);
	dup2(aout_fd, AOUTFD);	/* make the a.out file the standard input */
	dup2(Dev->fd, DEVFD);	/* make the device the standard output    */
	for ( i=ndbargs+1, j=1 ; j < argc && i < MAXARGS-3 ; )
		argvec[i++] = argv[j++];
	argvec[i++] = Dev->machine;
	argvec[i++] = Dev->locknm;
	if (i == MAXARGS) {
		fprintf(stderr,"%s: too many arguments\n", argv[0]);
		exit(1);
	}
	argvec[i] = NULL;
	strncat(execfile, ((A.downloader == NULL) ? get_download(Dev->machine)
			: A.downloader), MAXBIN - strlen(execfile) - 1);
	argvec[0] = execfile;
	if (A.verbose)
		fprintf(stderr,"exec binary %s\n",execfile);
	execv(execfile, argvec); /* run the downloader specified in db */
	perror(execfile);	/* execv failed */
}
	
/*
 *======================================================================
 * procargs - parse and check command line, modifying global A structure
 *======================================================================
 */
procargs(argv, argc)
char *argv[];
int argc;
{
	int arg, i;
	int unswitched;

	unswitched = 0;
	for ( arg=1 ; arg < argc ; arg++ ) {
		if ( argv[arg][0] == '-' ) {
			switch ( argv[arg][1] ) {
			case 'c':
				A.class = argv[arg]+2;
				break;
			case 'l':
				for (i=2; argv[arg][i] != '\0'; i++)
					if (!isdigit(argv[arg][i]&LOWBYTE))
						usagexit(argv[0]);
				A.machnum=atoi(argv[arg]+2);
				break;
			case 'B':
				if (*(argv[arg]+2) == '\0') {
					A.baudrate = NOBAUD;
					break;
				}
				for (i = 0; i < NBAUD; ++i)
					if (strcmp(baudlist[i].name,
						argv[arg]+2) == 0)
							break;
				if (i < NBAUD)
					A.baudrate = baudlist[i].rate;
				else {
					fprintf(stderr,
						"Unknown baud rate: %s\n",
						argv[arg]+1);
					exit(1);
				}
				break;
			case 'h':
				A.devflags |= GD_HLDDEVS;
				break;
			case 'e':
				A.reloadether = TRUE;
				break;
			case 'd':
				A.downloader = argv[arg]+2;
				break;
			case 'v':
				A.verbose = TRUE;
				break;
			case 's':
				A.silent = TRUE;
				break;
			case 'a':
				for (i=2; argv[arg][i] != '\0'; i++)
					if (!isdigit(argv[arg][i]&LOWBYTE))
						usagexit(argv[0]);
				break;
			default:
				usagexit(argv[0]);
			}
		} else { /* ( argv[arg][1] != '-' ) */
			switch ( unswitched++ ) {
			case 0:
				A.filename = argv[arg];
				break;
			default:
				usagexit(argv[0]);
			}
		}
	}
}

/*======================================================
 * initargs - set A structure to initial values
 *======================================================
*/
initargs()
{
	A.filename  = DEFFILE;
	A.baudrate = B9600;
	A.class = NULL;
	A.downloader = NULL;
	A.machnum = GD_ANYDEV;
	A.devflags = FALSE;
	A.reloadether = FALSE;
	A.verbose = FALSE;
	A.silent = FALSE;
	A.autostart = FALSE;
	A.startdelay = 0;
}

/*===========================================================
 * getdbargs - add argument string from database db to argvec
 *===========================================================
*/
getdbargs(Dev, argvec)
DevDesc *Dev;
char	*argvec[];
{
	char	*arglist;
	int	nargs;

	if (Dev != NULL) {
		arglist = get_args(Dev->class);
		arglist = skip_white(arglist);
		for (nargs = 1; *arglist != NULL && *arglist != QUOTE; ) {
			argvec[nargs++] = arglist;
			while( *arglist != NULL && *arglist != QUOTE &&
			      index(FIELD_END, *arglist) == 0 )
				arglist++;
			if (*arglist != NULL)
				*arglist++ = NULL;
			arglist = skip_white(arglist);
		}
	}
	return(--nargs);
}

/*
 *======================================================================
 * using_msg - print a message saying which dev is being downloaded to
 *======================================================================
*/
using_msg(Dev, sbProg)
DevDesc	*Dev;
char	*sbProg;
{
	if (Dev == NULL) {
		if (A.verbose)
			fprintf(stderr, "No devices Available.\n");
		exit(1);
	} else if (!A.silent && !A.verbose)
		printf("Using %s\n", shortname(Dev->machine));
	else if (A.verbose)
		printf("%s: Downloading to %s\n", sbProg, Dev->machine);
}

/*
 *=======================================
 * linemode - set up linemode and speed
 *=======================================
 */
linemode(fd,speed,mode,Dev)
int fd, speed, mode;
DevDesc	*Dev;
{
	struct sgttyb tcb;
	if ( gtty(fd,&tcb) < 0 ) {
		perror(get_name(Dev->machine));
		exit(1);
	}
	if (speed != NOBAUD)
		tcb.sg_ispeed = tcb.sg_ospeed = speed;
	tcb.sg_flags = mode;
	stty(fd,&tcb);
}

/*
 *==========================================
 * usagexit - print usage message and exit
 *==========================================
 */
usagexit(pgm)
char *pgm;
{
	fprintf(stderr,
	"usage: %s [filename] [-cCLASS] [-lMACHINE#] [-a[delay]] [-Bbaudrate] [-ddownloader] [-v] [-h] [-s] [-e]\n",
	pgm);
	exit(1);
}

/*
 *==========================================================
 * openfile - try to open file, exit with message if error
 *==========================================================
 */
openfile(name,mode)
char *name;
int mode;
{
	int fd;

	if ((fd=open(name,mode,0)) < 0 ) {
		perror(name);
		exit(1);
	}
	return(fd);
}