[comp.os.minix] lorder & tsort & ar for minix

walls@killer.UUCP (Monty Walls) (02/11/88)

--------------------------------------------------------------------------

	Enclosed is tsort (source & man), lorder (source, man & exe), 
ar (reposting of v7 compatible source & man), libupack (diff fixes bug).  
Some slight changes had to be made to my original posting of ar to 
support a 'pv' option.  The addition of support for 'pv' in ar allows
lorder to read in a simple way ar archives.  If you want to recompile
lorder you will need the decus lex program (check your local bbs it
should already be posted on one of them.  minix can run & compile it).
					-Monty Walls
------------------------CUT HERE------------------------------------------
echo x - ar.c
gres '^X' '' > ar.c << '/'
X/* ar - archiver		Author: Michiel Huisjes */
X/* V7 upgrade			Author:	Monty Walls */
X
X/*
X * Usage: ar 'key' [posname] archive [file] ...
X *
X *	where 'key' is one of: qrqtpmx
X *
X *	  q: quickly append to the end of the archive file
X *	  m: move named files 
X *	  r: replace (append when not in archive)
X *	  d: delete
X *	  t: print contents of archive
X *	  p: print named files
X *	  x: extract
X *
X *	concatencated with one or more of: vuaibcl
X *  
X *	  l: local temporary file for work instead of /tmp/ar.$$$$$
X *	  v: verbose
X *	  a: after 'posname'
X *	  b: before 'posname'
X *	  i: before 'posname'
X *	  c: create  (suppresses creation message)
X *	  u: replace only if dated later than member in archive
X */
X
X/* mods:
X *	1.2 upgrade.
X *	local directory support	(mrw).
X *	full V7 functionality + complete rewrite (mrw).
X *	changed verbose mode to give member name on print (mrw).
X *
X * notes:
X *	pdp11 long format & Intel long format are different.
X */
X
X/* include files */
X#include <stdio.h>
X#include <sys/stat.h>
X#include <signal.h>
X#include <ar.h>
X
X/* macro functions */
X#define FOREVER		(32766)
X#define odd(nr)		(nr & 1)
X#define even(nr)	(odd(nr) ? nr + 1 : nr)
X#define quit(pid,sig)	(kill(pid,sig),sleep(FOREVER))
X#ifndef tell 
X#	define tell(f)	(lseek(f, 0l, 1))
X#endif
X
X/* option switches */
X/* major options */
X#define EXTRACT		0x01
X#define REPLACE		0x02
X#define PRINT		0x04
X#define TABLE		0x08
X#define DELETE		0x10
X#define APPEND		0x20
X#define MOVE		0x40
X
X/* minor options */
X#define BEFORE		0x01
X#define AFTER		0x02
X#define LOCAL		0x01
X#define VERBOSE		0x01
X#define CREATE		0x01
X#define ONLY		0x01
X
X/* mode bits maps */
X#define EXEC_OWNER	00001
X#define EXEC_GROUP	00010
X#define EXEC_ALL	00100
X#define READ_OWNER	00004
X#define READ_GROUP	00040
X#define READ_ALL	00400
X#define WRITE_OWNER	00002
X#define WRITE_GROUP	00020
X#define WRITE_ALL	00200
X#define SET_UID		04000
X#define SET_GID		02000
X
X/* global defines */
X#define BUFFERSIZE	4096
X#define WRITE		2		/* both read & write */
X#define READ		0
X#define MAGICSIZE	sizeof(short)	/* size of magic number in file */
X
X/* option switches */
Xchar verbose = 0;
Xchar local = 0;
Xchar create = 0;
Xchar only = 0;
Xchar major = 0;
Xchar minor = 0;
X
X/* global variables */
Xchar *tmp1;
Xchar *tmp2;
Xchar *progname;
Xchar *posname = NULL;
Xchar *afile;
Xchar buffer[BUFFERSIZE];
Xlong pos_offset = -1;
Xint mypid;
X
X/* keep track of member moves using this struct */
Xstruct mov_list {
X	long pos;
X	struct mov_list *next;
X} *moves = NULL;
X
X/* forward declarations and external references */
Xextern char *malloc();
Xextern char *mktemp(), *rindex();
Xextern int strcmp();
Xextern print_date();
Xextern user_abort(), usage();
Xextern long lseek();
X
Xint
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int ac, opts_seen = 0, rc;
X	char *av;
X	
X	progname = argv[0];		
X	if (argc < 3) 
X		usage();
X
X	for (av = argv[1]; *av; ++av) {	
X		switch (*av) {		/* major option */
X			case 'q':
X				major |= APPEND;
X				++opts_seen;
X				break;
X			case 'r':
X				major |= REPLACE;
X				++opts_seen;
X				break;
X			case 'x':
X				major |= EXTRACT;
X				++opts_seen;
X				break;
X			case 'p':
X				major |= PRINT;
X				++opts_seen;
X				break;
X			case 'm':
X				major |= MOVE;
X				++opts_seen;
X				break;
X			case 'd':
X				major |= DELETE;
X				++opts_seen;
X				break;
X			case 't':
X				major |= TABLE;
X				++opts_seen;
X				break;
X			case 'l':
X				local |= LOCAL;
X				break;
X			case 'a':
X				minor |= AFTER;
X				break;
X			case 'i':
X			case 'b':
X				minor |= BEFORE;
X				break;
X			case 'v':
X				verbose |= VERBOSE;
X				break;
X			case 'c':
X				create |= CREATE;
X				break;
X			case 'u':
X				only |= ONLY;
X				break;
X			default:
X				usage();
X		}
X	}
X
X	if (opts_seen != 1) 
X		usage();
X
X	/* now do edits on options */
X	if (!(major & (REPLACE | MOVE))) {
X		if (minor & (AFTER | BEFORE))
X			usage();
X	}
X	else if (major & MOVE) {
X		if (!(minor & (AFTER | BEFORE)))
X			usage();
X	}
X	else if (only & ONLY)
X		if (!(major & REPLACE))
X			usage();
X	
X	if (local) 
X		tmp1 = mktemp("./ar.1.XXXXXX");
X	else
X		tmp1 = mktemp("/tmp/ar.1.XXXXXX");
X			
X	/* now if minor says AFTER or BEFORE - then get posname */
X	if (minor & (AFTER | BEFORE) && argc >= 4) {
X		posname = argv[2];
X		afile = argv[3];
X		ac = 4;
X	}
X	else {
X		posname = (char *)NULL;
X		afile = argv[2];
X		ac = 3;
X	}
X	
X	/* exit logic consists of doing a kill on my pid to insure that we */
X	/* get the current clean up and exit logic */
X	mypid = getpid();	
X	signal(SIGINT, user_abort);
X	
X	switch (major) {
X		case REPLACE:
X		case DELETE:
X		case MOVE:
X			ar_members(ac, argc, argv);
X			break;
X		case EXTRACT:
X		case TABLE:
X		case PRINT:
X			ar_common(ac, argc, argv);
X			break;
X		case APPEND:
X			append_members(ac, argc, argv);
X			break;
X		default:
X			usage();
X	}
X
X	for (rc = 0; ac < argc; ++ac) {
X		if (*argv[ac] != '\0') {
X			/* no processing done on this name */
X			fprintf(stderr,"Error %s: %s not found in ar\n", progname, argv[ac]);
X			rc = 1;
X		}
X	}
X	fflush(stdout);
X	exit(rc);
X}
X
Xusage()
X{
X	fprintf(stderr,"Usage: %s [qrxdpmt][abivulc] [posname] afile name ... \n",progname);
X	exit(1);
X}
X
Xuser_abort()
X{
X	unlink(tmp1);
X	exit(1);
X}
X
Xinsert_abort()
X{
X	unlink(tmp1);
X	unlink(tmp2);
X	exit(1);
X}
X
Xmwrite(fd, address, bytes)
Xint fd;
Xregister char *address;
Xregister int bytes;
X{
X  if (write(fd, address, bytes) != bytes) {
X	fprintf(stderr," Error: %s - Write error\n",progname);
X	quit(mypid, SIGINT);
X  }
X}
X
Xlong
Xswap(l)
Xlong l;
X{
X	union {
X		struct {
X			int word1, word2;
X		} words;
X		long n;
X	} u_in, u_out;
X	
X	u_in.n = l;
X	u_out.words.word1 = u_in.words.word2;
X	u_out.words.word2 = u_in.words.word1;
X	return (u_out.n);
X	
X}
X
Xaddmove(pos)
Xlong pos;
X{
X	struct mov_list *newmove;
X
X	newmove = (struct mov_list *)malloc(sizeof(struct mov_list));
X	newmove->pos = pos;
X	newmove->next = moves;
X	moves = newmove;		
X}
X
Xstruct ar_hdr *
Xget_member(fd)
Xint fd;
X{
X	int ret;
X	static struct ar_hdr member;
X	
X	if ((ret = read(fd,  &member, sizeof(struct ar_hdr))) <= 0) 
X		return ((struct ar_hdr *)NULL);
X	if (ret != sizeof(struct ar_hdr)) {
X		fprintf(stderr,"Error: ar corrupted archive ar\n");
X		quit(mypid,SIGINT);
X	}
X
X	/* the archive long format is pdp11 not intel
X	 * therefore we must reformat them for our internal use
X	 */
X
X	member.ar_date = swap(member.ar_date);
X	member.ar_size = swap(member.ar_size);
X	return (&member);
X}
X
Xint
Xopen_archive(filename, opt, to_create)
Xchar *filename;
Xint opt;
X{
X	static unsigned short magic;
X	int fd;
X	
X	/* to_create can have values of 0,1,2 */
X	/* 0 - don't create a file. */
X	/* 1 - create file but use create switch message mode */
X	/* 2 - create file but don't talk about it */
X	
X	if (to_create) {
X		if ((fd = creat(filename, 0644)) < 0) {
X			fprintf(stderr, "Error: %s can not create %s\n",progname, filename);
X			quit(mypid,SIGINT);
X		}
X		if (!create && to_create == 1) fprintf(stderr, "%s:%s created\n", progname, filename);
X		magic = ARMAG;
X		mwrite(fd, &magic, MAGICSIZE);
X		return (fd);
X	}
X	else {
X		if ((fd = open(filename, opt)) < 0) {
X			if (opt == WRITE) 
X				return (open_archive(filename, opt, 1));
X			else {
X				fprintf(stderr, "Error: %s can not open %s\n",progname, filename);
X				quit(mypid,SIGINT);
X			}
X		}
X		/* now check the magic number for ar V7 file */
X		lseek(fd, 0l, 0);
X		read(fd, &magic, MAGICSIZE);
X		if (magic != ARMAG) {
X			fprintf(stderr, "Error: not %s V7 format - %s\n",progname, filename);
X			quit(mypid,SIGINT);
X		}
X		if (major & APPEND)
X			lseek(fd, 0l, 2);	/* seek eof position */
X			
X		return (fd);
X	}		
X}
X
X
Xint
Xrebuild(fd, tempfd)
Xregister int fd, tempfd;
X{
X	register int n;
X
X	/* after we have built the archive to a temporary file and */
X	/* everything has worked out- we copy the archive back to */
X	/* original file */
X		
X	signal(SIGINT, SIG_IGN);
X	close(fd);
X	close(tempfd);
X	fd = open_archive(afile, WRITE, 2);
X	tempfd = open_archive(tmp1, WRITE, 0);
X	while ((n = read(tempfd, buffer, BUFFERSIZE)) > 0) 
X		mwrite(fd, buffer, n);
X	close(tempfd);
X	unlink(tmp1);
X	return (fd);
X}
X
Xprint_mode(mode)
Xshort mode;
X{
X	char g_ex, o_ex, all_ex;
X	char g_rd, o_rd, all_rd;
X	char g_wr, o_wr, all_wr;
X	
X	g_ex = EXEC_GROUP & mode ? 'x' : '-';
X	o_ex = EXEC_OWNER & mode ? 'x' : '-';
X	all_ex = EXEC_ALL & mode ? 'x' : '-';
X	
X	g_ex = SET_GID & mode ? 's' : g_ex;
X	o_ex = SET_UID & mode ? 's' : o_ex;
X	
X	g_rd = READ_GROUP & mode ? 'r' : '-';
X	o_rd = READ_OWNER & mode ? 'r' : '-';
X	all_rd = READ_ALL & mode ? 'r' : '-';
X	
X	g_wr = WRITE_GROUP & mode ? 'w' : '-';
X	o_wr = WRITE_OWNER & mode ? 'w' : '-';
X	all_wr = WRITE_ALL & mode ? 'w' : '-';
X
X	fprintf(stdout,"%c%c%c",o_rd, o_wr, o_ex);
X	fprintf(stdout,"%c%c%c",g_rd, g_wr, g_ex);
X	fprintf(stdout,"%c%c%c",all_rd, all_wr, all_ex);
X}
X
Xprint_header(member)
Xstruct ar_hdr *member;
X{
X	if (verbose) {
X		print_mode(member->ar_mode);
X		fprintf(stdout,"%3.3d",member->ar_uid);
X		fprintf(stdout,"/%-3.3d ",member->ar_gid);
X		fprintf(stdout,"%5.5d",member->ar_size);
X		print_date(member->ar_date);
X	}
X	fprintf(stdout,"%-14.14s\n",member->ar_name);
X}
X
Xprint(fd,member)
Xint fd;
Xstruct ar_hdr *member;
X{
X	int outfd;
X	register int cnt, ret;
X	int do_align;
X
X	if (major & EXTRACT) {
X		if ((outfd = creat(member->ar_name,0666)) < 0) {
X			fprintf(stderr,"Error: %s could not creat %s\n",progname, member->ar_name);
X			quit(mypid,SIGINT);
X		}
X		if (verbose)
X			fprintf(stdout,"x - %s\n",member->ar_name);
X	}
X	else {
X		if (verbose) {
X			fprintf(stdout,"p - %s\n",member->ar_name);
X			fflush(stdout);
X		}
X		outfd = fileno(stdout);
X	}
X	
X	for (cnt = member->ar_size; cnt > 0; cnt -= ret) {
X		ret = read(fd, buffer, (cnt < BUFFERSIZE ? cnt : BUFFERSIZE));
X		if (ret > 0)
X			write(outfd,buffer, ret);
X	}
X	if (odd(member->ar_size))
X		lseek(fd,1l,1);		/* realign ourselves */
X		
X	if (major & EXTRACT) {
X		close(outfd);
X		chmod(member->ar_name, member->ar_mode);
X	}		
X}
X
X/* copy a given member from fd1 to fd2 */
Xcopy_member(infd, outfd, member)
Xint infd, outfd;
Xstruct ar_hdr *member;
X{
X	int n, cnt;
X	long m, size;
X
X	/* save copies for our use */
X	m = size = member->ar_size;
X
X	/* format for disk usage */
X	member->ar_size = swap(member->ar_size);
X	member->ar_date = swap(member->ar_date);
X
X	mwrite(outfd, member, sizeof(struct ar_hdr));
X	for (; m > 0; m -= n) {
X		cnt = (m < BUFFERSIZE ? m : BUFFERSIZE);
X		if ((n = read(infd, buffer, cnt)) != cnt) {
X			fprintf(stderr,"Error: %s - read error on %s\n",progname, member->ar_name);
X			quit(mypid, SIGINT);
X		}
X		mwrite(outfd, buffer, n);
X	}	
X	if (odd(size)) {		/* pad to word boundary */
X		mwrite(outfd, buffer, 1);
X		lseek(infd,1l,1);		/* realign reading fd */ 
X	}
X}
X
X/* insert at current offset - name file */
Xinsert(fd, name, mess, oldmember)
Xint fd;
Xchar *name, *mess;
Xstruct ar_hdr *oldmember;
X{
X	static struct ar_hdr member;
X	static struct stat status;
X	int in_fd;
X
X	if (stat(name, &status) < 0) {
X		fprintf(stderr,"Error: %s cannot find file %s\n",progname,name);
X		quit(mypid,SIGINT);
X	}
X	else if ((in_fd = open(name, READ)) < 0) {
X		fprintf(stderr,"Error: %s cannot open file %s\n",progname,name);
X		quit(mypid,SIGINT);
X	}
X	strcpy(member.ar_name, basename(name));
X	member.ar_uid = status.st_uid;
X	member.ar_gid = status.st_gid;
X	member.ar_mode = status.st_mode & 07777;
X	member.ar_date = status.st_mtime;
X	member.ar_size = status.st_size;
X	if (only & ONLY)
X		if (oldmember != (struct ar_hdr *)NULL)  
X			if (member.ar_date <= oldmember->ar_date) {
X				close(in_fd);
X				if (verbose) fprintf(stdout, "not %s - %s\n",mess, name);
X				return (-1);
X			}
X		
X	copy_member(in_fd, fd, &member); 
X	if (verbose) 
X		fprintf(stdout, "%s - %s\n",mess, name);
X	close(in_fd);
X	return (1);
X}
X
Xint
Xar_move(oldfd, arfd,mov)
Xint oldfd, arfd;
Xstruct mov_list *mov;
X{
X	long pos;
X	int cnt, want, a, newfd;
X	struct ar_hdr *member;
X
X	if (local) 
X		tmp2 = mktemp("./ar.2.XXXXXX");
X	else
X		tmp2 = mktemp("/tmp/ar.2.XXXXXX");
X
X	close(oldfd);				/* close old temp file */
X	signal(SIGINT, insert_abort);		/* set new signal handler */
X	newfd = open_archive(tmp2, WRITE, 2);	/* open new tmp file */
X	oldfd = open_archive(tmp1, WRITE, 0);	/* reopen old tmp file */
X
X	/* copy archive till we get to pos_offset */
X	for (pos = pos_offset; pos > 0; pos -= cnt) {
X		want = (pos < BUFFERSIZE ? pos : BUFFERSIZE);
X		if ((cnt = read(oldfd, buffer, want)) > 0)
X			mwrite(newfd, buffer, cnt);
X	}
X	/* if minor = 'a' then skip over posname */
X	if (minor & AFTER) {
X		if ((member = get_member(oldfd)) != NULL)
X			copy_member(oldfd, newfd, member);
X	}
X	/* move members in the library */
X	while (mov != NULL) {
X		lseek(arfd, mov->pos, 0);
X		if ((member = get_member(arfd)) != NULL)
X			copy_member(arfd, newfd, member);
X		mov = mov->next;
X		if (verbose) fprintf(stdout, "m - %s\n", member->ar_name);
X	}
X
X	/* copy rest of library into new tmp file */
X	while ((member = get_member(oldfd)) != NULL) 
X		copy_member(oldfd, newfd, member);
X
X	/* detach old temp file */
X	close(oldfd);
X	unlink(tmp1);
X
X	/* change context temp file */
X	tmp1 = tmp2;
X	return (newfd);
X}
X
Xint
Xar_insert(oldfd, ac, argc, argv)
Xint oldfd;
Xint ac, argc;
Xchar **argv;
X{
X	long pos;
X	int cnt, want, a, newfd;
X	struct ar_hdr *member;
X
X	if (local) 
X		tmp2 = mktemp("./ar.2.XXXXXX");
X	else
X		tmp2 = mktemp("/tmp/ar.2.XXXXXX");
X
X	close(oldfd);				/* close old temp file */
X	signal(SIGINT, insert_abort);		/* set new signal handler */
X	newfd = open_archive(tmp2, WRITE, 2);	/* open new tmp file */
X	oldfd = open_archive(tmp1, WRITE, 0);	/* reopen old tmp file */
X
X	/* copy archive till we get to pos_offset */
X	for (pos = pos_offset; pos > 0; pos -= cnt) {
X		want = (pos < BUFFERSIZE ? pos : BUFFERSIZE);
X		if ((cnt = read(oldfd, buffer, want)) > 0)
X			mwrite(newfd, buffer, cnt);
X	}
X	/* if minor = 'a' then skip over posname */
X	if (minor & AFTER) {
X		if ((member = get_member(oldfd)) != NULL)
X			copy_member(oldfd, newfd, member);
X	}
X	
X	/* copy new members into the library */
X	for (a = ac+1; a <= argc; ++a)
X		if (argv[a-1] && *argv[a-1] != '\0') {
X			insert(newfd, argv[a-1], "a", (struct ar_hdr *)NULL);
X			*argv[a-1] = '\0';
X		}
X
X	/* copy rest of library into new tmp file */
X	while ((member = get_member(oldfd)) != NULL) 
X		copy_member(oldfd, newfd, member);
X
X	/* detach old temp file */
X	close(oldfd);
X	unlink(tmp1);
X
X	/* change context temp file */
X	tmp1 = tmp2;
X	return (newfd);
X}
X
Xar_common(ac, argc, argv)
Xint ac, argc;
Xchar **argv;
X{
X	int a, fd;
X	struct ar_hdr *member;
X
X	fd = open_archive(afile, READ, 0);
X	while ((member = get_member(fd)) != NULL) {
X		if (ac < argc) {
X			for (a = ac+1; a <= argc; ++a) {
X				if (strcmp(basename(argv[a-1]),member->ar_name) == 0) {
X					if (major & TABLE)
X						print_header(member);
X					else if (major & (PRINT | EXTRACT))
X						print(fd, member);
X					*argv[a-1] = '\0';
X					break;
X				}
X				else if (major & (PRINT | EXTRACT))
X					lseek(fd, (long)even(member->ar_size), 1);
X			}
X		}
X		else {
X			if (major & TABLE)
X				print_header(member);
X			else if (major & (PRINT | EXTRACT))
X				print(fd, member);
X		}
X		if (major & TABLE)
X			lseek(fd, (long)even(member->ar_size), 1);
X	}
X}
X
Xar_members(ac, argc, argv)
Xint ac, argc;
Xchar **argv;
X{
X	int a, fd, tempfd, rc;
X	struct ar_hdr *member;
X	long *lpos;
X
X	fd = open_archive(afile, WRITE, 0);
X	tempfd = open_archive(tmp1, WRITE, 2);
X	while ((member = get_member(fd)) != NULL) {
X
X		/* if posname specified check for our member */
X		/* if our member save his starting pos in our working file*/
X		if (posname && strcmp(posname, member->ar_name) == 0)
X			pos_offset = tell(tempfd) - MAGICSIZE;
X
X		if (ac < argc) { /* we have a list of members to check */
X			for (a = ac+1; a <= argc; ++a)
X				if (strcmp(basename(argv[a-1]),member->ar_name) == 0) {
X					if (major & REPLACE) {
X						if (insert(tempfd,argv[a-1],"r", member) < 0)
X							copy_member(fd, tempfd, member);
X						else 
X							lseek(fd, (long)even(member->ar_size), 1);
X					}
X					else if (major & MOVE) {
X						/* cheat by saving pos in archive */
X						addmove((tell(fd) - sizeof(struct ar_hdr)));
X						lseek(fd, (long)even(member->ar_size), 1);
X					}
X					*argv[a-1] = '\0';
X					break;
X				}
X		}
X		if (ac >= argc || a > argc) 	/*nomatch on a member name */
X			copy_member(fd, tempfd, member);
X		else if (major & DELETE) {
X			if (verbose) fprintf(stdout,"d - %s\n",member->ar_name);
X			lseek(fd, (long)even(member->ar_size), 1);
X		}
X	}
X	if (major & MOVE) {
X		if (posname == NULL) 
X			pos_offset = lseek(fd, 0l, 2);
X		else if (pos_offset == (-1)) {
X			fprintf(stderr,"Error: %s cannot find file %s\n",progname,posname);
X			quit(mypid,SIGINT);
X		}
X		tempfd = ar_move(tempfd, fd, moves);
X	}
X	else if (major & REPLACE) {
X		/* take care to add left overs */
X		/* if the posname is not found we just add to end of ar */
X		if (posname && pos_offset != (-1)) {
X			tempfd = ar_insert(tempfd, ac, argc, argv);
X		}
X		else {
X			for (a = ac+1; a <= argc; ++a)
X				if (*argv[a-1]) {
X					insert(tempfd, argv[a-1], "a", (struct ar_hdr *)NULL);
X					*argv[a-1] = '\0';
X				}
X		}
X	}
X	fd = rebuild(fd, tempfd);
X	close(fd);
X}
X
Xappend_members(ac, argc, argv)
Xint ac, argc;
Xchar **argv;
X{
X	int a, fd;
X	struct ar_hdr *member;
X	
X	/* quickly append members don't worry about dups in ar */
X	fd = open_archive(afile, WRITE, 0);
X	if (ac < argc) {
X		if (odd(lseek(fd, 0l, 2)))
X			mwrite(fd, buffer, 1);
X		/* while not end of member list insert member at end */
X		for (a = ac+1; a <= argc; ++a) {
X			insert(fd, argv[a-1], "a", (struct ar_hdr *)NULL);
X			*argv[a-1] = '\0';
X		}
X	}
X	close(fd);
X}
X
/
echo x - ar.h
gres '^X' '' > ar.h << '/'
X/* ar.c header file V7 */
X
X#define ARMAG	0177545l
Xstruct ar_hdr {
X	char ar_name[14];
X	long ar_date;		/* not Intel format */
X	char ar_uid;
X	char ar_gid;
X	int ar_mode;
X	long ar_size;		/* not Intel format */
X};
/
echo x - basename.c
gres '^X' '' > basename.c << '/'
X#include <stdio.h>
X
Xchar *basename(path)
Xchar *path;
X{
X  register char *ptr = path;
X  register char *last = (char *)NULL;
X
X  while (*ptr != '\0') {
X	if (*ptr == '/')
X		last = ptr;
X	ptr++;
X  }
X  if (last == (char *)NULL)
X	return path;
X  if (*(last + 1) == '\0') {
X	*last = '\0';
X	return basename(path);
X  }
X  return last + 1;
X}
/
echo x - date.c
gres '^X' '' > date.c << '/'
X#include <stdio.h>
X
X#define MINUTE	60L
X#define HOUR	(60L * MINUTE)
X#define DAY	(24L * HOUR)
X#define YEAR	(365L * DAY)
X#define LYEAR	(366L * DAY)
X
Xint mo[] = {
X  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
X};
X
Xchar *moname[] = {
X  " Jan ", " Feb ", " Mar ", " Apr ", " May ", " Jun ",
X  " Jul ", " Aug ", " Sep ", " Oct ", " Nov ", " Dec "
X};
X
X/* Print the date.  This only works from 1970 to 2099. */
Xprint_date(t)
Xlong t;
X{
X  int i, year, day, month, hour, minute;
X  long length, time(), original;
X
X  year = 1970;
X  original = t;
X  while (t > 0) {
X	length = (year % 4 == 0 ? LYEAR : YEAR);
X	if (t < length)
X		break;
X	t -= length;
X	year++;
X  }
X
X /* Year has now been determined.  Now the rest. */
X  day = (int) (t / DAY);
X  t -= (long) day * DAY;
X  hour = (int) (t / HOUR);
X  t -= (long) hour * HOUR;
X  minute = (int) (t / MINUTE);
X
X /* Determine the month and day of the month. */
X  mo[1] = (year % 4 == 0 ? 29 : 28);
X  month = 0;
X  i = 0;
X  while (day >= mo[i]) {
X	month++;
X	day -= mo[i];
X	i++;
X  }
X
X  /* At this point, 'year', 'month', 'day', 'hour', 'minute'  ok */
X  fprintf(stdout, "%s%2.2d ",moname[month],++day);
X  if (time((long *)NULL) - original >= YEAR / 2L)
X	fprintf(stdout,"%4.4D ",(long)year);
X  else 
X	fprintf(stdout,"%02.2d:%02.2d ",hour, minute);
X}
X
/
echo x - lorder.lxi
gres '^X' '' > lorder.lxi << '/'
X%{
X/*
X * lorder: find ordering relations for object library
X *
X * author:	Monty Walls
X * written:	1/29/88
X * Copyright:	Copyright (c) 1988 by Monty Walls.
X *		Not derived from licensed software.
X *
X *		Permission to copy and/or distribute granted under the
X *		following conditions:
X *	
X *		1). This notice must remain intact.
X *		2). The author is not responsible for the consequences of use
X *			this software, no matter how awful, even if they
X *			arise from defects in it.
X *		3). Altered version must not be represented as being the 
X *			original software.
X *
X * change log:
X *
X */
X
X#include <ctype.h>
X#include <signal.h>
X#include <ar.h>
X
X#define MAXLINE		256
X
Xchar *yyfile;
Xchar *tmpfile;
Xchar *progname;
Xint toklen;
Xchar token[MAXLINE], *cp;
Xchar template[] = "lorder.XXXXXX";
X
Xstruct filelist {
X	char *name;
X	struct filelist *next;
X};
X
Xstruct node {
X	char *name;
X	char *file;
X	struct filelist *list;
X	struct node *left, *right;
X};
X
Xstruct filelist *list;
Xstruct node *tree, *lastnode;
Xextern char *malloc(), *mktemp();
Xextern FILE *popen(), *fopen();
Xextern char *addfile();
Xextern FILE *lexin;
Xextern void user_abort();
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	int i;
X	char cmdstr[MAXLINE];
X
X	if (argc > 1) {
X		progname = argv[0];
X		signal(SIGINT, user_abort);
X		for (i = 1; argv[i] && *argv[i]; ++i ) {
X			/* the following code is caused by 
X			 * not enough memory on floppy systems.
X			 *
X			 * so instead of ar | libupack ->to us. we use
X			 * ar >tmpfle; libupack <tmpfile ->to us
X			 */
X			if (is_liba(argv[i])) {
X				tmpfile = mktemp(template);
X				sprintf(cmdstr,"ar pv %s >%s",argv[i],tmpfile);
X				system(cmdstr);
X				sprintf(cmdstr,"libupack <%s",tmpfile);
X			}
X			else {
X				yyfile = addfile(argv[i]);
X				sprintf(cmdstr, "libupack <%s", argv[i]);
X			}
X			if ((lexin = popen(cmdstr, "r")) != (FILE *)NULL) {
X				while (yylex()) ;
X				pclose(lexin);
X				if (tmpfile)
X					unlink(tmpfile);
X			}
X			else {
X				fprintf(stderr,"Error: %s could not open %s\n",progname, argv[i]);
X				exit(1);
X			}
X			llinit();
X		}
X		printtree(tree);
X		/* then print list of files for ar also */
X		for (; list; list = list->next) 
X			fprintf(stdout,"%s %s\n",list->name, list->name);
X	}
X	else {
X		fprintf(stderr,"Usage: %s file ....\n",progname);
X		exit(1);
X	}
X}
X
Xvoid
Xuser_abort()
X{
X	unlink(tmpfile);
X	exit(1);
X}
X
Xchar *
Xxalloc(n)
Xint n; 
X{
X	char *p;
X
X	if ((p = malloc(n)) == (char *)NULL) {
X		fprintf(stderr, "Error %s - out of memory\n", progname);
X		exit(1);
X	}
X	return (p);
X}
X
Xint
Xis_liba(s)	/* error handling done later */
Xchar *s;
X{
X	unsigned short key;
X	FILE *fp;
X	int ret = 0;
X
X	if ((fp = fopen(s,"r")) != (FILE *)NULL) {
X		fread(&key, sizeof(key), 1, fp);
X		if (key == ARMAG) ret = 1;
X		fclose(fp);
X	}
X	return (ret);
X}
X
Xchar *
Xstrsave(s)
Xchar *s;
X{
X	char *p;
X
X	p = xalloc(strlen(s) + 1);
X	strcpy(p,s);
X	return (p);
X}
X
Xchar *
Xaddfile(s)
Xchar *s;
X{
X	struct filelist *p;
X
X	p = (struct filelist *)xalloc(sizeof(struct filelist));
X	p->name = strsave(s);
X	if (list)
X		p->next = list;
X	else
X		p->next = NULL;
X	list = p;
X	return (p->name);
X}
X
Xprinttree(t)
Xstruct node *t;
X{
X	struct filelist *fp;
X
X	if (t) {
X		if (t->file) {
X			for (fp = t->list; fp && fp->name; fp = fp->next)
X				if (t->file != fp->name)
X					fprintf(stdout,"%s %s\n",t->file, fp->name);
X		}
X		printtree(t->right);
X		printtree(t->left);
X	}
X}
X
X
Xstruct node *
Xfinddef(s)
Xchar *s;
X{
X	struct node *n;
X	int cmp;
X
X	if (tree) {
X		lastnode = n = tree;
X		while (n && n->name) {
X			lastnode = n;
X			if (!(cmp=strcmp(s,n->name)))
X				return (n);
X			else if (cmp > 0)
X				n = n->left;
X			else 
X				n = n->right;
X		}			
X	}
X	return ((struct node *)NULL);
X}
X
Xstruct node *
Xmakedef(s)
Xchar *s;
X{
X	struct node *n;
X	int cmp;
X
X	n = (struct node *)xalloc(sizeof(struct node));
X	n->name = strsave(s);
X	n->left = (struct node *)NULL;
X	n->right = (struct node *)NULL;
X	if (tree) {
X		cmp = strcmp(s, lastnode->name);
X		if (cmp > 0)
X			lastnode->left = n;
X		else
X			lastnode->right = n;
X	}
X	else
X		tree = n;
X
X	return (n);
X}
X
Xvoid
Xdodef(s) 
Xchar *s;
X{
X	struct node *n;
X
X	if (n = finddef(s)) {
X		if (n->file != NULL) 
X			fprintf(stderr,"Error %s - %s defined twice in %s and %s", progname, s, n->file, yyfile);
X		else
X			n->file = yyfile;
X	}
X	else {
X		n = makedef(s);
X		n->file = yyfile;
X		n->list = (struct filelist *)NULL;
X	}
X}
X
Xvoid
Xusedef(s) 
Xchar *s;
X{
X	struct node *n;
X	struct filelist *fp, *lastfp;
X
X	if (n = finddef(s)) {
X		/* scan file list for match */
X		if (n->list) {
X			for (fp = n->list; fp ; fp = fp->next) {
X				if (fp->name == yyfile) {
X					return;
X				}
X				lastfp = fp;
X			}
X			/* reached here with no match */
X			lastfp->next = (struct filelist *)xalloc(sizeof(struct filelist));
X			lastfp->next->name = yyfile;
X			lastfp->next->next  = (struct filelist *)NULL;
X		}
X		else {
X			/* empty list so far */
X			n->list = (struct filelist *)xalloc(sizeof(struct filelist));
X			n->list->name = yyfile;
X			n->list->next = (struct filelist *)NULL;
X		}
X	}
X	else {
X		n = makedef(s);
X		n->file = (char *)NULL;
X		n->list = (struct filelist *) xalloc(sizeof(struct filelist));
X		n->list->name = yyfile;
X		n->list->next = (struct filelist *)NULL;
X	}
X}
X
X%}
Xany = [^\t\n ];
Xmember = "p - " any*;
Xname = '_'[a-zA-Z_][a-zA-Z0-9_]*;
Xdotdefine = ".define" ' '* name;
X%%
Xmember		{
X			toklen = lexlength() + 1;
X			gettoken(token, toklen);
X			yyfile = addfile(&token[4]);
X		}
Xdotdefine	{
X			toklen = lexlength() + 1;
X			gettoken(token,toklen);
X			for (cp = &token[7]; *cp && isspace(*cp); ++cp)
X				;
X			if (*cp)
X				dodef(cp);
X		}
Xname		{
X			toklen = lexlength() + 1;
X			gettoken(token,toklen);
X			usedef(token);
X		}
/
echo x - makefile
gres '^X' '' > makefile << '/'
Xlib=-llex -laux
X# decus lex rules
X.lxi.c:
X	lex -e $*
X
Xlorder: lorder.s
X	cc -o lorder -i lorder.s $(lib)
/
echo x - tsort.c
gres '^X' '' > tsort.c << '/'
X/*
X * tsort - do a topological sort on the ordered pairs of names
X *
X * syntax - tsort [ file ]
X *
X * based on the discussion in 'The AWK programming Language', by
X * Aho, Kernighan, & Weinberger.
X *	
X * author:	Monty Walls
X * written:	1/28/88
X * Copyright:	Copyright (c) 1988 by Monty Walls.
X *		Not derived from licensed software.
X *
X *		Permission to copy and/or distribute granted under the
X *		following conditions:
X *	
X *		1). This notice must remain intact.
X *		2). The author is not responsible for the consequences of use
X *			this software, no matter how awful, even if they
X *			arise from defects in it.
X *		3). Altered version must not be represented as being the 
X *			original software.
X *
X * change log:
X *
X *
X */
X
X#include <stdio.h>
X#include <errno.h>
X#include <ctype.h>
X
X#define printmem(_s)	(fprintf(stdout,"%s ",(_s)))
X#define MAXNAMELEN	32
X
Xstruct dependents {
X	struct node *nd;
X	struct dependents *next;
X};
X
Xstruct node {
X	char *name;
X	struct dependents *pred;
X	struct node *left, *right;
X};
X
Xchar *progname;
X
Xextern struct node *readnode(), *findnode();
Xextern char *malloc(), *xalloc(), *readone(), *strsave();
Xextern struct dependents *finddep();
Xextern void dumptree();
X
Xextern int errno;
Xextern char *sys_errlist[];
X
Xstruct node *tree, *lastnode;
Xstruct dependents *lastpred;
X
Xmain(argc, argv)
Xint argc;
Xchar **argv;
X{
X	progname = argv[0];
X	if (argc > 1) 
X		if (freopen(argv[1], "r", stdin) == (FILE *)NULL) {
X			fprintf(stderr,"Error: %s - %s\n",progname, sys_errlist[errno]);
X			exit(1);
X		}
X
X	/* read in the tree of entries */
X	while (readnode() != (struct node *)NULL) 
X		;
X	dumptree(tree);
X	fflush(stdout);
X	exit(0);
X}
X
X
Xstruct node *
Xreadnode()
X{
X	char *s1, *s2;
X	register struct node *n1, *n2;
X	struct dependents *pd;
X
X	if ((s1 = readone()) != (char *)NULL) {
X		if ((n1 = findnode(s1)) == (struct node *)NULL) {
X			/* is a new node so build it */
X			n1 = (struct node *)xalloc(sizeof(struct node));
X			n1->name = strsave(s1);
X			n1->pred = (struct dependents *)NULL;
X			n1->left = (struct node *)NULL;
X			n1->right = (struct node *)NULL;
X			linknode(n1);
X		}
X		if ((s2 = readone()) != (char *)NULL) {
X			if ((n2 = findnode(s2)) == (struct node *)NULL) {
X				/* is a new node so build it */
X				n2 = (struct node *)xalloc(sizeof(struct node));
X				n2->name = strsave(s2);
X				n2->pred = (struct dependents *)NULL;
X				n2->left = (struct node *)NULL;
X				n2->right = (struct node *)NULL;
X				linknode(n2);
X			}
X			if (finddep(n1->pred,s2) == (struct dependents *)NULL) {
X				/* new dependence here */
X				pd = (struct dependents *)xalloc(sizeof(struct dependents));
X				pd->nd = n2;
X				pd->next = (struct dependents *)NULL;
X				if (n1->pred == (struct dependents *)NULL) 
X					n1->pred = pd;
X				else
X					lastpred->next = pd;
X			}
X			return (n1);
X		}
X		else
X			return ((struct node *)NULL);
X	}
X	else
X		return ((struct node *)NULL);
X}
X
Xvoid
Xdumptree(t)
Xstruct node *t;
X{
X	register struct dependents *p;
X	register char *s;
X
X	if (t) {
X		if (t->name) {
X			s = t->name;		/* save name in s */
X			t->name = (char *)NULL;	/* mark this node as visited */
X			for (p = t->pred; p != (struct dependents *)NULL; p = p->next) 
X				dumptree(p->nd);
X			printmem(s);
X		}
X		dumptree(t->left);
X		dumptree(t->right);
X	}
X}
X
Xchar *
Xreadone()
X{
X	register int c, n = 0;
X	static char name[MAXNAMELEN];
X
X	/* eat up leading spaces */
X	while ((c = getchar()) != EOF && isspace(c))
X		;
X
X	if (c != EOF && !isspace(c))
X		ungetc(c,stdin);
X
X	while ((c = getchar()) != EOF && !isspace(c)) {
X		if (n < MAXNAMELEN)
X			name[n++] = c;
X	}
X
X	if (c == EOF) 
X		return ((char *)NULL);
X
X	name[n] = '\0';
X	return (name);
X}
X
Xstruct node *
Xfindnode(s)
Xchar *s;
X{
X	register struct node *n;
X	register int cmp;
X
X	if (tree) {
X		lastnode = n = tree;
X		while (n && n->name) {
X			lastnode = n;
X			if (!(cmp = strcmp(s,n->name)))
X				return (n);
X			else if (cmp > 0)
X				n = n->left;
X			else
X				n = n->right;
X		}
X	}
X	return ((struct node *)NULL);
X}
X
Xstruct dependents *
Xfinddep(dp, s)
Xregister struct dependents *dp;
Xregister char *s;
X{
X	lastpred = (struct dependents *)NULL;
X	while (dp && dp->nd) {
X		lastpred = dp;
X		if (strcmp(dp->nd->name,s) == 0)
X			return (dp);
X		else {
X			dp = dp->next;
X		}
X	}
X	return ((struct dependents *)NULL);
X}
X
Xlinknode(n)
Xregister struct node *n;
X{
X	register int cmp;
X
X	if (tree) {
X		cmp = strcmp(n->name,lastnode->name);
X		if (cmp > 0)
X			lastnode->left = n;
X		else
X			lastnode->right = n;
X	}
X	else
X		tree = n;
X}
X
Xchar *
Xxalloc(n)
Xint n;
X{
X	char *p;
X	
X	if ((p = malloc(n)) != (char *)NULL)
X		return (p);
X	else {
X		fprintf(stderr,"Error: %s out of memory\n",progname);
X		exit(1);
X	}
X}
X
Xchar *
Xstrsave(s)
Xchar *s;
X{
X	char *p;
X
X	p = xalloc(strlen(s)+1);
X	strcpy(p,s);
X	return (p);
X}
/
echo x - tsort.man
gres '^X' '' > tsort.man << '/'
XNAME
X	tsort -- topological sort
X
XSYNOPSIS
X	tsort [file]
X
XDESCRIPTION
X	tsort performs a topological sort on the partially order pairs of
X	strings given as input.  if no file is given standard input is 
X	used.  
X	The input consists of a list of pairs of strings separated by 
X	blanks between strings and newlines between pairs.  If the strings
X	of a pair is identical it indicates presence not ordering.
X
X
XSEE ALSO
X	lorder (1)
X
XBUGS
X	build a simple btree of dependent chains the just walks the
X	tree(uses lots of memory).
X
X
/
echo x - libupack.diff
gres '^X' '' > libupack.diff << '/'
X122,123c122,123
X< #define IBUFSIZE 2000
X< #define OBUFSIZE 24000
X---
X> #define IBUFSIZE 10000
X> #define OBUFSIZE 30000
/
echo x - lorder.uue
gres '^X' '' > lorder.uue << '/'
Xbegin 755 lorder.out
XM 0,@!"     @)@  10H  .$)           !      ")XXL/@\,"B<A T> !
XMV*,  %!34>@' (/$!E#HNQM5B>6![ (!@WX$ 7\#Z70!BUX&BQ^)'EH+N,$!
XM4+@" %#HYR"#Q 3'1OX! (M&_M'@B<,#7@:#/P!U ^D/ 8M&_M'@B<,#7@:+
XM'X _ '4#Z?L BT;^T>")PP->!O\WZ)(!1$0)P'1*N ( 4.@:'T1$HUP+BT;^
XMT>")PP->!O\V7 O_-[B6!%"-AO[^4.AO$8/$"(V&_OY0Z) +1$3_-EP+N*0$
XM4(V&_OY0Z%(1@\0&ZR^+1O[1X(G# UX&_S?HN %$1*->"XM&_M'@B<,#7@;_
XM-[BR!%"-AO[^4.@A$8/$!KC !%"-AO[^4.B;"8/$!*-B"X,^8@L ="3H? 4)
XMP'0"Z_?_-F(+Z(T*1$2#/EP+ '0R_S9<"^@((41$ZR>+1O[1X(G# UX&_S?_
XM-EH+N,($4/\V*@;HW R#Q BX 0!0Z'D:1$3HT ?_1O[IW_[_-E(*Z&T!1$2#
XM/E0* '1"BQY4"HLV5 K_-_\TN. $4/\V* ;HH R#Q B+'E0*BU\"B1Y4"NO2
XM_S9:"[CH!%#_-BH&Z($,@\0&N $ 4.@>&D1$B>Q=PU6)Y?\V7 OH="!$1+@!
XM %#H!1I$1(GL7<-5B>5,3/]V!.B!&T1$B4;^/0  =1O_-EH+N/X$4/\V*@;H
XM- R#Q :X 0!0Z-$91$2+1OZ)[%W#58GE@^P&QT;Z  "X& 50_W8$Z$@-@\0$
XMB4;\/0  =#3_=ORX 0!0N ( 4(U&_E#H0@R#Q @QP%#_=OY0N&7_4.B4(0G 
XM=07'1OH! /]V_.B,#$1$BT;ZB>Q=PU6)Y4Q,_W8$Z%T?1$1 4.A<_T1$B4;^
XM_W8$_W;^Z#0?@\0$BT;^B>Q=PU6)Y4Q,N 0 4.@X_T1$B4;^_W8$Z+__1$2+
XM7OZ)!X,^5 H = R+7OZ+#E0*B4\"ZPB+7O['1P(  (M>_HD>5 J+7OZ+!XGL
XM7<-5B>5,3(-^! !T9XM>!(-_ @!T2(M>!(M'!(E&_H-^_@!T.8M>_H,_ '0Q
XMBUX$BW;^BP0Y1P)T&8M>_HMV!/\W_W0"N!H%4/\V* ;H!0N#Q B+7OZ+1P*)
XM1O[KP8M>!/]W".B;_T1$BUX$_W<&Z)#_1$2)[%W#58GE@^P$@SY2"@!T6XL>
XM4@J)7OZ+'E(*B1Y0"H-^_@!T1HM>_H,_ '0^BU[^B1Y0"HM>_O\W_W8$Z%H5
XM@\0$B4;\/0  =07_=O[K'X-^_ !^"XM>_HM'!HE&_NN_BU[^BT<(B4;^Z[0Q
XMP%!8B>Q=PU6)Y8/L!+@* %#H"/Y$1(E&_O]V!.B/_D1$BU[^B0?'1P8  (M>
XM_L='"   @SY2"@!T+XL>4 K_-_]V!.CG%(/$!(E&_#T  'X,BQY0"HM&_HE'
XM!NL3BQY0"HM&_HE'".L'BU[^B1Y2"HM&_HGL7<-5B>5,3/]V!.@5_T1$B4;^
XM/0  =#:+7OZ#?P( ="&+7O[_-EX+_W<"_W8$_S9:"[@B!5#_-BH&Z,,)@\0,
XMZRF+7OZ+#EX+B4\"ZQW_=@3H/_]$1(E&_HM>_HL.7@N)3P*+7O['1P0  (GL
XM7<-5B>6#[ ;_=@3HJ/Y$1(E&_CT  '4#Z8( BU[^@W\$ '14BU[^BT<$B4;\
XM@W[\ '0@BU[\BPY>"SD/=02)[%W#BT;\B4;ZBU[\BT<"B4;\Z]JX! !0Z.'\
XM1$2+7OJ)1P*+7P*+#EX+B0^+7OJ+7P+'1P(  .M;N 0 4.B\_$1$BU[^B4<$
XMBU\$BPY>"XD/BU[^BU\$QT<"  #K-O]V!.B#_D1$B4;^BU[^QT<"  "X! !0
XMZ(3\1$2+7OZ)1P2+7P2+#EX+B0^+7OZ+7P3'1P(  (GL7<-5B>7_=@3IJ@"X
XM 0!0Z'\$6P'#B1Y8"_\V6 NX6 I0Z!P$@\0$N%P*4.CT_$1$HUX+Z88 N $ 
XM4.A4!%L!PXD>6 O_-E@+N%@*4.CQ X/$!,<&5@I?"HL>5@J /P!T&8L>5@J*
XM!YB)PXJ'*PF8J AT!X,&5@H!Z]Z+'E8*@#\ =#G_-E8*Z#?^1$3K+K@! %#H
XM_ -; <.)'E@+_S98"[A8"E#HF0.#Q 2X6 I0Z'S^1$3K![X0 %OITAVX__^)
XM[%W#58GE@SYB"P!U"(L>)@:)'F(+@SY,!0!U";A\!%#HNP-$1(GL7<-5B>6Y
XM P"+1@33^/]V!B4? %L!PXH'F%"Y @"[ @"+1@2Z 0!2Z+(=)0< B<%8T^!;
XM(<-36(GL7<-5B>6#[!#HF/_'1O8  .@M @G = 8QP%#IB0''1OP  ,=&^O__
XMBQY,!8E>\HM>\H-_$@!T1HM>\HM&_-'@B<8#=Q*+!(E&^#T  '0OQT;^  "#
XM?OX0?2&+3OZX 0#3X(5&^'0/BT;^T>")PXL.3@6)C\H+_T;^Z]G_1O:+7O*+
XM1OS1X(G& W<.BP2)1O0]__]T#HM&](E&^HL>3@6)'E(%Z 8!B4;^/0  ?0+K
XM2HM>\HM'%HE&\#T  '0=@W[V '47_W;P_W;^Z/W^@\0$"<!T!X,&3@7_ZQ^+
XM7O*+1PS_=OS_=O[_=O+_T(/$!HE&_#W__W0#Z37_BQY.!3D>4 5S"(L>3@6)
XM'E %@W[Z_W51BQY.!8D>4@6#?OP =0R#?OX ?08QP%#I>P"+7O*+1QB)1O ]
XM  !T(_]V\/]V_NB'_H/$! G =!/_=O[_=OZX6@50Z)0!@\0&Z:_^N  !4.M$
XMN0L BT;ZT_@E'P")1OX]  !T$HM&_M'@+0( B<.+G\H+B1Y2!8M&^B7_!XM>
XM\HM?$%#_TT1$B4;^/0  ?0/I:/[_=OY8B>Q=PU6)Y8/L!HL>3 6)7OR+1Q2)
XM1OJ+'E %.1Y.!7,+BQY.!3' B@=0ZQ.#/F0+ '0&N/__4.L$Z/< 4%A06(E&
XM_CT  'Q$@W[Z '02_W;Z_W;^Z,O]@\0$"<!T NNWBQY4!3D>3@5R$KAX!5#H
XMT@!$1+@! %#H)!-$1(L>3@6+1OZ(!X,&3@4!ZP;'!F0+ 0"+1OZ)[%W#58GE
XM@^P$QT;^9@N+'E(%B5[\BQY0!3E>_',5_W;\@T;\ 5N+=OZ*!X@$@T;^ >OB
XMQP9.!68+BQY.!8D>4@6+7OZ)'E %@SYD"P!T#8%^_F8+=0:X 0!0ZP,QP%!8
XMB>Q=PU6)Y<<&4@5F"XL>4@7_-E(%B1Y0!8\&3@7'!E0%R@O'!E@%  "+'E@%
XM_S98!8D>5@6/!F0+B>Q=PU6)Y?\V8@OHL@=$1(GL7<-5B>6#/E@% '02_S98
XM!;B.!5#_-BH&Z)L$@\0&_W8*_W8(_W8&_W8$_S8J!NB%!(/$"HGL7<-5B>6#
XM[ :+1@2)1OR+7@8#7OQ+B5[ZQT;^9@N+'E(%.5[^<QV+1OHY1OQS%?]V_H-&
XM_@%;BW;\B@>(!(-&_ 'KVHM>_,8' (M&_"M&!(GL7<-5B>6A4@4M9@N)[%W#
XM58GE3$R+'DP%B5[^BUX$B1Y,!8M&_HGL7<-5B>5,3(M>!(M&"-'@B<8#=PB+
XM! -&!HE&_HM'"CE&_G\?BUX$BW;^ W<&N0( NP( BT8(,=**%%+HSQE;.<-T
XM)8M>!(L'.48(=!6+7@2+=@@#=P**!##DB4;^B48(ZZ6X__]0ZPZ+7@2+=OX#
XM=P2*!##D4%B)[%W#58GE@^P&BUX&B@>84.L4QT;Z  #K%,=&^@$ ZPTQP%#I
XMYP"^E 5:Z5$9C4;\4.CH%41$"<!]!C' 4.G- .@2$:/,"X,^S L = /IA@"#
XM?OH =07_=OSK _]V_NB$$41$@W[Z '4&N $ 4.L#,<!0Z' 11$2#?OH =07_
XM=O[K _]V_.@ #D1$@W[Z '4%_W;^ZP/_=OSH2A%$1#' 4/]V!+BL!5"XJ 50
XMN* %4.CU#8/$"C' 4/]V!+C !5"XO 50N+ %4.C=#8/$"K@! %#H8Q!$1(,^
XMS O_=04QP%#K*X-^^@!U!?]V_NL#_W;\Z/(01$3_=@:#?OH =07_=OSK _]V
XM_NB; 8/$!%!8B>Q=PU6)Y8/L"O]V!.@O T1$N $ 4+@" %#H7!6#Q 2)1OJX
XM 0!0N , 4.A+%8/$!(E&^+@! %!0Z#T5@\0$B4;\C4;V4.AA%D1$B4;^BQ[,
XM"SE>_G0(@W[^_W0"Z^.#?O[_=07'1O;___]V^K@" %#H!16#Q 3_=OBX P!0
XMZ/@4@\0$_W;\N $ 4.CK%(/$!(M&]HGL7<-5B>6#[ RXQ 50Z+X/1$2)1O0]
XM  !T"(M>]( _ '4%QT;TR@7HB ^)1OP]  !U3_]V].A7%41$4/]V!/]V].A>
XM%8/$!@G =14QP%"XT@50_W;T_W;TZ*D,@\0(ZQ8QP%#_=@2XU@50_W;T_W;T
XMZ)$,@\0*N'\ 4.@7#T1$ZQ6#?OS_=0^XV@50Z&831$2X__]0ZV:X 0!0N ( 
XM4.A#%(/$!(E&^+@! %"X P!0Z#(4@\0$B4;VC4;Z4.A6%41$B4;^BT;\.4;^
XM= B#?O[_= +KY(-^_O]U!<=&^O___W;XN ( 4.C[$X/$!/]V]K@# %#H[A.#
XMQ 3_=OI8B>Q=PU6)Y8/L#,=&^@  QT;^  "+7O[1XX._)@8 =!&#?OX4? 8Q
XMP%#IOP#_1O[KXXM>!HH'F%#K+(%.^@( ZRR!3OH" +@" % QP%!0_W8$Z! /
XM@\0(ZQ2!3OH! .L-,<!0Z84 ON@%6NEQ%K@* %#HL ]$1(E&_#T  '4%,<!0
XMZVB+7OS'1P(  (M&!(M>_(D'BT;ZB4<$N  $4.B$#T1$BU[\B4<&@W\& '42
XMBU[\@\,$B5[XBP<-! ")!^L0BU[\@\,$B5[XBP<-( ")!XM>_(MV_(M'!HE$
XM"(M>_M'CBT;\B8<F!O]V_%B)[%W#58GEC48(4/]V!O]V!.@;!(/$!HM>!/9'
XM!$!T"/]V!.A7 D1$B>Q=PU6)Y8U&!E#_=@3_-B@&Z/(#@\0&BQXH!O9'!$!T
XM"?\V* ;H+ )$1(GL7<-5B>6#[ ;'1OP  ,=&_   @WX& '1+BT8(.4;\<T.+
XM1@:)1OK_=@KH>P)$1(E&_CW__W0.BUX$BT;^B >#1@0!ZP:+1OQ0ZQV+1OHM
XM 0")1OH]  !USHM&_ 4! (E&_.NUBT;\4%B)[%W#58GE3$S'1OX  (-^_A1]
XM)(M&_M'@B<.+AR8&.48$=0^+1O[1X(G#QX<F!@  ZP7_1O[KUH-^_A1\!KC_
XM_U#K.O]V!.AV 41$BUX$_S?H2 U$1(M>!/9'!"!T%(M>!(-_!@!T"XM>!/]W
XM!NC'#T1$_W8$Z+\/1$0QP%!8B>Q=PU6)Y8/L"L=&^   QT;^  "+1O[1X(G#
XM@[\F!@!T$8-^_A1\!C' 4.D. ?]&_NOABUX&B@>84.EX (%.^ ( N*0!4/]V
XM!.A9"8/$!(E&^CT  'UE,<!0Z=\ @4[X @"X 0!0_W8$Z$@0@\0$B4;Z/0  
XM?08QP%#IOP"X @!0,<!04/]V^NBQ#(/$".LL@4[X 0 QP%#_=@3H%A"#Q 2)
XM1OH]  !]$S' 4.F- #' 4.F' +[X!5KI^A.X"@!0Z#D-1$2)1OP]  !U!3' 
XM4.MJBU[\QT<"  "+1OJ+7OR)!XM&^(E'!+@ !%#H#0U$1(M>_(E'!H-_!@!U
XM$HM>_(/#!(E>]HL'#00 B0?K$(M>_(/#!(E>]HL'#2  B0>+7OR+=OR+1P:)
XM1 B+1O[1X(G#BT;\B8<F!O]V_%B)[%W#58GE@^P$BUX$]D<$!'4)BUX$]D<$
XM G4%,<!0ZUV+7@2#?P( ?P4QP%#K3XM>!(MV!(M^!/]W O]T!O\UZ)T1@\0&
XMB4;^BUX$BT<".4;^=1:+7@3'1P(  (MV!(M'!HE$"/]V_NL4BUX$@\,$B5[\
XMBP<-$ ")![C__U!8B>Q=PU6)Y8/L!(M>!/9'!!AT![C__U#IUP"+7@3V1P0!
XM=0>X__]0Z<< BUX$@\,"B5[\BP=(B0>+7OR#/P!^ ^F% (M>!/9'! 1T&XM>
XM!+@! %"-1OY0_S?H?P^#Q :+7@2)1P+K&XM>!(MV!+@ !%#_=P;_-.AB#X/$
XM!HM>!(E' HM>!(-_ @!_,8M>!(-_ @!U$HM>!(/#!(E>_(L'#0@ B0?K$(M>
XM!(/#!(E>_(L'#1  B0>X__]0ZS6+7@2+=@2+1P:)1 B+7@3V1P0$= B+1OXP
XMY%#K&(M>!(/#"(E>_(MV_/\W@P0!6XH'F##D4%B)[%W#58GE@^P*QT;V___'
XM1OJ" (M&!(E&_(M&!(E&_HU&"%#_=@:-1O90Z!< @\0&C4;V4#' 4.B%!8/$
XM!(M&!(GL7<-5B>6#[#*+1@B)1OZ+7@:*!Y@)P'4#Z;H"BUX&B@>8/24 =!?_
XM=@3_=@:#1@8!6XH'F%#H106#Q 3KT<=&^@  QT;X  #'1O8! ,9&[2"#1@8!
XMBUX&B@>8/2T =0G'1O;__X-&!@&+7@:*!Y@], !U",9&[3"#1@8!BUX&B@>8
XM/3  ?"J+7@:*!Y@].0!_'XM>!HH'F"TP /=F]E"X"@#W9OI; <.)7OJ#1@8!
XMZ\N+7@:*!Y@]+@!U-H-&!@&+7@:*!Y@], !\)XM>!HH'F#TY '\<BUX&B@>8
XM+3  4+@* /=F^%L!PXE>^(-&!@'KSHM>!HH'F%#IEP&#1OX"BU[^BT?^F8E&
XM\HE6],=&_ H Z84!@T;^ HM>_HM'_IF)1O*)5O2+1O+_=O1;)?__,=M3B4;R
XMCT;TQT;\"@#I60&#1OX"BU[^BT?^F8E&\HE6](M&\HM>]"T  (/; '4%(<!T
XM 4,)VWT3BT;R_W;T6R7__S';4XE&\H]&],=&_ @ Z18!@T;^ HM>_HM'_IF)
XM1O*)5O2+1O*+7O0M  "#VP!U!2' = %#"=M]$XM&\O]V]%LE__\QVU.)1O*/
XM1O3'1OP0 .G3 (-&_@2+7OZ+1_S_=_Z)1O*/1O3'1OP* .FX (-&_@2+7OZ+
XM1_S_=_Z)1O*/1O3'1OP( .F= (-&_@2+7OZ+1_S_=_Z)1O*/1O3'1OP0 .F"
XM (-&_@*+7OZ+1_Z(1O&*1O&8_W8$4.A. X/$!(-&!@'IU?V#1OX"BU[^BT?^
XMB4;N_W8$_W;NZ"H-1$10BD;MF%#_=OC_=OK_=N[H9P*#Q R#1@8!Z:']_W8$
XMN"4 4.@& X/$!/]V!/]V!H-&!@%;B@>84.CQ H/$!.E\_;Y.!EKI+ ^-1N%0
XM_W;\_W;T_W;RZ#  @\0(_W8$C4;A4.C##$1$4(I&[9A0_W;X_W;ZC4;A4.C_
XM 8/$#(-&!@'I.?V)[%W#58GE@^P6QT;P  "+1@2+7@8M  "#VP!U @G#"=MU
XM$XM>"L8',(M&"D")P\8' (GL7<.#?@@*=2V+1@2+7@8M  "#VP!U!2' = %#
XM"=M]%HM>!(M&!O?8]]L=  ")7@2)1@;_1O#'1NX  (-^[@Q]#(MV[L9"] #_
XM1N[K[L=&[@  @WX("G4Z_W8&_W8$,<!0N H 4.AD#XMV[HA2](MV[HI"])B9
XMBUX$BTX&*<,9T5%3,<!0N H 4.AM#HE&!(E.!H-^" AU,(M&!/]V!ELE!P Q
XMVXMV[HA"]+D# (M&!(M>!N,&T?O1V.+Z)?__@>/_'XE&!(E>!H-^"!!U,(M&
XM!/]V!ELE#P QVXMV[HA"]+D$ (M&!(M>!N,&T?O1V.+Z)?__@>/_#XE&!(E>
XM!O]&[HM&!(M>!BT  (/; '4""<,)VW0#Z3K_QT;R  "+1NY(B4;L@W[L 'Q2
XMBW;LBD+TF G =0^#?O( =0F+=NS&0O0@ZS.+=NR*0O28/0H ?1.+=NR-6O2)
XM7NJ*!Y@%, "(!^L1BW;LC5KTB5[JB@>8!3< B ?_1O+_3NSKJ(-^\ !T%;@M
XM %"-1O10_W;N_T;N6U@!PUB(!XM&[DB)1NR#?NP ?!2+=NR+7@J*0O2(!X-&
XM"@'_3NSKYHM>"L8' (GL7<-5B>6#[ 2+1@R)1OZ#?@@ ?@Z+1@@Y1@Q^!HM&
XM"(E&_HM&_HE&_(-^!@!^&XM&_CE&!GX3_TX&BD8*F/]V#E#H<0"#Q 3KY8M>
XM!(H'F G ="+_=O[_3OY8"<!T%_]V#O]V!(-&! %;B@>84.A% (/$!.O4@WX&
XM 'T9BD8*F#TP '40_W8.N"X 4.@G (/$!/]&!HM&_/?8.48&?1/_1@:*1@J8
XM_W8.4.@) (/$!.OCB>Q=PU6)Y8/L!L=&_   BUX&]D<$&'0'N/__4.GS (M>
XM!O9'! )U![C__U#IXP"+7@;V1P0$=".+7@:X 0!0C48$4/\WZ&L*@\0&B4;^
XMBUX&QT<" 0#_1OSK9(M>!H/#"(E>^HMV^C' BD8$4/\W@P0!6UB(!XM>!H/#
XM HE>^HL'0(D'BU[Z@3\ !'PRBUX&]D<$@'4IBUX&BW8&BWX&_W<"_W0&_S7H
XM"0J#Q :)1OZ+7@:+=@:+1P:)1 C_1OR#?OP =$>#?OX ?@N+7@:+1OXY1P)T
XM+H-^_@!]$HM>!H/#!(E>^HL'#1  B0?K$(M>!H/#!(E>^HL'#0@ B0>X__]0
XMZPZ+7@;'1P(  (I&!##D4%B)[%W#58GEBW8$BWX&,<"*!#H%? Y_" C = M'
XM1NOPL 'K [C__UW#58GE_W8$_W8&N @ 4+@! %#HQ F#Q B)[%W#58GE,<!0
XM4%!04/]V!+@I %"X 0!0Z&@)@\00B>Q=PU6)Y;C.$U"-1@90_W8$Z$X @\0&
XMB>Q=PU6)Y4Q,C5X&B5[^_W;^@T;^ EN#/P!T NOQBU[^_S>-1@90_W8$Z!X 
XM@\0&B>Q=PU6)Y;C.$U#_=@;_=@3H!P"#Q :)[%W#58GE@>P6!,>&\OL  ,>&
XM\/L  (M&!HF&_ON+1@B)AOS[_[;^^X.&_OL"6X,_ '0&_X;R^^OK_[;\^X.&
XM_/L"6X,_ '0&_X;P^^OKQX;L^P( BX;P^P.&\OL% P#WINS[B<:-F@#\B9[Z
XM^XN>\OL#GOK[ Y[P^XUV #GS<@>X^?]0Z6<!C9X _(F>^/N+AO+[B0>#AOC[
XM L>&]/L  (N&\OLYAO3[?6N-G@#\BX;Z^RG8B8;J^XN>^/N)!X.&^/L"_W8&
XM@T8& EN+!XF&]ON+GO;[B@>8"<!T)_^V]ON#AO;[ 5N+MOK[B@>(!(.&^OL!
XMC5X .9[Z^W+5N/G_4.GK (N>^OO&!P"#AOK[ ?^&]/OKBXN>^/O'!P  @X;X
XM^P+'AO3[  "+AO#[.8;T^WUJC9X _(N&^OLIV(F&ZON+GOC[B0>#AOC[ O]V
XM"(-&" );BP>)AO;[BY[V^XH'F G =";_MO;[@X;V^P%;B[;Z^XH'B 2#AOK[
XM 8U> #F>^OMRU;CY_U#K9(N>^OO&!P"#AOK[ ?^&]/OKC(N>^/O'!P  @X;X
XM^P*-G@#\BX;Z^RG8 X;L^TB9][[L^_>F[/N)AN[[,<!0C88 _%#_=@0QP%#_
XMMN[[_W8$Z P(1$10N#L 4#' 4.@;!X/$$%!8B>Q=PU6)Y8/L!,9&_ #&1OT 
XMQD;^ ,9&_P QP%"-1OQ0_W8$,<!0N 0 4/]V!.C)!T1$4+@[ % QP%#HV :#
XMQ!")[%W#58GE,<!04%!04/]V!+@! % QP%#HN@:#Q!")[%W#58GE,<!04%!0
XM4%"X @!0,<!0Z)X&@\00B>Q=PU6)Y8/L!HL>  ")7O[_=OZ#1OX"6XL'B4;\
XM/0  =$V+1@2)1OJ+7OR /P!T)(M>^H _ '0<BU[\B@>8BU[Z4(H'F%LYPW4*
XM@T;\ 8-&^@'KU(M>_( _/76TBU[Z@#\ = +KJH-&_ '_=OSK S' 4%B)[%W#
XM58GE,<!04%!04/]V!+@& %"X 0!0Z L&@\00B>Q=PU6)Y4Q,BUX$B1[Z$XM>
XM!HD> !2+7@B)'@(4BUX*B1[\$[@3 %"X 0!0Z'8&@\0$B4;^/0  = B+1OZ9
XM4E#K"/\V A3_-@ 46%J)[%W#58GE3$R+'M 3@\," UX$@\,/@>/P_X/#_HE>
XM_HL>T!,Y7OYR#/]V_N@> D1$"<!]!3' 4.LXBU[^B1[0$XL>TA.)7OZ+7OZ#
XM/P!T#8M>_HL')?[_B4;^Z^N+'M 3BW;^B1R+'M 3QP<  +@! %!8B>Q=PU6)
XMY8/L"(M&! 4! "7^_P4" (E&^(L>TA.)7OZ#/M(3 '4>N ( 4.CF 41$B4;^
XMBU[^B1[2$XM>_HD>T!/'!P  BU[^BW;^BP3_-XE&_%@]  !U ^EU /9&_ %T
XM"XM&_"7^_XE&_NO9BU[\BW;\BP3_-XE&^E@]  !T#O9&^@%U"(M&^HE&_.O?
XMBT;\*T;^.4;X=R^X 0#W9OB)PP->_HE>^HM&_#E&^G,(BT;\BU[ZB0>+1OH-
XM 0"+7OZ)!X/# E/K(XM&_(E&_NEU__]V^.B[_D1$"<!T"_]V!.@B_T1$4.L#
XM,<!06(GL7<-5B>6#[ R+7@2#P_Z)7OZ+1@8% 0 E_O\% @")1OB+7OZ+!R7^
XM_XE&_"M&!(E&]HM>_(MV_(L$_S>)1OI8/0  = [V1OH!=0B+1OJ)1OSKWXM&
XM_"M&_CE&^'<[N $ ]V;XB<,#7OZ)7OJ+1OPY1OIS%8M&_(M>^HD'BT;Z#0$ 
XMBU[^B0?K"XM&_ T! (M>_HD'_W8$ZS?_=@;H>?Y$1(E&^CT  '4%,<!0ZR+_
XM=O;_=OK_=@3HQ@2#Q :+1OZ)1O2+7O2+!R7^_XD'_W;Z6(GL7<-5B>5,3(M>
XM!(/#_HE>_HL')?[_B0>)[%W#58GE3$PQP%!0_W8$4%!0N!$ 4#' 4.A5 X/$
XM$(E&_CT  '4-BQX(%(D>=@8QP%#K!+C__U!8B>Q=PU6)Y8/L!(L>=@:)7OR+
XM7@0#'G8&B5[^4^BK_T1$/0  =07_=OSK!+C__U!8B>Q=PU6)Y8/L!NA3 (E&
XM_HM&!(E&^O]V^H-&^@%;B@>8"<!T NOO@T;Z_X-&^O^+7OJ*!Y@]6 !U'[L*
XM (M&_IGW^X/",(M>^H@7NPH BT;^F??[B4;^Z]*+1@2)[%W#58GE,<!04%!0
XM4%"X% !0,<!0Z),"@\00B>Q=PU6)Y?]V!/]V!K@% %"X 0!0Z+4"@\0(B>Q=
XMPU6)Y8,^]!, ? >#/O03(GX4N X 4+@2"5"X @!0Z"X"@\0&ZUS_=@3H< %>
XM4/]V!+@" %#H%P*#Q :X @!0N"()4+@" %#H!0*#Q :+'O03T>/_MW@&Z$(!
XM7HL>]!/1XU#_MW@&N ( 4.CB 8/$!K@! %"X)@E0N ( 4.C0 8/$!HGL7<-5
XMB>5,3#' 4%!04%!0N"H 4+@! %#HU &#Q!")1OX]  !\&(L>^A.+=@2)'(M>
XM!(L._!.)3P(QP%#K _]V_EB)[%W#58GE3$PQP%!0_W8&4/]V"/]V!+@# %"X
XM 0!0Z(L!@\00B4;^B>Q=PU6)Y8/L!(M&!-'@+0( B<.+A]03B4;\BT8$T> M
XM @")PXM&!HF'U!.+7@2)'OH3@WX& 70&@WX& '4%_W8&ZP2XDR%0CP8$%+@P
XM % QP%#HS0&#Q 2)1OX]  !]!?]V_NL#_W;\6(GL7<-04U%25E=5'@:)XXM?
XM$DL!VXN?U!/_-O@3_]./!O@3!Q]=7UY:65M8CP8H"<]5B>6+?@2+=@:LJ@C 
XM=?J+1@1=PU6)Y8M^!#' @#T = 1 1^OW7<-5B>7_3@A\*XM>!(H'F%#_=@:#
XM1@8!6XH'F%LYPW44_W8$@T8$ 5N*!Y@)P'75,<!0ZR"#?@@ ?04QP%#K%8M>
XM!(H'F(-&!O^+7@90B@>86RG#4UB)[%W#58GE_W8$,<!0N H 4+@! %#HE "#
XMQ B)[%W#58GE3$PQP%!04%!04+@' % QP%#H.0"#Q!")1OZ+'OH3BW8$B1R+
XM1OZ)[%W#58GE,<!04/]V!E#_=@C_=@2X! !0N $ 4.@' (/$$(GL7<-5B>6+
XM7@B)'OH3BUX*B1[\$XM>#(D>_A.+7@Z)'@ 4BUX0B1X"%(M>$HD>!!3_=@;_
XM=@3H: "#Q 2)[%W#58GE@^P$_W8*Z)L 1$2)1OZ+7OZ)'OH3BUX(B1[\$XM>
XM"HD>_A/'1OP %(-^_@Y_(/]V_O]._E@)P'05_W8*@T8* 5N+=OR*!X@$@T;\
XM >O@_W8&_W8$Z < @\0$B>Q=PU6)Y4Q,BUX&B1[X$[CV$U#_=@3H8 "#Q 2)
XM1OX]  !T!?]V_NL;@S[X$P!]$(L>^!/WVXD>]!.X__]0ZP3_-O@36(GL7<-5
XMB>5,3,=&_@  _W8$@T8$ 5N*!Y@)P'0%_T;^Z^R+1OY B>Q=P[D! .L(N0( 
XMZP.Y P!5B>6+1@2+7@;-(%W#58GEBTX(BWX&BW8$B?C1^7,#I'0#_/*E7<-;
XM,<!96EY?.==W"W(&.<YW!70!2/_C0/_CPXL4*UP".UP$=PG1XXM8!H7;=0F)
XMTX7;=0/HF@'_XZV3K9%)? >M.="M=?>3A=MU ^B# ?_C7SG+=!"#^P)T#8/[
XM!'42@_D"=0U:_^>#^01U!3'24O_G4.A7 56)Y5<I_XM6"HM&"(M>!HM.!(72
XM>0GWVO?8@]H ]]>%VWD)]]OWV8/; /?7Z!( A?]T!_?:]]B#V@!?78G1P@@ 
XMA=MU$HG#B= ITO?QD_?QB=&)VBG;PU575BG_A/]U)D=7B-^(ZXC-*,F)S8C%
XM*,F(X(C4B/(H]E)048GI.=IR#;C__^L*5U=24(G0*=+W\XG%]^%?*<>#T@")
XMUHG8]^4!\(/2 %XIQH/2 %@IT'D*30'/$=X5  #K](GYB?-?A?]T"(CIB-V(
XM^XC'B>@ITEY?7<.)YHM< HM$!)DYPG4Q(=)]!/?;="DQTHM,!HM$""' ?0;W
XMV/?9&=#W\Y'W\S';@WP( 'T']]OWVH/; ,(( (G',=LA_WT']]_W7 (9WXM$
XM!HM4""'2?0;WVO?8&=JY$ #1X-'2T=,YWW<'<KLY5 )V!.+MZ[DK5 (9^T#B
XMX^NON*P)ZQZXPPGK&;C:">L4N/$)ZP^X" KK"K@>"NL%N#4*ZP"[%@!34+@"
XM %#H P#H^?55B>7'!A 4! "+7@2)'A(4BUX(B1X4%(M>!HD>&!2X#A10N $ 
XM4+@! +L.%+D# ,T@B>Q=PP                !L;W)D97(N6%A86%A8 # &
XM   " '\%J@4"!O____\"  ( _____________________P$  0#_________
XM_P    #__Q04%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04$ X2%!04
XM%!04%!04%!$$%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04%!04
XM%!04%!04%!04%!04 0L4%!0%!@<*% @4%!04"10/ @(" @(" @(" @(" @("
XM @(" @(" @(" @(4%!04 A0" @(" @(" @(" @(" @(" @(" @(" @(" @,#
XM P,# P,# P,4%!04%!04 P,# P,# P,# P,# P,# P,# P,# P,# P,4%!04
XM Q0# P,# P,# P,# P,# P,# P,# P,# P,# PP,# P,# P,# P,# P,# P,
XM# P,# P,# P,%!04% P4# P,# P,# P,# P,# P,# P,# P,# P,# P-#0T-
XM#0T-#0T-%!04%!04% T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-%!04% T4
XM#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T-#0T3$Q,3$Q,3$Q,4%!,3$Q,3$Q,3
XM$Q,3$Q,3$Q,3$Q,3$Q03$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3
XM$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3
XM$Q,3$Q,3$Q,3$Q,3$Q,3$Q,3$P#_________________________________
XM_________P\*$?____________\0 /______________________________
XM_________________________________P *____! 4&"?\'_____PC_  $!
XM 0$! 0$! 0$! 0$! 0$! 0$! 0$! 0$!_____P'_ 0$! 0$! 0$! 0$! 0$!
XM 0$! 0$! 0$! 0$" @(" @(" @("_________P(" @(" @(" @(" @(" @("
XM @(" @(" @("_____P+_ @(" @(" @(" @(" @(" @(" @(" @(" @(+"PL+
XM"PL+"PL+"PL+"PL+"PL+"PL+"PL+"_____\+_PL+"PL+"PL+"PL+"PL+"PL+
XM"PL+"PL+"PL+# P,# P,# P,#/________\,# P,# P,# P,# P,# P,# P,
XM# P,# P,#/____\,_PP,# P,# P,# P,# P,# P,# P,# P,# P,$A(2$A(2
XM$A(2__\2$A(2$A(2$A(2$A(2$A(2$A(2$A+_$A(2$A(2$A(2$A(2$A(2$A(2
XM$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2
XM$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A(2$A( %!04 A04%!04%!04
XM% P*%!04%!(  #  >P                 "  $ M0   0           @![
XM 0     4 #X$1@!" E($^@$L"AP =@4          &%R('!V("5S(#XE<P  
XM;&EB=7!A8VL@/"5S  !L:6)U<&%C:R \)7,  '( 17)R;W(Z("5S(&-O=6QD
XM(&YO="!O<&5N("5S"@  )7,@)7,*  !5<V%G93H@)7,@9FEL92 N+BXN"@  
XM17)R;W(@)7,@+2!O=70@;V8@;65M;W)Y"@!R "5S("5S"@  17)R;W(@)7,@
XM+2 E<R!D969I;F5D('1W:6-E(&EN("5S(&%N9" E<P    !F"V8+9@O*"P  
XM  !);&QE9V%L(&-H87)A8W1E<CH@)6,@*"4P,V\I  !4;VME;B!B=69F97(@
XM;W9E<F9L;W< )60Z(   P@H" '( M IW +L*+V)I;B]S: !S:   +6,  "]U
XM<W(O8FEN+W-H '-H   M8P  4TA%3$P +V)I;B]S:  M:0  +6,  $-A;FYO
XM="!F;W)K+@  H@T# &$ @PUR )L-=P!\#1D0 P!A ,</<@#Z#W< IP\     
XM 0#.#\X/ 0   $( S@O."P(    &       (!A(&' 8                 
XM                            R!0) $0 (11/ #P46 !7%&, <A1D %83
XM;P";$W, E!1U &\3> #>$R84P ;(!M(&[ ;\!A0''@<X!TH'7 =L!W@'B@>:
XM!ZP'N ?.!^ '[ ?^!PX('@@N"$ (5 AH"'H(B@B:"+((P C6".8(\@@ "2, 
XM17)R;W(@, !.;W0@;W=N97( 3F\@<W5C:"!F:6QE(&]R(&1I<F5C=&]R>0!.
XM;R!S=6-H('!R;V-E<W, 26YT97)R=7!T960@<WES=&5M(&-A;&P 22]/(&5R
XM<F]R $YO('-U8V@@9&5V:6-E(&]R(&%D9')E<W, 07)G(&QI<W0@=&]O(&QO
XM;F< 17AE8R!F;W)M870@97)R;W( 0F%D(&9I;&4@;G5M8F5R $YO(&-H:6QD
XM<F5N $YO(&UO<F4@<')O8V5S<V5S $YO="!E;F]U9V@@8V]R90!097)M:7-S
XM:6]N(&1E;FEE9 !"860@861D<F5S<P!";&]C:R!D979I8V4@<F5Q=6ER960 
XM36]U;G0@9&5V:6-E(&)U<WD 1FEL92!E>&ES=', 0W)O<W,M9&5V:6-E(&QI
XM;FL 3F\@<W5C:"!D979I8V4  $YO="!A(&1I<F5C=&]R>0!)<R!A(&1I<F5C
XM=&]R>0  26YV86QI9"!A<F=U;65N=   1FEL92!T86)L92!O=F5R9FQO=P!4
XM;V\@;6%N>2!O<&5N(&9I;&5S $YO="!A('1Y<&5W<FET97(  %1E>'0@9FEL
XM92!B=7-Y  !&:6QE('1O;R!L87)G90  3F\@<W!A8V4@;&5F="!O;B!D979I
XM8V4 26QL96=A;"!S965K  !296%D+6]N;'D@9FEL92!S>7-T96T 5&]O(&UA
XM;GD@;&EN:W,  $)R;VME;B!P:7!E $UA=&@@87)G=6UE;G0 4F5S=6QT('1O
XM;R!L87)G90  26YV86QI9"!E<G)N;PH  #H@   *     " @(" @(" @( @(
XM" @((" @(" @(" @(" @(" @(" @"! 0$! 0$! 0$! 0$! 0$ 0$! 0$! 0$
XM! 00$! 0$! 004%!04%! 0$! 0$! 0$! 0$! 0$! 0$! 0$0$! 0$!!"0D)"
XM0D(" @(" @(" @(" @(" @(" @(" A 0$! @ $5R<F]R.B!$:79I<VEO;B!B
XM>2 P( H 26QL96=A;"!%32!I;G-T<G5C="=N"@!%<G(@:6X@14T@8V%S92!I
XM;G-T<B * %9A<FEA8FQE(&]U="!O9B!R86YG90H 17)R(&EN($5-('-E="!I
XM;G-T<B * $9L;V%T:6YG('!T(&YO="!I;7!L+@H 2&5A<"!O=F5R9FQO=R *
X! '-T
X 
Xend
/
echo x - lorder.man
gres '^X' '' > lorder.man << '/'
XNAME
X	lorder -- find an ordering relation for an assembler library
X
XSYNOPSIS
X	lorder file ....
X
XDESCRIPTION
X	Lorder accepts as input one or more packed or unpacked .s files or
X	libraries (ar(1) format).  It produces on the standard output a list
X	of pairs of .s file names.  The first file of the pair refers to
X	external identifiers defined in the second.  The output of lorder
X	may processed by tsort to produce a suitable ordering for a 
X	one pass access by asld(1).
X
X
XSEE ALSO
X	ar(1), libupack(1), tsort(1), asld(1)
X
XBUGS
X	only handles ar(1) and .s files.
X	only uses memory. no work files(no huge libraries please).
X	slow.
X
X
/
------------------------CUT HERE------------------------------------------
Monty Walls
MIS Division, Tech. Support
Oklahoma Tax Commission
2501 N. Lincoln
OKC, OK, 73194