精華區beta SetupBBS 關於我們 聯絡資訊
【 以下文字轉載自 Firebird 討論區 】 【 原文由 luzi 所發表 】 (先嘆一口气,今天到3:00am以為可以睡覺了的,突然發現這么 一個BUG,一直弄到4:30才總算搞定,赶緊寫下一篇文章准備向所有有 這個BUG的BBS站站長要XO) 一. 首先測試一下你的BBS站有沒有這個問題 (只有版主權限的可以在本版測試) 1. 最好找一個沒設過文摘的版面來測試,比如test,notpad版 然后按文章順序依次將3篇文章收入文摘,(三篇足夠測試了) 即先g第X篇,再g第X+1篇,再g第X+2篇。 2. 好,現在看看文摘模式,應該依次有第X,X+1,X+2篇文章的標題 3. 回到普通模式,取消第X+1篇文章的文摘標記(再按一下g) 4. 現在再看看文摘模式里的文章,顯示的是第X,X+1的標題 這証明你的BBS系統存在這個BUG 二. 哪里來的BUG (開始我一直以為是我移植老站代碼到新站造成的,對比了半天相關的新舊代碼, 發現沒有什么不同,于是只好怀疑FB系統的原始代碼了,只是不敢相信這個一個 常用的功能居然存在BUG) 1. 先看看bbs.c里的刪除文摘的函數int dele_digest(dname,direc) 它調用下面這個語句去搜索digest_name(文摘的文件名)在目錄文件new_dir里 的位置,返回相關的fileheader結构給fh,其中cmpfilename是用來比較讀取 到的fileheader->filename与digest_name是否匹配的函數。 search_record(new_dir, &fh, sizeof(fh), cmpfilename, digest_name); 2. 再看看search_record()函數,它每讀取一個fileheader結构就調用 if((*fptr)(farg,rptr)) 去比較异同,在dele_digest的調用中 即等同于調用 comfilename(digest_name,&fh); 3. 再看看comfilename函數 int cmpfilename(struct fileheader *fhdr) { if(!strncmp(fhdr->filename,currfile,STRLEN)) return 1 ; return 0 ; } 天!居然和第2步調用的接口不一樣。 首先digest_name的定義是 char[STRLEN],而不是srtuct fileheader; 不過好在struct fileheader里的第一個item就是char filename[STRLEN]; 在這個函數里歪打正著沒有內存指針錯誤。 但是它比較的卻是digest_name和currentfile,faint.. 4. 隙艘艘currentfile岆妦繫陲陲ㄛ涴ヷ岆珨跺擁講﹝ 珨眻梑善郔輪珨棒跤currentfile董硉腔華源ㄛ婓dele_digest滲杅爵ㄛ 撈覃蚚search_record()ゴㄛヷ岆珨曆賑儉腔strcpy(currfile,digest_name); 埻懂涴跺comfilename腔賦彆箝隅峈淩ㄛ稱稱ㄛ垀眕search_record殿隙腔硉 嗣圉岆菴珨沭暮翹腔硉﹝ 5. 涴繫珨懂ㄛ渣昫憩岆....(嬪賸ㄛ擱腕迡賸 :( ) ゙. 賤樵BUG 郔疑腔源楊絞」岆赻撩迡珨跺comfilename腔滲杅懂巠茼search_record()腔覃蚚徽 饒繫饒珨曆strcpy(currentfile,digest_name)岆祥岆憩羶蚚賸儸ˋ no,no,no,遜岆衄蚚腔ㄛ狟醱delete_file滲杅猁蚚善坳﹝ 鍚俋艘賸comfilename腔埭鎢珩憩眭耋徽ㄛ坳掀誕腔岆strncmp(str1,str2,STRLEN) 奧祥奀strcmp()ㄛ垀眕斕郔疑蚚strncpy(currentfile,str,STRLEN); 參bbs.c爵饒虳垀衄蚚strcpy(currentfile,str)腔逄曆飲蜊傖strncpy勘﹝ 祥徹疑砓憩岆dele_digest滲杅爵腔猁蜊ㄛ梗腔滲杅飲蚚勤賸ㄛ裞裞 扂忒芛腔FireBird 2.5X, 2.66M唳腔埭鎢飲衄涴跺BUGㄛ砑斛岆珨跺橾BUG(崋繫芼」 砑お賸奠隱眅) 修正FireBird 2.X 刪除文摘功能的BUG 一、在bbs.c里添加下面這段函數代碼 int cmpdigestfilename(digest_name,fhdr) char *digest_name; struct fileheader *fhdr ; { if(!strcmp(fhdr->filename,digest_name)) return 1 ; return 0 ; } /* comapare file names for dele_digest function. Luzi 99.3.30 */ 二、然后用下面的代碼替換掉原來bbs.c里的dele_digest函數 int dele_digest(dname,direc) /* updated bye Luzi 99.3.30 */ char *dname; char *direc; { char digest_name[STRLEN]; char new_dir[STRLEN]; char buf[STRLEN]; char *ptr; struct fileheader fh; int pos; strncpy(digest_name,dname,STRLEN); strcpy(new_dir,direc); digest_name[0]='G'; ptr = strrchr(new_dir, '/') + 1; strcpy(ptr, DIGEST_DIR); strncpy(buf,currfile,STRLEN); strncpy(currfile,digest_name,STRLEN); pos=search_record(new_dir, &fh, sizeof(fh), cmpdigestfilename, digest_name); if(pos<=0) { return; } delete_file(new_dir,sizeof(struct fileheader),pos,cmpfilename); strncpy(currfile,buf,STRLEN); *ptr='\0'; sprintf(buf,"%s%s",new_dir,digest_name); unlink(buf); return; } -- ※ 來源:‧大紅花的國度 MSIA.pine.ncu.edu.tw‧[FROM: 202.96.134.135] -- ※ 轉載:‧大紅花的國度 MSIA.pine.ncu.edu.tw‧[FROM: 202.96.134.135]