summaryrefslogblamecommitdiffstats
path: root/mbbsd/cache.c
blob: e56c162aeddb150e72801961314cccb55324f305 (plain) (tree)
1
2
3
4
5
6
7
8
9
          
                
 
                   
                                                                                               
      
 
  
                              
   
 











                                            
    
                                    
 
                                       
                      
                               

                                                        

                           
                                 
                            

                                                  





                   
   
                                             
 
                               
                             
 
                                     
                                 

                                                                     




                             
   


                                                                          

                   
                  
                 
                                            
                                                           

                                  
                 

                                                                        
                                                

                                                          

                                                                  

                                                       












                                


             
    

                              
                                
                                         
                          
 
 




                                         
                    
                                    
                                                                           

     







                              
 
  
                  
   
 
                                  
   


                                           
                                 

                                                            
                                                                      
                                   



                        
 
                                                
 
                                        


















                                                                          
     


             
                            

                               

                      

                                 
 


                              



                                                                           


                                
                                   
                                             
                              
 
                                          
                    
 
                                    
                      
 

                                    
 
                                
                            

                          


                                                
                                                
                              
 







                                        
 






                                             
                            



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

#ifdef _BBS_UTIL_C_
#error sorry, mbbsd/cache.c does not support utility mode anymore. please use libcmbbs instead.
#endif

/*
 * section - user & utmp cache
 */

int
getuser(const char *userid, userec_t *xuser)
{
    int             uid;

    if ((uid = searchuser(userid, NULL))) {
    passwd_sync_query(uid, xuser);
    xuser->money = moneyof(uid);
    }
    return uid;
}

void
getnewutmpent(const userinfo_t * up)
{
/* Ptt:這裡加上 hash 觀念找空的 utmp */
    register int    i;
    register userinfo_t *uentp;
    unsigned int p = StringHash(up->userid) % USHM_SIZE;
    for (i = 0; i < USHM_SIZE; i++, p++) {
    if (p == USHM_SIZE)
        p = 0;
    uentp = &(SHM->uinfo[p]);
    if (!(uentp->pid)) {
        memcpy(uentp, up, sizeof(userinfo_t));
        currutmp = uentp;
        return;
    }
    }
    exit(1);
}

int
apply_ulist(int (*fptr) (const userinfo_t *))
{
    register userinfo_t *uentp;
    register int    i, state;

    for (i = 0; i < USHM_SIZE; i++) {
    uentp = &(SHM->uinfo[i]);
    if (uentp->pid && (PERM_HIDE(currutmp) || !PERM_HIDE(uentp)))
        if ((state = (*fptr) (uentp)))
        return state;
    }
    return 0;
}

int
count_logins(int uid, int show)
{
    register int    i = 0, j, start = 0, end = SHM->UTMPnumber - 1, count;
    int *ulist;
    userinfo_t *u; 
    if (end == -1)
    return 0;
    ulist = SHM->sorted[SHM->currsorted][7];
    for (i = ((start + end) / 2);; i = (start + end) / 2) {
    u = &SHM->uinfo[ulist[i]];
    j = uid - u->uid;
    if (!j) {
        for (; i > 0 && uid == SHM->uinfo[ulist[i - 1]].uid; i--);
                            /* 指到第一筆 */
        for (count = 0; (ulist[i + count] &&
            (u = &SHM->uinfo[ulist[i + count]]) &&
            uid == u->uid); count++) {
        if (show)
            prints("(%d) 目前狀態為: %-17.16s(來自 %s)\n",
               count + 1, modestring(u, 0),
               u->from);
        }
        return count;
    }
    if (end == start) {
        break;
    } else if (i == start) {
        i = end;
        start = end;
    } else if (j > 0)
        start = i;
    else
        end = i;
    }
    return 0;
}

void
purge_utmp(userinfo_t * uentp)
{
    logout_friend_online(uentp);
    memset(uentp, 0, sizeof(userinfo_t));
    SHM->UTMPneedsort = 1;
}

void
setutmpmode(unsigned int mode)
{
    if (currstat != mode)
    currutmp->mode = currstat = mode;
    /* 追蹤使用者 */
    if (HasUserPerm(PERM_LOGUSER)) {
    log_user("setutmpmode to %s(%d)\n", modestring(currutmp, 0), mode);
    }
}

unsigned int 
getutmpmode(void)
{
    if (currutmp)
    return currutmp->mode;
    return currstat;
}

/*
 * section - board
 */

/* HasBoardPerm() in board.c... */
int
apply_boards(int (*func) (boardheader_t *))
{
    register int    i;
    register boardheader_t *bhdr;

    for (i = 0, bhdr = bcache; i < numboards; i++, bhdr++) {
    if (!(bhdr->brdattr & BRD_GROUPBOARD) && HasBoardPerm(bhdr) &&
        (*func) (bhdr) == QUIT)
        return QUIT;
    }
    return 0;
}

int is_BM_cache(int bid) /* bid starts from 1 */
{
    assert(0<=bid-1 && bid-1<MAX_BOARD);
    int *pbm = SHM->BMcache[bid-1];
    // XXX potential issue: (thanks for mtdas@ptt)
    //  buildBMcache use -1 as "none".
    //  some function may call is_BM_cache early 
    //  without having currutmp->uid (maybe?)
    //  and may get BM permission accidentally.
    // quick check
    if (!HasUserPerm(PERM_BASIC) || !currutmp->uid || currutmp->uid == -1)
    return 0;
    // XXX hard coded MAX_BMs=4
    if( currutmp->uid == pbm[0] ||
    currutmp->uid == pbm[1] ||
    currutmp->uid == pbm[2] ||
    currutmp->uid == pbm[3] )
    {
    // auto enable BM permission
    if (!HasUserPerm(PERM_BM))
        cuser.userlevel |= PERM_BM;
    return 1;
    }
    return 0;
}

// TODO move this to board.c
const char *
postperm_msg(const char *bname)
{
    register int    i;
    char            buf[PATHLEN];
    boardheader_t   *bp = NULL;

    if (!(i = getbnum(bname)))
    return "看板不存在";

    // system internal read only boards (no matter what attribute/flag set)
    if (is_readonly_board(bname))
    return "看板唯讀";

    if (HasUserPerm(PERM_SYSOP))
    return NULL;

    setbfile(buf, bname, fn_water);
    if (file_exist_record(buf, cuser.userid))
    return "使用者水桶中";

    if (!strcasecmp(bname, DEFAULT_BOARD))
    return NULL;

    assert(0<=i-1 && i-1<MAX_BOARD);
    bp = getbcache(i);

    if (bp->brdattr & BRD_GUESTPOST)
        return NULL;

    if (!HasUserPerm(PERM_POST))
    return "無發文權限";

    /* 秘密看板特別處理 */
    if (bp->brdattr & BRD_HIDE)
    return NULL;
    else if (bp->brdattr & BRD_RESTRICTEDPOST &&
        !is_hidden_board_friend(i, usernum))
    return "看板限制發文";

    if (HasUserPerm(PERM_VIOLATELAW))
    {
    // 在罰單的討論相關板可以發文
    if (bp->level & PERM_VIOLATELAW)
        return NULL;
    else 
        return "罰單未繳";
    }

    if (!(bp->level & ~PERM_POST))
    return NULL;
    if (!HasUserPerm(bp->level & ~PERM_POST))
    return "未達看板要求權限";
    return NULL;
}

// TODO move this to board.c
int
haspostperm(const char *bname)
{
    return postperm_msg(bname) == NULL ? 1 : 0;
}