int unread_position(char *dirfile, board_data_t *ptr) { struct fileheader fh; char filename[STRLEN]; int fd, offset, step, num; num = ptr->total + 1; if (ptr->unread && (fd = open (dirfile, O_RDWR))> 0) { if (!brc_initial (currentuser.userid, ptr->name)) { num = 1; } else { offset = (int) ((char *) &(fh.filename[0]) - (char *) &(fh)); num = ptr->total - 1; step = 4; while (num> 0) { lseek (fd, (off_t) (offset + num * sizeof (fh)), SEEK_SET); if (read (fd, filename, STRLEN) <= 0 || !brc_unread (filename)) break; num -= step; if (step < 32) step += step / 2; } if (num < 0) num = 0; while (num < ptr->total) { lseek (fd, (off_t) (offset + num * sizeof (fh)), SEEK_SET); if (read (fd, filename, STRLEN) <= 0 || brc_unread (filename)) break; num++; } } close (fd); } if (num < 0) num = 0; return num; }
int gen_super_filter_index2(char *index, struct fileheader* fileinfo, char * boardname, int isbm) { struct fileheader *ptr1; struct flock ldata, ldata2; int fd, fd2, size = sizeof(fileheader), total, i, count = 0; char direct[PATHLEN]; char newdirect[PATHLEN]; char *ptr; struct stat buf; int load_content=0, found=0, load_stat=0; int gid = fileinfo->groupid; //TODO: 这么大的index! load_content = (strstr(index, "content")!=NULL||strstr(index, "文章内容")!=NULL); load_stat = (strstr(index, "asize")!=NULL||strstr(index, "总长度")!=NULL); setbdir(DIR_MODE_NORMAL, direct, boardname); setbdir(DIR_MODE_SUPERFITER, newdirect, boardname); if ((fd = open(newdirect, O_WRONLY | O_CREAT, 0664)) == -1) { bbslog("user", "%s", "recopen err"); return -9999; } ldata.l_type = F_WRLCK; ldata.l_whence = 0; ldata.l_len = 0; ldata.l_start = 0; if (fcntl(fd, F_SETLKW, &ldata) == -1) { bbslog("user", "%s", "reclock err"); close(fd); return -9999; } if ((fd2 = open(direct, O_RDONLY, 0664)) == -1) { bbslog("user", "%s", "recopen err"); ldata.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &ldata); close(fd); return -9999; } fstat(fd2, &buf); ldata2.l_type = F_RDLCK; ldata2.l_whence = 0; ldata2.l_len = 0; ldata2.l_start = 0; fcntl(fd2, F_SETLKW, &ldata2); total = buf.st_size / size; if ((i = safe_mmapfile_handle(fd2, PROT_READ, MAP_SHARED, (void **) &ptr, &buf.st_size)) != 1) { if (i == 2) end_mmapfile((void *) ptr, buf.st_size, -1); ldata2.l_type = F_UNLCK; fcntl(fd2, F_SETLKW, &ldata2); close(fd2); ldata.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &ldata); close(fd); return -9999; } ptr1 = (struct fileheader *) ptr; libs = (char*)malloc(LIBLEN); for (i = 0; i < total; i++) { struct stat st; char* p; char ffn[80]; int j=0; off_t fsize; libptr = libs; ferr = 0; set_vard(fvars+fget_var("cid"), fileinfo->id); set_vard(fvars+fget_var("creid"), fileinfo->reid); set_vard(fvars+fget_var("cgroupid"), fileinfo->groupid); set_vars(fvars+fget_var("cauthor"), fileinfo->owner); set_vars(fvars+fget_var("cfname"), fileinfo->filename); set_vard(fvars+fget_var("cftime"), get_posttime(fileinfo)); set_vard(fvars+fget_var("ceffsize"), fileinfo->eff_size); set_vard(fvars+fget_var("no"), i+1); set_vard(fvars+fget_var("文章号"), i+1); set_vard(fvars+fget_var("id"), ptr1->id); set_vard(fvars+fget_var("reid"), ptr1->reid); set_vard(fvars+fget_var("groupid"), ptr1->groupid); set_vard(fvars+fget_var("thread"), ptr1->groupid==gid); set_vard(fvars+fget_var("本主题"), ptr1->groupid==gid); set_vard(fvars+fget_var("origin"), ptr1->id==ptr1->groupid); set_vard(fvars+fget_var("原作"), ptr1->id==ptr1->groupid); set_vard(fvars+fget_var("m"), ptr1->accessed[0]&FILE_MARKED); set_vard(fvars+fget_var("保留"), ptr1->accessed[0]&FILE_MARKED); set_vard(fvars+fget_var("g"), ptr1->accessed[0]&FILE_DIGEST); set_vard(fvars+fget_var("文摘"), ptr1->accessed[0]&FILE_DIGEST); set_vard(fvars+fget_var("b"), (ptr1->accessed[0]&FILE_MARKED)&&(ptr1->accessed[0]&FILE_DIGEST)); if (isbm) { set_vard(fvars+fget_var("noreply"), ptr1->accessed[1]&FILE_READ); set_vard(fvars+fget_var("不可回复"), ptr1->accessed[1]&FILE_READ); set_vard(fvars+fget_var("sign"), ptr1->accessed[0]&FILE_SIGN); set_vard(fvars+fget_var("标记"), ptr1->accessed[0]&FILE_SIGN); #ifdef PERCENT_SIGN_SUPPORT set_vard(fvars+fget_var("percent"), ptr1->accessed[0]&FILE_PERCENT); set_vard(fvars+fget_var("百分号"), ptr1->accessed[0]&FILE_PERCENT); #endif #ifdef FILTER set_vard(fvars+fget_var("censor"), ptr1->accessed[1]&FILE_CENSOR); set_vard(fvars+fget_var("审核"), ptr1->accessed[1]&FILE_CENSOR); #endif set_vard(fvars+fget_var("del"), ptr1->accessed[1]&FILE_DEL); set_vard(fvars+fget_var("删除"), ptr1->accessed[1]&FILE_DEL); set_vard(fvars+fget_var("import"), ptr1->accessed[0]&FILE_IMPORTED); set_vard(fvars+fget_var("精华"), ptr1->accessed[0]&FILE_IMPORTED); } set_vard(fvars+fget_var("attach"), ptr1->attachment); set_vard(fvars+fget_var("附件"), ptr1->attachment); set_vars(fvars+fget_var("title"), ptr1->title); set_vars(fvars+fget_var("标题"), ptr1->title); set_vars(fvars+fget_var("author"), ptr1->owner); set_vars(fvars+fget_var("作者"), ptr1->owner); set_vars(fvars+fget_var("fname"), ptr1->filename); set_vars(fvars+fget_var("文件名"), ptr1->filename); set_vard(fvars+fget_var("my"), !strcmp(ptr1->owner,getCurrentUser()->userid)); set_vard(fvars+fget_var("我的"), !strcmp(ptr1->owner,getCurrentUser()->userid)); #ifdef HAVE_BRC_CONTROL set_vard(fvars+fget_var("unread"), brc_unread(ptr1->id, getSession())); set_vard(fvars+fget_var("未读"), brc_unread(ptr1->id, getSession())); #endif setbfile(ffn, boardname, ptr1->filename); set_vard(fvars+fget_var("ftime"), get_posttime(ptr1)); set_vard(fvars+fget_var("时间"), get_posttime(ptr1)); set_vard(fvars+fget_var("effsize"), ptr1->eff_size); set_vard(fvars+fget_var("有效长度"), ptr1->eff_size); if(load_stat) { if(stat(ffn, &st)!=-1) { set_vard(fvars+fget_var("asize"), st.st_size); set_vard(fvars+fget_var("总长度"), st.st_size); } else { set_vard(fvars+fget_var("asize"), 0); set_vard(fvars+fget_var("总长度"), 0); } } if(load_content) { set_vars(fvars+fget_var("content"), ptr1->filename); set_vars(fvars+fget_var("文章内容"), ptr1->filename); j = safe_mmapfile(ffn, O_RDONLY, PROT_READ, MAP_SHARED, (void **) &p, &fsize, NULL); if(j) { set_vars(fvars+fget_var("content"), p); set_vars(fvars+fget_var("文章内容"), p); } } ferr=0; feval(fvars+fget_var("res"), index, 0, strlen(index)-1); if(ferr) break; if(fvars[fget_var("res")].s) { write(fd, ptr1, size); count++; found++; } if(load_content) { if(j) end_mmapfile((void*)p, fsize, -1); } ptr1++; } free(libs); end_mmapfile((void *) ptr, buf.st_size, -1); ldata2.l_type = F_UNLCK; fcntl(fd2, F_SETLKW, &ldata2); close(fd2); ftruncate(fd, count * size); ldata.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &ldata); /* 退出互斥区域*/ close(fd); if(ferr) { return -ferr; } else { return count; } }
/* * 根據 stypen 選擇上/下一篇已讀過的文章 * * @param locmem 用來存在某看板游標位置的 structure。 * @param stypen 游標移動的方法 * CURSOR_NEXT, CURSOR_PREV: * 與游標目前位置的文章同標題 的 下一篇/前一篇 文章。 * * @return 新的游標位置 */ static int search_read(const int bid, const keeploc_t * locmem, int stypen) { fileheader_t fh; int pos = locmem->crs_ln; int rk; int fd = -1; int forward = (stypen & RS_FORWARD) ? 1 : 0; time4_t ftime, result; int ret; int step = forward ? 1 : -1; if( last_line <= 1 ) return pos; /* First load the timestamp of article where cursor points to */ reload_fh: rk = get_record_keep(currdirect, &fh, sizeof(fileheader_t), pos, &fd); if( fd < 0 || rk < 0 ) return pos; if( rk == 0 /* EOF */ ) { /* 如果是置底文章, 則要將 ftime 設定成最大 (代表比最後一篇還要新) */ ftime = 2147483647; } else { #ifdef SAFE_ARTICLE_DELETE if (fh.filename[0] == '.' || fh.owner[0] == '-') { /* 游標所在文章已被刪除, 跳過, 往下找下一篇文章 */ close(fd); pos += step; goto reload_fh; } #endif ftime = atoi( &fh.filename[2] ); } /* given the ftime to resolve the read article */ ret = brc_search_read(bid, ftime, forward, &result ); if( ret < 0 ) { /* No read record is found. Try to traverse from last article to * the first until a read article is found (via brc_unread()). * Note that this is O(n) since the brc_unread() returns at * either (ftime <= brc_expire_time) or (bnum <= 0). */ int i; for( i = last_line; i >= 0; --i ) { rk = get_record_keep(currdirect, &fh, sizeof(fileheader_t), i, &fd); if( fd < 0 || rk < 0) goto out; if( 0 == brc_unread( bid, fh.filename, 0 ) ) { pos = i; goto out; } } } else if( ret ) { /* yes we found the read article and stored in result. */ int i; /* find out the position for the article result */ for( i = pos; i >= 0 && i <= last_line; i += step ) { rk = get_record_keep(currdirect, &fh, sizeof(fileheader_t), i, &fd); if( fd < 0 || rk < 0) goto out; #ifdef SAFE_ARTICLE_DELETE if (fh.filename[0] == '.' || fh.owner[0] == '-') { /* 這篇文章已被刪除, 跳過, 試試下一篇 */ continue; } #endif if( atoi( &fh.filename[2] ) == result ) { pos = i; goto out; } } } out: if( fd != -1 ) close(fd); return pos; }