summaryrefslogblamecommitdiffstats
path: root/util/reaper.c
blob: d89f6e567426c7accb0d1a4e1de7460480646bee (plain) (tree)
1
2
3
4
5
6
          
                
                
 
            
 














                                                    
                                           
              
                  
               









                                                  
                              
                                        


                                                                















                                                                                     
                                   











                                                                             


                             
                                                        
                                                   









































                                                                                  





             









































                                                                                                     

                               


                                                             

                 
                     
                
                              

                                               


             
/* $Id$ */
#define _UTIL_C_
#include "bbs.h"

time4_t now;

#undef MAX_GUEST_LIFE
#undef MAX_LIFE

// override max life
#define MAX_GUEST_LIFE     (365L * 24 * 60 * 60)
#define MAX_LIFE           (365L *10 * 24 * 60 * 60)

static int free_accs = 0;
int check_free(void *data, int n, userec_t *u)
{
    if (u->userid[0] == 0)
    free_accs++;
    return 0;
}

int check(void *data, int n, userec_t *u) {
    time4_t d;
    char buf[256];
    (void)data;

    if (u->userid[0] == 0 && u->userid[1])
    {
    // expired user, clean record!
    syslog(LOG_ERR, "reset record (%d)", n+1);
    memset(u, 0, sizeof(userec_t));
    passwd_update(n+1, u);
    return 0;
    }

    if(u->userid[0] != '\0') {
    if(!is_validuserid(u->userid)) {
        syslog(LOG_ERR, "bad userid(%d): %s", n, u->userid);
        u->userid[0] = '\0';
    } else {
        // test PASSWD synchronization
        /*
        int unum = searchuser(u->userid, u->userid);
        if (unum == 0)
        {
        strcpy(buf, ctime4(&u->lastlogin));
        syslog(LOG_NOTICE, "invalid user record (%d): %s (%s) %s", n+1, 
            u->userid, (u->userlevel & PERM_LOGINOK) ? "regok" : "unreg",
            buf
            );
        u->userid[0] = '\0';
        passwd_update(n+1, u);
        }
        return 0;
        */

        d = now - u->lastlogin;

        // ignore regged accounts now.
        if (u->userlevel & PERM_LOGINOK)
        return 0;
        if (u->userlevel & PERM_SYSOP)
        return 0;
        if (u->userlevel & PERM_XEMPT)
        return 0;

        // if((d > MAX_GUEST_LIFE && (u->userlevel & PERM_LOGINOK) == 0) 
        // || (d > MAX_LIFE && (u->userlevel & PERM_XEMPT) == 0)) {
        if(d > MAX_GUEST_LIFE) {
        /* expired */
        int unum;
        
        unum = searchuser(u->userid, u->userid);
        strcpy(buf, ctime4(&u->lastlogin));
        if (unum != n+1)
        {
            syslog(LOG_NOTICE, "out-of-sync user(%d/%d): %s %s", unum, n, 
                u->userid, buf);
        } 
        else if (unum != 0)
        {
            syslog(LOG_NOTICE, "kill user(%d): %s %s", unum, 
                // (u->userlevel & PERM_LOGINOK) ? "regok" : "guest",
                u->userid, buf);

            log_filef(FN_USIES, LOG_CREAT,
                "%s %s %-12s %s",
                Cdate(&now), "CLEAN(EXPIRE)", u->userid, buf);

            sprintf(buf, "mv home/%c/%s tmp/", u->userid[0], u->userid);
            if(system(buf))
            syslog(LOG_ERR, "can't move user home: %s", u->userid);
            u->userid[0] = '\0';
            setuserid(unum, u->userid);

            // flush into passwd
            memset(u, 0, sizeof(userec_t));
            passwd_update(unum, u);
        } else {
            /*
            static int changed = 0;

            if (changed ++ > 10)
            exit(0);
            */
    
            syslog(LOG_NOTICE, "clean user(%d): %s %s", n+1, 
                u->userid, buf);

            log_filef(FN_USIES, LOG_CREAT,
                "%s %s %-12s %s",
                Cdate(&now), "CLEAN(CLEAR)", u->userid, buf);
            u->userid[0] = '\0';
            memset(u, 0, sizeof(userec_t));
            passwd_update(n+1, u);
        }
        }
    }
    }
    return 0;
}

int check_last_login(void *data, int n, userec_t *u) {
    char buf[256];

    if (u->userid[0] == 0)
        return 0;

    // ignore all XEMPTY users
    if (u->userlevel & PERM_XEMPT)
        return 0;

    strcpy(buf, Cdate(&u->firstlogin));

    if (u->lastlogin > now + 86400 || u->lastlogin < 0) // should not be newer than now plus one day.
    {
        // invalid record
        printf("使用者 %-*s (登入%3d 次, %s%s, %s [%04X])\n 最後登入日期異常 [%04X]: %s",
                IDLEN, u->userid, u->numlogins,
                (u->userlevel & PERM_LOGINOK) ? "已過認證" : "未過認證",
                (u->userlevel & PERM_SYSOP) ? "[SYSOP]" : "",
                buf,
                (unsigned)u->firstlogin,
                (unsigned)u->lastlogin,
                ctime4(&u->lastlogin));
        // fix it
        u->lastlogin = u->firstlogin;

        if (u->lastlogin > now)
        {
            printf(" (首次登入日期也異常)");
            u->lastlogin = u->firstlogin = 0x362CFC7E;
        }

        printf(" 已修正登入日期為: %s\n", ctime4(&u->lastlogin));

        // flush
        passwd_update(n+1, u);
    }

    return 0;
}


int main(int argc, char **argv)
{
    now = time(NULL);
    openlog("reaper", LOG_PID | LOG_PERROR, SYSLOG_FACILITY);
    chdir(BBSHOME);

    attach_SHM();
    if(passwd_init())
    exit(1);
    passwd_apply(NULL, check);
    // passwd_apply(NULL, check_free);
    // printf("free accounts=%d\n", free_accs);
    
    return 0;
}