示例#1
0
int getbnum_safe(const char *bname, session_t *session, const int mode)
{
    register int i;

    for (i = 0; i < brdshm->numboards; i++)
        if ((((mode == 1) && check_read_perm(session->currentuser,&bcache[i]))) || ((mode == 2) && check_see_perm(session -> currentuser, &bcache[i])))
            if (!strncasecmp(bname, bcache[i].filename, STRLEN))
                return i + 1;
    return 0;
}
示例#2
0
int fill_super_board(struct userec* user,const char *searchname, int result[], int max)
{
    register int i;
    int total=0;

    for (i = 0; i < brdshm->numboards && total < max ; i++) {
        if (bcache[i].filename[0] == '\0')
            continue;
        if (check_read_perm(user, &bcache[i])) {
            if (strcasestr(bcache[i].filename, searchname) || strcasestr(bcache[i].des, searchname) || strcasestr(bcache[i].title, searchname)) {
                result[total] = i + 1;
                total ++;
            }
        }
    }
    return total;
}
示例#3
0
/* return .-delimited manageable bid list */
int get_manageable_bids(struct userec *user, char *buf, int buflen)
{
    register int i;
    int total=0;
    char *bufptr = buf;

    buf[0] = '\0';
    for (i = 0; i < brdshm->numboards; i++) {
        if (bcache[i].filename[0] == '\0')
            continue;
        if (check_read_perm(user, &bcache[i])) {
            if (chk_BM_instr(bcache[i].BM, user->userid)) {
                total++;
                sprintf(bufptr, "%d.", i+1);
                bufptr += strlen(bufptr);
                if (bufptr - buf > buflen - 10) break;
            }
        }
    }
    if (total) *(bufptr-1) = '\0';
    return total;
}
示例#4
0
static inline int process_article(const struct fileheader *f,int n,const struct boardheader *b){
    static const struct flock lck_set={.l_type=F_RDLCK,.l_whence=SEEK_SET,.l_start=0,.l_len=0,.l_pid=0};
    static const struct flock lck_clr={.l_type=F_UNLCK,.l_whence=SEEK_SET,.l_start=0,.l_len=0,.l_pid=0};
    static struct stat st;
    static struct tm *p;
    static char name[BOUND];
    static int fd,i,j,k,l;
    static time_t timestamp;
    static const char *S,*M,*N;
    static void *vp;
    do{
        if((timestamp=get_posttime(f))<from||timestamp>to)
            break;
        if(ISSET(PARAM_P)&&strcmp(f->owner,post))
            break;
        setbfile(name,b->filename,f->filename);
        if(stat(name,&st)==-1||!S_ISREG(st.st_mode)||st.st_size<size)
            break;
        if((fd=open(name,O_RDONLY
#ifdef O_NOATIME
            |O_NOATIME
#endif /* O_NOATIME */
            ,0644))==-1)
            break;
        if(fcntl(fd,F_SETLKW,&lck_set)==-1){
            close(fd);
            break;
        }
        vp=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,fd,0);
        fcntl(fd,F_SETLKW,&lck_clr);
        close(fd);
        if((S=(const char*)vp)==MAP_FAILED)
            break;
        for(p=NULL,j=0,i=0;S[i]&&i<st.st_size;i++){
#define EQUAL(cp,cs)    (((cp)==(cs))||(ISSET(PARAM_I)&&((cp)==toupper(cs))))
            while(j>0&&!EQUAL(P[j],S[i]))
                j=L[j-1];
            if(EQUAL(P[j],S[i]))
                j++;
            if(!P[j]){
                M=&S[l=((i-j)+1)];
                if(!ISSET(PARAM_N)){
                    for(k=0,N=M;!(N<S);N--)
                        if((*N)&0x80)
                            k++;
                    if(!(k&0x01))
                        continue;
                }
                if(!p&&!(p=localtime(&timestamp)))
                    continue;
                count++;
                fprintf(out,"%6d %-20.20s %4d %4s %04d%02d%02d%02d%02d%02d %-17.17s %6d %-13.13s %s\n",
                    n,b->filename,current,mode,(p->tm_year+1900),(p->tm_mon+1),(p->tm_mday),
                    (p->tm_hour),(p->tm_min),(p->tm_sec),f->filename,l,f->owner,f->title);
                if(ISSET(PARAM_S))
                    break;
                j=L[j-1];
            }
#undef EQUAL
        }
        munmap(vp,st.st_size);
        number++;
    }
    while(0);
    return 0;
}

static inline int process_board(const struct boardheader *b,int n,void *v){
    static char name[BOUND];
    do{
        if(ISSET(PARAM_A))
            break;
        if(ISSET(PARAM_U)){
            if(!check_read_perm(user,b))
                return -1;
            break;
        }
        if(ISSET(PARAM_B))
            break;
        if(!public_board(b))
            return -2;
    }
    while(0);
    current=n;
    if(!ISSET(PARAM_Q))
        fprintf(stdout,"正在处理版面 %-29.29s ... ",b->filename);
    if(!ISSET(PARAM_E)){
        mode="版面";
        setbdir(DIR_MODE_NORMAL,name,b->filename);
        APPLY_RECORD(name,process_article,sizeof(struct fileheader),b,0,true);
    }
    if(ISSET(PARAM_D)){
        mode="回收";
        setbdir(DIR_MODE_DELETED,name,b->filename);
        APPLY_RECORD(name,process_article,sizeof(struct fileheader),b,0,true);
    }
    if(ISSET(PARAM_J)){
        mode="自删";
        setbdir(DIR_MODE_JUNK,name,b->filename);
        APPLY_RECORD(name,process_article,sizeof(struct fileheader),b,0,true);
    }
    if(!ISSET(PARAM_Q))
        fprintf(stdout,"%s\n","处理完成!");
    return 0;
}

int main(int argc,char **argv){
#define EXIT(msg)  do{fprintf(stderr,"%s\n",(msg));if(out)fclose(out);exit(__LINE__);}while(0)
    const struct boardheader *board;
    char name[BOUND],path[BOUND];
    const char *desc;
    int ret;
    double cost;
    if(!getcwd(path,BOUND))
        EXIT("获取当前工作目录时发生错误");
    if(chdir(BBSHOME)==-1)
        EXIT("切换工作目录时发生错误...");
    if((mark=time(NULL))==(time_t)(-1))
        EXIT("获取时间时发生错误...");
    resolve_ucache();
    resolve_boards();
    to=mark;
    opterr=0;
    while((ret=getopt(argc,argv,"r:f:t:ab:u:p:djesnio:qh"))!=-1){
        switch(ret){
#define CHECK_CONFLICT(param)   do{if(ISSET(param))EXIT("给定的选项间存在冲突...");}while(0)
#define CHECK_DEPENDENCE(param) do{if(!ISSET(param))EXIT("给定的选项间缺少依赖...");}while(0)
#define CHECK_DUP(param)        do{if(ISSET(param))EXIT("给定的选项中存在重复...");}while(0)
#define SET(param)              do{CHECK_DUP(param);flag|=(param);}while(0)
            case 'r':
                CHECK_CONFLICT(PARAM_F|PARAM_T);
                SET(PARAM_R);
                do{
                    struct tm t,*p;
                    int n;
                    if(!isdigit(optarg[0]))
                        EXIT("选项 -r 的参数无法解析...");
                    n=atoi(optarg);
                    if(!(p=localtime(&mark)))
                        EXIT("解析时间时发生错误...");
                    memcpy(&t,p,sizeof(struct tm));
                    t.tm_hour=0;
                    t.tm_min=0;
                    t.tm_sec=0;
                    if((from=mktime(&t))==(time_t)(-1))
                        EXIT("设定时间时发生错误...");
                }
                while(0);
                break;
#define PARSE2(p)   ((((p)[0]*10)+((p)[1]*1))-('0'*11))
#define PARSE4(p)   ((PARSE2(p)*100)+(PARSE2(&(p)[2])*1))
            case 'f':
                CHECK_CONFLICT(PARAM_R);
                SET(PARAM_F);
                do{
                    struct tm t;
                    int i;
                    for(i=0;optarg[i];i++)
                        if(!isdigit(optarg[i]))
                            break;
                    if(i!=14)
                        EXIT("选项 -f 的参数无法解析...");
                    memset(&t,0,sizeof(struct tm));
                    t.tm_year=(PARSE4(optarg)-1900);
                    t.tm_mon=(PARSE2(&optarg[4])-1);
                    t.tm_mday=PARSE2(&optarg[6]);
                    t.tm_hour=PARSE2(&optarg[8]);
                    t.tm_min=PARSE2(&optarg[10]);
                    t.tm_sec=PARSE2(&optarg[12]);
                    if((from=mktime(&t))==(time_t)(-1))
                        EXIT("设定时间时发生错误...");
                }
                while(0);
                break;
            case 't':
                CHECK_CONFLICT(PARAM_R);
                SET(PARAM_T);
                do{
                    struct tm t;
                    int i;
                    for(i=0;optarg[i];i++)
                        if(!isdigit(optarg[i]))
                            break;
                    if(i!=14)
                        EXIT("选项 -t 的参数无法解析...");
                    memset(&t,0,sizeof(struct tm));
                    t.tm_year=(PARSE4(optarg)-1900);
                    t.tm_mon=(PARSE2(&optarg[4])-1);
                    t.tm_mday=PARSE2(&optarg[6]);
                    t.tm_hour=PARSE2(&optarg[8]);
                    t.tm_min=PARSE2(&optarg[10]);
                    t.tm_sec=PARSE2(&optarg[12]);
                    if((from=mktime(&t))==(time_t)(-1))
                        EXIT("设定时间时发生错误...");
                }
                while(0);
                break;
#undef PARSE2
#undef PARSE4
            case 'a':
                CHECK_CONFLICT(PARAM_B|PARAM_U);
                SET(PARAM_A);
                break;
            case 'b':
                CHECK_CONFLICT(PARAM_A|PARAM_U);
                SET(PARAM_B);
                if(!(current=getbid(optarg,&board)))
                    EXIT("选项 -b 所指定的版面无法获取...");
                break;
            case 'u':
                CHECK_CONFLICT(PARAM_A|PARAM_B);
                SET(PARAM_U);
                do{
                    struct userec *u;
                    if(!getuser(optarg,&u))
                        EXIT("选项 -u 所指定的用户无法获取...");
                    user=u;
                }
                while(0);
                break;
            case 'p':
                SET(PARAM_P);
                snprintf(post,OWNER_LEN,"%s",optarg);
                break;
            case 'd':
                SET(PARAM_D);
                break;
            case 'j':
                SET(PARAM_J);
                break;
            case 'e':
                CHECK_DEPENDENCE(PARAM_D|PARAM_J);
                SET(PARAM_E);
                break;
            case 's':
                SET(PARAM_S);
                break;
            case 'n':
                SET(PARAM_N);
                break;
            case 'i':
                SET(PARAM_I);
                break;
            case 'o':
                SET(PARAM_O);
                if(optarg[0]!='/')
                    snprintf(name,BOUND,"%s/%s",path,optarg);
                else
                    snprintf(name,BOUND,"%s",optarg);
                break;
            case 'q':
                SET(PARAM_Q);
                break;
            case 'h':
                usage();
                return 0;
            default:
                usage();
                EXIT("不可识别的选项...");
                break;
#undef CHECK_CONFLICT
#undef CHECK_DEPENDENCE
#undef CHECK_DUP
#undef SET
        }
    }
    if(from>to){
        usage();
        EXIT("当前时间设定不合法...");
    }
    if(!ISSET(PARAM_Q)&&setvbuf(stdout,NULL,_IONBF,BUFSIZ))
        EXIT("调整文件缓冲时发生错误...");
    if((argc-optind)!=1){
        usage();
        EXIT("不可识别的参数...");
    }
    set_pattern(argv[optind]);
    set_link(argv[optind]);
    if(!size)
        EXIT("模式串不能为空串...");
    if(!ISSET(PARAM_O))
        snprintf(name,BOUND,"%s/res_%lu.us",path,mark);
    if(!(out=fopen(name,"w")))
        EXIT("打开文件时发生错误...");
    fprintf(out,"%6s %-20.20s %4s %4s %-14.14s %-17.17s %6s %-13.13s %s\n",
        "文章号","版面名称"," BID","位置","发表时间","文件名","偏移量","作者","标题");
    if(!(P[0]&0x80))
        flag|=PARAM_N;
    if(ISSET(PARAM_B))
        process_board(board,current,NULL);
    else
        APPLY_BIDS(process_board,NULL);
    fclose(out);
    cost=difftime(time(NULL),mark);
    if(cost>86400){
        cost/=86400;
        desc="天";
    }
    else if(cost>3600){
        cost/=3600;
        desc="小时";
    }
    else if(cost>60){
        cost/=60;
        desc="分钟";
    }
    else
        desc="秒";
    fprintf(stdout,"\n操作已完成! 共处理 %d 篇文章, 获得 %d 处匹配, 耗时 %.2lf %s!\n",
        number,count,cost,desc);
    return 0;
#undef EXIT
}
示例#5
0
char * ann_numtopath(char *path, char *numpath, struct userec *user)
{
	int bid=0;
	char *c;
	char *ptr = NULL;
	const struct boardheader *bh = NULL;
    char filename[256];
    FILE *fp;
    char buf[256];
	int endfile=0;
    char currpath[256];
    char title[STRLEN];
	int ok;

	path[0]='\0';
	title[0]='\0';
	currpath[0]='\0';

	while(1){

		if(path[0]=='\0'){
			c=strchr(numpath, '-');
			if(c!=NULL)
				*c='\0';
			bid = atoi(numpath);

			if((bh=getboard(bid))==NULL) return NULL;

    		if (check_read_perm(user, bh) == 0)
		        return NULL;

		    snprintf(path,255,"0Announce/groups/%s",bh->ann_path);
			
			if(c==NULL)
				break;

			ptr = c + 1;

			continue;
		}else{
			if(ptr[0]=='\0') break;
			c = strchr(ptr, '-');
			if(c==NULL) endfile=1;
			else{
				*c='\0';
			}
			bid = atoi(ptr);
			if(c!=NULL) ptr = c+1;
			if(bid <=0) return NULL;
		}

	    snprintf(filename, sizeof(filename), "%s/.Names", path);

		ok = 0;
        if ((fp = fopen(filename, "r")) == NULL)
            return NULL;
        while (fgets(buf, sizeof(buf), fp) != NULL) {
            if ((c = strrchr(buf, '\n')) != NULL)
                *c = '\0';
            if (strncmp(buf, "Name=", 5) == 0) {
                strncpy(title, buf + 5, sizeof(title) - 1);
                title[sizeof(title) - 1] = '\0';
                continue;
            }else if (strncmp(buf, "Path=~/", 7) == 0){
                snprintf(currpath, sizeof(currpath), "%s/%s", path, buf + 7);
				continue;
			}else if (strncmp(buf, "Path=", 5) == 0){
                snprintf(currpath, sizeof(currpath), "%s/%s", path, buf + 5);
				continue;
			}else if(strncmp(buf, "Numb=", 5) == 0){
				if(bid != atoi(buf+5)){
					title[0]='\0';
					currpath[0]='\0';
					continue;
				}
            	if (ann_can_access(title, bh->filename, user) == 0) {
					break;
				}else{
					ok = 1;
					strcpy(path, currpath);
					break;
				}
			}else
				continue;
        }
        fclose(fp);
		if(!ok)
			return NULL;
		if(endfile)
			break;
    }
	if(path[0]=='/' || strncmp(path, "0Announce/groups/", 17) || strstr(path, "..") ) return NULL;
    return path;
}
示例#6
0
/* 返回值意义:
       -1  没有权限
        0  有看的权限
        1  有管理的权限
*/
int ann_traverse_check(char *path, struct userec *user)
{
    char *ptr;
    char *ptr2;
    size_t i = 0;
    char filename[256];
    char buf[256], *fnameptr;
    char pathbuf[256];
    char currpath[256];
    char title[STRLEN];
    FILE *fp;
    char board[STRLEN];

    bool has_perm_boards = false, sysop_only = false;
    char *bmstr;
    int bms_level = 0;

    /* path parameter can not have leading '/' character */
    if (path[0] == '/')
        return -1;
    board[0] = '\0';
    if ((ptr = strstr(path, "groups/")) != NULL)
        ann_get_board(ptr, board, sizeof(board));
    bzero(pathbuf, sizeof(pathbuf));
    if (board[0] == '\0') {
        ptr = path;
    } else {
        const struct boardheader *bh;
        bh = getbcache(board);
        if (check_read_perm(user, bh) == 0) return -1;
        ann_get_path(board, filename, sizeof(filename));
        snprintf(pathbuf, sizeof(pathbuf), "0Announce%s", filename);
        ptr = path + strlen(pathbuf);
        i = strlen(pathbuf);
        /* 如果是本版版主 则获得版主权限 TODO */
        if (chk_currBM(bh->BM, user))
            has_perm_boards = true;
    }

    /* 如果是站务 则获得版主权限 */
    if (HAS_PERM(user, PERM_OBOARDS) || HAS_PERM(user, PERM_ANNOUNCE) || HAS_PERM(user, PERM_SYSOP))
        has_perm_boards = true;

    /* 开始逐级判断权限 */
    while (*ptr != '\0') {
        if (*ptr == '/')
        {
            snprintf(filename, sizeof(filename), "%s/.Names", pathbuf);
        }
        else {
            if (i < sizeof(pathbuf))
                pathbuf[i] = *ptr;
            ptr++;
            i++;
            continue;
        }
        if ((fp = fopen(filename, "r")) == NULL)
            return -1;
        while (fgets(buf, sizeof(buf), fp) != NULL) {

            if ((ptr2 = strrchr(buf, '\n')) != NULL)
                *ptr2 = '\0';
            if (strncmp(buf, "Name=", 5) == 0) {
                strncpy(title, buf + 5, sizeof(title) - 1);
                title[sizeof(title) - 1] = '\0';
                continue;
            }
            if (strncmp(buf, "Path=~/", 7) == 0)
                fnameptr = buf + 7;
            else if (strncmp(buf, "Path=", 5) == 0)
                fnameptr = buf + 5;
            else
                continue;
            snprintf(currpath, sizeof(currpath), "%s/%s", pathbuf, fnameptr);
            if (strncmp(currpath, path, strlen(currpath)) != 0)
                continue;
            if (path[strlen(currpath)] != '/' && path[strlen(currpath)]!='\0' ) continue;
            
            /* 如果有指定BM 则按BM名单获得版主权限 */
            bmstr = strstr(title, "(BM:");
            if (bmstr != NULL)
                if (chk_currBM(bmstr + 4, user))
                    has_perm_boards = true;
            /* 如果指定BMS 则目录的版主权限级别升高 */
            if (strstr(title, "(BM: BMS)"))
                bms_level++;
            /* 如果指定SYSOPS 则目录为仅站务可见 */
            if (strstr(title, "(BM: SYSOPS)"))
                sysop_only = true;

#ifdef ANN_CTRLK    /* 如果Ctrl+K权限验证不通过 则禁止 */
            if(!canread(has_perm_boards ? PERM_BOARDS : 0, pathbuf, fnameptr, title))
            {
                fclose(fp);
                return -1;
            }
#endif

            /* 如果在一级BMS目录下且用户不具备版主权限 则禁止 */
            if ((bms_level >=1) && !HAS_PERM(user, PERM_BOARDS)) {
                fclose(fp);
                return -1;
            }
            /* 如果在二级BMS目录下且用户不具备本版版主权限 则禁止 */
            if ((bms_level >=2) && !has_perm_boards) {
                fclose(fp);
                return -1;
            }
            /* 如果在SYSOPS目录下且用户不是站务 则禁止 */
            if (sysop_only && !HAS_PERM(user, PERM_SYSOP)) {
                fclose(fp);
                return -1;
            }
            break;

        }
        if (feof(fp)) {
            fclose(fp);
            return -1;
        }
        fclose(fp);
        if (i < sizeof(pathbuf))
            pathbuf[i] = *ptr;
        ptr++;
        i++;
    }

    return has_perm_boards ? 1 : 0;
}