summaryrefslogtreecommitdiffstats
path: root/util/uhash_loader.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/uhash_loader.c')
-rw-r--r--util/uhash_loader.c129
1 files changed, 129 insertions, 0 deletions
diff --git a/util/uhash_loader.c b/util/uhash_loader.c
new file mode 100644
index 00000000..2d88dd06
--- /dev/null
+++ b/util/uhash_loader.c
@@ -0,0 +1,129 @@
+/* $Id: uhash_loader.c,v 1.1 2002/03/07 15:13:47 in2 Exp $ */
+/* standalone uhash loader -- jochang */
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#ifdef __FreeBSD__
+#include <machine/param.h>
+#endif
+
+#include "config.h"
+#include "pttstruct.h"
+#include "common.h"
+
+unsigned string_hash(unsigned char *s);
+void add_to_uhash(int n, userec_t *id);
+void fill_uhash(void);
+void load_uhash(void);
+
+uhash_t *uhash;
+
+int main() {
+ setgid(BBSGID);
+ setuid(BBSUID);
+ chdir(BBSHOME);
+ load_uhash();
+ return 0;
+}
+
+void load_uhash(void) {
+ int shmid;
+ shmid = shmget(UHASH_KEY, sizeof(uhash_t), IPC_CREAT | 0600);
+/* note we didn't use IPC_EXCL here.
+ so if the loading fails,
+ (like .PASSWD doesn't exist)
+ we may try again later.
+*/
+ if (shmid < 0)
+ {
+ perror("shmget");
+ exit(1);
+ }
+
+ uhash = (void *) shmat(shmid, NULL, 0);
+ if (uhash == (void *) -1)
+ {
+ perror("shmat");
+ exit(1);
+ }
+
+/* in case it's not assumed zero, this becomes a race... */
+ uhash->loaded = 0;
+
+ fill_uhash();
+
+/* ok... */
+ uhash->loaded = 1;
+}
+
+void fill_uhash(void)
+{
+ int fd, usernumber;
+ usernumber = 0;
+
+ for (fd = 0; fd < (1 << HASH_BITS); fd++)
+ uhash->hash_head[fd] = -1;
+
+ if ((fd = open(FN_PASSWD, O_RDONLY)) > 0)
+ {
+ struct stat stbuf;
+ caddr_t fimage, mimage;
+
+ fstat(fd, &stbuf);
+ fimage = mmap(NULL, stbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (fimage == (char *) -1)
+ {
+ perror("mmap");
+ exit(1);
+ }
+ close(fd);
+ fd = stbuf.st_size / sizeof(userec_t);
+ if (fd > MAX_USERS)
+ fd = MAX_USERS;
+
+ for (mimage = fimage; usernumber < fd; mimage += sizeof(userec_t))
+ {
+ add_to_uhash(usernumber, mimage);
+ usernumber++;
+ }
+ munmap(fimage, stbuf.st_size);
+ }
+ else
+ {
+ perror("open");
+ exit(1);
+ }
+ uhash->number = usernumber;
+ printf("total %d names loaded.\n", usernumber);
+}
+unsigned string_hash(unsigned char *s)
+{
+ unsigned int v = 0;
+ while (*s)
+ {
+ v = (v << 8) | (v >> 24);
+ v ^= toupper(*s++); /* note this is case insensitive */
+ }
+ return (v * 2654435769UL) >> (32 - HASH_BITS);
+}
+
+void add_to_uhash(int n, userec_t *user)
+{
+ int *p, h = string_hash(user->userid);
+ strcpy(uhash->userid[n], user->userid);
+ uhash->money[n] = user->money;
+ p = &(uhash->hash_head[h]);
+
+ while (*p != -1)
+ p = &(uhash->next_in_hash[*p]);
+
+ uhash->next_in_hash[*p = n] = -1;
+}