精華區beta SetupBBS 關於我們 聯絡資訊
※ 引述《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點歌的一個必要步驟 我想應該是啦 :)