home *** CD-ROM | disk | FTP | other *** search
-
- /*
- * 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));
- }
-
-