char *whoami = "mailhub.gen";
char *ingres_date_and_time();
char *perm_malloc();
+char *pstrsave();
char *divide = "##############################################################";
#define ML_WID 72
#define FALSE 0
#define TRUE (!FALSE)
+FILE *out= stdout;
+
main(argc, argv)
int argc;
char **argv;
{
long tm = time(NULL);
- FILE *out= stdout;
char filename[64], *targetfile;
struct stat sb;
## int flag;
sort_info();
fprintf(stderr, "Dumping information\n");
- do_lists(out);
- do_people(out);
+ do_people();
fprintf(out, "\n%s\n# End of aliases file\n", divide);
## retrieve (buf = list.modtime) where list.list_id = 0
cnt = 0;
- machines = create_hash(1000);
-## retrieve (id = machine.mach_id, name = machine.#name) {
+ machines = create_hash(10);
+## retrieve (id = machine.mach_id, name = machine.#name)
+## where machine.mach_id = users.pop_id {
if (s = index(name, '.'))
*s = 0;
+ else
+ strtrim(name);
#ifdef ATHENA
- sprintf(buf, "%s.LOCAL", name);
- if (hash_store(machines, id, strsave(buf)) < 0) {
-#else
- if (hash_store(machines, id, strsave(name)) < 0) {
+ strcat(name, ".LOCAL");
#endif
+ if (hash_store(machines, id, pstrsave(name)) < 0) {
fprintf(stderr, "Out of memory!\n");
exit(MR_NO_MEM);
}
fprintf(stderr, "Loaded %d machines\n", cnt);
cnt = 0;
- strings = create_hash(2000);
+ strings = create_hash(4000);
## retrieve (id = strings.string_id, name = strings.string) {
- if (hash_store(strings, id, strsave(strtrim(name))) < 0) {
+ if (hash_store(strings, id, pstrsave(strtrim(name))) < 0) {
fprintf(stderr, "Out of memory!\n");
exit(MR_NO_MEM);
}
## type = u.potype, pid = u.pop_id, bid = u.box_id)
## where u.status != 3 {
u = (struct user *) perm_malloc(sizeof(struct user));
- u->login = strsave(strtrim(name));
- u->first = strsave(strtrim(fname));
- u->last = strsave(strtrim(lname));
+ u->login = pstrsave(strtrim(name));
+ u->first = pstrsave(strtrim(fname));
+ u->last = pstrsave(strtrim(lname));
if (mname[0] != ' ')
u->mi = mname[0];
else
u->mi = 0;
if (type[0] == 'P' && (s = hash_lookup(machines, pid))) {
- sprintf(buf, "%s@%s", strtrim(name), s);
- u->pobox = strsave(buf);
+ sprintf(buf, "%s@%s", u->login, s);
+ u->pobox = pstrsave(buf);
} else if (type[0] == 'S') {
u->pobox = hash_lookup(strings, bid);
} else
## type = l.acl_type, acl = l.acl_id)
## where l.active != 0 {
l = (struct list *) perm_malloc(sizeof(struct list));
- l->name = strsave(strtrim(name));
+ l->name = pstrsave(strtrim(name));
l->maillist = maillistp;
l->acl_t = type[0];
l->acl_id = acl;
register struct member *m;
register struct list *l1;
- if (l->maillist == 2 ||
- l->maillist == 3 ||
+ if (l->maillist > 1 ||
(l->maillist == 0 && !force))
return;
return;
}
l->maillist = 2;
- insert_name(l->name, -id, TRUE, FALSE);
+ insert_name(l->name, -1, TRUE, FALSE);
+ output_mlist(id, l);
if (l->acl_t == 'L' && (l1 = (struct list *)hash_lookup(lists, l->acl_id)))
save_mlist(0, l1, TRUE);
exit(MR_NO_MEM);
}
if (copy)
- ns->name = strsave(s);
+ ns->name = pstrsave(s);
else
ns->name = s;
ns->keep = nodups;
ns->id = id;
+ ns->next = NULL;
if (hash_store(names, code, ns) < 0) {
fprintf(stderr, "Out of memory!\n");
exit(MR_NO_MEM);
}
ns = ns->next;
if (copy)
- ns->name = strsave(s);
+ ns->name = pstrsave(s);
else
ns->name = s;
ns->keep = nodups;
ns->id = id;
+ ns->next = NULL;
return;
}
foundns:
- if (nodups || ns->keep)
- return;
+ if (nodups || ns->keep) {
+ if (nodups && ns->keep)
+ fprintf(stderr, "duplicated named: %s\n", s);
+ return;
+ }
ns->id = 0;
}
{
names = create_hash(20001);
hash_step(users, insert_login, NULL);
+ incount = 0;
+ fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
hash_step(lists, save_mlist, FALSE);
+ fprintf(stderr, "Output %d lists\n", incount);
hash_step(users, insert_names, NULL);
fprintf(stderr, "Inserted %d names\n", incount);
}
int lwid, bol, awid;
-output_mlist(id, l, out)
+output_mlist(id, l)
int id;
register struct list *l;
-FILE *out;
{
struct list *l1;
register struct member *m;
register struct user *u;
- if (l->maillist != 2)
- return;
if (l->acl_t == 'L' &&
(l1 = (struct list *) hash_lookup(lists, l->acl_id)))
fprintf(out, "owner-%s: %s\n%s: ", l->name, l1->name, l->name);
else if (l->acl_t == 'U' &&
(u = (struct user *) hash_lookup(users, l->acl_id)))
fprintf(out, "owner-%s: %s\n%s: ", l->name, u->login, l->name);
+ else
+ fprintf(out, "%s: ", l->name);
+
lwid = strlen(l->name) + 2;
bol = 1;
}
-do_lists(out)
-FILE *out;
-{
- incount = 0;
- fprintf(out, "\n%s\n# Mailing lists\n%s\n", divide, divide);
- hash_step(lists, output_mlist, out);
- fprintf(stderr, "Output %d lists\n", incount);
-}
-
-do_people(out)
-FILE *out;
+do_people()
{
incount = 0;
fprintf(out, "\n%s\n# People\n%s\n", divide, divide);
return(ret);
}
+
+/*
+ * Make a (permenant) copy of a string.
+ */
+char *
+pstrsave(s)
+ char *s;
+{
+ register int len;
+ register char *p;
+ /* Kludge for sloppy string semantics */
+ if (!s) {
+ printf("NULL != \"\" !!!!\r\n");
+ p = perm_malloc(1);
+ *p = '\0';
+ return p;
+ }
+ len = strlen(s) + 1;
+ p = perm_malloc((u_int)len);
+ if (p) bcopy(s, p, len);
+ return p;
+}
+
+#define hash_func(h, key) (key >= 0 ? (key % h->size) : (-key % h->size))
+
+/* Create a hash table. The size is just a hint, not a maximum. */
+
+struct hash *create_hash(size)
+int size;
+{
+ struct hash *h;
+
+ h = (struct hash *) perm_malloc(sizeof(struct hash));
+ if (h == (struct hash *) NULL)
+ return((struct hash *) NULL);
+ h->size = size;
+ h->data = (struct bucket **) perm_malloc(size * sizeof(char *));
+ if (h->data == (struct bucket **) NULL) {
+ free(h);
+ return((struct hash *) NULL);
+ }
+ bzero(h->data, size * sizeof(char *));
+ return(h);
+}
+
+/* Lookup an object in the hash table. Returns the value associated with
+ * the key, or NULL (thus NULL is not a very good value to store...)
+ */
+
+char *hash_lookup(h, key)
+struct hash *h;
+register int key;
+{
+ register struct bucket *b;
+
+ b = h->data[hash_func(h, key)];
+ while (b && b->key != key)
+ b = b->next;
+ if (b && b->key == key)
+ return(b->data);
+ else
+ return(NULL);
+}
+
+
+/* Update an existing object in the hash table. Returns 1 if the object
+ * existed, or 0 if not.
+ */
+
+int hash_update(h, key, value)
+struct hash *h;
+register int key;
+char *value;
+{
+ register struct bucket *b;
+
+ b = h->data[hash_func(h, key)];
+ while (b && b->key != key)
+ b = b->next;
+ if (b && b->key == key) {
+ b->data = value;
+ return(1);
+ } else
+ return(0);
+}
+
+
+/* Store an item in the hash table. Returns 0 if the key was not previously
+ * there, 1 if it was, or -1 if we ran out of memory.
+ */
+
+int hash_store(h, key, value)
+struct hash *h;
+register int key;
+char *value;
+{
+ register struct bucket *b, **p;
+
+ p = &(h->data[hash_func(h, key)]);
+ if (*p == NULL) {
+ b = *p = (struct bucket *) perm_malloc(sizeof(struct bucket));
+ if (b == (struct bucket *) NULL)
+ return(-1);
+ b->next = NULL;
+ b->key = key;
+ b->data = value;
+ return(0);
+ }
+
+ for (b = *p; b && b->key != key; b = *p)
+ p = (struct bucket **) *p;
+ if (b && b->key == key) {
+ b->data = value;
+ return(1);
+ }
+ b = *p = (struct bucket *) perm_malloc(sizeof(struct bucket));
+ if (b == (struct bucket *) NULL)
+ return(-1);
+ b->next = NULL;
+ b->key = key;
+ b->data = value;
+ return(0);
+}
+
+
+/* Search through the hash table for a given value. For each piece of
+ * data with that value, call the callback proc with the corresponding key.
+ */
+
+hash_search(h, value, callback)
+struct hash *h;
+register char *value;
+void (*callback)();
+{
+ register struct bucket *b, **p;
+
+ for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
+ for (b = *p; b; b = b->next) {
+ if (b->data == value)
+ (*callback)(b->key);
+ }
+ }
+}
+
+
+/* Step through the hash table, calling the callback proc with each key.
+ */
+
+hash_step(h, callback, hint)
+struct hash *h;
+void (*callback)();
+char *hint;
+{
+ register struct bucket *b, **p;
+
+ for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
+ for (b = *p; b; b = b->next) {
+ (*callback)(b->key, b->data, hint);
+ }
+ }
+}
+
+
+/* Deallocate all of the memory associated with a table */
+
+hash_destroy(h)
+struct hash *h;
+{
+ register struct bucket *b, **p, *b1;
+
+ for (p = &(h->data[h->size - 1]); p >= h->data; p--) {
+ for (b = *p; b; b = b1) {
+ b1 = b->next;
+ free(b);
+ }
+ }
+}