荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: hace.bbs@hace.dhs.org (半边海), 信区: InstallBBS
标 题: [转载]实现 `个人文章阅读' v0.2 [1]
发信站: 半边海BBS (Mon Apr 7 18:35:24 2003)
转信站: SZU!news.tiaozhan.com!news.bjsing.net!SCUT-x12
【 以下文字转载自 sysop 讨论区 】
【 原文由 hace 所发表 】
实现 `个人文章阅读' v0.2 [1]
$$ 2003.04.07 hace $ BBS 版本: firebird2000 v1106 $$
1. 实现方法
首先在 /home/bbs 中创建目录 PersonalPost ,即 /home/bbs/PersonalPost
然后创建目录 /home/bbs/PersonalPost/?/ ?为A到Z
每个人的文章放到目录 /home/bbs/PersonalPost/?/userid/ 中
如 hace 的文章将放到 /home/bbs/PersonalPost/H/hace/ 中
每发表一篇文章需要记录时,
就用symlink()做链接到 /home/bbs/PersonalPost/?/userid/
如发表了 /home/bbs/boards/sysop/M.1049382934.A 后,
将在目录 /home/bbs/PersonalPost/?/userid/ 中创建链接
M.1049382934.A 文件,让它指向
/home/bbs/boards/sysop/M.1049382934.A
目录 /home/bbs/PersonalPost/?/userid 中的文件读取跟精华区一样,
用的是 .Names 来索引.
2. 代码更改.
a) 修改 munu.ini
先修改 /home/bbs/etc/menu.ini ,在特别服务那增加一行:
@Hace_post 12,29, PERM_POST, "Hace_post", "(H) 个人文章"
~~~~~~ 这两个数字是定位的,没什么关系.
然后在comm_lists.c中的 MENU sysconf_cmdlist[]
增加一行如下,前面有++的为增加的:
MENU sysconf_cmdlist[] = {
{"domenu", domenu, 0},
++ {"Hace_post",hace_post,0},
//....
//....
}
b) 增加文件 hace_post.c ,内容如下
/* hace_post.c */
#include "bbs.h"
int hace_post(void){
char path[512],lookid[IDLEN + 6];
modify_user_mode(PERSONALREAD);
refresh();
move(1,0);
clrtobot();
prints("您想看谁的文章:\n<输入使用者代号, 按空白键可列出符合字串>\n");
move(1,16);
usercomplete(NULL,lookid);
if(!getuser(lookid) || lookid[0]==0){
presskeyfor("经查实,无此ID...",2);
}else{
sprintf(path,"%s/%c/%s",PerPostPath,toupper(lookid[0]),lookid);
a_menu("",path,0,-2003);
}
clear();
return 1;
}
c) 修改 Makefile
对 CFILE 增加 hace_post.c ,对 COBJS 增加 hace_post.o
d) 修改 bbs.h
在 bbs.h 中加上一行:
#define PerPostPath "/home/bbs/PersonalPost"
e) 修改 modetype.c
在 char *ModeType(mode) 中加上:(前有 ++ 的为新加的
char *ModeType(mode)
int mode;
{
//....
//....
++ case PERSONALREAD:
++ return "览个人文章";
//....
}
f) 修改 modes.h , 在里面加上一行:
#define PERSONALREAD 2003
g) 修改 bbs.c
g.0 在前面加上下列函数说明:
/* add by hace */
extern void h_del_post(char *path,char *fname);
extern char * h_split(const char *s,char *buf);
extern void h_title_change(char *path,const char *filename,
const char *newtitle);
extern void h_post_link(char *,char *,char *,char *);
int h_delete_range(char *,int,int);
extern int h_link_board(char *board);
/* end */
g.1 修改函数 int post_article(postboard, mailid)
int post_article(postboard, mailid)
char *postboard, *mailid;
{
//.... //省掉了N行
if (!junkboard()) {
set_safe_record();
currentuser.numposts++;
substitute_record(PASSFILE, ¤tuser,
sizeof(currentuser), usernum);
}
++ /* add by hace */
++ if(h_link_board(postboard)==1)
++ h_post_link(currentuser.userid,postfile.title,filepath,fname);
++ /* end */
return FULLUPDATE;
}
g.2 修改函数 int edit_title(ent, fileinfo, direct)
int edit_title(ent, fileinfo, direct)
int ent;
struct fileheader *fileinfo;
char *direct;
{
//.... //省掉了N行
/* add by hace */
++ if(h_link_board(currboard)==1){
++ sprintf(genbuf,"%s/%c/%s",PerPostPath,
++ toupper(fileinfo->owner[0]),fileinfo->owner);
++ h_title_change(genbuf,fileinfo->filename,buf);
++ }
/* end */
substitute_record(direct, fileinfo, sizeof(*fileinfo), ent);
}
return PARTUPDATE;
}
g.3 修改函数 int UndeleteArticle(ent, fileinfo, direct)
int UndeleteArticle(ent, fileinfo, direct)
int ent;
struct fileheader *fileinfo;
char *direct;
{
//.... //省掉了N行
clear();
move(2, 0);
prints("'%s' 已恢复到 %s 板 \n", UFile.title, UBoard);
pressreturn();
++ /* add by hace */
++ if(h_link_board(UBoard)==1){
++ memset(buf,0,sizeof(buf));
++ sprintf(buf,"boards/%s/%s",UBoard,UFile.filename);
++ h_post_link(UFile.owner,UFile.title,buf,UFile.filename);
++ }
++ /* end */
return FULLUPDATE;
}
g.4 修改函数 int del_post(int ent, struct fileheader *fileinfo,
char *direct)
int del_post(int ent, struct fileheader *fileinfo, char *direct)
{
//..... //省掉了N行
}
}
++ /* add by hace */
++ if(h_link_board(currboard)==1){
++ char path[512];
++ memset(path,0,sizeof(path));
++ sprintf(path,"%s/%c/%s",PerPostPath,
++ toupper(fileinfo->owner[0]),fileinfo->owner);
++ h_del_post(path,fileinfo->filename);
++ }
++ /* end */
return DIRCHANGED;
}else if (SR_BMDELFLAG) {
return -1;
}
move(t_lines - 1, 0);
prints("删除失败...");
clrtoeol();
egetch();
return PARTUPDATE;
}
g.5 增加函数 h_delete_range()
/*
* h_delete_range() 由 record.c 中的
* delete_range 增加下面 前面标有`++'的代码而得到
*/
int h_delete_range(char *filename, int id1, int id2)
{
struct fileheader fhdr;
char tmpfile[STRLEN], deleted[STRLEN];
int fdr, fdw, fd, count;
char h_path[128];
tmpfilename(filename, tmpfile, deleted);
if ((fd = open(".dellock", O_RDWR | O_CREAT | O_APPEND, 0644)) == -1)
return -1;
flock(fd, LOCK_EX);
if ((fdr = open(filename, O_RDONLY, 0)) == -1) {
flock(fd, LOCK_UN);
close(fd);
return -1;
}
if ((fdw = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0644)) == -1) {
close(fdr);
flock(fd, LOCK_UN);
close(fd);
return -1;
}
count = 1;
while (read(fdr, &fhdr, sizeof(fhdr)) == sizeof(fhdr)) {
if (count < id1 || count > id2 || fhdr.accessed[0] &
(FILE_MARKED | FILE_DIGEST)) {
if ((safewrite(fdw, (char *) &fhdr, sizeof(fhdr)) == -1)) {
close(fdw);
unlink(tmpfile);
close(fdr);
flock(fd, LOCK_UN);
close(fd);
return -1;
}
} else {
char *t;
char buf[STRLEN], fullpath[STRLEN];
strcpy(buf, filename);
if ((t = strrchr(buf, '/')) != NULL)
*t = '\0';
sprintf(fullpath, "%s/%s", buf, fhdr.filename);
#ifdef BACKUP_RANGE_DELETE
/*
if (strcmp(currboard, "deleted")&&strcmp(currboard,"junk")){
cancelpost(currboard, currentuser.userid,&fhdr,
!strcmp(fhdr.owner, currentuser.userid));
}
*/
/* added by wer to backup the posts deleted with 'D'*/
/* Expand the non-backup range by quickmouse */
if (!NotBackupBoard()) {
cancelpost(currboard, currentuser.userid,
&fhdr, !strcmp(fhdr.owner, currentuser.userid));
}
#endif
unlink(fullpath);
++ /* add by hace */
++ h_split(fullpath,buf);
++ if(h_link_board(buf)==1){
++ sprintf(h_path,"%s/%c/%s",PerPostPath,
++ toupper(fhdr.owner[0]),fhdr.owner);
++ h_del_post(h_path,fhdr.filename);
++ }
++ /* end */
}
count++;
}
close(fdw);
close(fdr);
if (rename(filename, deleted) == -1) {
flock(fd, LOCK_UN);
close(fd);
return -1;
}
if (rename(tmpfile, filename) == -1) {
flock(fd, LOCK_UN);
close(fd);
return -1;
}
flock(fd, LOCK_UN);
close(fd);
return 0;
}
h) 修改 record.c , 把 delete_range() 函数注释掉.
i) 修改 announce.c ,
i.0
在前面增加下面的函数说明:
char * h_split(const char *s,char *buf);
int h_link_boards(char *board);
i.1 增加下面的函数:
i.1.1 h_split()
/* h_split()
* 本函数用于获取路径中的板面字符串.
* 若 *s="/home/bbs/boards/sysop/M.1049611297.A"
* 则返回 *buf="sysop"
*/
char * h_split(const char *s,char *buf)
{
int start,end;
int len=strlen(s);
start=end=0;
for(;len>=0;)
if(s[--len]=='/'){
end=len;
break;
}
for(;len>=0;)
if(s[--len]=='/'){
start=len+1;
break;
}
for(len=0;len<end-start;len++)
buf[len]=s[start+len];
buf[len]='\0';
return buf;
}
}
/* end h_split() */
i.1.2 h_del_post()
/*
* 当删除一篇文章时(用d,D,b)
* 本调用本函数在个人文章里删除掉对应的链接
* 和修改 .Names
* 输入的 path="/home/bbs/PersonalPost/?/userid"
* ? 为 A 到 Z
* fname 为文件名,如 fname="M.1049546104.A"
*/
void h_del_post(char *path,char *fname)
{
MENU me;
int i=0;
char fpath[128];
me.path = path;
me.level = -2003;
a_loadnames(&me);
for(i=0;i<me.num;i++){
if(!strcmp(me.item[i]->fname,fname))break;
}
if(i>=me.num)return;
sprintf(fpath,"%s/%s",path,fname);
unlink(fpath);
(me.num)--;
me.now=i;
for(i=me.now;i<me.num;i++){
strcpy(me.item[i]->title,me.item[i+1]->title);
strcpy(me.item[i]->fname,me.item[i+1]->fname);
}
a_savenames(&me);
}
/* end h_del_post() */
i.1.3 h_title_change()
/*
* 当发表的文章被修改标题后
* 会调本函数去修改相应的.Names中的标题
*/
void h_title_change(char *path,const char *filename,const char *newtitle)
{
MENU me;
int i;
me.path=path;
me.level=-2003;
a_loadnames(&me);
for(i=0;i<me.num;i++){
if(!strcmp(me.item[i]->fname,filename)){
strcpy(me.item[i]->title,newtitle);
break;
}
}
a_savenames(&me);
}
/* end h_title_change() */
i.1.4 h_link_board()
/*
* 本函数检查发表文章所在的板块 board 是否
* 需要记录到个人文章区里去,需要的话返回 1
*/
int h_link_board(char * board)
{
char *n_lnboard[]={ //所定义的为不需要被记录到`个人文章区'里的
"bbslists", //注意,修改了n_lnboard[]后要修改后面的 len
"BBS_help",
"board",
"cnAnnounce",
"cnLists",
"cnTest",
"cnWeather",
"deleted",
"syssecurity",
"junk",
"newcomers",
"notepad",
"Penalization",
"test",
"vote",
"Water",
};
int i,len=16;
for(i=0;i<len;i++)
if(!strcmp(board,n_lnboard[i]))return -1;
return 1;
}
/* end h_link_board() */
i.1.5 h_post_link()
/*
* 当发表一篇后,如果需要记录到`个人文章区'里的话
* 就调用此函数, whopost 为文章发表者, title 为文章标题
* filepath 为文件路径,如 boards/sysop/M.1049611297.A
* fname 为文件名,如 M.1049611297.A
*/
void h_post_link(char *whopost,char *title,char *filepath,char *fname)
{
char path[128],oldpath[128],newpath[128];
FILE *fp;
sprintf(oldpath,"%s/%s",BBSHOME,filepath);
sprintf(newpath,"%s/%c/%s/%s",PerPostPath,toupper(whopost[0]),
whopost,fname);
sprintf(path,"%s/%c/%s/.Names",PerPostPath,toupper(whopost[0]),whopost);
fp=fopen(path,"r");
if(fp==NULL){
memset(path,0,sizeof(path));
sprintf(path,"%s/%c",PerPostPath,toupper(whopost[0]));
mkdir(path,0755);
sprintf(path,"%s/%s",path,whopost);
mkdir(path,0755);
sprintf(path,"%s/.Names",path);
fp=fopen(path,"w");
fprintf(fp,"#\n");
fprintf(fp,"# Title= %s ● [%s] 的最近作品 \n",BBSNAME,whopost);
fprintf(fp,"#\n");
fprintf(fp,"Name=%s\n",title);
fprintf(fp,"Path=~/%s\n",fname);
fprintf(fp,"Numb=1\n#\n");
fclose(fp);
}else{
MENU me;
int i;
memset(path,0,sizeof(path));
sprintf(path,"%s/%c/%s",PerPostPath,toupper(whopost[0]),whopost);
me.path=path;
me.level=-2003;
a_loadnames(&me);
me.item[me.num]=(ITEM *)malloc(sizeof(ITEM));
for(i=me.num;i>0;i--){
strcpy(me.item[i]->title,me.item[i-1]->title);
strcpy(me.item[i]->fname,me.item[i-1]->fname);
}
strcpy(me.item[0]->title,title);
strcpy(me.item[0]->fname,fname);
me.item[0]->host=NULL;
me.item[0]->port=0;
(me.num)++;
a_savenames(&me);
fclose(fp);
}
symlink(oldpath,newpath);
}
/* end h_post_link() */
--
/
/__ __ __ __
/ / / ) / /__)
/ / \_/\ \__ \__
※ 修改:·hace 於 04月07日18:28:51 修改本文·[FROM: 深海]
※ 来源:·半边海BBS hace.dhs.org·[FROM: 深海]
--
※ 转载:·半边海BBS hace.dhs.org·[FROM: hace]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店