Linux 版 (精华区)
发信人: cucme (说你说我), 信区: Linux
标 题: 一塌糊涂个人精华区代码[part1]
发信站: 紫 丁 香 (Tue Apr 25 09:09:21 2000), 转信
发信人: ecnegrevid (车人一月刀), 信区: Linux
标 题: [转载] Part I
发信站: 一塌糊涂 BBS (Mon Apr 24 18:16:00 2000), 转信
【 以下文字转载自 Personal_Corpus 讨论区 】
【 原文由 ecnegrevid 所发表 】
一塌糊涂(ytht.net)个人精华区代码 Part I
修改都集中在announce.c中.
***********************************************************************
amenu函数的起始部分做了如下改动, 以判断是否个人精华区, 如是则给予相应权限:
me.level = lastlevel;
bmonly=lastbmonly;
a_loadnames( &me );
bzero(buf,sizeof(buf));
strcpy(buf,me.mtitle);
bmstr=strstr(buf+38,"(BM:"); /*buf+38是为了避免与标题内容混淆了, 原来的
代码此处是Bug*/
if(bmstr!=NULL)
{ switch(chk_currBM_Personal(bmstr+4))
{ case 3: /*PERM_BLEVELS且该目录是不不属于自己的
个人目录, 不能进不属于自己的目录*/
return;
case 2: /*是版主*/
case 1: /*是个人版, 并且当前ID是拥有者*/
if((me.level&PERM_BOARDS)==0)
{ me.level |= PERM_BOARDS;
a_loadnames(&me);
}
break;
case -1: /*是个人版, 并且当前ID不是拥有者*/
if((me.level&PERM_BOARDS)!=0)
{ me.level &= ~PERM_BOARDS;
a_loadnames(&me);
}
break;
}
if(strstr(bmstr, "(BM: BMS)") ||strstr( bmstr, "(BM: SECRET)")||
strstr(bmstr, "(BM: SYSOPS)"))
bmonly=1;
}
if(bmonly==1&&!(me.level & PERM_BOARDS)) return
me.page = 9999;
me.now = 0;
while( 1 ) {
***********************************************************************
announce.c中增加如下函数, 用来判断对目录的权限, 被a_menu调用:
/*chk_currBM_Personal用于对个人精华区的支持, by ecnegrevid*/
int
chk_currBM_Personal(BMstr)
char BMstr[STRLEN-1];
{
char *ptr;
char BMstrbuf[STRLEN-1];
int chk1=0, chk2=0;
strcpy(BMstrbuf,BMstr);
ptr=strtok(BMstrbuf,",: ;|&()\0\n");
while(1)
{
if(ptr==NULL) break;
if(!strcmp(ptr,currentuser.userid))
chk1=1;
if(!strcmp(ptr,"_Personal"))
chk2=1;
if(chk1&&chk2) break;
ptr=strtok(NULL,",: ;|&()\0\n");
}
if(chk2==0)
{ if(!HAS_PERM(PERM_BOARDS)) return 0;
if(chk1==1||HAS_PERM(PERM_BLEVELS)) return 2;
return 0;
}
if(chk1==0&&HAS_PERM(PERM_BLEVELS)) return 3;
if(chk1==1&&HAS_PERM(PERM_SPECIAL8)) return 1;
return 0;
}
***********************************************************************
announce.c中的函数a_loadnames做如下修改, 以隐藏<HIDE>目录,
并且在判断SYSOPS的时候给 title加上了38, 以避免将版主设置和文字
标题混淆
pm->num = 0;
sprintf( buf, "%s/.Names", pm->path );
if( (fn = fopen( buf, "r" )) == NULL )
return 0;
hostname[0]='\0';
while( fgets( buf, sizeof(buf), fn ) != NULL ) {
if( (ptr = strchr( buf, '\n' )) != NULL )
*ptr = '\0';
if( strncmp( buf, "Name=", 5 ) == 0 ) {
bzero(litem.title,sizeof(litem.title)); /*add by ecnegrevid*/
strncpy( litem.title, buf + 5, 72 );
litem.title[71] = '\0';
} else if( strncmp( buf, "Path=", 5 ) == 0 ) {
if( strncmp( buf, "Path=~/", 7 ) == 0 )
strncpy( litem.fname, buf + 7, 80 );
else
strncpy( litem.fname, buf + 5, 80 );
litem.fname[79] = '\0';
if((!strstr(litem.title+38,"(BM: BMS)")||HAS_PERM(PERM_BOARDS))&&
(!strstr(litem.title+38,"(BM: SYSOPS)")||HAS_PERM(PERM_SYSOP))&&
(strstr(litem.title,"<HIDE>")!=litem.title
||(pm->level&PERM_BOARDS))) /*modified by ecnegrevid*/
{
if(strstr(litem.fname,"!@#$%"))
{
***********************************************************************
由于增添了<HIDE>隐藏目录的功能, bbs2www的代码也要相应修改
才隐藏得完善. 在bbs0an.c中做两处修改:
第一处, 判断改目录是否允许打开
rewind (inf);
while (fgets (buf, STRLEN, inf))
{
if ((ptr = strchr (buf, '\n')) != NULL)
*ptr = '\0';
if (strncmp (buf, "# Title=", 8) == 0)
{
if (strstr (buf, "(BM: BMS)") != NULL
|| strstr (buf, "(BM: SYSOPS)") != NULL
|| strstr (buf, "(BM: SECRET)") != NULL
//add
|| strstr (buf,"<HIDE>")!= NULL
//en//endd
)
第二处, 显示文章列表处判断是否隐藏
else if (strncmp (buf, "Path=", 5) == 0)
{
if (strncmp (buf, "Path=~/", 7) == 0)
strncpy (fname, buf + 7, sizeof (fname));
else
strncpy (fname, buf + 5, sizeof (fname));
if (!strstr (title, "(BM: BMS)") && !strstr (title, "(BM: SYSOPS)")
//add
&&!strstr(title,"<HIDE>")&&!strstr(title,"(BM: SECRET)")
//end
)
{
pos = 37;
while (title[pos] == ' ')
title[pos--] = '\0';
index++;
***********************************************************************
在bbs代码中有处错误, 在版主在精华区用s显示文件名称后, 到别的目录也显示
目录名称, 尽管在那里他不是版主. a_showmenu函数中应该做如下改动:
if( a_fmode ) {
sprintf( fname,"%s", pm->item[n]->fname );
sprintf( genbuf, "%s/%s", pm->path, fname );
/*加上对level的检测, 使得出到非自己的管辖区时看不到文件名 ecnegrevid*/
if( a_fmode == 2&&(pm->level&PERM_BOARDS)!=0 ) {
ch = (dashf( genbuf ) ? ' ' : (dashd( genbuf ) ? '/' : ' '));
fname[10]='\0';
} else {
if( dashf( genbuf )||dashd( genbuf ) ) {
stat( genbuf, &st );
mtime = st.st_mtime;
}else
mtime=time(0);
***********************************************************************
a_Import函数应该修改, 以便个人整理精华区, 方法是判断丝路是否已经设定, 设定了
就往精华区放文章, 否则不放. 判断方法依据丝路给定方法修改.
// add by gluon
sprintf(buf,"/home/bbs/tmp/%s.anpath",currentuser.userid);
if ((fn = fopen(buf, "r")) != NULL ) {
fscanf(fn,"%s",Importname);
fclose(fn);
if (!dashd(Importname)) {
if(!nomsg)
a_prompt(-1,"你设定的丝路已丢失,请重新设置",ans,2);
}else iflag=1;
}
//end
if(!iflag)return 0;
pm.path = Importname;
strcpy( pm.mtitle, "" );
pm.level|=PERM_BOARDS; /* add by ecnegrevid*/
a_loadnames ( &pm );
strcpy(fname,fileinfo->filename);
sprintf(bname,"%s/%s",pm.path , fname);
ip=&fname[strlen(fname)-1];
while(dashf(bname))
{
if(*ip == 'Z')
ip++,*ip = 'A', *(ip + 1) = '\0' ;
else
(*ip)++ ;
sprintf(bname,"%s/%s",pm.path , fname);
}
***********************************************************************
由于个人精华区时常发生条目丢失的情况, 因此增加收集丢失条目的函数a_repair
/* 下面的函数a_repair用来收集丢失的条目, 把它们放进精华区的目录中 by ecnegrevid*/
int
a_repair(pm)
MENU *pm;
{ DIR *dirp;
struct dirent *direntp;
int i, changed;
changed=0;
dirp=opendir(pm->path);
if(dirp==NULL) return -1;
while((direntp=readdir(dirp))!=NULL)
{ if(direntp->d_name[0]=='.') continue;
for(i=0;i<pm->num;i++)
{ if(strcmp(pm->item[i]->fname, direntp->d_name)==0)
{ i=-1;
break;
}
}
if(i!=-1)
{ a_additem(pm, direntp->d_name, direntp->d_name, NULL, 0);
changed++;
}
}
closedir(dirp);
if(changed>0) a_savenames(pm);
return changed;
}
这个函数放置在a_manage中:
case 'c': a_copypaste( pm,0); break;
/*收集丢失条目, add by ecnegrevid */
case Ctrl('r'):
sprintf(genbuf,
"发现 %d 个丢失条目, 请按<Enter>继续...",
a_repair(pm));
a_prompt(-1,genbuf, ans, 2);
pm->page = 9999;
break;
/*--- end add by ecnegrevid ---*/
}
***********************************************************************
下面是几处容易发生条目丢失的代码的修改:
在执行announce.c中a_loadnames函数读取.Names文件时, 一部分特殊
目录被隐藏. 而在执行a_savenames保存.Names文件时, 使用的是
a_loadnames读取的条目, 这时那些被隐藏的条目就会丢失.
要修改这个Bug, 只需要保证有权修改.Names者总能读取完整的.Names,
没有任何隐藏. 因此, 只要使a_loadnames(pm)在pm->level包含PERM_
BOARDS时读取完整的目录(上文已经做到), 并且使修改.Names者在读取
调用a_loadnames(pm)时pm->level总包含PERM_BOARDS即可.
修改announce.c中的a_loadnames函数, 其中判断是否隐藏条目
的地方改为只要level包含PERM_BOARDS就不隐藏:
strncpy( litem.fname, buf + 7, 80 );
else
strncpy( litem.fname, buf + 5, 80 );
litem.fname[79] = '\0';
if(((!strstr(litem.title+38,"(BM: BMS)")||HAS_PERM(PERM_BOARDS))&&
(!strstr(litem.title+38,"(BM: SYSOPS)")||HAS_PERM(PERM_SYSOP))&&
(strstr(litem.title,"<HIDE>")!=litem.title))||
(pm->level&PERM_BOARDS) ) /*modified by ecnegrevid*/
{
if(strstr(litem.fname,"!@#$%"))
修改a_Import函数, 其中一处调用a_loadnames:
pm.path = Importname;
strcpy( pm.mtitle, "" );
pm.level|=PERM_BOARDS; /* add by ecnegrevid*/
a_loadnames ( &pm );
strcpy(fname,fileinfo->filename);
修改linkto函数, 其中一处调用a_loadnames:
strcpy(pm.mtitle,title);
pm.level|=PERM_BOARDS; /*add by ecnegrevid*/
a_loadnames(&pm);
a_additem(&pm,title,fname ,NULL,0);
修改del_grp函数, 其中一处调用a_loadnames:
sprintf(bpath,"%s/%s",gpath,bname);
deltree(bpath) ;
pm.path=gpath;
pm.level|=PERM_BOARDS; /*add by ecnegrevid*/
a_loadnames(&pm);
for(i=0;i<pm.num;i++)
{
修改edit_grp函数, 其中一处调用a_loadnames:
if(!seek_in_file(buf,bname))
return 0;
pm.path=gpath;
pm.level|=PERM_BOARDS; /*add by ecnegrevid*/
a_loadnames(&pm);
for(i=0;i<pm.num;i++)
{
--
※ 修改:.ecnegrevid 于 Apr 24 18:23:01 修改本文.[FROM: 162.105.21.117]
※ 来源:.一塌糊涂 BBS ytht.net.[FROM: 162.105.21.117]
--
※ 转载:.一塌糊涂 BBS ytht.net.[FROM: 162.105.21.117]
--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.118.244.207]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.476毫秒