Ejemplo n.º 1
0
void u_exit(char *mode) {
    userec_t xuser;
    int diff = (time(0) - login_start_time) / 60;

    passwd_query(usernum, &xuser);
    
    auto_backup();
    
    setflags(PAGER_FLAG, currutmp->pager != 1);
    setflags(CLOAK_FLAG, currutmp->invisible);
    
    xuser.invisible = currutmp->invisible % 2;
    xuser.pager = currutmp->pager % 5;
    
    if(!(HAS_PERM(PERM_SYSOP) && HAS_PERM(PERM_DENYPOST)))
	do_aloha("<<下站通知>> -- 我走囉!");
    
    purge_utmp(currutmp);
    if((cuser.uflag != enter_uflag) || (currmode & MODE_DIRTY) || !diff) {
	xuser.uflag = cuser.uflag;
	xuser.numposts = cuser.numposts;
	if(!diff && cuser.numlogins)
	    xuser.numlogins = --cuser.numlogins; /* Leeym 上站停留時間限制式 */
	reload_money();
	passwd_update(usernum, &xuser);
    }
    log_usies(mode, NULL);
}
Ejemplo n.º 2
0
void 
u_exit(char *mode)
{
	extern void	auto_backup();	/* 編輯器自動備份 */
	userec		xuser;
	int		diff = (time(0) - login_start_time) / 60;

	rec_get(fn_passwd, &xuser, sizeof(xuser), usernum);
	auto_backup();
	setflags(PAGER_FLAG, currutmp->pager != 1);
	setflags(CLOAK_FLAG, currutmp->invisible);
	xuser.pager = currutmp->pager;	/* 記錄pager狀態, add by wisely */
	xuser.invisible = currutmp->invisible;	/* 紀錄隱形狀態 by wildcat */
	xuser.totaltime += time(0) - update_time;
	xuser.numposts = cuser.numposts;
	xuser.feeling[4] = '\0';

	if (!HAS_PERM(PERM_DENYPOST) && !currutmp->invisible) {
		char		buf       [256];
		time_t		now;

		time(&now);
		sprintf(buf, "<<下站通知>> -- 我走囉! - %s", Etime(&now));
		do_aloha(buf);
	}
	purge_utmp(currutmp);
	if (!diff && cuser.numlogins > 1 && strcmp(cuser.userid, STR_GUEST))
		xuser.numlogins = --cuser.numlogins;	/* Leeym 上站停留時間限制式 */
	substitute_record(fn_passwd, &xuser, sizeof(userec), usernum);
	log_usies(mode, NULL);
}
Ejemplo n.º 3
0
Archivo: shmctl.c Proyecto: ptt/pttbbs
int utmpfix(int argc, char **argv)
{
    int     i, fast = 0, nownum = SHM->UTMPnumber;
    int     which, nactive = 0, dofork = 1, daemonsleep = 0;
    time_t  now;
    const char    *clean;
    char buf[1024];
    IDLE_t  idle[USHM_SIZE];
    char    changeflag = 0;
    time_t  idletimeout = IDLE_TIMEOUT;
    int     lowerbound = 100, upperbound = 0;
    char    ch;

    int     killtop = 0;
    struct {
	pid_t   pid;
	int     where;
    } killlist[USHM_SIZE];

    while( (ch = getopt(argc, argv, "nt:l:FD:u:")) != -1 )
	switch( ch ){
	case 'n':
	    fast = 1;
	    break;
	case 't':
	    idletimeout = atoi(optarg);
	    break;
	case 'l':
	    lowerbound = atoi(optarg);
	    break;
	case 'F':
	    dofork = 0;
	    break;
	case 'D':
	    daemonsleep = atoi(optarg);
	    break;
	case 'u':
	    upperbound = atoi(optarg);
	    break;
	default:
	    printf("usage:\tshmctl\tutmpfix [-n] [-t timeout] [-F] [-D sleep]\n");
	    return 1;
	}

    if( daemonsleep )
	switch( fork() ){
	case -1:
	    perror("fork()");
	    return 0;
	case 0:
	    break;
	default:
	    return 0;
	}

    if( daemonsleep || dofork ){
	int     times = 1000, status;
	pid_t   pid;
	while( daemonsleep ? 1 : times-- )
	    switch( pid = fork() ){
	    case -1:
		sleep(1);
		break;
	    case 0:
#ifndef VALGRIND
		setproctitle("utmpfix");
#endif
		goto DoUtmpfix;
	    default:
#ifndef VALGRIND
		setproctitle(daemonsleep ? "utmpfixd(wait for %d)" :
			     "utmpfix(wait for %d)", (int)pid);
#endif
		waitpid(pid, &status, 0);
		if( WIFEXITED(status) && !daemonsleep )
		    return 0;
		if( !WIFEXITED(status) ){
		    /* last utmpfix fails, so SHM->UTMPbusystate is holded */
		    SHM->UTMPbusystate = 0;
		}
	    }
	return 0; // never reach
    }

 DoUtmpfix:
    killtop=0;
    changeflag=0;
    for( i = 0 ; i < 5 ; ++i )
	if( !SHM->UTMPbusystate )
	    break;
	else{
	    puts("utmpshm is busy....");
	    sleep(1);
	}
    SHM->UTMPbusystate = 1;

    printf("starting scaning... %s \n", (fast ? "(fast mode)" : ""));
    nownum = SHM->UTMPnumber;
    now = time(NULL);
    for( i = 0, nactive = 0 ; i < USHM_SIZE ; ++i )
	if( SHM->uinfo[i].pid ){
	    idle[nactive].index = i;
	    idle[nactive].idle = now - SHM->uinfo[i].lastact;
	    ++nactive;
	}
    if( !fast )
	qsort(idle, nactive, sizeof(IDLE_t), sfIDLE);

    #define addkilllist(a)			\
        do {					\
	    pid_t pid=SHM->uinfo[(a)].pid;	\
	    if(pid > 0) {			\
		killlist[killtop].where = (a);	\
		killlist[killtop++].pid = pid;	\
	    }					\
        } while( 0 )
    for( i = 0 ; i < nactive ; ++i ){
	which = idle[i].index;
	clean = NULL;
	if( !isalpha(SHM->uinfo[which].userid[0]) ){
	    clean = "userid error";
	    addkilllist(which);
	}
	else if( memchr(SHM->uinfo[which].userid, '\0', IDLEN + 1) == NULL ){
	    clean = "userid without z";
	    addkilllist(which);
	}
	else if( SHM->uinfo[which].friendtotal > MAX_FRIEND || SHM->uinfo[which].friendtotal<0 ){
	    clean = "too many/less friend";
	    addkilllist(which);
	}
	else if( searchuser(SHM->uinfo[which].userid, NULL) == 0 ){
	    clean = "user not exist";
	    addkilllist(which);
	}
	else if( kill(SHM->uinfo[which].pid, 0) < 0 ){
	    /* 此條件應放最後; 其他欄位沒問題但 process 不存在才 purge_utmp */
	    clean = "process error";
	    purge_utmp(&SHM->uinfo[which]);
	}
#ifdef DOTIMEOUT
	else if( (strcasecmp(SHM->uinfo[which].userid, STR_GUEST)==0 &&
	      idle[i].idle > 60*15) ||
	    (!fast && nownum > lowerbound && 
	     idle[i].idle > idletimeout ) ) {
	  sprintf(buf, "timeout(%s",
	      ctime4(&SHM->uinfo[which].lastact));
	  buf[strlen(buf) - 1] = 0;
	  strcat(buf, ")");
	  clean = buf;
	  addkilllist(which);
	  purge_utmp(&SHM->uinfo[which]);
	  printf("%s\n", buf);
	  --nownum;
	  continue;
	}
#endif
	
	if( clean ){
	    printf("clean %06d(%s), userid: %s\n",
		   i, clean, SHM->uinfo[which].userid);
	    memset(&SHM->uinfo[which], 0, sizeof(userinfo_t));
	    --nownum;
	    changeflag = 1;
	}
    }
    for( i = 0 ; i < killtop ; ++i ){
	printf("sending SIGHUP to %d\n", (int)killlist[i].pid);
	kill(killlist[i].pid, SIGHUP);
    }
    sleep(3);
    for( i = 0 ; i < killtop ; ++i )
	// FIXME 前面已經 memset 把 SHM->uinfo[which] 清掉了, 此處檢查 pid 無用
	if( SHM->uinfo[killlist[i].where].pid == killlist[i].pid &&
	    kill(killlist[i].pid, 0) == 0 ){ // still alive
	    printf("sending SIGKILL to %d\n", (int)killlist[i].pid);
	    kill(killlist[i].pid, SIGKILL);
	    purge_utmp(&SHM->uinfo[killlist[i].where]);
	}
    SHM->UTMPbusystate = 0;
    if( changeflag )
	SHM->UTMPneedsort = 1;

    if( daemonsleep ){
	do{
	    sleep(daemonsleep);
	} while( upperbound && SHM->UTMPnumber < upperbound );
	goto DoUtmpfix; /* XXX: goto */
    }
    return 0;
}