taylor@hplabsc.UUCP (Dave Taylor) (03/18/87)
Well it appears that even more of the Elm transmission was a wee bit
mangled - "aliasdb.c" didn't survive the trip to a lot of sites. Gad.
So I've attached herein Another copy of the file. Please replace the
copy you have with this if you had any unpacking problems.
-- Dave Taylor
Hewlett-Packard Labs
---- Shell Archive:
# Shell Archive created by hpldat!taylor at Tue Mar 17 16:53:09 1987
# To unpack the enclosed files, please use this file as input to the
# Bourne (sh) shell. This can be most easily done by the command;
# sh < thisfilename
# This archive contains;
# src/aliasdb.c
if [ ! -d src ]
then
echo creating directory src
mkdir src
fi
# ---------- file src/aliasdb.c ----------
filename="src/aliasdb.c"
if [ -f $filename ]
then
echo File \"$filename\" already exists\! Skipping...
filename=/dev/null # throw it away
else
echo extracting file src/aliasdb.c...
fi
cat << 'END-OF-FILE' > $filename
/** aliasdb.c **/
/** Alias database files...
(C) Copyright 1986 Dave Taylor
**/
#include "headers.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
extern int errno;
#ifdef USE_DBM
# include <dbm.h>
#endif
#define absolute(x) ((x) > 0 ? x : -(x))
char *shift_lower(), *find_path_to(), *strcat(), *strcpy();
unsigned long sleep();
int findnode_has_been_initialized = FALSE;
findnode(name, display_error)
char *name;
int display_error;
{
/** break 'name' into machine!user or user@machine and then
see if you can find 'machine' in the path database..
If so, return name as the expanded address. If not,
return what was given to us! If display_error, then
do so...
**/
#ifndef DONT_TOUCH_ADDRESSES
char old_name[SLEN];
char address[SLEN];
if (strlen(name) == 0)
return;
if (! findnode_has_been_initialized) {
if (! mail_only)
error("initializing internal tables...");
#ifndef USE_DBM
get_connections();
open_domain_file();
#endif
init_findnode();
clear_error();
findnode_has_been_initialized = TRUE;
}
strcpy(old_name, name); /* save what we were given */
if (expand_site(name, address) == -1) {
if (display_error && name[0] != '!') {
dprint2(2,"Couldn't expand host %s in address. (%s)\n",
name, "findnode");
if (! check_only && warnings) { /* be silent if just checking */
if (mail_only)
printf("Warning: couldn't expand %s...\n\r", name);
else {
error1("Warning: couldn't expand %s...", name);
sleep(1);
}
}
}
strcpy(name, old_name); /* and restore... */
}
else
strcpy(name, address);
#endif
return;
}
int
expand_site(cryptic, expanded)
char *cryptic, *expanded;
{
/** Given an address of the form 'xyz@site' or 'site!xyz'
return an address of the form <expanded address for site>
with 'xyz' embedded according to the path database entry.
Note that 'xyz' can be eiher a simple address (as in "joe")
or a complex address (as in "joe%xerox.parc@Xerox.ARPA")!
0 = found, -1 return means unknown site code
Modified to strip out parenthetical comments...
**/
#ifdef ACSNET
strcpy(expanded, cryptic); /* fast and simple */
return(0);
#else
# ifdef USE_DBM
datum key, contents;
# endif
char name[VERY_LONG_STRING], sitename[VERY_LONG_STRING],
temp[VERY_LONG_STRING], old_name[VERY_LONG_STRING],
comment[LONG_STRING];
char *expand_domain(), *addr;
register int i = 0, j = 0, domain_name;
strcpy(old_name, cryptic); /* remember what we were given */
/** break down **/
/** first, rip out the comment, if any **/
if ((i = chloc(cryptic, '(')) > -1) {
comment[j++] = ' '; /* leading space */
for ( ;cryptic[i] != ')'; i++)
comment[j++] = cryptic[i];
comment[j++] = ')';
comment[j] = '\0';
/* and remove this from cryptic string too... */
if (cryptic[(j = chloc(cryptic,'('))-1] == ' ')
cryptic[j-1] = '\0';
else
cryptic[j] = '\0';
}
else
comment[0] = '\0';
i = j = 0; /* reset */
while (cryptic[i] != AT_SIGN && cryptic[i] != BANG &&
cryptic[i] != '\0' && cryptic[i] != '(')
sitename[j++] = cryptic[i++];
sitename[j++] = '\0';
j = 0;
if (cryptic[i] == '\0') return(-1); /* nothing to expand! */
domain_name = (cryptic[i] == AT_SIGN);
i++;
while (cryptic[i] != '\0' && cryptic[i] != '(' &&
! whitespace(cryptic[i]))
name[j++] = cryptic[i++];
name[j] = '\0';
if (domain_name) {
strcpy(temp, name);
strcpy(name, sitename);
strcpy(sitename, temp);
}
dprint3(5,"\nBroke address into '%s' @ '%s' '%s'\n\n",
name, sitename, comment);
#ifdef USE_DBM
if (size_of_pathfd == 0)
return(-1);
key.dptr = sitename;
key.dsize = strlen(sitename) + 1;
contents = fetch(key);
if (contents.dptr == 0)
return(-1); /* can't find it! */
sprintf(expanded, contents.dptr, name);
strcat(expanded, " "); /* add a single space... */
strcat(expanded, comment); /* ...and add comment */
return(0);
#endif
#ifndef LOOK_CLOSE_AFTER_SEARCH
if (talk_to(sitename)) {
strcpy(expanded, old_name); /* restore! */
return(0);
}
#endif
if ((addr = find_path_to(sitename, TRUE)) == NULL) {
#ifdef LOOK_CLOSE_AFTER_SEARCH
if (talk_to(sitename)) {
strcpy(expanded, old_name); /* restore! */
return(0);
}
else
#endif
if ((addr = expand_domain(cryptic)) != NULL) {
strcpy(expanded, addr); /* into THIS buffer */
strcat(expanded, comment); /* patch in comment */
return(0);
}
else if (size_of_pathfd == 0) { /* no path database! */
strcpy(expanded, old_name); /* restore! */
return(0);
}
else { /* We just can't get there! */
strcpy(expanded, old_name); /* restore! */
return(-1);
}
}
else { /* search succeeded */
sprintf(expanded, addr, name);
strcat(expanded, comment); /* add comment */
return(0);
}
#endif
}
int
binary_search(name, address)
char *name, *address;
{
/* binary search file for name. Return 0 if found, -1 if not */
char machine[40];
register long first = 0, last, middle;
register int compare;
address[0] = '\0';
last = size_of_pathfd;
do {
middle = (long) ((first+last) / 2);
get_entry(machine, address, pathfd, middle);
compare = strcmp(name, machine);
if (compare < 0)
last = middle - 1;
else if (compare == 0)
return(0);
else /* greater */
first = middle + 1;
} while (absolute(last) - absolute(first) > FIND_DELTA);
return(-1);
}
get_entry(machine, address, fileid, offset)
char *machine, *address;
FILE *fileid;
long offset;
{
/** get entry...return machine and address immediately
following given offset in fileid. **/
fseek(fileid, offset, 0);
/* read until we hit an end-of-line */
while (getc(fileid) != '\n')
;
fscanf(fileid, "%s\t%s", machine, address);
}
init_findnode()
{
/** Initialize the FILE and 'size_of_file' values for the
findnode procedure **/
struct stat buffer;
if (stat(pathfile, &buffer) == -1) {
dprint2(1, "Warning: No pathalias file [filename %s] found! (%s)\n",
pathfile, "init_findnode");
size_of_pathfd = 0;
return;
}
size_of_pathfd = (long) buffer.st_size;
#ifdef USE_DBM
if (dbminit(pathfile) != 0) {
dprint1(1, "Warning: couldn't initialize DBM database %s\n",
pathfile);
dprint2(1, "** %s - %s **\n\n", error_name(errno),
error_description(errno));
size_of_pathfd = 0; /* error flag, in this case */
return;
}
return;
#else
if ((pathfd = fopen(pathfile,"r")) == NULL) {
dprint2(1, "Warning: Can't read pathalias file [filename %s] (%s)\n",
pathfile, "init_findnode");
size_of_pathfd = 0;
}
else
dprint2(2, "\nOpened file '%s' as path alias database. (%s)\n\n",
pathfile, "init_findnode");
#endif
}
char *find_path_to(machine, printf_format)
char *machine;
int printf_format;
{
/** Returns either the path to the specified machine or NULL if
not found. If "printf_format" is TRUE, then it leaves the
'%s' intact, otherwise it assumes that the address is a uucp
address for the domain expansion program and removes the
last three characters of the expanded name ("!%s") since
they're redundant with the expansion!
**/
static char buffer[LONG_SLEN]; /* space for path */
if (size_of_pathfd > 0)
if (binary_search(machine, buffer) != -1) { /* found it! */
if (! printf_format && strlen(buffer) > 3)
buffer[strlen(buffer)-3] = '\0';
return( (char *) buffer);
}
return(NULL); /* failed if it's here! */
}
END-OF-FILE
if [ "$filename" != "/dev/null" ]
then
size=`wc -c < $filename`
if [ $size != 7752 ]
then
echo $filename changed - should be 7752 bytes, not $size bytes
fi
chmod 644 $filename
fi
echo done
exit 0