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 + -
显示快捷键?