home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The CDPD Public Domain Collection for CDTV 4
/
CDPD_IV.bin
/
networking
/
uucp
/
amigauucpsrc
/
lib
/
alias.c
next >
Wrap
C/C++ Source or Header
|
1994-06-29
|
7KB
|
311 lines
/*
* ALIAS.C
*
* (C) Copyright 1989-1990 by Matthew Dillon, All Rights Reserved.
*
* Interpret UULIB:Aliases file. To save space we do not load
* the entire file, just sections on demand.
*
* # = comment
* id: name [, name...]
*
* name is a user name, path, or |filter, or quoted name. Example,
* "|more" or "|rnews"
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <time.h>
#include "config.h"
#include "log.h"
#define HASHSIZE 256
#define HASHMASK (HASHSIZE-1)
#define HF_TERM 0x01 /* terminator name */
#define HF_ALIAS 0x02 /* alias */
#define HF_LOADED 0x04 /* def loaded */
#define HF_NOEXPAND 0x08 /* do not expand alias */
typedef struct Hash {
struct Hash *Next;
short NumAlias; /* # of aliases */
short Flags;
char *Name; /* aliased user name */
union {
struct Hash **Alias; /* list of aliases */
long Offset; /* offset into file */
} u;
} Hash;
Prototype void LoadAliases(void);
Prototype int UserAliasList(const char *, int (*)(const char *, long, int), long, int);
Prototype int AliasExists(const char *);
Local Hash *FindHashObject(const char *);
Local void LoadHashObject(Hash *);
Local int HashFunc(const char *);
static Hash *HashTab[HASHSIZE];
static char Tmp[256];
void
LoadAliases()
{
FILE *fi = fopen(MakeConfigPath(UULIB, "Aliases"), "r");
short i;
short j;
short k;
short line = 0;
long newoffset = 0;
long offset;
Hash *h;
char *buf = Tmp;
if (fi == NULL) {
strcpy(buf, MakeConfigPath(UULIB, "Aliases"));
ulog(-1, "Can't open %s", buf);
return;
}
while (fgets(buf, 256, fi)) {
offset = newoffset;
newoffset = ftell(fi);
++line;
for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i);
if (buf[i] == '#' || buf[i] == '\n')
continue;
for (j = i; buf[j] && buf[j] != ':'; ++j);
if (buf[j] == 0) {
strcpy(buf, MakeConfigPath(UULIB, "Aliases"));
ulog(-1, "No Colon %s line %d", buf, line);
continue;
}
buf[j] = 0;
k = HashFunc(buf + i);
h = malloc(sizeof(Hash));
h->Next = HashTab[k];
h->NumAlias = 0;
h->Flags = HF_ALIAS;
h->Name = malloc(strlen(buf+i) + 1);
if (buf[j+1] == ':') {
h->Flags |= HF_NOEXPAND;
++j;
}
h->u.Offset = offset + j + 1;
strcpy(h->Name, buf + i);
HashTab[k] = h;
/*
* if trailing comma, list continues onto next line
*/
for (;;) {
for (++j; buf[j]; ++j);
while (buf[j-1] == ' ' || buf[j-1] == 9 || buf[j-1] == '\n')
--j;
if (buf[j-1] != ',')
break;
if (fgets(buf, 256, fi) == NULL)
break;
newoffset = ftell(fi);
j = 0;
}
}
fclose(fi);
}
static
Hash *
FindHashObject(name)
const char *name;
{
short k = HashFunc(name);
Hash *h;
for (h = HashTab[k]; h; h = h->Next) {
if (stricmp(name, h->Name) == 0)
return(h);
}
return(NULL);
}
static
void
LoadHashObject(hash)
Hash *hash;
{
FILE *fi = fopen(MakeConfigPath(UULIB, "Aliases"), "r");
char *buf = Tmp;
short i, j;
short c;
short numalloc = 4;
Hash **hv = malloc(sizeof(Hash *) * 4);
Hash *h;
if (fi == NULL) {
ulog(-1, "Can't open %s", MakeConfigPath(UULIB, "Aliases"));
return;
}
hash->Flags |= HF_LOADED;
fseek(fi, hash->u.Offset, 0);
while (fgets(buf, 256, fi)) {
i = 0;
c = 'x';
for (i = 0; buf[i] == ' ' || buf[i] == 9; ++i);
if (buf[i] == '#')
continue;
for (;;) {
while (buf[i] == ' ' || buf[i] == 9)
++i;
if (buf[i] == 0 || buf[i] == '\n' || buf[i] == '#')
break;
for (j = i; buf[j] != '\n' && buf[j] != ' ' && buf[j] != 9 && buf[j] != ','; ++j) {
if (buf[j] == '\"') {
i = j + 1;
for (++j; buf[j] != '\n' && buf[j] != '\"'; ++j);
break;
}
}
c = buf[j];
buf[j] = 0;
/*
* skip remaining junk before comma
*/
while (c && c != '\n' && c != ',')
c = buf[++j];
if ((h = FindHashObject(buf + i)) == NULL) {
short k = HashFunc(buf + i);
h = malloc(sizeof(Hash));
h->Next = HashTab[k];
h->NumAlias = 0;
h->Flags = HF_TERM;
h->Name = malloc(strlen(buf + i) + 1);
h->u.Alias = NULL;
strcpy(h->Name, buf + i);
HashTab[k] = h;
}
if (hash->NumAlias == numalloc) {
Hash **hvo = hv;
short add = 4;
hv = malloc(sizeof(Hash *) * (numalloc + add));
movmem((char *)hvo, (char *)hv, sizeof(Hash *) * numalloc);
numalloc += add;
}
hv[hash->NumAlias++] = h;
if (c == '\n' || c == 0)
i = j;
else
i = j + 1;
}
if (c != ',')
break;
}
hash->u.Alias = hv;
}
int
AliasExists(user)
const char *user;
{
if (FindHashObject(user))
return(1);
return(0);
}
/*
* UserAliasList returns whether the 'user' should be displayed in the
* To: field of the letter. Normally it isn't, but if an alias is
* specified to NOT expand on the To: field then the alias name itself
* IS put on the To: field.
*
* showto is passed from an upper level. If set, the callback specifies
* expansion (unless overriden by the alias), else the callback specifies
* no expansion.
*
* In the case where a high level alias is expanded but a low level alias
* is not, the callback function is called for the low level alias with
* a showto of -1, indicating that it should be placed on the To: list
* WITHOUT being placed on the actual send-to list (because its expansion
* is passed normally)
*/
int
UserAliasList(user, callback, arg, showto)
const char *user;
int (*callback)(const char *, long, int);
long arg;
int showto;
{
short i;
int r;
Hash *hash = FindHashObject(user);
static short stack;
if (++stack == 32) {
ulog(-1, "%s recursion near user %s", MakeConfigPath(UULIB, "Aliases"), user);
--stack;
return;
}
if (hash) {
if ((hash->Flags & HF_TERM) == 0) {
if ((hash->Flags & HF_LOADED) == 0)
LoadHashObject(hash);
for (i = 0; i < hash->NumAlias; ++i) {
Hash *h = hash->u.Alias[i];
int r;
if (showto)
r = UserAliasList(h->Name, callback, arg, !(hash->Flags & HF_NOEXPAND));
else
r = UserAliasList(h->Name, callback, arg, 0);
--stack;
if (r && showto && !(hash->Flags & HF_NOEXPAND))
(*callback)(h->Name, arg, -1);
}
} else {
if (showto)
(*callback)(user, arg, !(hash->Flags & HF_NOEXPAND));
else
(*callback)(user, arg, 0);
}
} else {
(*callback)(user, arg, showto);
}
--stack;
if (hash && (hash->Flags & HF_NOEXPAND))
return(1);
return(0);
}
static int
HashFunc(str)
const char *str;
{
unsigned long v = 0x14FBA5C3;
while (*str) {
v = (v << 5) ^ (*str & 0x1F) ^ (v >> 27);
++str;
}
return((int)(v & HASHMASK));
}