※ 引述《wildcat (嘆息)》之銘言:
: 看了一下ptt放在CCode裡面的src...
: 發現一個很喜歡的東西, Board Attribution
: 也就是直接定義看板是要匿名、要成為群組板、要隱藏....etc.
: 這個真是非常好用,例如要匿名也不用去改src了...
: 所以興高采烈的就把他加到我自己的code裡面了
: 才發現要改的地方真不少,
: admin.c,board.c,edit.c,cache.c.....etc.
: 改cache.c的時候,發現ptt加了一個brd_sem...hmm....
: 這樣會比較快?
: 跟著加下去吧....
: 霹靂啪啦改了一堆、make過了之後....進站....嗯,看起來不錯
: 可是...動態看板不見了?!
: 更慘的是,只要等12秒(ps.動態看板更換的週期)
: 就死當住不能動了...
: 如果把動態看板關了,則一切都沒有問題....
: 原本以為是舊病復發...(ps.race condition)
: 所以檢查一下cache.c跟menu.c....
: 不對勒....原本就都有修正過了...
: 把舊的 cache.c 再copy 回來....結果還是一樣...
: 這真是難倒我了.....難道還有別的地方會造成無窮迴圈的嗎...?!
: @_@ (暈頭轉向中)
要把看版改成像Ptt版的
要修改cache,c中的pttcache部份
/*-------------------------------------------------------*/
/* PTT cache */
/*-------------------------------------------------------*/
/* cachefor 動態看版 */
struct PTTCACHE *ptt;
int ptt_semid;
void
reload_pttcache()
{
if (ptt->busystate)
{
/*sleep(1);*/
}
else
{
fileheader item;
char pbuf[256], buf[256], *chr;
FILE *fp;
int num, id, j;
ptt->busystate = 1;
sem_init(PTTSEM_KEY,&ptt_semid);
sem_lock(SEM_ENTER,ptt_semid);
ptt->max_film = 0;
bzero(ptt->notes, sizeof ptt->notes);
#if !defined(_BBS_UTIL_C_)
setapath(pbuf, "Note");
setadir(buf, pbuf);
num = get_num_records(buf, sizeof item);
#endif /* !defined(_BBS_UTIL_C_) */
id =0;
for (ptt->max_film = 20, j = 0; j <= num; j++)
#if !defined(_BBS_UTIL_C_)
if (get_record(buf, &item, sizeof item, j) != -1)
if (item.title[3]=='<' && item.title[8]=='>')
{
char path[256],buf1[256];
int num1,k;
fileheader subitem;
setapath(path,"Note");
sprintf(buf1,"%s/%s",path,item.filename);
setadir(path, buf1);
num1 = get_num_records(path, sizeof item);
for (k = 0; k <= num1; k++)
{
if (get_record(path, &subitem, sizeof item, k) != -1)
{
sprintf(ptt->notes[id++],"%s/%s",
item.filename , subitem.filename);
if (id >= MAX_MOVIE) break;
}
}
if (id >= MAX_MOVIE) break;
}
ptt->max_film = id-1;
ptt->max_history = ptt->max_film - 2;
if (ptt->max_history > MAX_HISTORY - 1)
ptt->max_history = MAX_HISTORY - 1;
if (ptt->max_history <0) ptt->max_history=0;
#endif /* !defined(_BBS_UTIL_C_) */
fp=fopen("etc/today_is","r");
if(fp)
{
fgets(ptt->today_is,15,fp);
if(chr=strchr(ptt->today_is,'\n')) *chr=0;
ptt->today_is[15]=0;
fclose(fp);
}
/* 等所有資料更新後再設定 uptime */
ptt->uptime = ptt->touchtime;
#if !defined(_BBS_UTIL_C_)
log_usies("CACHE", "reload pttcache");
#endif
sem_lock(SEM_LEAVE,ptt_semid);
ptt->busystate = 0;
}
}
void
resolve_garbage()
{
int count=0;
if (ptt == NULL)
{
ptt = attach_shm(PTTSHM_KEY, sizeof(*ptt));
if (ptt->touchtime == 0)
ptt->touchtime = 1;
}
while (ptt->uptime < ptt->touchtime)
{
count++;
reload_pttcache();
if(count > 3)
{
ptt->busystate =0;
#if !defined(_BBS_UTIL_C_)
log_usies("CACHE", "error:free pttcache dead lock!");
#endif
}
}
}
還有menu.c的movie(i)
{ extern struct PTTCACHE *ptt;
static short history[MAX_HISTORY];
static char myweek[] = "天一二三四五六";
static char buf[256],pbuf[256];
/* static char today_is[20];*/
struct tm *ptime;
FILE *fp;
time_t now;
resolve_garbage();
if ((currstat != CLASS) && (cuser.uflag & MOVIE_FLAG))
{
if(!ptt->busystate /*&& ptt->max_film*/) /* race condition */
{
do {
if (!i)
i = (rand() % ptt->max_film) + 1;
for (now = ptt->max_history; now >= 0; now--)
if (i == history[now]) {
i = 0;
break;
}
} while (i == 0);
}
else
{
i = 1;
}
memcpy(history, &history[1], ptt->max_history * sizeof(short));
history[ptt->max_history] = now = i;
if (i == 999) /* Goodbye my friend */
i = 0;
........
struct.h
struct PTTCACHE
{
char notes[MAX_MOVIE][FNLEN];
char today_is[20];
int max_film;
int max_history;
time_t uptime;
time_t touchtime;
int busystate;
};
然後到util/account.c改一下
+#include "bbs.h"
#include <time.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
#include "record.c"
/* Ptt about share memory */
struct UCACHE *uidshm;
struct PTTCACHE *ptt;
struct FROMCACHE *fcache;
static void
attach_err(shmkey, name)
int shmkey;
char *name;
{
fprintf(stderr, "[%s error] key = %x\n", name, shmkey);
exit(1);
}
static void *
attach_shm(shmkey, shmsize)
int shmkey, shmsize;
{
void *shmptr;
int shmid;
shmid = shmget(shmkey, shmsize, 0);
if (shmid < 0)
{
shmid = shmget(shmkey, shmsize, IPC_CREAT | 0600);
if (shmid < 0)
attach_err(shmkey, "shmget");
shmptr = (void *) shmat(shmid, NULL, 0);
if (shmptr == (void *) -1)
attach_err(shmkey, "shmat");
memset(shmptr, 0, shmsize);
}
else
{
shmptr = (void *) shmat(shmid, NULL, 0);
if (shmptr == (void *) -1)
attach_err(shmkey, "shmat");
}
return shmptr;
}
void
reset_garbage()
{
int n;
if (ptt == NULL)
{
ptt = attach_shm(PTTSHM_KEY, sizeof(*ptt));
if (ptt->touchtime == 0)
ptt->touchtime = 1;
}
printf("動態看板數[%d]\n",ptt->max_film );
printf("最大留言數[%d]\n",ptt->max_history );
for(n=0;n<=ptt->max_film;n++)
printf(" (%d) %s \n",n,ptt->notes[n]);
ptt->uptime =0;
}
在account.c最後面的地方
system(buf);
}
/* Ptt reset Ptt's share memory */
+ reset_garbage();
}
然後到Note建一個目錄 目錄名是<XXX>
裡面要有一些看版
然後用站長去執行reload_cache()
去/bbs下跑 bin/account 看看版有沒有讀入
如果有讀入會出縣
動態看板數[163]
最大留言數[4]
(0) D.893242915.A/M.879619766.A
(1) D.893242915.A/M.891441002.A
(2) D.893242915.A/M.893242983.A
(3) D.893242915.A/M.893573330.A
(4) D.893242915.A/M.896819056.A
(5) D.893242944.A/M.893242999.A
(6) S.893344641.A/M.896465130.A
(7) S.893344641.A/M.896495533.A
(8) S.893344641.A/M.896543309.A
(9) S.893344641.A/M.896528695.A
這樣的結果 這樣就改成功了 :)
這也是要使用Ptt點歌的一個必要步驟 我想應該是啦 :)