summaryrefslogtreecommitdiffstats
path: root/util/uhash_loader.c
diff options
context:
space:
mode:
authorptt <ptt@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-01-27 04:01:50 +0800
committerptt <ptt@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2005-01-27 04:01:50 +0800
commitc321fa85ecaef456ce58135fa3af76645673bffe (patch)
tree72ce82c30dacd37140bb91ad2538f3603f5258a8 /util/uhash_loader.c
parent949977dfed6a77c6c0daaeae498a9919dd22fdee (diff)
downloadpttbbs-c321fa85ecaef456ce58135fa3af76645673bffe.tar
pttbbs-c321fa85ecaef456ce58135fa3af76645673bffe.tar.gz
pttbbs-c321fa85ecaef456ce58135fa3af76645673bffe.tar.bz2
pttbbs-c321fa85ecaef456ce58135fa3af76645673bffe.tar.lz
pttbbs-c321fa85ecaef456ce58135fa3af76645673bffe.tar.xz
pttbbs-c321fa85ecaef456ce58135fa3af76645673bffe.tar.zst
pttbbs-c321fa85ecaef456ce58135fa3af76645673bffe.zip
Let admin fix passwd shm on the fly.
Don't need to restart mbbsd. git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@2435 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'util/uhash_loader.c')
-rw-r--r--util/uhash_loader.c89
1 files changed, 62 insertions, 27 deletions
diff --git a/util/uhash_loader.c b/util/uhash_loader.c
index add528ba..ed902689 100644
--- a/util/uhash_loader.c
+++ b/util/uhash_loader.c
@@ -3,8 +3,8 @@
#include "bbs.h"
unsigned string_hash(unsigned char *s);
-void userec_add_to_uhash(int n, userec_t *id);
-void fill_uhash(void);
+void userec_add_to_uhash(int n, userec_t *id, int onfly);
+void fill_uhash(int onfly);
void load_uhash(void);
SHM_t *SHM;
@@ -18,42 +18,63 @@ int main() {
}
void load_uhash(void) {
- int shmid;
- shmid = shmget(SHM_KEY, sizeof(SHM_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.
-*/
+ int shmid, err;
+ shmid = shmget(SHM_KEY, sizeof(SHM_t), IPC_CREAT | IPC_EXCL | 0600);
+ err = errno;
+ if( err == EEXIST)
+ shmid = shmget(SHM_KEY, sizeof(SHM_t), IPC_CREAT | 0600);
if (shmid < 0)
{
perror("shmget");
exit(1);
}
-
SHM = (void *) shmat(shmid, NULL, 0);
if (SHM == (void *) -1)
{
perror("shmat");
exit(1);
}
+ if( err != EEXIST)
+ SHM->number=SHM->loaded = 0;
-/* in case it's not assumed zero, this becomes a race... */
- SHM->loaded = 0;
-
- fill_uhash();
-/* ok... */
- SHM->loaded = 1;
+// in case it's not assumed zero, this becomes a race...
+ if(SHM->number==0 && SHM->loaded == 0)
+ {
+ SHM->loaded = 0;
+ fill_uhash(0);
+ SHM->loaded = 1;
+ }
+ else
+ {
+ fill_uhash(1);
+ }
}
-void fill_uhash(void)
+void checkhash(int h)
+{
+ int *p = &(SHM->hash_head[h]), ch;
+ while(*p != -1)
+ {
+ ch = string_hash( SHM->userid[*p]);
+ if(ch!=h)
+ {
+ printf("remove %d!=%d %d [%s]\n", h, ch, *p, SHM->userid[*p]);
+ *p = SHM->next_in_hash[*p]; //remove from link
+ }
+ p = &(SHM->next_in_hash[*p]);
+ }
+}
+void fill_uhash(int onfly)
{
int fd, usernumber;
usernumber = 0;
for (fd = 0; fd < (1 << HASH_BITS); fd++)
- SHM->hash_head[fd] = -1;
+ if(!onfly)
+ SHM->hash_head[fd] = -1;
+ else
+ checkhash(fd);
if ((fd = open(FN_PASSWD, O_RDWR)) > 0)
{
@@ -71,10 +92,10 @@ void fill_uhash(void)
fd = stbuf.st_size / sizeof(userec_t);
if (fd > MAX_USERS)
fd = MAX_USERS;
-
+
for (mimage = fimage; usernumber < fd; mimage += sizeof(userec_t))
{
- userec_add_to_uhash(usernumber, (userec_t *)mimage);
+ userec_add_to_uhash(usernumber, (userec_t *)mimage, onfly);
usernumber++;
}
munmap(fimage, stbuf.st_size);
@@ -85,7 +106,8 @@ void fill_uhash(void)
exit(1);
}
SHM->number = usernumber;
- printf("total %d names loaded.\n", usernumber);
+
+ printf("total %d names %s.\n", usernumber, onfly ? "checked":"loaded");
}
unsigned string_hash(unsigned char *s)
{
@@ -98,16 +120,29 @@ unsigned string_hash(unsigned char *s)
return (v * 2654435769U) >> (32 - HASH_BITS);
}
-void userec_add_to_uhash(int n, userec_t *user)
+void userec_add_to_uhash(int n, userec_t *user, int onfly)
{
- int *p, h = string_hash(user->userid);
- strcpy(SHM->userid[n], user->userid);
- SHM->money[n] = user->money;
+ int *p, h, l=0;
+
+ h = string_hash(user->userid);
p = &(SHM->hash_head[h]);
-
+ if(!onfly || SHM->userid[n][0] != user->userid[0] ||
+ strncmp(SHM->userid[n], user->userid, IDLEN-1))
+ {
+ strcpy(SHM->userid[n], user->userid);
+ SHM->money[n] = user->money;
+ if(onfly)
+ printf("add %s\n", user->userid);
+ }
while (*p != -1)
+ {
+ if(onfly && *p==n ) // already in hash
+ return;
+ l++;
p = &(SHM->next_in_hash[*p]);
-
+ }
+ if(onfly)
+ printf("add %d %d %d [%s] in hash\n", l, h, n, user->userid);
SHM->next_in_hash[*p = n] = -1;
}