]> andersk Git - moira.git/commitdiff
Initial revision
authormar <mar>
Tue, 26 Sep 1989 12:10:47 +0000 (12:10 +0000)
committermar <mar>
Tue, 26 Sep 1989 12:10:47 +0000 (12:10 +0000)
afssync/Makefile [new file with mode: 0644]
afssync/resync.qc [new file with mode: 0644]

diff --git a/afssync/Makefile b/afssync/Makefile
new file mode 100644 (file)
index 0000000..c3e4fd9
--- /dev/null
@@ -0,0 +1,36 @@
+# $Header$
+
+CFLAGS = -I/mit/afsdev/build/vax/include -I../include -O
+
+OBJS = prprocs.o prutils.o utils.o ubik.o
+LIBS= -L../lib -lsms -lcom_err \
+        /usr/rtingres/lib/libqlib /usr/rtingres/lib/compatlib
+
+.SUFFIXES: .qc
+
+.qc.c: 
+       rm -f $*.c
+       /usr/rtingres/bin/eqc -p $*
+
+all: sync resync
+
+sync: sync.o $(OBJS)
+       cc -o sync sync.o $(OBJS) $(LIBS)
+sync.c: sync.qc
+
+resync: resync.o $(OBJS)
+       cc -o resync resync.o $(OBJS) $(LIBS)
+resync.c: resync.qc
+
+prnewuser: prnewuser.o $(OBJS)
+       cc -o prnewuser prnewuser.o $(OBJS)
+
+prnewlist: prnewlist.o $(OBJS)
+       cc -o prnewlist prnewlist.o $(OBJS)
+
+startsync: startsync.o
+       cc -o startsync startsync.o
+
+
+clean:
+       rm -f *.o resync.c sync.c resync sync startsync prnewlist prnewuser
diff --git a/afssync/resync.qc b/afssync/resync.qc
new file mode 100644 (file)
index 0000000..e81d30f
--- /dev/null
@@ -0,0 +1,417 @@
+/* $Header$
+ *
+ */
+
+#include <mit-copyright.h>
+#include <stdio.h>
+#include <sys/file.h>
+#include <rx/xdr.h>
+#include "print.h"
+#include "prserver.h"
+#include "prerror.h"
+#include <sms.h>
+#include <sms_app.h>
+#include <ctype.h>
+
+
+#define min(x,y)       ((x) < (y) ? (x) : (y))
+#define abs(x)         (((x) > 0) ? (x) : -(x))
+struct hash *users, *groups, *usersid, *groupsid;
+char *whoami = "sync";
+
+char *malloc(), *strsave();
+int dbase_fd;
+struct prheader prh;
+
+
+main(argc, argv)
+int argc;
+char **argv;
+{
+    int ingerr();
+
+    if (argc != 2) {
+       fprintf(stderr, "usage: %s dbfile\n", argv[0]);
+       exit(SMS_ARGS);
+    }
+
+    dbase_fd = open(argv[1], O_RDONLY, 0660);
+    if (dbase_fd < 0) {
+       perror("opening file %s", argv[1]);
+       exit(1);
+    }  
+    IIseterr(ingerr);
+    initialize_sms_error_table ();
+
+##  ingres sms
+##  set lockmode session where level = table
+##  begin transaction
+
+    get_users();
+    get_groups();
+    get_members();
+
+##  end transaction
+##  exit
+
+    pr_Read(NULL, 0, 0, &prh, sizeof(prh));
+    check_users_and_groups();
+
+    exit(SMS_SUCCESS);
+}
+
+
+/*
+ * ingerr: (supposedly) called when Ingres indicates an error.
+ * I have not yet been able to get this to work to intercept a
+ * database open error.
+ */
+#define INGRES_DEADLOCK 4700
+
+static int ingerr(num)
+    int *num;
+{
+    char buf[256];
+    int ingres_errno;
+
+    switch (*num) {
+    case INGRES_DEADLOCK:
+       ingres_errno = SMS_DEADLOCK;
+       break;
+    default:
+       ingres_errno = SMS_INGRES_ERR;
+    }
+    com_err(whoami, SMS_INGRES_ERR, " code %d\n", *num);
+    exit(ingres_errno);
+}
+
+
+prserror(status, msg, arg1, arg2)
+int status;
+char *msg;
+unsigned long arg1, arg2;
+{
+    char buf[512];
+
+    sprintf(buf, msg, arg1, arg2);
+    switch (status) {
+    case PREXIST:
+       msg = "name already exists";
+       break;
+    case PRIDEXIST:
+       msg = "ID already exists";
+       break;
+    case PRNOIDS:
+       msg = "no IDs available";
+       break;
+    case PRDBFAIL:
+       msg = "database failed";
+       break;
+    case PRNOENT:
+       msg = "no space left in database";
+       break;
+    case PRPERM:
+       msg = "permission denied";
+       break;
+    case PRNOTGROUP:
+       msg = "not a group";
+       break;
+    case PRNOTUSER:
+       msg = "not a user";
+       break;
+    case PRBADNAM:
+       msg = "bad name";
+       break;
+    case 0:
+       msg = "no error";
+       break;
+    default:
+       msg = "unknown code";
+       break;
+    }
+    fprintf(stderr, "%s (%d): %s\n", msg, status, buf);
+}
+
+
+nomem(msg)
+char *msg;
+{
+    fprintf(stderr, "Out of memory: %s\n", msg);
+    exit(1);
+}
+
+
+struct user {
+    char login[9];
+    char flag;
+    short uid;
+};
+
+
+get_users()
+##{
+##  char login[9];
+##  int uid, id;
+    struct user *u;
+
+    fprintf(stderr, "Loading users from Moira\n");
+    users = create_hash(10000);
+    usersid = create_hash(10000);
+##  range of u is users
+##  retrieve (login = u.#login, uid = u.#uid, id = u.users_id)
+##     where u.#status = 1 {
+           strtrim(login);
+           u = (struct user *)malloc(sizeof(struct user));
+           if (u == NULL)
+             nomem("loading users");
+           strncpy(u->login, login, 9);
+           u->flag = 0;
+           u->uid = uid;
+           hash_store(users, uid, u);
+           hash_store(usersid, id, u);
+##  }
+##}
+
+
+#define CHUNKSIZE 10
+struct chunk {
+    short member[CHUNKSIZE];
+    struct chunk *xmem;
+};
+
+struct group {
+    char name[33];
+    char flag;
+    short gid;
+    short members;
+    struct chunk ch;
+};
+
+
+get_groups()
+##{
+##  char name[33];
+##  int gid, id;
+    struct group *g;
+
+    fprintf(stderr, "Loading groups from Moira\n");
+    groups = create_hash(10000);
+    groupsid = create_hash(10000);
+##  range of l is list
+##  retrieve (name = l.#name, gid = l.#gid, id = l.list_id)
+##     where l.#active = 1 and l.#group = 1 {
+           strtrim(name);
+           g = (struct group *)malloc(sizeof(struct group));
+           if (g == NULL)
+             nomem("loading groups");
+           bzero(g, sizeof(struct group));
+           strncpy(g->name, name, 33);
+           hash_store(groups, gid, g);
+           hash_store(groupsid, id, g);
+##  }
+##}
+
+
+get_members()
+##{
+    struct user *u;
+    struct group *g;
+##  int id, lid;
+
+    fprintf(stderr, "Fetching members from Moira\n");
+
+##  range of m is imembers
+
+##  retrieve (lid = m.list_id, id = m.member_id)
+##     where m.member_type = "USER" {
+      if ((u = (struct user *) hash_lookup(usersid, id)) &&
+         (g = (struct group *) hash_lookup(groupsid, lid))) {
+         if (g->members < CHUNKSIZE) {
+             g->ch.member[g->members] = u->uid;
+         } else {
+             int i = g->members - CHUNKSIZE;
+             struct chunk *c;
+
+             if ((c = g->ch.xmem) == NULL) {
+                 c = (struct chunk *) malloc(sizeof(struct chunk));
+                 if (c == NULL)
+                   nomem("loading members");
+                 g->ch.xmem = c;
+             }
+             while (i >= CHUNKSIZE) {
+                 i -= CHUNKSIZE;
+                 if (c->xmem == NULL) {
+                     c->xmem = (struct chunk *) malloc(sizeof(struct chunk));
+                     if (c->xmem == NULL)
+                       nomem("loading members");
+                 }
+                 c = c->xmem;
+             }
+             c->member[i] = u->uid;
+         }
+         g->members++;
+      }
+##  }
+
+##}
+
+
+
+checkuser(id, u)
+int id;
+struct user *u;
+{
+    if (u->flag == 0)
+      printf("< User %s id %d is in Moira but not in prs\n", u->login, u->uid);
+}
+
+checkgroup(id, g)
+int id;
+struct group *g;
+{
+    register int i, j;
+    struct chunk *c;
+
+    if (g->flag == 0)
+      printf("< Group %s id %d is in Moira but not in prs\n", g->name, g->gid);
+    c = (struct chunk *)&(g->ch);
+    for (i = 0; i < g->members; i++) {
+       j = i % CHUNKSIZE;
+       printf("< Group %s contains user %d in Moira but not in prs\n",
+              g->name, c->member[j]);
+       if (j == CHUNKSIZE - 1)
+         c = c->xmem;
+    }
+}
+
+check_users_and_groups()
+{
+    register int i;
+    int offset;
+
+    fprintf(stderr, "Scanning PRS database\n");
+
+    for (i = 0; i < HASHSIZE; i++) {
+       offset = ntohl(prh.idHash[i]);
+       while (offset)
+         offset = check_entry(offset);
+    }
+    hash_step(users, checkuser, NULL);
+    hash_step(groups, checkgroup, NULL);
+}
+
+check_entry(offset)
+int offset;
+{
+    struct prentry entry;
+    int flags, id, status;
+    struct user *u;
+    struct group *g;
+
+    status = pr_Read(NULL, 0, offset, &entry, sizeof(entry));
+    if (status)
+      prserror(status, "reading prentry at %d", offset, 0);
+    flags = ntohl(entry.flags);
+    id = ntohl(entry.id);
+    if ((flags & PRFREE) == 0) {
+       if (flags & PRGRP) {
+           g = (struct group *) hash_lookup(groups, abs(id));
+           if (g == NULL)
+             printf("> Group %s, id %d is in prs but not moira\n",
+                    entry.name, id);
+           else if (strcasecmp(g->name, index(entry.name, ':')+1))
+             printf("> Group id %d in prs is %s, but GID %d in moira is %s\n",
+                    id, entry.name, -id, g->name);
+           else {
+               g->flag = 1;
+               if (entry.entries[0])
+                 do_members(&entry, g);
+           }
+       } else {
+           u = (struct user *) hash_lookup(users, abs(id));
+           if (u == NULL)
+             printf("> User %s, id %d is in prs but not moira\n",
+                    entry.name, id);
+           else if (strcasecmp(u->login, entry.name))
+             printf("> User id %d in prs is %s, but UID %d in moira is %s\n",
+                    id, entry.name, id, u->login);
+           else
+             u->flag = 1;
+       }
+    }
+    return(ntohl(entry.nextID));
+}
+
+
+do_members(e, g)
+struct prentry *e;
+struct group *g;
+{
+    register int i;
+    int offset;
+    struct contentry prco;
+
+    for (i = 0; i < PRSIZE; i++) {
+       if (e->entries[i] == 0)
+         return;
+       mark_member(g, ntohl(e->entries[i]));
+    }
+    offset = ntohl(e->next);
+    while (offset) {
+       pr_Read(NULL, 0, offset, &prco, sizeof(struct contentry));
+       for (i = 0; i < COSIZE; i++) {
+           if (prco.entries[i] == 0)
+             return;
+           mark_member(g, ntohl(prco.entries[i]));
+       }
+       offset = ntohl(prco.next);
+    }
+}
+
+
+mark_member(g, uid)
+struct group *g;
+int uid;
+{
+    register int i, j;
+
+    if (g->members >= CHUNKSIZE) {
+       short *s = NULL, s1;
+       struct chunk *c = (struct chunk *)&(g->ch);
+
+       for (i = 0; i < g->members; i++) {
+           j = i % CHUNKSIZE;
+           if (c->member[j] == uid) {
+               s = &(c->member[j]);
+           }
+           if (j == CHUNKSIZE - 1) {
+               s1 = c->member[CHUNKSIZE - 1];
+               c = c->xmem;
+           }
+       }
+       if (j != CHUNKSIZE - 1)
+         s1 = c->member[j];
+       if (s) {
+           *s = s1;
+           g->members--;
+           return;
+       }
+       printf("> Group %s contains user %d in prs but not in Moira\n", g->name,
+              uid);
+       return;
+    }
+    for (i = 0; i < g->members; i++) {
+       if (g->ch.member[i] == uid) {
+           if (g->members == i + 1)
+             g->ch.member[i] = 0;
+           else {
+               g->ch.member[i] = g->ch.member[g->members];
+               g->ch.member[g->members] = 0;
+           }
+           g->members--;
+           return;
+       }
+    }
+    printf("> Group %s contains user %d in prs but not in Moira\n", g->name,
+          uid);
+}
This page took 0.274535 seconds and 5 git commands to generate.