Example #1
0
File: utmp.c Project: wyat/kbs
void resolve_utmp()
{
    int iscreate;

    if (utmpshm == NULL) {
        utmpshm = (struct UTMPFILE *) attach_shm("UTMP_SHMKEY", 3699, sizeof(*utmpshm), &iscreate);     /*attach user tmp cache */
        if (iscreate) {
            int i, utmpfd;
            utmphead = (struct UTMPHEAD *) attach_shm("UTMPHEAD_SHMKEY", 3698, sizeof(struct UTMPHEAD), &iscreate);     /*attach user tmp cache */
            utmpfd = utmp_lock();
            bzero(utmpshm, sizeof(struct UTMPFILE));
            bzero(utmphead, sizeof(struct UTMPHEAD));
            utmphead->number = 0;
            utmphead->hashhead[0] = 1;
            for (i = 0; i < USHM_SIZE - 1; i++)
                utmphead->next[i] = i + 2;
            utmphead->next[USHM_SIZE - 1] = 0;
            /*
                     utmphead->listhead=0;
            */
            utmp_unlock(utmpfd);
        } else
            utmphead = (struct UTMPHEAD *) attach_shm1("UTMPHEAD_SHMKEY", 3698, sizeof(struct UTMPHEAD), &iscreate, 0, NULL);   /*attach user tmp head */
    }
}
Example #2
0
// Refreshes utmp(cache for online users.)
int refresh_utmp(void)
{
	int utmpfd, ucachefd;
	struct user_info *uentp;
	int n;
	int count = 0; // Online users count.
	time_t now;

	resolve_utmp();
	if (resolve_ucache() == -1)
		return -1;
	now = time(NULL);
	// Lock caches.
	utmpfd = utmp_lock();
	if (utmpfd == -1)
		return -1;
	ucachefd = ucache_lock();
	if (ucachefd == -1)
		return -1;

	memset(uidshm->status, 0, sizeof(uidshm->status));
	for (n = 0; n < USHM_SIZE; n++) {
		uentp = &(utmpshm->uinfo[n]);
		if (uentp->active && uentp->pid) {
			 // See if pid exists.
			if (bbskill(uentp, 0) == -1) {
				memset(uentp, 0, sizeof(struct user_info));
				continue;
			} else {
				// Kick idle users out.
				if (uentp->mode != BBSNET
						&& now - uentp->idle_time > IDLE_TIMEOUT) {
					bbskill(uentp, SIGHUP);
					memset(uentp, 0, sizeof(struct user_info));
				} else {
					// Increase status.
					uidshm->status[uentp->uid - 1]++;
					// Count online users.
					++count;
				}
			}
		}
	}
	utmpshm->total_num = count;
	// Get count of all users from ucache.
	utmpshm->usersum = allusers();
	// Unlock caches.
	ucache_unlock(ucachefd);
	utmp_unlock(utmpfd);
	return count;
}
Example #3
0
File: utmp.c Project: wyat/kbs
void clear_utmp(int uent, int useridx, int pid)
{
    int lockfd;

    /* ulock todo: use user lock
    */
    lockfd = utmp_lock();
    utmp_setreadonly(0);

    if (((useridx == 0) || (utmpshm->uinfo[uent - 1].uid == useridx)) && pid == utmpshm->uinfo[uent - 1].pid)
        clear_utmp2(uent);

    utmp_setreadonly(1);
    utmp_unlock(lockfd);
}
Example #4
0
int getnewutmpent(struct user_info *up)
{
	int utmpfd, ucachefd;
	struct user_info *uentp;
	int i;

	resolve_utmp();
	if (resolve_ucache() == -1)
		return -1;

	utmpfd=utmp_lock();
	if (utmpfd == -1) {
		return -1;
	}

	if (utmpshm->max_login_num < get_online())
		utmpshm->max_login_num = get_online();
	for (i = 0; i < USHM_SIZE; i++) {
		uentp = &(utmpshm->uinfo[i]);
		if (!uentp->active || !uentp->pid)
			break;
	}
	if (i >= USHM_SIZE) {
		utmp_unlock(utmpfd);
		return -2;
	}
	utmpshm->uinfo[i] = *up;
	utmpshm->total_num++;

	utmp_unlock(utmpfd);

	ucachefd=ucache_lock();
	uidshm->status[up->uid-1]++;
	ucache_unlock(ucachefd);

	return i + 1;
}
Example #5
0
File: utmp.c Project: wyat/kbs
/* same as getnewutmpent() except no updating of utmpshm
 * only called in www
 */
int getnewutmpent2(struct user_info *up, int is_www)
{
    int pos, i,ret;
    int utmpfd, hashkey;

    utmpfd = utmp_lock();
    utmp_setreadonly(0);
    up->utmpkey = rand() % 100000000;
    pos = utmphead->hashhead[0] - 1;
    if (pos == -1) {
        ret=-1;
    } else {
        /* add to sorted list  */

        if (!utmphead->listhead) {  /* init the list head  */
            utmphead->list_prev[pos] = pos + 1;
            utmphead->list_next[pos] = pos + 1;
            utmphead->listhead = pos + 1;
        } else {
            int i;

            i = utmphead->listhead;
            if (strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) >= 0) {
                /* add to head */
                utmphead->list_prev[pos] = utmphead->list_prev[i - 1];
                utmphead->list_next[pos] = i;

                utmphead->list_prev[i - 1] = pos + 1;

                utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1;

                utmphead->listhead = pos + 1;
            } else {
                int count;

                count = 0;
                i = utmphead->list_next[i - 1];
                while ((strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) < 0) && (i != utmphead->listhead)) {
                    i = utmphead->list_next[i - 1];
                    count++;
                    if (count > USHM_SIZE) {
                        utmphead->listhead = 0;
                        bbslog("3system", "UTMP:maybe loop rebuild..!");
                        apply_ulist((APPLY_UTMP_FUNC) rebuild_list, NULL);
                        utmp_setreadonly(1);
                        utmp_unlock(utmpfd);
                        exit(-1);
                    }
                }

                utmphead->list_prev[pos] = utmphead->list_prev[i - 1];
                utmphead->list_next[pos] = i;

                utmphead->list_prev[i - 1] = pos + 1;

                utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1;
            }
        }

        utmphead->hashhead[0] = utmphead->next[pos];

        if (utmpshm->uinfo[pos].active)
            if (utmpshm->uinfo[pos].pid) {
                bbslog("3system", "utmp: alloc a active utmp! old:%s new:%s", utmpshm->uinfo[pos].userid, up->userid);
                kill(utmpshm->uinfo[pos].pid, SIGHUP);
            }
        utmpshm->uinfo[pos] = *up;
        hashkey = utmp_hash(up->userid);

        i = utmphead->hashhead[hashkey];
        /* not need sort */
        utmphead->next[pos] = i;
        utmphead->hashhead[hashkey] = pos + 1;

        utmphead->number++;
        setpublicshmreadonly(0);
        if (!is_www) {
            get_publicshm()->logincount ++;
        } else {
            get_publicshm()->wwwlogincount ++;
        }
        setpublicshmreadonly(1);
        ret=pos+1;
    }
    utmp_setreadonly(1);
    utmp_unlock(utmpfd);
    return ret;
}
Example #6
0
File: utmp.c Project: wyat/kbs
int getnewutmpent(struct user_info *up, int is_www)
{
    struct user_info *uentp;
    time_t now;
    int pos, n, i,ret;
    int utmpfd, hashkey;

    utmpfd = utmp_lock();
    utmp_setreadonly(0);
    up->utmpkey=rand() % 100000000;
    pos = utmphead->hashhead[0] - 1;
    if (pos == -1) {
        ret=-1;
    } else {
        /* add to sorted list  */

        if (!utmphead->listhead) {  /* init the list head  */
            utmphead->list_prev[pos] = pos + 1;
            utmphead->list_next[pos] = pos + 1;
            utmphead->listhead = pos + 1;
        } else {
            int i;

            i = utmphead->listhead;
            if (strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) >= 0) {
                /* add to head */
                utmphead->list_prev[pos] = utmphead->list_prev[i - 1];
                utmphead->list_next[pos] = i;

                utmphead->list_prev[i - 1] = pos + 1;

                utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1;

                utmphead->listhead = pos + 1;
            } else {
                int count;

                count = 0;
                i = utmphead->list_next[i - 1];
                while ((strcasecmp(utmpshm->uinfo[i - 1].userid, up->userid) < 0) && (i != utmphead->listhead)) {
                    i = utmphead->list_next[i - 1];
                    count++;
                    if (count > USHM_SIZE) {
                        utmphead->listhead = 0;
                        bbslog("3system", "UTMP:maybe loop rebuild!");
                        apply_ulist((APPLY_UTMP_FUNC) rebuild_list, NULL);
                        utmp_setreadonly(1);
                        utmp_unlock(utmpfd);
                        exit(-1);
                    }
                }

                utmphead->list_prev[pos] = utmphead->list_prev[i - 1];
                utmphead->list_next[pos] = i;

                utmphead->list_prev[i - 1] = pos + 1;

                utmphead->list_next[utmphead->list_prev[pos] - 1] = pos + 1;
            }
        }
        /*    */

        utmphead->hashhead[0] = utmphead->next[pos];

        if (utmpshm->uinfo[pos].active)
            if (utmpshm->uinfo[pos].pid) {
                bbslog("3system", "utmp: alloc a active utmp! old:%s new:%s", utmpshm->uinfo[pos].userid, up->userid);
                kill(utmpshm->uinfo[pos].pid, SIGHUP);
            }
        utmpshm->uinfo[pos] = *up;
        hashkey = utmp_hash(up->userid);

        i = utmphead->hashhead[hashkey];
        /* not need sort */
        utmphead->next[pos] = i;
        utmphead->hashhead[hashkey] = pos + 1;

        utmphead->number++;

        setpublicshmreadonly(0);
        if (!is_www) {
            get_publicshm()->logincount ++;
        } else {
            get_publicshm()->wwwlogincount ++;
        }
        setpublicshmreadonly(1);

        if (get_utmp_number() + getwwwguestcount()>get_publicshm()->max_user) {
            setpublicshmreadonly(0);
            save_maxuser();
            setpublicshmreadonly(1);
        }
        now = time(NULL);
        if ((now > utmphead->uptime + 120) || (now < utmphead->uptime - 120)) {
            utmphead->uptime = now;
            newbbslog(BBSLOG_USIES, "UTMP:Clean user utmp cache");
            for (n = 0; n < USHM_SIZE; n++) {
                utmphead->uptime = now;
                uentp = &(utmpshm->uinfo[n]);
                if ((uentp->pid == 1)
                        && ((now - uentp->freshtime) < IDLE_TIMEOUT)) {
                    continue;
                }
                if (uentp->active && uentp->pid && kill(uentp->pid, 0) == -1) {     /*uentp检查 */
                    char buf[STRLEN];

                    strncpy(buf, uentp->userid, IDLEN + 2);
                    clear_utmp2(n + 1);     /* 不需要再lock了 */
                    RemoveMsgCountFile(buf);
                }
            }
        }
        ret=pos+1;
    }
    utmp_setreadonly(1);
    utmp_unlock(utmpfd);
    return ret;
}
Example #7
0
int main(void)
{
    int n,prev,pos,next,nn,ppd;
	int pig=0;
	int i,j;//,k;
	//int inlist=0;
    int utmpfd;//, hashkey;

    init_all();
	pos=-1;

#if 1
    utmpfd = utmp_lock();

	utmphead->hashhead[0]=0;

    for (i = 0; i <= USHM_SIZE - 1; i++) {
		if (!utmpshm->uinfo[i].active) {
                        add_empty(i+1);
		}
	}

                        utmp_unlock(utmpfd);

						printf("end\n");
//						return;
#endif
						j=0;
		for(i = utmphead->hashhead[0]; i; i = utmphead->next[i - 1])
			j++;

		printf("items on hashhead[0] chain:%d\n",j);
		j=0; pig=0;
		for(i=0;i<USHM_SIZE;i++){
			if (!utmpshm->uinfo[i].active) j++;
			else pig++;
		}
		printf("direct iteration: inactive:%d, active:%d\n",j,pig);
pig=0;
    for(n=1;n<=UTMP_HASHSIZE;n++) {
        ppd=false;
        next = utmphead->hashhead[n];
        prev = -1;
        while(next) {
            nn = utmphead->next[next - 1];
            if (!utmpshm->uinfo[next - 1].active) {
                if (pos==-1) pos=prev;
                //printf("%d, %d, %s\n", next, nn, utmpshm->uinfo[next - 1].userid);
                ppd=true;
            } else {
				int hash = utmp_hash(getuserid2(utmpshm->uinfo[next - 1].uid));
				if (hash!=n) {
					printf("utmp_hash err: %d %d %d %d %s\n", n, next,
							utmphead->hashhead[n], nn,
							getuserid2(utmpshm->uinfo[next - 1].uid));
					if (0) {
						if (utmphead->hashhead[n] == next) {
							utmphead->hashhead[n] = nn;
						} else {
							utmphead->next[prev - 1] = nn;
						}
					}
				}
			}
            prev = next;
            next = nn;
            pig++;
        }

        if(ppd) printf("ERROR:%d,%d,%d\n", n, utmphead->hashhead[n], pos);
    }
    printf("active: %d, total: %d\n", pig, pig+j);
	n=utmphead->listhead;
	pig=0; prev=-1;
	while(n) {
		pig++;
		if (prev>0) {
			if (strcasecmp(utmpshm->uinfo[prev-1].userid, utmpshm->uinfo[n-1].userid) > 0) {
				printf("list chain error: %d %d\n", prev, n);
			}
		}
		prev=n;
		n=utmphead->list_next[n-1];
		if (utmphead->list_prev[n-1]!=prev) {
			printf("list chain list_prev error: %d %d\n", prev, n);
		}
		if (n==utmphead->listhead) {
			break;
		}
	}
	printf("active on list chain: %d\n", pig);
//		return 0;
#if 0
		for (i = 0; i <= USHM_SIZE - 1; i++) {
		if (!utmpshm->uinfo[i].active) {
			if(!in_hash(i+1)){
				//printf("%d empty but not in hash\n", i);
				pig ++;
				if(in_list(i))
					inlist++;
				//if(pig >=40) break;
			}
		}
	}


	printf("%d total,%d inlist\n", pig, inlist);
	if(i==USHM_SIZE) return;

	return;

	k=utmphead->listhead;
	for(j=utmphead->list_next[k-1]; j!=k && j; j=utmphead->list_next[j-1]){
		if(j==i+1) printf("in listhead\n");
	}

	return;
#endif
	pig=0;
		next = utmphead->hashhead[0];
		while(next) {
			if (pos!=-1 &&pos==next) {
				printf("%d: on empty list\n", pos);
				return 0;
			}
			nn = utmphead->next[next - 1];
			next = nn;
			pig++;
		}
		printf("%d %ld %ld\n", pig, utmphead->uptime, time(NULL));
        time_t now = time(NULL); int web=0;int kick=0;
pig=0;
            for (n = 0; n < USHM_SIZE; n++) {
                struct user_info *uentp = &(utmpshm->uinfo[n]);
				//printf("%d, %d\n", n, uentp->pid);
                if ((uentp->pid == 1)
                    && ((now - uentp->freshtime) < IDLE_TIMEOUT)) {
                    continue;
                }
				if (uentp->pid==0 && uentp->active) kick++;
                if (/*uentp->active &&*/ uentp->pid && kill(uentp->pid, 0) == -1) {     /*uentp¼ì²é */
					pig++;
					if(uentp->pid==1) web++;
                }
            }
			printf("killable: %d, web: %d, pid0: %d\n", pig, web, kick);
    return 0;
}