bbslib.c

来自「linux/unix环境下的建站系统」· C语言 代码 · 共 1,534 行 · 第 1/4 页

C
1,534
字号
/* * $Id: bbslib.c,v 1.311 2006/11/03 09:13:53 etnlegend Exp $ */#include "bbslib.h"void f_append(FILE *fp, char *buf){    char *ptr;    ptr = buf;    while (*ptr != '\0') {        if (*ptr == '\x09')     /* horizontal tab */            fprintf(fp, "    ");        else            fputc(*ptr, fp);        ptr++;    }}int file_exist(char *file){    struct stat buf;    if (stat(file, &buf) == -1) return 0;    if (!S_ISREG(buf.st_mode)) return 0;    return 1;}int del_mail(int ent, struct fileheader *fh, char *direct){    char buf[PATHLEN];    char *t;    char genbuf[PATHLEN];    struct stat st;    strcpy(buf, direct);    if ((t = strrchr(buf, '/')) != NULL)        *t = '\0';    if (!delete_record(direct, sizeof(*fh), ent, (RECORD_FUNC_ARG) cmpname, fh->filename)) {        sprintf(genbuf, "%s/%s", buf, fh->filename);        if (strstr(direct, ".DELETED") || HAS_MAILBOX_PROP(getSession()->currentuinfo, MBP_FORCEDELETEMAIL)) {            if (lstat(genbuf, &st) == 0 && S_ISREG(st.st_mode) && st.st_nlink == 1) {                if (getCurrentUser()->usedspace > st.st_size)                    getCurrentUser()->usedspace -= st.st_size;                else                    getCurrentUser()->usedspace = 0;            }            unlink(genbuf);        } else {            strcpy(buf, direct);            t = strrchr(buf, '/') + 1;            strcpy(t, ".DELETED");            append_record(buf, fh, sizeof(*fh));        }        return 0;    }    return 1;}int is_BM(const struct boardheader *board,const struct userec *user){    char BM[STRLEN];    strncpy(BM, board->BM, sizeof(BM) - 1);    BM[sizeof(BM) - 1] = '\0';    return chk_currBM(BM, (struct userec *)user);}/* Convert string to Unix format */char *unix_string(char *str){    char *ptr1, *ptr2;    ptr1 = ptr2 = str;    while (*ptr1 != '\0') {        if (*ptr1 == '\r' && *(ptr1 + 1) == '\n') {            ptr1++;            continue;        }        if (ptr1 != ptr2)            *ptr2 = *ptr1;        ptr1++;        ptr2++;    }    *ptr2 = '\0';    return str;}int send_msg(char *srcid, int srcutmp, char *destid, int destpid, char *msg){    uinfo_t *uin;    process_control_chars(msg,"\n");    uin = t_search(destid, destpid);    if (uin == NULL)        return -1;    if (strcasecmp(uin->userid, destid))        return -1;    strcpy(getSession()->MsgDesUid, uin->userid);    return sendmsgfunc(uin, msg, 2, 1, getSession());}int isfriend(char *id){    if (getCurrentUser() && strcmp(getCurrentUser()->userid, "guest")) {        return myfriend(searchuser(id), NULL, getSession());    } else {        return false;    }}/* 以下的代码是cgi和php都使用的*/static struct user_info www_guest_uinfo;static int www_guest_calc_hashkey(struct in_addr *fromhostn){	unsigned int i=ntohl(fromhostn->s_addr);	unsigned int j;			            j =  i & 0x0000FFFF;    j |= (((i&0xFF000000)>>8) + (i&0x00FF0000)) & 0x000F0000;    return j;}static int www_guest_start_map(int key){	return ( key % MAX_WWW_MAP_ITEM + 1 );}#define WWW_GUEST_HASHTAB(key) wwwguest_shm->hashtab[key>>16][(key&0x0000FF00)>>8][key&0x000000FF]/*   stiger:  1 guest entry per IPreturn:	<0: error	0: 正常登录,idx	1: 有重复,使用idx的entry**************/static int www_new_guest_entry(struct in_addr *fromhostn, int * idx){    struct public_data *pub;    int oldidx, num, fd, i, j = 0;    time_t now;    struct userec *user;	int hashkey;	int startkey;    fd = www_guest_lock();    if (fd == -1)        return -1;    setpublicshmreadonly(0);    pub = get_publicshm();    if (pub->www_guest_count >= MAX_WWW_GUEST) {    	www_guest_unlock(fd);        setpublicshmreadonly(1);        return -1;    }    user = getCurrentUser();    getuser("guest", &getCurrentUser());    if (getCurrentUser() == NULL){    	www_guest_unlock(fd);    	setpublicshmreadonly(1);        return -1;	}    now = time(NULL);    if ((now > wwwguest_shm->uptime + 240) || (now < wwwguest_shm->uptime - 240)) {        newbbslog(BBSLOG_USIES, "WWW guest:Clean guest table:%d", wwwguest_shm->uptime);        wwwguest_shm->uptime = now;        for (i = 0; i < MAX_WWW_GUEST; i++) {	    struct user_info guestinfo;            if (!(wwwguest_shm->use_map[i / 32] & (1 << (i % 32))) || (now - wwwguest_shm->guest_entry[i].freshtime < MAX_WWW_GUEST_IDLE_TIME))                continue;            newbbslog(BBSLOG_USIES, "EXIT: Stay:%3ld (guest)[%d %d](www)", now - wwwguest_shm->guest_entry[i].freshtime, wwwguest_shm->guest_entry[i].key);            /*             * 清除use_map              */	    guestinfo.currentboard=wwwguest_shm->guest_entry[i].currentboard;	    do_after_logout(getCurrentUser(), &guestinfo, i, 1,false);	    do_after_logout(getCurrentUser(), &guestinfo, i, 1,true);            wwwguest_shm->use_map[i / 32] &= ~(1 << (i % 32));			/* 清除hashtab */			WWW_GUEST_HASHTAB(www_guest_calc_hashkey(& wwwguest_shm->guest_entry[i].fromip)) = 0;            if (pub->www_guest_count > 0) {                pub->www_guest_count--;	        	pub->wwwguestlogoutcount++;	       		pub->wwwgueststaytime += now - wwwguest_shm->guest_entry[i].logintime;                /*                 * 清除数据                  */                bzero(&wwwguest_shm->guest_entry[i], sizeof(struct WWW_GUEST_S));            }        } //for    }//if need kick www guest	hashkey = www_guest_calc_hashkey(fromhostn);	oldidx = WWW_GUEST_HASHTAB(hashkey);	num=0;    pub->wwwguestlogincount++;/* 如果已经有相同的登录 */if( oldidx != 0 && fromhostn->s_addr == wwwguest_shm->guest_entry[oldidx].fromip.s_addr ){	*idx = oldidx;	num=-1;}else{	startkey = www_guest_start_map(hashkey);/* 如果hashtab有值但是IP不同,遍历 */	if( oldidx != 0 ){		for ( num = 0, i = startkey; num < MAX_WWW_MAP_ITEM; num++, i++){			if( i>= MAX_WWW_MAP_ITEM)				i=1;        	if (wwwguest_shm->use_map[i] != 0) {            	int map = wwwguest_shm->use_map[i];            	for (j = 0; j < 32; j++){                	if ((map & 1) != 0) {						/* 找到相同的IP了 */						if( wwwguest_shm->guest_entry[i*32+j].fromip.s_addr == fromhostn->s_addr ){							num = -1;							*idx = i*32+j;							break;						}					}					map = map >> 1;				}        	}			if( num == -1 )				break;		}	}/* 如果遍历发现没有相同IP的 */	if( num != -1 ){		/* 找一个新的空位 */	    for (num=0, i = startkey; num < MAX_WWW_MAP_ITEM; num++, i++){			if( i>= MAX_WWW_MAP_ITEM)				i=1;        	if (wwwguest_shm->use_map[i] != 0xFFFFFFFF) {            	int map = wwwguest_shm->use_map[i];            	for (j = 0; j < 32; j++)                	if ((map & 1) == 0) {                    	wwwguest_shm->use_map[i] |= 1 << j;                    	wwwguest_shm->guest_entry[i * 32 + j].freshtime = time(0);						/* 设置hashtab */						WWW_GUEST_HASHTAB(hashkey) = i*32+j;                    	/*                     	* 避免被kick下去                      	*/                    	break;                	} else                    	map = map >> 1;            	break;        	}		}    	if (num != MAX_WWW_MAP_ITEM) {        	pub->www_guest_count++;        	if (get_utmp_number() + getwwwguestcount() > get_publicshm()->max_user) {            	save_maxuser();        	}    	}		*idx = i*32+j;	}}    setCurrentUser(user);    setpublicshmreadonly(1);    www_guest_unlock(fd);    if (num == MAX_WWW_MAP_ITEM)        return -1;	if (num == -1)		return 1;    return 0;}struct WWW_GUEST_S* www_get_guest_entry(int idx){    return  &wwwguest_shm->guest_entry[idx];}static int www_free_guest_entry(int idx){    int fd;    struct public_data *pub;    struct user_info guestinfo;    if ((idx < 0) || (idx > MAX_WWW_GUEST))        return -1;    guestinfo.currentboard=wwwguest_shm->guest_entry[idx].currentboard;    do_after_logout(getCurrentUser(), &guestinfo, idx, 1,false);    do_after_logout(getCurrentUser(), &guestinfo, idx, 1,true);    setpublicshmreadonly(0);    pub = get_publicshm();    fd = www_guest_lock();    if (wwwguest_shm->use_map[idx / 32] & (1 << (idx % 32))) {		time_t staytime = time(NULL)-wwwguest_shm->guest_entry[idx].logintime;        wwwguest_shm->use_map[idx / 32] &= ~(1 << (idx % 32));		WWW_GUEST_HASHTAB(www_guest_calc_hashkey(&wwwguest_shm->guest_entry[idx].fromip))=0;    	bzero(&wwwguest_shm->guest_entry[idx], sizeof(struct WWW_GUEST_S));        if (pub->www_guest_count > 0){	       	pub->wwwguestlogoutcount++;	       	pub->wwwgueststaytime += staytime;            pub->www_guest_count--;		}    }    www_guest_unlock(fd);    setpublicshmreadonly(1);    return 0;}void www_data_detach(){    shmdt((void*)wwwguest_shm);    wwwguest_shm = NULL;}int www_data_init(){    struct userec *guest;    /*     * www_guest_info目前先使用一个全局变量来做,这样     * 会导致线程不安全:P   但是对于进程模型的cgi 和php     * 足够了     */    bzero(&www_guest_uinfo, sizeof(www_guest_uinfo));    www_guest_uinfo.active = true;    www_guest_uinfo.uid = getuser("guest", &guest);    if (www_guest_uinfo.uid == 0)        return -1;    www_guest_uinfo.invisible = true;    www_guest_uinfo.pid = 1;    www_guest_uinfo.mode = WEBEXPLORE;    strcpy(www_guest_uinfo.username, guest->username);    strcpy(www_guest_uinfo.userid, guest->userid);    www_guest_uinfo.pager = 0;    {        struct userdata ud;        read_userdata(guest->userid, &ud);        strcpy(www_guest_uinfo.realname, ud.realname);    }    www_guest_uinfo.utmpkey = 0;    /*     * destuid 将被用来存放www guest表的入口      */    www_guest_uinfo.destuid = 0;    if (resolve_guest_table() != 0)        return -1;    return 0;}static void set_idle_time(struct user_info * uentp, time_t t){    if (strcasecmp(uentp->userid, "guest"))        uentp->freshtime = t;    else {        int idx;        idx = uentp->destuid;        if (idx >= 1 && idx < MAX_WWW_GUEST)            wwwguest_shm->guest_entry[uentp->destuid].freshtime = t;    }}int www_user_init(int useridx, char *userid, int key, struct userec **x, struct user_info **y,long compat_telnet){    /*     * printf("utmpuserid = %s\n", id);     */    /*     * printf("utmpnum = %s\n", num);      */    if (userid&&!strcasecmp(userid, "new"))        return -1;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?