home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Filename: expandalias $
- * $Revision: 1.11 $
- * $Date: 1994/03/13 18:24:34 $
- *
- * Copyright (C) 1993 by Peter Simons <simons@peti.GUN.de>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- * $Id: expandalias.c,v 1.11 1994/03/13 18:24:34 simons Exp simons $
- *
- */
-
- /**************************************************************************
- * *
- * Sektion: Macros, Definitions, Includes, Structures *
- * *
- **************************************************************************/
-
- /************************************* Includes ***********/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <fcntl.h>
- #include <time.h>
-
- #include <libraries/netsupport.h>
- #include <proto/netsupport.h>
-
- #include "protos.h"
-
- /************************************* Defines ************/
- #define MAX_RECEIPIENTS 1024 /*
- * max. number of receipients
- */
-
- #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;
-
- /************************************* Prototypes *********/
- static void callBack(char *, long, int);
- static Hash *FindHashObject(const char *);
- static void LoadHashObject(Hash *);
- static int HashFunc(const char *);
-
- /************************************* global Variables ***/
- static const char __RCSId[] = "$Id: expandalias.c,v 1.11 1994/03/13 18:24:34 simons Exp simons $";
-
- static char **new_receipients;
- static Hash *HashTab[HASHSIZE];
- static char Tmp[256];
-
-
- /**************************************************************************
- * *
- * Sektion: Unterprogramme *
- * *
- **************************************************************************/
-
- char **ExpandAliases(char *receipients[])
- {
- char **new_receipients2;
-
- if (*receipients == NULL)
- return NULL;
-
- if ((new_receipients = malloc(sizeof(char *[MAX_RECEIPIENTS]))) == NULL)
- return NULL;
-
- new_receipients2 = new_receipients;
- LoadAliases();
- while (*receipients != NULL) {
- UserAliasList(*receipients, (int (*)(char *, long, int)) callBack, 0L, 1);
- receipients++;
- }
- *new_receipients = NULL;
- return new_receipients2;
- }
-
- static void callBack(char *name, long dummy, int show)
- {
- switch (name[0]) {
- case '|':
- case '>':
- case '<':
- break;
- case '\\':
- ++name;
- default:
- *new_receipients = name;
- new_receipients++;
- break;
- }
- }
-
- void LoadAliases(void)
- {
- FILE *fi = fopen("UULib:Aliases", "r");
- short i, j, k, line = 0;
- long offset, newoffset = 0;
- Hash *h;
- char *buf = Tmp;
-
- if (fi == NULL) {
- MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "Can't open UULib:Aliases!");
- 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) {
- MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "No Colon UULib:Aliases line %d.", 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(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)
- {
- FILE *fi = fopen("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) {
- MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "Can't open 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(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(const char *user,
- int (*callback) (const char *, long, int),
- long arg,
- int showto)
- {
- short i;
- Hash *hash = FindHashObject(user);
- static short stack;
-
- if (++stack == 32) {
- MakeLogEntry(PRGNAME, MLE_FATAL_ERROR, "UULib:Aliases recursion near user %s.", user);
- --stack;
- return 0;
- }
-
- 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(const char *str)
- {
- unsigned long v = 0x14FBA5C3;
-
- while (*str) {
- v = (v << 5) ^ (*str & 0x1F) ^ (v >> 27);
- ++str;
- }
- return ((int) (v & HASHMASK));
- }
-