char * u_namearray(char buf[][IDLEN + 1], int max, int *pnum, char *tag, char *atag, int *full) /* 根据tag ,生成 匹配的user id 列表 (针对所有注册用户)*/ { struct UCACHEHASH *reg_ushm = binfo->ucachehashshm; int n, num, i; int hash, len, ksz, alen; char tagv[IDLEN + 1]; len = strlen(tag); alen = strlen(atag); if (len > IDLEN) return NULL; if (!len) { return NULL; } ksz = ucache_hash_deep(tag); strcpy(tagv, tag); if (len >= ksz || len == IDLEN) { tagv[ksz] = 0; hash = ucache_hash(tagv) - 1; for (n = 0; n < UCACHE_HASHBSIZE; n++) { num = reg_ushm->hash_head[(hash + n % UCACHE_HASHBSIZE) % UCACHE_HASHSIZE + 1]; while (num) { if (!strncasecmp (passwdptr[num - 1].userid, atag, alen) && (passwdptr[num - 1].kickout == 0)) { strcpy(buf[(*pnum)++], passwdptr[num - 1].userid); /*如果匹配, add into buf */ if (*pnum >= max) { *full = 1; return buf[0]; } } num = reg_ushm->next[num]; } } } else { for (i = 'A'; i <= 'Z'; i++) { tagv[len] = i; tagv[len + 1] = 0; u_namearray(buf, max, pnum, tagv, atag, full); if (*full == 1) return buf[0]; if (mytoupper(tagv[len]) == 'Z') { tagv[len] = 'A'; return buf[0]; } else { tagv[len]++; } } } return buf[0]; }
int deluseridhash(const char *userid) { int i; unsigned h; struct UCACHEHASH *uhash = binfo->ucachehashshm; int prev = -1; h = ucache_hash(userid); i = uhash->hash_head[h]; while (i) { if (!strcasecmp(userid, passwdptr[i - 1].userid)) { if (prev != -1) { uhash->next[prev] = uhash->next[i]; } else { uhash->hash_head[h] = uhash->next[i]; } if (userid[0] == 0) uhash->next[0]--; return i; } prev = i; i = uhash->next[i]; } return -1; }
static int utmp_hash(const char *userid) { int hash; hash = ucache_hash(userid); if (hash == 0) return 0; hash = (hash / 3) % UTMP_HASHSIZE; if (hash == 0) return 1; return hash; }
int finduseridhash(const char *userid) { // 在一个用id字符所生成的hash表里面(每个ASCII码为一个分支点)查找所需的userid int i; unsigned h; struct UCACHEHASH *uhash = binfo->ucachehashshm; h = ucache_hash(userid); i = uhash->hash_head[h]; while (i) { if (!strcasecmp(userid, passwdptr[i - 1].userid)) { return i; } i = uhash->next[i]; } return -1; }
//insertuseridhash和finduseridhash的num都是按照起始值为1进行的 //这个其实是调用者决定的 //调用者要保证插入的 num 处对应条目即将或已经被设置为userid //tohead参数表示,如果插入的是空用户,插入在表的头部还是尾部 int insertuseridhash(const char *userid, const int num, const int tohead) { int i; unsigned int h; static int lastspace = -1; struct UCACHEHASH *uhash = binfo->ucachehashshm; h = ucache_hash(userid); i = uhash->hash_head[h]; if (h != 0 || tohead) { uhash->next[num] = uhash->hash_head[h]; uhash->hash_head[h] = num; } else { if (lastspace == -1) uhash->hash_head[h] = num; else uhash->next[lastspace] = num; uhash->next[num] = 0; lastspace = num; } if (userid[0] == 0) uhash->next[0]++; return 0; }