mkid 02/11 (identifier cross reference tool)

Tom Horsley tom at ssd.csd.harris.com
Thu Dec 13 01:40:04 AEST 1990


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 2 (of 11)."
# Contents:  Status bitsvec.c fid.c hash.c id.h kshgetwd.c opensrc.c
#   stoi.c unsymlink.c
# Wrapped by tom at hcx2 on Wed Dec 12 07:21:55 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Status' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Status'\"
else
echo shar: Extracting \"'Status'\" \(1521 characters\)
sed "s/^X//" >'Status' <<'END_OF_FILE'
XThis is the mkid package originally posted to the net around September of
X1987 by Greg McGary (who then vanished from the net). Since then I have been
Xextensively hacking it, and so have others. In an effort to have all of us
Xbenefit from the modifications and improvements we all have made, I have
X(probably foolishly :-) volunteered to "take over" mkid.
X
XTo get the ball rolling, I am posting this version to alt.sources, and I
Xexpect people to send me their patches. I will merge them all and eventually
Xpost an "official" version to comp.sources.unix.
X
XI know there are probably portability problems with this version of the
Xsource, I have some stuff in here that references functions you only have if
Xyour system supports symbolic links, etc, so it will need to have some
Xconfig parameters and ifdef code added for sure.
X
XAnyway, keep those patches rolling in...
X
X======================================================================
Xdomain: tahorsley at csd.harris.com       USMail: Tom Horsley
X  uucp: ...!uunet!hcx1!tahorsley               511 Kingbird Circle
X                                               Delray Beach, FL  33444
X+==== Censorship is the only form of Obscenity ======================+
X|     (Wait, I forgot government tobacco subsidies...)               |
X+====================================================================+
X
XP.S.
X
X   The TUTORIAL has not been changed since 1987, so a lot of stuff is not
X   well documented. This situation also need to improve prior to the
X   official release.
END_OF_FILE
if test 1521 -ne `wc -c <'Status'`; then
    echo shar: \"'Status'\" unpacked with wrong size!
fi
# end of 'Status'
fi
if test -f 'bitsvec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'bitsvec.c'\"
else
echo shar: Extracting \"'bitsvec.c'\" \(1614 characters\)
sed "s/^X//" >'bitsvec.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)bitsvec.c	1.1 86/10/09";
X
X#include	<stdio.h>
X#include	<bitops.h>
X#include	<string.h>
X#include	<extern.h>
X#include	<id.h>
X
Xint vecToBits();
Xint bitsToVec();
Xchar *intToStr();
Xint getsFF();
Xint strToInt();
Xvoid skipFF();
X
Xint
XvecToBits(bitArray, vec, size)
X	register char	*bitArray;
X	register char	*vec;
X	int		size;
X{
X	register int	i;
X	int		count;
X
X	for (count = 0; (*vec & 0xff) != 0xff; count++) {
X		i = strToInt(vec, size);
X		BITSET(bitArray, i);
X		vec += size;
X	}
X	return count;
X}
X
Xint
XbitsToVec(vec, bitArray, bitCount, size)
X	register char	*vec;
X	char		*bitArray;
X	int		bitCount;
X	int		size;
X{
X	register char	*element;
X	register int	i;
X	int		count;
X
X	for (count = i = 0; i < bitCount; i++) {
X		if (!BITTST(bitArray, i))
X			continue;
X		element = intToStr(i, size);
X		switch (size) {
X		case 4: *vec++ = *element++;
X		case 3: *vec++ = *element++;
X		case 2: *vec++ = *element++;
X		case 1: *vec++ = *element++;
X		}
X		count++;
X	}
X	*vec++ = 0xff;
X
X	return count;
X}
X
Xchar *
XintToStr(i, size)
X	register int	i;
X	int		size;
X{
X	static char	buf0[4];
X	register char	*bufp = &buf0[size];
X
X	switch (size)
X	{
X	case 4:	*--bufp = (i & 0xff); i >>= 8;
X	case 3: *--bufp = (i & 0xff); i >>= 8;
X	case 2: *--bufp = (i & 0xff); i >>= 8;
X	case 1: *--bufp = (i & 0xff);
X	}
X	return buf0;
X}
X
Xint
XstrToInt(bufp, size)
X	register char	*bufp;
X	int		size;
X{
X	register int	i = 0;
X
X	bufp--;
X	switch (size)
X	{
X	case 4: i |= (*++bufp & 0xff); i <<= 8;
X	case 3: i |= (*++bufp & 0xff); i <<= 8;
X	case 2: i |= (*++bufp & 0xff); i <<= 8;
X	case 1: i |= (*++bufp & 0xff);
X	}
X	return i;
X}
END_OF_FILE
if test 1614 -ne `wc -c <'bitsvec.c'`; then
    echo shar: \"'bitsvec.c'\" unpacked with wrong size!
fi
# end of 'bitsvec.c'
fi
if test -f 'fid.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fid.c'\"
else
echo shar: Extracting \"'fid.c'\" \(2394 characters\)
sed "s/^X//" >'fid.c' <<'END_OF_FILE'
Xstatic char copyright[] = "@(#)Copyright (c) 1986, Greg McGary";
Xstatic char sccsid[] = "@(#)fid.c	1.2 86/10/17";
X
X#include	<bool.h>
X#include	<stdio.h>
X#include	<string.h>
X#include	<ctype.h>
X#include	<radix.h>
X#include	<id.h>
X#include	<bitops.h>
X#include	<extern.h>
X
Xvoid fileId();
X
XFILE		*IdFILE;
Xstruct idhead	Idh;
Xstruct idarg	*IdArgs;
X
Xchar *MyName;
Xstatic void
Xusage()
X{
X	fprintf(stderr, "Usage: %s [-f<file>] file1 file2\n", MyName);
X	exit(1);
X}
Xmain(argc, argv)
X	int		argc;
X	char		**argv;
X{
X	char		*idFile = IDFILE;
X	char		*arg;
X	float		occurPercent = 0.0;
X	int		occurNumber = 0;
X	int		op;
X
X	MyName = basename(GETARG(argc, argv));
X
X	while (argc) {
X		arg = GETARG(argc, argv);
X		switch (op = *arg++)
X		{
X		case '-':
X		case '+':
X			break;
X		default:
X			UNGETARG(argc, argv);
X			goto argsdone;
X		}
X		while (*arg) switch (*arg++)
X		{
X		case 'f': idFile = arg; goto nextarg;
X		default: usage();
X		}
X	nextarg:;
X	}
Xargsdone:
X
X	if ((idFile = LookUp(idFile)) == NULL) {
X		filerr("open", idFile);
X		exit(1);
X	}
X	if ((IdFILE = initID(idFile, &Idh, &IdArgs)) == NULL) {
X		filerr("open", idFile);
X		exit(1);
X	}
X
X	if (argc < 1 || argc > 2)
X		usage();
X
X	fileId(argc, argv);
X	exit(0);
X}
X
Xvoid
XfileId(argc, argv)
X	int		argc;
X	char		**argv;
X{
X	char		*buf;
X	int		want, got;
X	int		bitoff[2];
X	int		i, j;
X	int		argLength;
X	int		pathLength;
X	int		lengthDiff;
X	char		*pathVec;
X	register struct idarg	*idArgs;
X
X	want = 0;
X	for (j = 0; j < argc; j++, argv++) {
X		want |= (1<<j);
X		argLength = strlen(*argv);
X		bitoff[j] = -1;
X		for (idArgs = IdArgs, i = 0; i < Idh.idh_pthc; i++, idArgs++) {
X			pathLength = strlen(idArgs->ida_arg);
X			if (argLength > pathLength)
X				continue;
X			lengthDiff = pathLength - argLength;
X			if (strequ(&idArgs->ida_arg[lengthDiff], *argv)) {
X				bitoff[j] = i;
X				break;
X			}
X		}
X		if (bitoff[j] < 0) {
X			fprintf(stderr, "%s: not found\n", *argv);
X			exit(1);
X		}
X	}
X
X	buf = malloc((int)Idh.idh_bsiz);
X	fseek(IdFILE, Idh.idh_namo, 0);
X
X	for (i = 0; i < Idh.idh_namc; i++) {
X		pathVec = 1 + buf + fgets0(buf, Idh.idh_bsiz, IdFILE);
X		getsFF(pathVec, IdFILE);
X		got = 0;
X		while ((*pathVec & 0xff) != 0xff) {
X			j = strToInt(pathVec, Idh.idh_vecc);
X			if ((want & (1<<0)) && j == bitoff[0])
X				got |= (1<<0);
X			if ((want & (1<<1)) && j == bitoff[1])
X				got |= (1<<1);
X			if (got == want) {
X				printf("%s\n", ID_STRING(buf));
X				break;
X			}
X			pathVec += Idh.idh_vecc;
X		}
X	}
X}
END_OF_FILE
if test 2394 -ne `wc -c <'fid.c'`; then
    echo shar: \"'fid.c'\" unpacked with wrong size!
fi
# end of 'fid.c'
fi
if test -f 'hash.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hash.c'\"
else
echo shar: Extracting \"'hash.c'\" \(2237 characters\)
sed "s/^X//" >'hash.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)hash.c	1.1 86/10/09";
X
Xchar *hashSearch();
Xint h1str();
Xint h2str();
X
X/*
X	Look for `key' in the hash table starting at address `base'.
X	`base' is a table containing `nel' elements of size `width'.
X	The hashing strategy we use is open addressing.  Apply the
X	primary hash function `h1' and the secondary hash function
X	`h2' when searching for `key' or an empty slot.  `compar'
X	is the comparison function that should be used to compare
X	the key with an element of the table.  It is called with two
X	arguments.  The first argument is the address of the key, and
X	the second argument is the address of the hash table element
X	in question.  `compar' should return 0 if the key matches the
X	element or the empty slot, and non-zero otherwise.
X
X	If a pointer to a long is provided for `probes' we will keep
X	a running total of open addressing hash probes.
X*/
Xchar *
XhashSearch(key, base, nel, width, h1, h2, compar, probes)
X	char		*key;		/* key to locate */
X	char		*base;		/* base of hash table */
X	register int	nel;		/* number of elements in table */
X	int		width;		/* width of each element */
X	unsigned int	(*h1)();	/* primary hash function */
X	unsigned int	(*h2)();	/* secondary hash function */
X	int		(*compar)();	/* key comparison function */
X	long		*probes;
X{
X	register unsigned int	hash1;
X	register unsigned int	hash2;
X	register char	*slot;
X
X	hash1 = (*h1)(key) % nel;
X	slot = &base[hash1 * width];
X
X	if (probes)
X		(*probes)++;
X	if ((*compar)(key, slot) == 0)
X		return slot;
X
X	hash2 = (*h2)(key);
X	for (;;) {
X		hash1 = (hash1 + hash2) % nel;
X		slot = &base[hash1 * width];
X
X		if (probes)
X			(*probes)++;
X		if ((*compar)(key, slot) == 0)
X			return slot;
X	}
X}
X
X#define	ABS(n)		((n) < 0 ? -(n) : (n))
X
X/*
X	A Primary hash function for string keys.
X*/
Xint
Xh1str(key)
X	register char	*key;
X{
X	register int	sum;
X	register int	s;
X
X	for (sum = s = 0; *key; s++)
X		sum += ((*key++) << s);
X
X	return ABS(sum);
X}
X
X/*
X	A Secondary hash function for string keys.
X*/
Xint
Xh2str(key)
X	register char	*key;
X{
X	register int	sum;
X	register int	s;
X	char		*keysav;
X
X	keysav = key;
X	key = &key[strlen(key)];
X
X	for (sum = s = 0; key > keysav; s++)
X		sum += ((*--key) << s);
X
X	return ABS(sum) | 1;
X}
END_OF_FILE
if test 2237 -ne `wc -c <'hash.c'`; then
    echo shar: \"'hash.c'\" unpacked with wrong size!
fi
# end of 'hash.c'
fi
if test -f 'id.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'id.h'\"
else
echo shar: Extracting \"'id.h'\" \(1716 characters\)
sed "s/^X//" >'id.h' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
X/* @(#)id.h	1.1 86/10/09 */
X
X#define	IDFILE	"ID"
X
Xstruct idhead {
X	char	idh_magic[2];	/* magic number */
X#define	IDH_MAGIC "\311\304"	/* magic-number ("ID" with hi bits) */
X	short	idh_vers;	/* id-file version number */
X#define	IDH_VERS	2	/* current version */
X	int	idh_argc;	/* # of args for mkid update */
X	int	idh_pthc;	/* # of paths for mkid update */
X	int	idh_namc;	/* # of identifiers */
X	int	idh_vecc;	/* # of bytes in a path vector entry */
X	int	idh_bsiz;	/* # of bytes in entry (bufsiz for lid) */
X	long	idh_argo;	/* file offset of args for mkid update */
X	long	idh_namo;	/* file offset of identifier names */
X	long	idh_endo;	/* file offset of EOF */
X};
X
Xstruct idarg {
X	struct idarg	*ida_next;
X	char	*ida_arg;
X	int	ida_index;
X	char	ida_flags;
X#define	IDA_ADJUST	0x01
X#define	IDA_SCAN	0x02
X#define	IDA_PATH	0x04
X#define	IDA_ARG		0x08
X#define	IDA_BLANK	0x10
X};
X
Xstruct idname {
X	char	*idn_name;
X	char	*idn_bitv;
X	char	idn_flags;
X#define	IDN_SOLO	0x01	/* occurs only once */
X#define	IDN_NUMBER	0x02	/* is a number */
X#define	IDN_NAME	0x04	/* is a name */
X#define	IDN_STRING	0x08	/* is a string */
X#define	IDN_LITERAL	0x10	/* occurs as a literal (not string) */
X#define	IDN_NOISE	0x20	/* occurs very frequently */
X};
X
X/*
X	Extract the various logical fields of a name:
X
X	NAME: null-terminated ascii string
X	TAG:  index of name within a sorted array of all names
X	SOLO: boolean indicating that this name occurs exactly once
X*/
X#define	ID_PATHS(b) ((b)+strlen(b)+1)
X#define	ID_FLAGS(b) (*(b))
X#define	ID_STRING(b) ((b)+1)
X
X#define	NEW(type)	((type *)calloc(1, sizeof(type)))
X
X#define	GETARG(argc, argv)	((argc)--, *(argv)++)
X#define	UNGETARG(argc, argv)	((argc)++, *--(argv))
END_OF_FILE
if test 1716 -ne `wc -c <'id.h'`; then
    echo shar: \"'id.h'\" unpacked with wrong size!
fi
# end of 'id.h'
fi
if test -f 'kshgetwd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'kshgetwd.c'\"
else
echo shar: Extracting \"'kshgetwd.c'\" \(1781 characters\)
sed "s/^X//" >'kshgetwd.c' <<'END_OF_FILE'
X#include <string.h>
X#include <sys/param.h>
X#include <sys/stat.h>
X
Xextern char * getenv();
Xextern void cannoname();
Xextern char * unsymlink();
Xextern char * getwd();
X
X/* kshgetwd is a routine that acts just like getwd, but is optimized
X * for ksh users, taking advantage of the fact that ksh maintains
X * an environment variable named PWD holding path name of the
X * current working directory.
X *
X * The primary motivation for this is not really that it is algorithmically
X * simpler, but that it is much less likely to bother NFS if we can just
X * guess the name of the current working directory using the hint that
X * ksh maintains. Anything that avoids NFS gettar failed messages is
X * worth doing.
X */
Xchar *
Xkshgetwd(pathname)
X   char *   pathname;
X{
X   struct stat kshstat, dotstat ;
X   char        kshname[MAXPATHLEN] ;
X   char *      kshp ;
X
X   kshp = getenv("PWD") ;
X   if (kshp) {
X      /* OK, there was a PWD environment variable */
X      strcpy(kshname, kshp) ;
X      if (unsymlink(kshname)) {
X         /* And we could resolve the symbolic links through it */
X         if (kshname[0] == '/') {
X            /* And the name we have is an absolute path name */
X            if (stat(kshname, &kshstat) == 0) {
X               /* And we can stat the name */
X               if (stat(".", &dotstat) == 0) {
X                  /* And we can stat "." */
X                  if ((kshstat.st_dev == dotstat.st_dev) &&
X                      (kshstat.st_ino == dotstat.st_ino)) {
X                     /* By golly, that name is the same file as "." ! */
X                     return(strcpy(pathname, kshname)) ;
X                  }
X               }
X            }
X         }
X      }
X   }
X   /* Oh well, something did not work out right, do it the hard way */
X   return(getwd(pathname)) ;
X}
END_OF_FILE
if test 1781 -ne `wc -c <'kshgetwd.c'`; then
    echo shar: \"'kshgetwd.c'\" unpacked with wrong size!
fi
# end of 'kshgetwd.c'
fi
if test -f 'opensrc.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'opensrc.c'\"
else
echo shar: Extracting \"'opensrc.c'\" \(2529 characters\)
sed "s/^X//" >'opensrc.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)opensrc.c	1.1 86/10/09";
X
X#include	<stdio.h>
X#include	<string.h>
X#include	<sys/types.h>
X#include	<sys/stat.h>
X
Xchar *findSrcFILE();
Xchar *getSCCS();
Xchar *coRCS();
X
XFILE *
XopenSrcFILE(path, sccsDir, rcsDir, filter)
X	char		*path;
X	char		*sccsDir;
X	char		*rcsDir;
X	char		*filter;
X{
X	char		*command = NULL;
X	char		*what = NULL;
X	char		*get = "get SCCS file";
X	char		*checkout = "checkout RCS file";
X	char		*dirName;
X	char		*baseName;
X	struct stat	statb;
X	char		popcom[1024];
X	FILE		*srcFILE;
X
X	if (stat(path, &statb) != 0) {
X		if ((baseName = strrchr(path, '/')) == NULL) {
X			dirName = ".";
X			baseName = path;
X		} else {
X			dirName = path;
X			*baseName++ = '\0';
X		}
X
X		if (rcsDir && (command = coRCS(dirName, baseName, rcsDir)))
X			what = checkout;
X		else if (sccsDir && (command = getSCCS(dirName, baseName, sccsDir)))
X			what = get;
X		else if ((command = coRCS(dirName, baseName, "RCS"))
X		     ||  (command = coRCS(dirName, baseName, ".")))
X			what = checkout;
X		else if ((command = getSCCS(dirName, baseName, "SCCS"))
X		     ||  (command = getSCCS(dirName, baseName, "sccs"))
X		     ||  (command = getSCCS(dirName, baseName, ".")))
X			what = get;
X
X		if (dirName == path)
X			*--baseName = '/';
X
X		if (!command) {
X			filerr("open", path);
X			return NULL;
X		}
X
X		system(command);
X		fprintf(stderr, "%s\n", command);
X	}
X	if (stat(path, &statb) != 0) {
X		filerr("open", path);
X		return NULL;
X	}
X	if (filter != NULL) {
X		sprintf(popcom,filter,path);
X		srcFILE = popen(popcom, "r");
X	} else {
X		srcFILE = fopen(path, "r");
X	}
X	if (srcFILE == NULL) {
X		filerr("open", path);
X	}
X	return srcFILE;
X}
X
Xvoid
XcloseSrcFILE(fp, filter)
X	FILE		*fp;
X	char		*filter;
X{
X	if (filter != NULL) {
X		pclose(fp);
X	} else {
X		fclose(fp);
X	}
X}
X
Xchar *
XgetSCCS(dir, base, sccsDir)
X	char		*dir;
X	char		*base;
X	char		*sccsDir;
X{
X	static char	cmdBuf[BUFSIZ];
X	char		fileBuf[BUFSIZ];
X	struct stat	statBuf;
X
X	if (!*sccsDir)
X		sccsDir = ".";
X
X	sprintf(fileBuf, "%s/%s/s.%s", dir, sccsDir, base);
X	if (stat(fileBuf, &statBuf) < 0)
X		return NULL;
X	sprintf(cmdBuf, "cd %s; get -s %s/s.%s", dir, sccsDir, base);
X
X	return cmdBuf;
X}
X
Xchar *
XcoRCS(dir, base, rcsDir)
X	char		*dir;
X	char		*base;
X	char		*rcsDir;
X{
X	static char	cmdBuf[BUFSIZ];
X	char		fileBuf[BUFSIZ];
X	struct stat	statBuf;
X
X	if (!*rcsDir)
X		rcsDir = ".";
X
X	sprintf(fileBuf, "%s/%s/%s,v", dir, rcsDir, base);
X	if (stat(fileBuf, &statBuf) < 0)
X		return NULL;
X	sprintf(cmdBuf, "cd %s; co -q %s/%s,v", dir, rcsDir, base);
X
X	return cmdBuf;
X}
END_OF_FILE
if test 2529 -ne `wc -c <'opensrc.c'`; then
    echo shar: \"'opensrc.c'\" unpacked with wrong size!
fi
# end of 'opensrc.c'
fi
if test -f 'stoi.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stoi.c'\"
else
echo shar: Extracting \"'stoi.c'\" \(1883 characters\)
sed "s/^X//" >'stoi.c' <<'END_OF_FILE'
X/* Copyright (c) 1986, Greg McGary */
Xstatic char sccsid[] = "@(#)stoi.c	1.1 86/10/09";
X
X#include	<radix.h>
X#include	<ctype.h>
X
Xint dtoi();
Xint otoi();
Xint radix();
Xint stoi();
Xint xtoi();
X
X/*
X	Use the C lexical rules to determine an ascii number's radix.
X	The radix is returned as a bit map, so that more than one radix
X	may apply.  In particular, it is impossible to determine the
X	radix of 0, so return all possibilities.
X*/
Xint
Xradix(name)
X	register char	*name;
X{
X	if (!isdigit(*name))
X		return 0;
X	if (*name != '0')
X		return RADIX_DEC;
X	name++;
X	if (*name == 'x' || *name == 'X')
X		return RADIX_HEX;
X	while (*name && *name == '0')
X		name++;
X	return (RADIX_OCT | ((*name)?0:RADIX_DEC));
X}
X
X/*
X	Convert an ascii string number to an integer.
X	Determine the radix before converting.
X*/
Xint
Xstoi(name)
X	char		*name;
X{
X	switch (radix(name))
X	{
X	case RADIX_DEC:	return(dtoi(name));
X	case RADIX_OCT:	return(otoi(&name[1]));
X	case RADIX_HEX:	return(xtoi(&name[2]));
X	case RADIX_DEC|RADIX_OCT: return(0);
X	default:	return(-1);
X	}
X}
X
X/*
X	Convert an ascii octal number to an integer.
X*/
Xint
Xotoi(name)
X	char		*name;
X{
X	register int	n = 0;
X
X	while (*name >= '0' && *name <= '7') {
X		n *= 010;
X		n += *name++ - '0';
X	}
X	if (*name == 'l' || *name == 'L')
X		name++;
X	return (*name ? -1 : n);
X}
X
X/*
X	Convert an ascii decimal number to an integer.
X*/
Xint
Xdtoi(name)
X	char		*name;
X{
X	register int	n = 0;
X
X	while (isdigit(*name)) {
X		n *= 10;
X		n += *name++ - '0';
X	}
X	if (*name == 'l' || *name == 'L')
X		name++;
X	return (*name ? -1 : n);
X}
X
X/*
X	Convert an ascii hex number to an integer.
X*/
Xint
Xxtoi(name)
X	char		*name;
X{
X	register int	n = 0;
X
X	while (isxdigit(*name)) {
X		n *= 0x10;
X		if (isdigit(*name))
X			n += *name++ - '0';
X		else if (islower(*name))
X			n += 0xa + *name++ - 'a';
X		else
X			n += 0xA + *name++ - 'A';
X	}
X	if (*name == 'l' || *name == 'L')
X		name++;
X	return (*name ? -1 : n);
X}
END_OF_FILE
if test 1883 -ne `wc -c <'stoi.c'`; then
    echo shar: \"'stoi.c'\" unpacked with wrong size!
fi
# end of 'stoi.c'
fi
if test -f 'unsymlink.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unsymlink.c'\"
else
echo shar: Extracting \"'unsymlink.c'\" \(2622 characters\)
sed "s/^X//" >'unsymlink.c' <<'END_OF_FILE'
X#include <string.h>
X#include <sys/param.h>
X#include <sys/stat.h>
X
Xextern void cannoname();
X
X/* unsymlink is a routine that resolves all symbolic links in
X * a file name, transforming a name to the "actual" file name
X * instead of the name in terms of symbolic links.
X *
X * If it can resolve all links and discover an actual file
X * it returns a pointer to its argument string and transforms
X * the argument in place to the actual name.
X *
X * If no such actual file exists, or for some reason the links
X * cannot be resolved, it returns a NULL pointer and leaves the
X * name alone.
X */
Xchar *
Xunsymlink(n)
X   char *    n;
X{
X   char          newname[MAXPATHLEN];
X   char          partname[MAXPATHLEN];
X   char          linkname[MAXPATHLEN];
X   char *        s;
X   char *        d;
X   char *        lastcomp;
X   int           linksize;
X   struct stat   statb;
X
X   /* Just stat the file to automagically do all the symbolic
X    * link verification checks and make sure we have access to
X    * directories, etc.
X    */
X   if (stat(n, &statb) != 0) return(NULL) ;
X   strcpy(newname, n);
X   /* Now loop, lstating each component to see if it is a symbolic
X    * link. For symbolic link components, use readlink() to get
X    * the real name, put the read link name in place of the
X    * last component, and start again.
X    */
X   cannoname(newname) ;
X   s = &newname[0] ;
X   d = &partname[0] ;
X   if (*s == '/') {
X      *d++ = *s++ ;
X   }
X   lastcomp = d ;
X   for ( ; ; ) {
X      if ((*s == '/') || (*s == '\0')) {
X         /* we have a complete component name in partname, check it out */
X         *d = '\0' ;
X         if (lstat(partname, &statb) != 0) return(NULL) ;
X         if ((statb.st_mode & S_IFMT) == S_IFLNK) {
X            /* This much of name is a symbolic link, do a readlink
X             * and tack the bits and pieces together
X             */
X            linksize = readlink(partname, linkname, MAXPATHLEN) ;
X            if (linksize < 0) return(NULL) ;
X            linkname[linksize] = '\0' ;
X            strcpy(lastcomp, linkname) ;
X            lastcomp += linksize ;
X            strcpy(lastcomp, s) ;
X            strcpy(newname, partname) ;
X            cannoname(newname) ;
X            s = &newname[0] ;
X            d = &partname[0] ;
X            if (*s == '/') {
X               *d++ = *s++ ;
X            }
X            lastcomp = d ;
X         } else {
X            /* Not a symlink, just keep scanning to next component */
X            if (*s == '\0') break ;
X            *d++ = *s++ ;
X            lastcomp = d ;
X         }
X      } else {
X         *d++ = *s++ ;
X      }
X   }
X   strcpy(n, newname) ;
X   return(n) ;
X}
END_OF_FILE
if test 2622 -ne `wc -c <'unsymlink.c'`; then
    echo shar: \"'unsymlink.c'\" unpacked with wrong size!
fi
# end of 'unsymlink.c'
fi
echo shar: End of archive 2 \(of 11\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 11 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
--
======================================================================
domain: tahorsley at csd.harris.com       USMail: Tom Horsley
  uucp: ...!uunet!hcx1!tahorsley               511 Kingbird Circle
                                               Delray Beach, FL  33444
+==== Censorship is the only form of Obscenity ======================+
|     (Wait, I forgot government tobacco subsidies...)               |
+====================================================================+



More information about the Alt.sources mailing list