void setaidfile(char *buf, const char *bn, aidu_t aidu) { // try to load by AID int bid = 0; int n = 0, fd = 0; char bfpath[PATHLEN]; boardheader_t *bh = NULL; fileheader_t fh; buf[0] = 0; bid = getbnum(bn); if (bid <= 0) return; assert(0<=bid-1 && bid-1<MAX_BOARD); bh = getbcache(bid); if (!HasBoardPerm(bh)) return; setbfile(bfpath, bh->brdname, FN_DIR); n = search_aidu(bfpath, aidu); if (n < 0) return; fd = open(bfpath, O_RDONLY); if (fd < 0) return; lseek(fd, n*sizeof(fileheader_t), SEEK_SET); memset(&fh, 0, sizeof(fh)); if (read(fd, &fh, sizeof(fh)) > 0) { setbfile(buf, bh->brdname, fh.filename); if (!dashf(buf)) buf[0] = 0; } close(fd); }
/* make a deep copy of one specified template, caller guarantees permission * @to_board, from_board - board name, no NULL. **/ static int deepcopy(struct a_template *to, const char *to_board, struct a_template *from, const char *from_board) { if (to == from) return -1; /* copy basic structure */ if (!(to->tmpl = malloc(sizeof(struct s_template)))) return -1; memcpy(to->tmpl, from->tmpl, sizeof(struct s_template)); /* copy questions */ if (to->tmpl->content_num > 0) { int size = (to->tmpl->content_num + 1) * sizeof(struct s_content); if (!(to->cont = malloc(size))) { free(to->tmpl); to->tmpl = NULL; return -1; } memcpy(to->cont, from->cont, size); } else { to->cont = NULL; } /* copy template text */ if (from->tmpl->filename[0] != '\0') { char to_filepath[STRLEN]; char from_filepath[STRLEN]; setbfile(to_filepath, to_board, ""); if (GET_POSTFILENAME(to->tmpl->filename, to_filepath) != 0) { free(to->tmpl); to->tmpl = NULL; free(to->cont); to->cont = NULL; return -2; } modify_user_mode(uinfo.mode); setbfile(to_filepath, to_board, to->tmpl->filename); setbfile(from_filepath, from_board, from->tmpl->filename); if (f_cp(from_filepath, to_filepath, 0)) { free(to->tmpl); to->tmpl = NULL; free(to->cont); to->cont = NULL; return -3; } } return 0; }
static void strip_index_file(const char *bname, const char *dir) { char old_dir_path[256]; char dir_path[256]; char buf[256]; int old_fd; int fd; fileheader_v1_2 *ptr; size_t fsize; setbfile(old_dir_path, bname, dir); if ((old_fd = open(old_dir_path, O_RDONLY, 0644)) < 0) { fprintf(stderr, "Warning: %s/%s not found.\n", bname, dir); return; } sprintf(buf, "%s.NEW", dir); setbfile(dir_path, bname, buf); if ((fd = open(dir_path, O_RDWR | O_CREAT, 0644)) < 0) { close(old_fd); return; } if (safe_mmapfile_handle(old_fd, PROT_READ, MAP_SHARED, (void **)&ptr, (off_t *)&fsize)) { int i; int rec_count; fileheader fh; rec_count = fsize / sizeof(fileheader_v1_2); for (i = 0; i < rec_count; i++) { bzero(&fh, sizeof(fh)); strip_fileheader(ptr + i, &fh, bname, dir); write(fd, &fh, sizeof(fh)); } end_mmapfile((void*)ptr, fsize, -1); close(fd); close(old_fd); sprintf(buf, "%s.v1.2", old_dir_path); rename(old_dir_path, buf); rename(dir_path, old_dir_path); } else { close(fd); close(old_fd); } }
static void article_list(struct evbuffer *buf, boardheader_t *bptr, int offset, int length) { int total, fd = -1; char path[PATH_MAX]; fileheader_t fhdr; setbfile(path, bptr->brdname, FN_DIR); total = get_num_records(path, sizeof(fileheader_t)); if (total <= 0) return; while (offset < 0) offset += total; while (length-- > 0) { if (get_records_keep(path, &fhdr, sizeof(fhdr), ++offset, 1, &fd) <= 0) break; DBCS_safe_trim(fhdr.title); evbuffer_add_printf(buf, "%d,%s,%s,%d,%d,%s,%s\n", offset, fhdr.filename, fhdr.date, fhdr.recommend, fhdr.filemode, fhdr.owner, fhdr.title); } if (fd >= 0) close(fd); }
static int answer_articleselect(struct evbuffer *buf, const boardheader_t *bptr, const char *rest_key, select_part_func sfunc, void *ctx) { char path[PATH_MAX]; const char *ck, *filename; int cklen, offset, maxlen = 0; struct stat st; if (!parse_articlepart_key(rest_key, &ck, &cklen, &offset, &maxlen, &filename)) return -1; if (!is_valid_article_filename(filename)) return -1; setbfile(path, bptr->brdname, filename); if (answer_file(buf, path, &st, ck, cklen, offset, maxlen) < 0) return -1; int sel_offset, sel_size; int len = evbuffer_get_length(buf); if (sfunc(evbuffer_pullup(buf, len), len, &sel_offset, &sel_size, ctx) != 0 || evbuffer_slice(buf, sel_offset, sel_size) != 0) return -1; struct evbuffer *meta = evbuffer_new(); evbuffer_add_printf(meta, "%d-%d,%lu,%d,%d\n", (int) st.st_dev, (int) st.st_ino, st.st_size, sel_offset, sel_size); evbuffer_prepend_buffer(buf, meta); evbuffer_free(meta); return 0; }
int fh_recovertitle(char* bname, int num, int count) { off_t filesize; int total, i, j; char *ptr, tmptitle[ARTICLE_TITLE_LEN], *ch, fname[PATHLEN], buf[1024]; struct fileheader *pfh; FILE *fp; if (num <= 0) { printf("number must be specified.\n"); exit(0); } BBS_TRY { if (safe_mmapfile_handle(fd, PROT_READ | PROT_WRITE, MAP_SHARED, &ptr, &filesize) == 0) { BBS_RETURN(0); } total = filesize / sizeof(struct fileheader); pfh = (struct fileheader *)ptr; for (i=num-1; i<num+count-1; i++) { if (i >= total) break; strcpy(tmptitle, pfh[i].title); if ((ch = strrchr(tmptitle, '-')) != NULL) { *ch = 0; for (j=strlen(tmptitle)-1; j>=0; j--) { if (tmptitle[j] != ' ') break; else tmptitle[j] = 0; } } setbfile(fname, bname, pfh[i].filename); fp = fopen(fname, "r"); if (!fp) continue; j = 0; while ((!feof(fp)) && (j < 2)) { skip_attach_fgets(buf, 1024, fp); if (feof(fp)) break; if (strstr(buf, "发信人: ") && strstr(buf, "), 信区: ")) { j++; } else if (strstr(buf, "标 题: ")) { j++; strncpy(tmptitle, buf + 8, sizeof(tmptitle)); tmptitle[sizeof(tmptitle)-1] = '\0'; if ((ch = strchr(tmptitle, '\n')) != NULL) *ch = 0; } } fclose(fp); strcpy(pfh[i].title, tmptitle); } } BBS_CATCH { } BBS_END; munmap(ptr, filesize); return 1; }
int my_after_post(struct fileheader *fh, char *boardname) { char buf[256]; int fd, err = 0, nowid = 0; if (!strncmp(fh->title, "Re:", 3)) { strncpy(fh->title, fh->title + 4, STRLEN); } setbfile(buf, boardname, DOT_DIR); if ((fd = open(buf, O_WRONLY | O_CREAT, 0664)) == -1) { err = 1; } if (!err) { writew_lock(fd, 0, SEEK_SET, 0); nowid = get_nextid(boardname); fh->id = nowid; fh->groupid = fh->id; fh->reid = fh->id; #ifdef HAVE_REPLY_COUNT fh->replycount = 1; #endif /* HAVE_REPLY_COUNT */ set_posttime(fh); lseek(fd, 0, SEEK_END); if (safewrite(fd, fh, sizeof(fileheader)) == -1) { err = 1; } un_lock(fd, 0, SEEK_SET, 0); close(fd); } if (err) { setbfile(buf, boardname, fh->filename); unlink(buf); return 1; } updatelastpost(boardname); if (fh->id == fh->groupid) setboardorigin(boardname, 1); setboardtitle(boardname, 1); return 0; }
static void rollback_board_file(const char *bname, const char *dir) { char dir_path[256]; char old_dir_path[256]; setbfile(dir_path, bname, dir); sprintf(old_dir_path, "%s.v1.2", dir_path); if (dashf(old_dir_path)) rename(old_dir_path, dir_path); }
static int strip_board(struct boardheader *bh, void *arg) { char dir_path[256]; if (strcmp(bh->filename, SYSMAIL_BOARD)) { /* if not SYSMAIL_BOARD */ strip_index_file(bh->filename, ".DIR"); strip_index_file(bh->filename, ".DIGEST"); strip_index_file(bh->filename, ".DELETED"); strip_index_file(bh->filename, ".JUNK"); strip_index_file(bh->filename, ".TOPFILE"); setbfile(dir_path, bh->filename, ".ORIGIN"); unlink(dir_path); setbfile(dir_path, bh->filename, ".MARK"); unlink(dir_path); setbfile(dir_path, bh->filename, ".THREAD"); unlink(dir_path); } return 0; }
/**** * add by stiger, template, 摸板 */ static void bbs_make_tmpl_array(zval * array, struct a_template * ptemp, char *board) { add_assoc_string(array, "TITLE", ptemp->tmpl->title, 1); add_assoc_string(array, "TITLE_TMPL", ptemp->tmpl->title_tmpl, 1); add_assoc_long(array, "CONT_NUM", ptemp->tmpl->content_num); if( ptemp->tmpl->filename[0] ){ char path[STRLEN]; setbfile( path, board, ptemp->tmpl->filename ); add_assoc_string(array, "FILENAME", path,1); }else add_assoc_string(array, "FILENAME", ptemp->tmpl->filename,1); }
int bbsnet_report(char *station, char *addr, long id, int mode) { struct fileheader fh; char buf[1024]; char fname[256]; time_t now; FILE *fp; bzero(&fh, sizeof(fh)); setbpath(buf, BBSNET_LOG_BOARD); GET_POSTFILENAME(fname, buf); strncpy(fh.filename, fname, sizeof(fh.filename)-1); fh.filename[sizeof(fh.filename)-1] = '\0'; setbfile(fname, BBSNET_LOG_BOARD, fh.filename); now = time(NULL); strcpy(fh.owner, "deliver"); fh.innflag[0] = 'L'; fh.innflag[1] = 'L'; if (mode == 0) snprintf(fh.title, ARTICLE_TITLE_LEN, "[%ld]%s穿梭到%s", id, user, station); else snprintf(fh.title, ARTICLE_TITLE_LEN, "[%ld]%s结束到%s的穿梭", id, user, station); if ((fp = fopen(fname, "w")) == NULL) return -1; fprintf(fp, "发信人: deliver (自动发信系统), 信区: %s\n", BBSNET_LOG_BOARD); fprintf(fp, "标 题: %s\n", fh.title); fprintf(fp, "发信站: %s (%24.24s)\n\n", BBS_FULL_NAME, ctime(&now)); fprintf(fp, " \033[1;33m%s\033[m 于 \033[1;37m%24.24s\033[m 利用本站bbsnet程序,\n", user, ctime(&now)); if (mode == 0) { fprintf(fp, " 穿梭到 \033[1;32m%s\033[m 站, 地址为\033[1;31m%s\033[m.\n", station, addr); } else { int t; int h; fprintf(fp, " 结束到 \033[1;32m%s\033[m 站的穿梭, 地址为\033[1;31m%s\033[m.\n", station, addr); t = now - id; if (t < 2400) sprintf(buf, "\033[1;32m%d\033[m分钟", t/60); else { h = t / 2400; t -= h * 2400; sprintf(buf, "\033[1;32m%d\033[m小时\033[1;32m%d\033[m分钟", h, t/60); } fprintf(fp, " 本次穿梭一共用了 %s.\n", buf); } fprintf(fp, " 该用户从 \033[1;31m%s\033[m 登录本站.\n", getSession()->fromhost); fclose(fp); return after_post(NULL, &fh, BBSNET_LOG_BOARD, NULL, 0, getSession()); }
static int choose_tmpl_key(struct _select_def *conf, int key) { switch (key) { case 's' : { char filepath[STRLEN]; if (conf->pos > template_num) return SHOW_CONTINUE; if (ptemplate[conf->pos-1].tmpl->filename[0]) { clear(); setbfile(filepath,currboard->filename, ptemplate[conf->pos-1].tmpl->filename); ansimore(filepath, 1); return SHOW_REFRESH; } return SHOW_CONTINUE; } break; case 'w': { clear(); if (ptemplate[conf->pos-1].tmpl->content_num <= 0) { move(5,0); prints("斑竹还没有设置问题,本模板暂不可用\n"); } else { int i; for (i=0; i<ptemplate[conf->pos-1].tmpl->content_num; i++) { move(i+2,0); prints("\033[1;32m问题 %d\033[m:%s \033[1;32m最长回答\033[m%d\033[1;32m字节\033[m", i+1, ptemplate[conf->pos-1].cont[i].text, ptemplate[conf->pos-1].cont[i].length); } } pressanykey(); return SHOW_REFRESH; } case 'x' : { clear(); move(2,0); prints("此模版的标题设置为"); move(4,0); prints("%s",ptemplate[conf->pos-1].tmpl->title_tmpl); pressanykey(); return SHOW_REFRESH; } default: break; } return SHOW_CONTINUE; }
static int _iter_paste_tag(void *item, void *optarg) { char buf[PATHLEN]; char title[TTLEN + 1] = "◇ "; fileheader_t *fhdr = (fileheader_t*) item; _iter_paste_tag_param *param = (_iter_paste_tag_param*) optarg; param->item ++; // XXX many process crashed here as fhdr.filename[0] == 0 // let's workaround it? or trace? if (!fhdr->filename[0]) { grayout(0, b_lines-2, GRAYOUT_DARK); move(b_lines-1, 0); clrtobot(); prints("處理 #%d 項發生錯誤。 請把你剛剛進行的完整步驟貼到 " BN_BUGREPORT " 板。\n", param->item); vmsg("忽略錯誤並繼續進行。"); return 0; } if (!FindTaggedItem(fhdr)) return 0; if (TagBoard == 0) sethomefile(buf, cuser.userid, fhdr->filename); else { setbfile(buf, param->bh->brdname, fhdr->filename); } if (!dashf(buf)) return 0; strlcpy(title + 3, fhdr->title, sizeof(title) - 3); a_copyitem(buf, title, 0, 0); if (param->mode) { param->mode--; a_pasteitem(param->pm, 0); } else a_appenditem(param->pm, 0); param->copied++; RemoveTagItem(fhdr); return IsEmptyTagList(); }
/* completely destroy a template, caller guarantees permission */ static void deepfree(struct a_template *ptemp, const char *board) { char filepath[STRLEN]; if (ptemp->tmpl->filename[0]) { setbfile(filepath, board, ptemp->tmpl->filename); if (dashf(filepath)) my_unlink(filepath); } if (ptemp->tmpl) { free(ptemp->tmpl); ptemp->tmpl = NULL; } if (ptemp->cont) { free(ptemp->cont); ptemp->cont = NULL; } }
static int find_thread(struct fileheader *fh, char *board, char *title) { char direct[255]; char *p; int ret; int fd; setbfile(direct, board, DOT_DIR); if ((fd = open(direct, O_RDONLY, 0644)) == -1) return 0; if (!strncasecmp(title, "Re:", 3)) p = title + 4; else if (!strncasecmp(title, "回复:", 5)) p = title + 6; else p = title; ret = search_record_back_lite(fd, sizeof(struct fileheader), 0, 1000, (RECORD_FUNC_ARG) cmp_title, p, fh, 1); close(fd); return ret; }
int orig_tmpl_save(struct a_template * ptemp, int temp_num, char *board) { int i; FILE *fp; char tmpldir[STRLEN]; setbfile(tmpldir, board, TEMPLATE_DIR); if ((fp = fopen(tmpldir, "w")) == NULL) { return -1; } for (i=0; i<temp_num; i++) { if (ptemp[i].tmpl == NULL) continue; fwrite(ptemp[i].tmpl, sizeof(struct s_template), 1, fp); fwrite(ptemp[i].cont, sizeof(struct s_content), ptemp[i].tmpl->content_num, fp); } fclose(fp); return 0; }
int bbsmnote_main() { FILE *fp; char *ptr, path[256], buf[10000], board[256], notestr[40], buf2[128]; struct boardmem *x; int mode; html_header(1); check_msg(); printf("<center>\n"); if (!loginok || isguest) http_fatal("´Ò´Ò¹ý¿Í£¬ÇëÏȵǼ"); changemode(EDIT); strsncpy(board, getparm("board"), 30); x = getboard(board); mode = atoi(getparm("mode")); if (!has_BM_perm(¤tuser, x)) http_fatal("ÄãÎÞȨ½øÐб¾²Ù×÷"); switch (mode) { case 1: sprintf(path, "vote/%s/notes", board); sprintf(notestr, "Ò»°ã±¸Íü¼"); break; case 2: sprintf(path, "vote/%s/secnotes", board); sprintf(notestr, "ÃØÃܱ¸Íü¼"); break; case 3: default: setbfile(path, board, "introduction"); sprintf(notestr, "°æÃæ¼ò½é"); break; } if (!strcasecmp(getparm("type"), "update")){ if (mode == 2){ sprintf(buf2, "vote/%s/notespasswd", board); unlink(buf2); } save_note(path); } printf("%s -- ±à¼%s [ÌÖÂÛÇø: %s]<hr>\n", BBSNAME, notestr, board); printf ("<form name=form1 method=post action=bbsmnote?type=update&board=%s&mode=%d>\n", board, mode); fp = fopen(path, "r"); if (fp) { fread(buf, 9999, 1, fp); ptr = strcasestr(buf, "<textarea>"); if (ptr) ptr[0] = 0; fclose(fp); } printf("<table border=1><tr><td>"); printf ("<textarea onkeydown='if(event.keyCode==87 && event.ctrlKey) {document.form1.submit(); return false;}' onkeypress='if(event.keyCode==10) return document.form1.submit()' name=text rows=20 cols=80 wrap=virtual>\n"); printf("%s", nohtml(void1(buf))); printf("</textarea></table>\n"); printf("<input type=submit value=´æÅÌ> "); printf("<input type=reset value=¸´Ô>\n"); printf("<hr>\n"); http_quit(); return 0; }
static char * get_file_info(char *boardname, int threadid, char *title, char *userid, char *filename, int pic) { char dirfile[256]; int fd; struct fileheader fh; setbdir(DIR_MODE_NORMAL, dirfile, boardname); if ((fd = open(dirfile, O_RDWR, 0644)) < 0) return NULL; if (get_records_from_id(fd, threadid, &fh, 1, NULL) == 0) { close(fd); return NULL; } close(fd); #ifdef NEWSMTH // pig2532 Feb 2008: ignore topic with FEN flag in top10 if (fh.accessed[1] & FILE_FEN) { printf("skip:%s/%d/%s/%s\n", boardname, fh.id, fh.owner, fh.title); return NULL; } #endif /* NEWSMTH */ if (pic) { if (!fh.attachment) { return NULL; } else { // 读取楼主的第一个附件,判断是否为图片,是则输出该图以备缩略之用,否则返回NULL char fn[PATHLEN]; int fd_pic; char *src, *dst, *dot; off_t size_src, size_dst; char *aname, *start; long asize; setbfile(fn, boardname, fh.filename); if ((fd = open(fn, O_RDONLY)) == -1) return NULL; if (readw_lock(fd, 0, SEEK_SET, 0) == -1) { close(fd); return NULL; } if (safe_mmapfile_handle(fd, PROT_READ, MAP_PRIVATE, &src, &size_src) == 0) { un_lock(fd, 0, SEEK_SET, 0); close(fd); return NULL; } if (!(aname = checkattach(src + fh.attachment, size_src - fh.attachment, &asize, &start))) return NULL; dot = strrchr(aname, '.'); // 是否图片? if (get_attachment_type_from_ext(dot) != ATTACH_IMG) { end_mmapfile(src, size_src, -1); un_lock(fd, 0, SEEK_SET, 0); close(fd); return NULL; } sprintf(fn, "hotpic/%s_%d", boardname, threadid); if ((fd_pic = open(fn, O_RDWR | O_CREAT, 0600)) == -1) { end_mmapfile(src, size_src, -1); un_lock(fd, 0, SEEK_SET, 0); close(fd); return NULL; } ftruncate(fd_pic, asize); if (safe_mmapfile_handle(fd_pic, PROT_WRITE, MAP_SHARED, &dst, &size_dst) == 0) { close(fd_pic); un_lock(fd, 0, SEEK_SET, 0); close(fd); return NULL; } printf("HOTPIC: %s_%d\n", boardname, threadid); memcpy(dst, start, asize); end_mmapfile(dst, size_dst, -1); end_mmapfile(src, size_src, -1); close(fd_pic); un_lock(fd, 0, SEEK_SET, 0); close(fd); } } strncpy(title, fh.title, 80); title[80]=0; strncpy(userid, fh.owner, IDLEN); userid[IDLEN]='\0'; strncpy(filename, fh.filename, FILENAME_LEN); filename[FILENAME_LEN]='\0'; return title; }
int bbsnot_main() { FILE *fp; char buf[512], board[80], filename[128], notestr[STRLEN]; struct boardmem *x; int mode; html_header(1); check_msg(); changemode(READING); strsncpy(board, getparm("B"), 32); if (!board[0]) strsncpy(board, getparm("board"), 32); if (!(x = getboard(board))) http_fatal("´íÎóµÄ°æÃæ"); mode = atoi(getparm("mode")); switch (mode) { case 1: sprintf(filename, "vote/%s/notes", board); sprintf(notestr, "Ò»°ã±¸Íü¼"); break; /* case '2': sprintf(filename, "vote/%s/secnotes", board); sprintf(notestr, "ÃØÃܱ¸Íü¼"); break; */ case 3: default: setbfile(filename, board, "introduction"); sprintf(notestr, "°æÃæ¼ò½é"); break; } printf("<center>\n"); printf("%s -- %s [ÌÖÂÛÇø: %s]<hr>\n", notestr, BBSNAME, board); fp = fopen(filename, "r"); if (fp == 0) { printf("<br>±¾ÌÖÂÛÇøÉÐÎÞ¡¸%s¡¹¡£\n", notestr); http_quit(); } printf("<table border=1><tr><td class=f2>\n"); while (1) { char *s; bzero(buf, 512); if (fgets(buf, 512, fp) == 0) break; while (1) { int i; s = strstr(buf, "$userid"); if (s == 0) break; for (i = 0; i < 7; i++) s[i] = 32; for (i = 0; i < strlen(currentuser.userid); i++) s[i] = currentuser.userid[i]; } fhhprintf(stdout, "%s", buf); } fclose(fp); printf("</table><hr>\n"); printf("[<a href=%s%s>±¾ÌÖÂÛÇø</a>] ", showByDefMode(), board); if (has_BM_perm(¤tuser, x)) printf("[<a href=bbsmnote?board=%s&mode=%d>±à¼%s</a>]", board, mode, notestr); printf("</center>\n"); http_quit(); return 0; }
/* * returns: * -1: some error * -2: tmpl version updated. needs term relogin and www restart * >=0: number of tmpls */ int orig_tmpl_init(char * nboard, int mode, struct a_template ** pptemp) { /*********** * mode 0: 用户看,不显示有斑竹权限的 * mode 1: 斑竹管理 ************/ int fd; char tmpldir[STRLEN]; struct s_template tmpl; struct s_content * cont; int templ_num; setbfile(tmpldir, nboard, TEMPLATE_DIR); if (pptemp == NULL) { return -1; } if (* pptemp == NULL) { * pptemp = (struct a_template *) malloc(sizeof(struct a_template) * MAX_TEMPLATE); if (* pptemp == NULL) return -1; } bzero(* pptemp, sizeof(struct a_template) * MAX_TEMPLATE); templ_num = 0; if ((fd = open(tmpldir, O_RDONLY)) == -1) { return 0; } while (read(fd, &tmpl, sizeof(struct s_template)) == sizeof(struct s_template)) { if (tmpl.version > TMPL_NOW_VERSION) { close(fd); return -2; } if (mode == 0 && (tmpl.flag & TMPL_BM_FLAG)) { lseek(fd, sizeof(struct s_content) * tmpl.content_num , SEEK_CUR); continue; } cont = (struct s_content *) malloc(sizeof(struct s_content) * tmpl.content_num); if (cont == NULL) break; bzero(cont, sizeof(struct s_content) * tmpl.content_num); if (read(fd, cont, sizeof(struct s_content)*tmpl.content_num) != sizeof(struct s_content)*tmpl.content_num) continue; (* pptemp)[templ_num].tmpl = (struct s_template *)malloc(sizeof(struct s_template)); if ((* pptemp)[templ_num].tmpl == NULL) { free(cont); break; } bzero((* pptemp)[templ_num].tmpl , sizeof(struct s_template)); memcpy((* pptemp)[templ_num].tmpl, &tmpl, sizeof(struct s_template)); (* pptemp)[templ_num].cont = cont; templ_num ++; if (templ_num >= MAX_TEMPLATE) break; } close(fd); return templ_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; } }
static int tmpl_key(struct _select_def *conf, int key) { int oldmode; switch (key) { case 'a' : tmpl_check_limit(template_num); tmpl_add(); return SHOW_DIRCHANGE; break; case 'd' : { char ans[3]; getdata(t_lines - 1, 0, "确实要删除吗(Y/N)? [N]: ", ans, sizeof(ans), DOECHO, NULL, true); if (ans[0] == 'Y' || ans[0] == 'y') { int i; deepfree(ptemplate + conf->pos - 1, currboard->filename); template_num--; for (i=conf->pos-1; i<template_num; i++) memcpy(ptemplate+i, ptemplate+i+1, sizeof(struct a_template)); ptemplate[template_num].tmpl = NULL; ptemplate[template_num].cont = NULL; tmpl_save(); } if (template_num > 0) return SHOW_DIRCHANGE; else return SHOW_QUIT; } break; case 'c': do { extern bool in_do_sendmsg; extern int super_select_board(char *bname); int ret; char bname[STRLEN] = ""; move(0,0); clrtoeol(); prints("%s","复制到讨论区 [ \033[1;32mSPACE/TAB\033[m - 自动补全, \033[1;32mESC\033[m - 退出 ]"); move(1,0); clrtoeol(); prints("请输入讨论区名称 [\033[1;32m%s\033[m]: ",currboard->filename); make_blist(0, 3); in_do_sendmsg=1; ret = namecomplete(NULL, bname); in_do_sendmsg=0; CreateNameList(); /* free list memory. */ if (ret == KEY_ESC) { /* noop */ } else if (!*bname || !strcmp(bname, currboard->filename)) { /* copy to current board */ tmpl_check_BM(currboard->filename); /* sanity check, how about stick here when deposing? */ tmpl_check_limit(template_num); if (tmpl_copy(conf->pos)) tmplcp_sorry(); else tmplcp_success(); } else { /* copy to another board */ struct a_template *ptemp; int temp_num = tmpl_init_ex(0, bname, &ptemp); if (temp_num >= 0) { tmpl_check_BM(bname); /* sanity check */ tmpl_check_limit(temp_num); if (tmpl_copy_to_board(bname, &ptemp, &temp_num, conf->pos)) tmplcp_sorry(); else tmplcp_success(); tmpl_free_ex(&ptemp, temp_num); } } } while (0); return SHOW_DIRCHANGE; /* etnlegend, 2006.05.19, move templates... */ case 'm': do { struct a_template temp; char ans[4]; int i,pos; getdata(t_lines-1,0,"请输入希望移动到的位置序号: ",ans,4,DOECHO,NULL,true); trimstr(ans); if (!isdigit(ans[0])) break; pos=atoi(ans); pos=((pos<1)?1:((pos>template_num)?template_num:pos)); if (pos==conf->pos) break; memcpy(&temp,&ptemplate[conf->pos-1],sizeof(struct a_template)); if (pos>conf->pos) { for (i=(conf->pos-1); i<(pos-1); i++) memcpy(&ptemplate[i],&ptemplate[i+1],sizeof(struct a_template)); } else { for (i=(conf->pos-1); i>(pos-1); i--) memcpy(&ptemplate[i],&ptemplate[i-1],sizeof(struct a_template)); } memcpy(&ptemplate[pos-1],&temp,sizeof(struct a_template)); tmpl_save(); } while (0); return SHOW_DIRCHANGE; /* END - etnlegend, 2006.05.19, move templates ... */ case 't' : { char newtitle[60]; strcpy(newtitle, ptemplate[conf->pos-1].tmpl->title); getdata(t_lines - 1, 0, "新名称: ", newtitle, 50, DOECHO, NULL, false); if (newtitle[0] == '\0' || newtitle[0]=='\n' || ! strcmp(newtitle,ptemplate[conf->pos-1].tmpl->title)) return SHOW_REFRESH; strncpy(ptemplate[conf->pos-1].tmpl->title, newtitle, 50); ptemplate[conf->pos-1].tmpl->title[49]='\0'; tmpl_save(); return SHOW_REFRESH; } break;/* case 'z' : { char newtitle[30]; strcpy(newtitle, ptemplate[conf->pos-1].tmpl->title_prefix); getdata(t_lines - 1, 0, "请输入此模板的文章标题前缀: ", newtitle, 20, DOECHO, NULL, false); if( newtitle[0] == '\0' || newtitle[0]=='\n' || ! strcmp(newtitle,ptemplate[conf->pos-1].tmpl->title_prefix) ) return SHOW_REFRESH; strncpy(ptemplate[conf->pos-1].tmpl->title_prefix, newtitle, 20); ptemplate[conf->pos-1].tmpl->title_prefix[19]='\0'; tmpl_save(); return SHOW_REFRESH; }*/ case 'f' : { char filepath[STRLEN]; int oldmode; oldmode = uinfo.mode; modify_user_mode(EDITUFILE); if (ptemplate[conf->pos-1].tmpl->filename[0] == '\0') { setbfile(filepath, currboard->filename, ""); if (GET_POSTFILENAME(ptemplate[conf->pos-1].tmpl->filename, filepath) != 0) { clear(); move(3,0); prints("创建模板文件失败!"); pressanykey(); return SHOW_REFRESH; } tmpl_save(); } setbfile(filepath, currboard->filename, ptemplate[conf->pos-1].tmpl->filename); vedit(filepath,0,NULL,NULL,0); modify_user_mode(oldmode); return SHOW_REFRESH; } case 's' : { char filepath[STRLEN]; setbfile(filepath, currboard->filename, ptemplate[conf->pos-1].tmpl->filename); clear(); ansimore(filepath,1); return SHOW_REFRESH; } case 'b' : { if (ptemplate[conf->pos-1].tmpl->flag & TMPL_BM_FLAG) ptemplate[conf->pos-1].tmpl->flag &= ~TMPL_BM_FLAG ; else ptemplate[conf->pos-1].tmpl->flag |= TMPL_BM_FLAG; tmpl_save(); return SHOW_REFRESH; } case 'i' : { char newtitle[STRLEN]; strcpy(newtitle, ptemplate[conf->pos-1].tmpl->title_tmpl); getdata(t_lines - 1, 0, "新文章标题: ", newtitle, STRLEN, DOECHO, NULL, false); if (newtitle[0] == '\0' || newtitle[0]=='\n' || ! strcmp(newtitle,ptemplate[conf->pos-1].tmpl->title_tmpl)) return SHOW_REFRESH; strncpy(ptemplate[conf->pos-1].tmpl->title_tmpl, newtitle, STRLEN); ptemplate[conf->pos-1].tmpl->title_tmpl[STRLEN-1]='\0'; tmpl_save(); return SHOW_REFRESH; } case 'x' : { clear(); move(2,0); prints("此模版的标题设置为"); move(4,0); prints("%s",ptemplate[conf->pos-1].tmpl->title_tmpl); pressanykey(); return SHOW_REFRESH; } /* case 'h': { clear(); move(1,0); prints(" x : 查看标题格式\n"); prints(" i : 修改标题格式"); pressanykey(); return SHOW_REFRESH; } */ case 'l': /* by pig2532 on 2005.12.01 */ oldmode = uinfo.mode; show_allmsgs(); modify_user_mode(oldmode); return SHOW_REFRESH; case 'w': /* by pig2532 on 2005-12-1 */ oldmode = uinfo.mode; if (!HAS_PERM(getCurrentUser(), PERM_PAGE)) break; s_msg(); modify_user_mode(oldmode); return SHOW_REFRESH; case 'u': /* by pig2532 on 2005-12-1 */ clear(); oldmode = uinfo.mode; modify_user_mode(QUERY); t_query(NULL); modify_user_mode(oldmode); return SHOW_REFRESH; case 'U': /* pig2532 2005.12.10 */ board_query(); return SHOW_REFRESH; default : break; } return SHOW_CONTINUE; }
int bbssnd_main(void) { if (!loginok) return BBS_ELGNREQ; if (parse_post_data() < 0) return BBS_EINVAL; int bid = strtol(getparm("bid"), NULL, 10); struct boardheader *bp = getbcache2(bid); if (bp == NULL || !haspostperm(¤tuser, bp)) return BBS_ENOBRD; if (bp->flag & BOARD_DIR_FLAG) return BBS_EINVAL; bool isedit = (*(getparm("e")) == '1'); unsigned int fid; struct fileheader fh; char *f = getparm("f"); bool reply = !(*f == '\0'); if (reply) { fid = strtoul(f, NULL, 10); if (!bbscon_search(bp, fid, 0, &fh)) return BBS_ENOFILE; if (!isedit && fh.accessed[0] & FILE_NOREPLY) return BBS_EPST; if (isedit && !chkBM(bp, ¤tuser) && strcmp(fh.owner, currentuser.userid)) return BBS_EACCES; } char title[sizeof(fh.title)]; if (!isedit) { strlcpy(title, getparm("title"), sizeof(title)); printable_filter(title); if (*title == '\0') return BBS_EINVAL; } // TODO: ... #ifdef SPARC if(abs(time(0) - *(int*)(u_info->from+34))<6) { //modified from 36 to 34 for sparc solaris by roly 02.02.28 *(int*)(u_info->from+34)=time(0); //modified from 36 to 34 for sparc solaris by roly 02.02.28 return BBS_EPFREQ; } *(int*)(u_info->from+34)=time(0);//modified from 36 to 34 for sparc solaris by roly 02.02.28 #else if(abs(time(0) - *(int*)(u_info->from+36))<6) { //modified from 36 to 34 for sparc solaris by roly 02.02.28 *(int*)(u_info->from+36)=time(0); //modified from 36 to 34 for sparc solaris by roly 02.02.28 return BBS_EPFREQ; } *(int*)(u_info->from+36)=time(0);//modified from 36 to 34 for sparc solaris by roly 02.02.28 #endif if (isedit) { char file[HOMELEN]; setbfile(file, bp->filename, fh.filename); if (edit_article(file, getparm("text"), mask_host(fromhost)) < 0) return BBS_EINTNL; } else { post_request_t pr = { .autopost = false, .crosspost = false, .userid = NULL, .nick = NULL, .user = ¤tuser, .bp = bp, .title = title, .content = getparm("text"), .sig = strtol(getparm("sig"), NULL, 0), .ip = mask_host(fromhost), .o_fp = reply ? &fh : NULL, .noreply = false, .mmark = false }; if (do_post_article(&pr) < 0) return BBS_EINTNL; } if (!isedit && !junkboard(bp)) { currentuser.numposts++; save_user_data(¤tuser); } char buf[sizeof(fh.title) + sizeof(bp->filename)]; snprintf(buf, sizeof(buf), "%sed '%s' on %s", isedit ? "edit" : "post", title, bp->filename); report(buf, currentuser.userid); snprintf(buf, sizeof(buf), "doc?board=%s", bp->filename); http_header(); refreshto(1, buf); printf("</head>\n<body>发表成功,1秒钟后自动转到<a href='%s'>版面</a>\n" "</body>\n</html>\n", buf); return 0; }
void resolve_boards() { int boardfd=-1; int iscreate = 0; char errbuf[STRLEN]; if (bcache == NULL) { if ((boardfd = open(BOARDS, O_RDWR | O_CREAT, 0644)) == -1) { bbslog("3system", "Can't open " BOARDS "file %s", strerror_r(errno, errbuf, STRLEN)); exit(-1); } bcache = (struct boardheader *) mmap(NULL, MAXBOARD * sizeof(struct boardheader), PROT_READ, MAP_SHARED, boardfd, 0); if (bcache == (struct boardheader *) -1) { bbslog("4system", "Can't map " BOARDS "file %s", strerror_r(errno, errbuf, STRLEN)); close(boardfd); exit(-1); } } if (brdshm == NULL) { brdshm = attach_shm("BCACHE_SHMKEY", 3693, sizeof(*brdshm), &iscreate); /* attach board share memory */ if (iscreate) { int i, maxi = -1; int fd; bbslog("3system", "reload bcache!"); fd = bcache_lock(); for (i = 0; i < MAXBOARD; i++) if (bcache[i].filename[0]) { int count; char filename[MAXPATH]; struct fileheader lastfh; getlastpost(bcache[i].filename, &brdshm->bstatus[i].lastpost, &brdshm->bstatus[i].total); /* ulock: get nowid from the last fileheader and idseq*/ setbfile(filename,bcache[i].filename,DOT_DIR); count=get_num_records(filename,sizeof(struct fileheader)); if (count > 0) { get_record(filename, &lastfh, sizeof(struct fileheader), count-1); brdshm->bstatus[i].nowid=lastfh.id+1; if (bcache[i].idseq>lastfh.id+1) brdshm->bstatus[i].nowid=bcache[i].idseq; else brdshm->bstatus[i].nowid=lastfh.id+1; } else brdshm->bstatus[i].nowid=bcache[i].idseq; /* update top title */ board_update_toptitle(i+1,false); #ifdef RECORDMAXONLINE /* load board max online record */ brdshm->bstatus[i].maxonline = bcache[i].maxonline; brdshm->bstatus[i].maxtime = bcache[i].maxtime; #endif #ifdef TITLEKEYWORD load_title_key(1, i+1, bcache[i].filename); #endif maxi = i; } if (maxi != -1) brdshm->numboards = maxi + 1; bcache_unlock(fd); } } if (bdirshm == NULL) { bdirshm = attach_shm("BDIRCACHE_SHMKEY", 3697, sizeof(*bdirshm), &iscreate); /* attach board share memory */ if (iscreate) { bbslog("3system", "reload bdircache!"); load_allboard(bdirshm->allbrd_list, &bdirshm->allbrd_list_t); load_wwwboard(bdirshm->wwwbrd_list, &bdirshm->wwwbrd_list_t); } } if (boardfd!=-1) close(boardfd); }
static inline int process_article(const struct fileheader *f,int n,const struct boardheader *b){ static const struct flock lck_set={.l_type=F_RDLCK,.l_whence=SEEK_SET,.l_start=0,.l_len=0,.l_pid=0}; static const struct flock lck_clr={.l_type=F_UNLCK,.l_whence=SEEK_SET,.l_start=0,.l_len=0,.l_pid=0}; static struct stat st; static struct tm *p; static char name[BOUND]; static int fd,i,j,k,l; static time_t timestamp; static const char *S,*M,*N; static void *vp; do{ if((timestamp=get_posttime(f))<from||timestamp>to) break; if(ISSET(PARAM_P)&&strcmp(f->owner,post)) break; setbfile(name,b->filename,f->filename); if(stat(name,&st)==-1||!S_ISREG(st.st_mode)||st.st_size<size) break; if((fd=open(name,O_RDONLY #ifdef O_NOATIME |O_NOATIME #endif /* O_NOATIME */ ,0644))==-1) break; if(fcntl(fd,F_SETLKW,&lck_set)==-1){ close(fd); break; } vp=mmap(NULL,st.st_size,PROT_READ,MAP_PRIVATE,fd,0); fcntl(fd,F_SETLKW,&lck_clr); close(fd); if((S=(const char*)vp)==MAP_FAILED) break; for(p=NULL,j=0,i=0;S[i]&&i<st.st_size;i++){ #define EQUAL(cp,cs) (((cp)==(cs))||(ISSET(PARAM_I)&&((cp)==toupper(cs)))) while(j>0&&!EQUAL(P[j],S[i])) j=L[j-1]; if(EQUAL(P[j],S[i])) j++; if(!P[j]){ M=&S[l=((i-j)+1)]; if(!ISSET(PARAM_N)){ for(k=0,N=M;!(N<S);N--) if((*N)&0x80) k++; if(!(k&0x01)) continue; } if(!p&&!(p=localtime(×tamp))) continue; count++; fprintf(out,"%6d %-20.20s %4d %4s %04d%02d%02d%02d%02d%02d %-17.17s %6d %-13.13s %s\n", n,b->filename,current,mode,(p->tm_year+1900),(p->tm_mon+1),(p->tm_mday), (p->tm_hour),(p->tm_min),(p->tm_sec),f->filename,l,f->owner,f->title); if(ISSET(PARAM_S)) break; j=L[j-1]; } #undef EQUAL } munmap(vp,st.st_size); number++; } while(0); return 0; } static inline int process_board(const struct boardheader *b,int n,void *v){ static char name[BOUND]; do{ if(ISSET(PARAM_A)) break; if(ISSET(PARAM_U)){ if(!check_read_perm(user,b)) return -1; break; } if(ISSET(PARAM_B)) break; if(!public_board(b)) return -2; } while(0); current=n; if(!ISSET(PARAM_Q)) fprintf(stdout,"正在处理版面 %-29.29s ... ",b->filename); if(!ISSET(PARAM_E)){ mode="版面"; setbdir(DIR_MODE_NORMAL,name,b->filename); APPLY_RECORD(name,process_article,sizeof(struct fileheader),b,0,true); } if(ISSET(PARAM_D)){ mode="回收"; setbdir(DIR_MODE_DELETED,name,b->filename); APPLY_RECORD(name,process_article,sizeof(struct fileheader),b,0,true); } if(ISSET(PARAM_J)){ mode="自删"; setbdir(DIR_MODE_JUNK,name,b->filename); APPLY_RECORD(name,process_article,sizeof(struct fileheader),b,0,true); } if(!ISSET(PARAM_Q)) fprintf(stdout,"%s\n","处理完成!"); return 0; } int main(int argc,char **argv){ #define EXIT(msg) do{fprintf(stderr,"%s\n",(msg));if(out)fclose(out);exit(__LINE__);}while(0) const struct boardheader *board; char name[BOUND],path[BOUND]; const char *desc; int ret; double cost; if(!getcwd(path,BOUND)) EXIT("获取当前工作目录时发生错误"); if(chdir(BBSHOME)==-1) EXIT("切换工作目录时发生错误..."); if((mark=time(NULL))==(time_t)(-1)) EXIT("获取时间时发生错误..."); resolve_ucache(); resolve_boards(); to=mark; opterr=0; while((ret=getopt(argc,argv,"r:f:t:ab:u:p:djesnio:qh"))!=-1){ switch(ret){ #define CHECK_CONFLICT(param) do{if(ISSET(param))EXIT("给定的选项间存在冲突...");}while(0) #define CHECK_DEPENDENCE(param) do{if(!ISSET(param))EXIT("给定的选项间缺少依赖...");}while(0) #define CHECK_DUP(param) do{if(ISSET(param))EXIT("给定的选项中存在重复...");}while(0) #define SET(param) do{CHECK_DUP(param);flag|=(param);}while(0) case 'r': CHECK_CONFLICT(PARAM_F|PARAM_T); SET(PARAM_R); do{ struct tm t,*p; int n; if(!isdigit(optarg[0])) EXIT("选项 -r 的参数无法解析..."); n=atoi(optarg); if(!(p=localtime(&mark))) EXIT("解析时间时发生错误..."); memcpy(&t,p,sizeof(struct tm)); t.tm_hour=0; t.tm_min=0; t.tm_sec=0; if((from=mktime(&t))==(time_t)(-1)) EXIT("设定时间时发生错误..."); } while(0); break; #define PARSE2(p) ((((p)[0]*10)+((p)[1]*1))-('0'*11)) #define PARSE4(p) ((PARSE2(p)*100)+(PARSE2(&(p)[2])*1)) case 'f': CHECK_CONFLICT(PARAM_R); SET(PARAM_F); do{ struct tm t; int i; for(i=0;optarg[i];i++) if(!isdigit(optarg[i])) break; if(i!=14) EXIT("选项 -f 的参数无法解析..."); memset(&t,0,sizeof(struct tm)); t.tm_year=(PARSE4(optarg)-1900); t.tm_mon=(PARSE2(&optarg[4])-1); t.tm_mday=PARSE2(&optarg[6]); t.tm_hour=PARSE2(&optarg[8]); t.tm_min=PARSE2(&optarg[10]); t.tm_sec=PARSE2(&optarg[12]); if((from=mktime(&t))==(time_t)(-1)) EXIT("设定时间时发生错误..."); } while(0); break; case 't': CHECK_CONFLICT(PARAM_R); SET(PARAM_T); do{ struct tm t; int i; for(i=0;optarg[i];i++) if(!isdigit(optarg[i])) break; if(i!=14) EXIT("选项 -t 的参数无法解析..."); memset(&t,0,sizeof(struct tm)); t.tm_year=(PARSE4(optarg)-1900); t.tm_mon=(PARSE2(&optarg[4])-1); t.tm_mday=PARSE2(&optarg[6]); t.tm_hour=PARSE2(&optarg[8]); t.tm_min=PARSE2(&optarg[10]); t.tm_sec=PARSE2(&optarg[12]); if((from=mktime(&t))==(time_t)(-1)) EXIT("设定时间时发生错误..."); } while(0); break; #undef PARSE2 #undef PARSE4 case 'a': CHECK_CONFLICT(PARAM_B|PARAM_U); SET(PARAM_A); break; case 'b': CHECK_CONFLICT(PARAM_A|PARAM_U); SET(PARAM_B); if(!(current=getbid(optarg,&board))) EXIT("选项 -b 所指定的版面无法获取..."); break; case 'u': CHECK_CONFLICT(PARAM_A|PARAM_B); SET(PARAM_U); do{ struct userec *u; if(!getuser(optarg,&u)) EXIT("选项 -u 所指定的用户无法获取..."); user=u; } while(0); break; case 'p': SET(PARAM_P); snprintf(post,OWNER_LEN,"%s",optarg); break; case 'd': SET(PARAM_D); break; case 'j': SET(PARAM_J); break; case 'e': CHECK_DEPENDENCE(PARAM_D|PARAM_J); SET(PARAM_E); break; case 's': SET(PARAM_S); break; case 'n': SET(PARAM_N); break; case 'i': SET(PARAM_I); break; case 'o': SET(PARAM_O); if(optarg[0]!='/') snprintf(name,BOUND,"%s/%s",path,optarg); else snprintf(name,BOUND,"%s",optarg); break; case 'q': SET(PARAM_Q); break; case 'h': usage(); return 0; default: usage(); EXIT("不可识别的选项..."); break; #undef CHECK_CONFLICT #undef CHECK_DEPENDENCE #undef CHECK_DUP #undef SET } } if(from>to){ usage(); EXIT("当前时间设定不合法..."); } if(!ISSET(PARAM_Q)&&setvbuf(stdout,NULL,_IONBF,BUFSIZ)) EXIT("调整文件缓冲时发生错误..."); if((argc-optind)!=1){ usage(); EXIT("不可识别的参数..."); } set_pattern(argv[optind]); set_link(argv[optind]); if(!size) EXIT("模式串不能为空串..."); if(!ISSET(PARAM_O)) snprintf(name,BOUND,"%s/res_%lu.us",path,mark); if(!(out=fopen(name,"w"))) EXIT("打开文件时发生错误..."); fprintf(out,"%6s %-20.20s %4s %4s %-14.14s %-17.17s %6s %-13.13s %s\n", "文章号","版面名称"," BID","位置","发表时间","文件名","偏移量","作者","标题"); if(!(P[0]&0x80)) flag|=PARAM_N; if(ISSET(PARAM_B)) process_board(board,current,NULL); else APPLY_BIDS(process_board,NULL); fclose(out); cost=difftime(time(NULL),mark); if(cost>86400){ cost/=86400; desc="天"; } else if(cost>3600){ cost/=3600; desc="小时"; } else if(cost>60){ cost/=60; desc="分钟"; } else desc="秒"; fprintf(stdout,"\n操作已完成! 共处理 %d 篇文章, 获得 %d 处匹配, 耗时 %.2lf %s!\n", number,count,cost,desc); return 0; #undef EXIT }
static int choose_tmpl_post(char * title, char *fname) { FILE *fp; FILE *fpsrc; char filepath[STRLEN]; int i, ret=1; int write_ok = 0; char * tmp[ MAX_CONTENT ]; char newtitle[STRLEN], oldtitle[STRLEN]; int oldmode = uinfo.mode; bool modifying=false, loop=true; if (t_now <= 0 || t_now > MAX_TEMPLATE) return -1; if (ptemplate[t_now-1].tmpl->content_num <= 0) return -1; strncpy(oldtitle, title, STRLEN); while (loop) { if ((fp = fopen(fname, "w"))==NULL) { return -1; } modify_user_mode(POSTTMPL); for (i=0; i< ptemplate[t_now-1].tmpl->content_num; i++) { char *ans; if (modifying) ans = tmp[i]; else { ans = (char *)malloc(ptemplate[t_now-1].cont[i].length + 2); ans[0] = '\0'; } if (ans == NULL) { modify_user_mode(oldmode); fclose(fp); return -1; } clear(); move(1,0); prints("Ctrl+Q 换行, ENTER 发送"); move(3,0); prints("模板问题:%s",ptemplate[t_now-1].cont[i].text); move(4,0); prints("模板回答(最长%d字符):",ptemplate[t_now-1].cont[i].length); multi_getdata(6, 0, 79, NULL, ans, ptemplate[t_now-1].cont[i].length+1, 11, false, 0); tmp[i] = ans; } modify_user_mode(oldmode); if (ptemplate[t_now-1].tmpl->filename[0]) { struct stat st; setbfile(filepath,currboard->filename, ptemplate[t_now-1].tmpl->filename); if (stat(filepath, &st) == 0 && S_ISREG(st.st_mode) && st.st_size>2) { if ((fpsrc = fopen(filepath,"r"))!=NULL) { char buf[256]; while (fgets(buf,255,fpsrc)) { int l; int linex = 0; char *pn,*pe; #ifdef ENHANCED_TEMPLATE int sign, fmtlen, sysdef; char tmpbuf[STRLEN]; #endif for (pn = buf; *pn!='\0'; pn++) { if (*pn != '[' || *(pn+1)!='$') { fputc(*pn, fp); linex++; } else { pe = strchr(pn,']'); if (pe == NULL) { fputc(*pn, fp); continue; } #ifdef ENHANCED_TEMPLATE /* 获得[]中间的内容 */ strncpy(tmpbuf, pn+2, pe-pn-2); tmpbuf[pe-pn-2]='\0'; sysdef = 0; sign = get_parameter_index_len(tmpbuf, &l, &fmtlen, &sysdef); #else l = atoi(pn+2); #endif if (l<=0 || l > ptemplate[t_now-1].tmpl->content_num) { fputc('[', fp); continue; } #ifdef ENHANCED_TEMPLATE char *p; if (sysdef == 0) { p = malloc(strlen(tmp[l-1])+1); strcpy(p, tmp[l-1]); } else { p = malloc(STRLEN); if (!strcmp(tmpbuf, "USER")) strcpy(p, getCurrentUser()->userid); else if (!strcmp(tmpbuf, "BOARD")) strcpy(p, currboard->filename); else if (!strcmp(tmpbuf, "BNAME")) strcpy(p, currboard->title+13); else if (!strcmp(tmpbuf, "BMS")) strcpy(p, currboard->BM); else if (!strcmp(tmpbuf, "DATE")) { time_t t=time(0); struct tm *mytm; mytm = localtime(&t); sprintf(p, "%d-%02d-%02d", mytm->tm_year + 1900, mytm->tm_mon+1, mytm->tm_mday); } else strcpy(p, "未定义"); } if (fmtlen>0) { int t1, t2; t1=strlen(p); if (t1 >= fmtlen) fprintf(fp,"%s",p); else { if (sign == -1) { /* 左对齐 */ fprintf(fp, "%-*s", fmtlen, p); } else if (sign == 1) { /* 右对齐 */ fprintf(fp, "%*s", fmtlen, p); } else { /* 居中对齐 */ t2 = (fmtlen - t1)/2; fprintf(fp,"%*s%*s",t2+t1,p,t2 + t1%2, ""); } } } else fprintf(fp,"%s",p); free(p); #else fprintf(fp,"%s",tmp[l-1]); #endif pn = pe; continue; } } } fclose(fpsrc); write_ok = 1; } } } if (write_ok == 0) { for (i=0; i< ptemplate[t_now-1].tmpl->content_num; i++) fprintf(fp,"\033[1;32m%s:\033[m\n%s\n\n",ptemplate[t_now-1].cont[i].text, tmp[i]); } fclose(fp); if (ptemplate[t_now-1].tmpl->title_tmpl[0]) { char *pn,*pe; char *buf; int l; int newl = 0; #ifdef ENHANCED_TEMPLATE int sysdef; char tmpbuf[STRLEN]; #endif newtitle[0]='\0'; buf = ptemplate[t_now-1].tmpl->title_tmpl; for (pn = buf; *pn!='\0' && newl < STRLEN-1; pn++) { if (*pn != '[' || *(pn+1)!='$') { if (newl < STRLEN - 1) { newtitle[newl] = *pn ; newtitle[newl+1]='\0'; newl ++; } } else { pe = strchr(pn,']'); if (pe == NULL) { if (newl < STRLEN - 1) { newtitle[newl] = *pn ; newtitle[newl+1]='\0'; newl ++; } continue; } #ifdef ENHANCED_TEMPLATE /* 获得[]中间的内容 */ strncpy(tmpbuf, pn+2, pe-pn-2); tmpbuf[pe-pn-2]='\0'; sysdef = 0; get_parameter_index_len(tmpbuf, &l, NULL, &sysdef); #else l = atoi(pn+2); #endif if (l<0 || l > ptemplate[t_now-1].tmpl->content_num) { if (newl < STRLEN - 1) { newtitle[newl] = *pn ; newtitle[newl+1]='\0'; newl ++; } continue; } if (l == 0) { int ti; for (ti=0; oldtitle[ti]!='\0' && newl < STRLEN - 1; ti++, newl++) { newtitle[newl] = oldtitle[ti] ; newtitle[newl+1]='\0'; } } else { int ti; #ifdef ENHANCED_TEMPLATE char *p; if (sysdef == 0) { p = malloc(strlen(tmp[l-1])+1); strcpy(p, tmp[l-1]); } else { p = malloc(STRLEN); if (!strcmp(tmpbuf, "USER")) strcpy(p, getCurrentUser()->userid); else if (!strcmp(tmpbuf, "BOARD")) strcpy(p, currboard->filename); else if (!strcmp(tmpbuf, "BNAME")) strcpy(p, currboard->title+13); else if (!strcmp(tmpbuf, "BMS")) strcpy(p, currboard->BM); else if (!strcmp(tmpbuf, "DATE")) { time_t t=time(0); struct tm *mytm; mytm = localtime(&t); sprintf(p, "%d-%02d-%02d", mytm->tm_year + 1900, mytm->tm_mon+1, mytm->tm_mday); } else strcpy(p, "未定义"); } for (ti=0; p[ti]!='\0' && p[ti]!='\n' && p[ti]!='\r' && newl < STRLEN - 1; ti++, newl++) { newtitle[newl] = p[ti] ; newtitle[newl+1]='\0'; } free(p); #else for (ti=0; tmp[l-1][ti]!='\0' && tmp[l-1][ti]!='\n' && tmp[l-1][ti]!='\r' && newl < STRLEN - 1; ti++, newl++) { newtitle[newl] = tmp[l-1][ti] ; newtitle[newl+1]='\0'; } #endif } pn = pe; continue; } } strncpy(title, newtitle, STRLEN); title[STRLEN-1]='\0'; } do { char ans[4]; clear(); ansimore2(fname,false,0,19); move(21,0); clrtobot(); prints("标题: %s",title); getdata(t_lines-1,0,"确认发表 (Y)发表 (N)退出 (E)重新编辑 [Y]: ",ans,2,DOECHO,NULL,true); switch (toupper(ans[0])) { case 'N': loop=false; ret=-1; break; case 'E': modifying=true; break; default: loop=false; ret=1; break; } } while (0); } for (i=0; i< ptemplate[t_now-1].tmpl->content_num; i++) free(tmp[i]); return ret; }
int more_web(char *fpath, int promptend) { char *ch; char genbuf[41]; if (ch = strstr(fpath, "mailto:")) { if (!HAS_PERM(PERM_LOGINOK)) { outmsg("[41m ±zªºÅv¤£¨¬µLªk¨Ï¥Îinternet mail... [m"); return 0; } if (!not_addr(&ch[7]) && getdata(b_lines - 1, 0, "[±H«H]¥DÃD¡G", genbuf, 40, DOECHO, 0)) { do_send(&ch[7], genbuf); } else { outmsg("[41m ¦¬«H¤Hemail ©Î ¼ÐÃD ¦³»~... [m"); } return 0; } #if 0 if (ch = strstr(fpath, "gopher://")) { ITEM item; strcpy(item.X.G.server, &ch[9]); strcpy(item.X.G.path, "1/"); item.X.G.port = 70; gem(fpath, &item, 0); return 0; } #endif /* wildcat : ¤ä´©ª½±µ¶i¤J¬ÝªO */ if (ch = strstr(fpath, "board://")) { char bname[20], bpath[60], oldch[STRLEN]; struct stat st; int mode0 = currutmp->mode; int stat0 = currstat; int pos; boardheader *bhdr, *getbcache(); strcpy(oldch, ch); strcpy(bname, strtok(oldch + 8, "#")); setbpath(bpath, bname); if ((*bname == '\0') || (stat(bpath, &st) == -1)) { pressanykey(err_bid); return RC_FULL; } if (bhdr = getbcache(bname)) { if (Ben_Perm(bhdr) != 1) { pressanykey("§A¨S¦³¶i¤J¸ÓªOªºÅv"); return 0; } } else { pressanykey("§A¨S¦³¶i¤J¸ÓªOªºÅv"); return 0; } /* shakalaca.000123: ¤ä´©¬Ý¬Y¤@½g */ if (ch = strstr(fpath, "#")) { fileheader fhdr; pos = atoi(ch + 1); setbdir(bpath, bname); rec_get(bpath, &fhdr, sizeof(fileheader), pos); setbfile(bpath, bname, fhdr.filename); more(bpath, 0); } else { /* shakalaca.000124: ¸Ñ¨M "¥¼Åª" °ÝÃD.. */ brc_initial(bname); Read(); } currutmp->mode = mode0; currstat = stat0; return 0; } }
int calcboard(struct boardheader *bh, void *arg) { char fn[80]; int fd, total, i; struct stat buf; struct flock ldata; struct fileheader *ptr1; char *ptr; int size = sizeof(struct fileheader); setbdir(0, fn, bh->filename); printf("\r%s:\n", bh->filename); if ((fd = open(fn, O_RDWR, 0664)) == -1) { bbslog("user", "%s", "recopen err"); return 0; /* 创建文件发生错误 */ } fstat(fd, &buf); ldata.l_type = F_RDLCK; ldata.l_whence = 0; ldata.l_len = 0; ldata.l_start = 0; fcntl(fd, F_SETLKW, &ldata); total = buf.st_size / size; if ((i = safe_mmapfile_handle(fd, PROT_READ | PROT_WRITE, MAP_SHARED, (void **) &ptr, &buf.st_size)) != 1) { if (i == 2) end_mmapfile((void *) ptr, buf.st_size, -1); ldata.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &ldata); close(fd); return 0; } ptr1 = (struct fileheader *) ptr; for (i = 0; i < total; i++) { struct stat st; char *p, *op; char ffn[80]; int j; off_t fsize; printf("\r%d", i); setbfile(ffn, bh->filename, ptr1->filename); { int k, abssize = 0, entercount = 0, ignoreline = 0; char *attach; long attach_len; j = safe_mmapfile(ffn, O_RDONLY, PROT_READ, MAP_SHARED, (void **) &p, &fsize, NULL); op = p; if (j) { k = fsize; while (k) { /* if (NULL != (checkattach(p, k, &attach_len, &attach))) { k -= (attach - p) + attach_len; p = attach + attach_len; continue; } */ if (k >= 3 && *p == '\n' && *(p + 1) == '-' && *(p + 2) == '-' && *(p + 3) == '\n') break; if (*p == '\n') { entercount++; ignoreline = 0; } if (k >= 5 && *p == '\n' && *(p + 1) == '\xa1' && *(p + 2) == '\xbe' && *(p + 3) == ' ' && *(p + 4) == '\xd4' && *(p + 5) == '\xda') ignoreline = 1; if (k >= 2 && *p == '\n' && *(p + 1) == ':' && *(p + 2) == ' ') ignoreline = 2; if (k >= 2 && *p == KEY_ESC && *(p + 1) == '[' && *(p + 2) == 'm') ignoreline = 3; k--; p++; if (entercount >= 4 && !ignoreline) abssize++; } ptr1->eff_size = abssize; end_mmapfile((void *) op, fsize, -1); } } //ptr1->posttime = get_posttime(ptr1); set_posttime(ptr1); ptr1++; } end_mmapfile((void *) ptr, buf.st_size, -1); ldata.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &ldata); close(fd); return 0; }
int bbssbs_main() { int result[MAXBOARD], i, total=0; char keyword[80], *ptr, buf[128], bmbuf[(IDLEN + 1) * 4]; struct boardmem *bp; html_header(1); check_msg(); changemode(READING); strsncpy(keyword, getparm("keyword"), 32); printf("<body><center>"); printf("<div class=rhead>%s -- 超级版面选择</div><hr>\n", BBSNAME); if (strlen(strtrim(keyword))) { for (i = 0; i < shm_bcache->number && total < MAXBOARD ; i++){ if (shm_bcache->bcache[i].header.filename[0] == '\0') continue; if (has_read_perm_x(¤tuser, &(shm_bcache->bcache[i].header))) { if (strcasestr(shm_bcache->bcache[i].header.filename, keyword) || strcasestr(shm_bcache->bcache[i].header.keyword, keyword) || strcasestr(shm_bcache->bcache[i].header.title, keyword) ){ result[total] = i; total++; } } } if (total == 0){ printf("Sorry,我真的帮你找了,没找到符合条件的讨论区啊!"); printf("<p><a href=javascript:history.go(-1)>快速返回</a>"); http_quit(); /* }else if (total == 1){ sprintf(buf, "%s?board=%s", "bbshome", shm_bcache->bcache[result[0]].header.filename); redirect(buf); */ }else { printf("<table width=\"100%\" border=0 cellpadding=0 cellspacing=0><tr>\n" "<td width=40> </td>\n" "<td colspan=2 class=\"level1\"><TABLE width=\"90%\" border=0 cellPadding=2 cellSpacing=0>\n" "<TBODY>\n"); printf("<TR>\n" "<TD class=tdtitle>未</TD>\n" "<TD class=tduser>讨论区名称</TD>\n" "<TD class=tdtitle>V</TD>\n" "<TD class=tdtitle>类别</TD>\n" "<TD class=tdtitle>中文描述</TD>\n" "<TD class=tdtitle>版主</TD>\n" "<TD class=tdtitle>文章数</TD>\n" "<TD class=tdtitle>人气</TD>\n" "<TD class=tdtitle>在线</TD>\n" "</TR>\n"); //brc_initial(currentuser.userid, NULL); printf("<tr>\n"); for (i = 0; i < total; i++){ bp=&(shm_bcache->bcache[result[i]]); printf("<td class=tdborder>%s</td>\n", board_read(bp->header.filename, bp->lastpost) ? "◇" : "◆"); printf("<td class=tduser><a href=%s?B=%s >%s</a></td>\n", "bbsdoc", bp->header.filename, bp->header.filename); printf("<td class=tdborder>"); if (bp->header.flag & VOTE_FLAG) printf("<a href=vote?B=%s>V</a>", bp->header.filename); else printf(" "); printf("</td>\n"); printf("<td class=tdborder>[%4.4s]</td>\n", bp->header.type); printf("<td class=tdborder><a href=%s?B=%s>%s</a></td>\n", "bbshome",bp->header.filename, bp->header.title); ptr = userid_str(bm2str(bmbuf, &(bp->header))); if (strlen(ptr) == 0) printf("<td class=tdborder>诚征版主中</td>\n"); else printf("<td class=tdborder>%s</td>\n", ptr); printf("<td class=tdborder>%d</td>\n" "<td class=tdborder>%d</td>\n" "<td class=tdborder>%d</td>\n</tr>\n", bp->total, bp->score, bp->inboard); setbfile(buf, bp->header.filename, "introduction"); if (file_exist(buf)) { printf("<tr><td> </td>\n" "<td class=tduser>版面简介: </td>\n" "<td class=tdborder colspan=7>" "<div title=\"本版关键字: %s\">\n", bp->header.keyword[0] ? bp->header.keyword: "(暂无)"); fshowcon(stdout, buf, 2); printf("</div></td></tr>\n"); } printlastmark(bp->header.filename); } printf("</TR></TBODY></TABLE></td></tr></table>\n"); } } printf("<br><form action=bbssbs>\n"); printf ("<div title=\"支持中英文版名/版面关键字定位至版面。例如,输入“铁路”可定位至traffic版。\">" "<input name=keyword maxlength=20 size=20>\n"); printf("<input type=submit value=开始搜索></div>\n"); printf("</form><hr>\n"); http_quit(); return 0; }
static void answer_key(struct evbuffer *buf, const char *key) { int bid; boardheader_t *bptr; if (isdigit(*key)) { char *p; if ((bid = atoi(key)) == 0 || bid > MAX_BOARD) return; if ((p = strchr(key, '.')) == NULL) return; bptr = getbcache(bid); if (!bptr->brdname[0] || BOARD_HIDDEN(bptr)) return; key = p + 1; if (strcmp(key, "isboard") == 0) evbuffer_add_printf(buf, "%d", (bptr->brdattr & BRD_GROUPBOARD) ? 0 : 1); else if (strcmp(key, "over18") == 0) evbuffer_add_printf(buf, "%d", (bptr->brdattr & BRD_OVER18) ? 1 : 0); else if (strcmp(key, "hidden") == 0) evbuffer_add_printf(buf, "%d", BOARD_HIDDEN(bptr) ? 1 : 0); else if (strcmp(key, "brdname") == 0) evbuffer_add(buf, bptr->brdname, strlen(bptr->brdname)); else if (strcmp(key, "title") == 0) evbuffer_add(buf, bptr->title + 7, strlen(bptr->title) - 7); else if (strcmp(key, "class") == 0) evbuffer_add(buf, bptr->title, 4); else if (strcmp(key, "BM") == 0) evbuffer_add(buf, bptr->BM, strlen(bptr->BM)); else if (strcmp(key, "parent") == 0) evbuffer_add_printf(buf, "%d", bptr->parent); else if (strcmp(key, "count") == 0) { char path[PATH_MAX]; setbfile(path, bptr->brdname, FN_DIR); evbuffer_add_printf(buf, "%d", get_num_records(path, sizeof(fileheader_t))); } else if (strcmp(key, "children") == 0) { if (!(bptr->brdattr & BRD_GROUPBOARD)) return; for (bid = bptr->firstchild[1]; bid > 0; bid = bptr->next[1]) { bptr = getbcache(bid); evbuffer_add_printf(buf, "%d,", bid); } } else if (strncmp(key, "articles.", 9) == 0) { int offset, length; key += 9; if (!isdigit(*key) && *key != '-') return; offset = atoi(key); p = strchr(key, '.'); if (!p || (length = atoi(p+1)) == 0) length = DEFAULT_ARTICLE_LIST; article_list(buf, bptr, offset, length); } else if (strncmp(key, "article.", 8) == 0) { if (!is_valid_article_filename(key + 8)) return; char path[PATH_MAX]; struct stat st; int fd; setbfile(path, bptr->brdname, key + 8); if ((fd = open(path, O_RDONLY)) < 0) return; if (fstat(fd, &st) < 0 || st.st_size == 0 || evbuffer_add_file(buf, fd, 0, st.st_size) != 0) close(fd); } else if (strncmp(key, "articlestat.", 12) == 0) { if (!is_valid_article_filename(key + 12)) return; char path[PATH_MAX]; struct stat st; setbfile(path, bptr->brdname, key + 12); if (stat(path, &st) < 0) return; evbuffer_add_printf(buf, "%d-%d,%ld", (int) st.st_dev, (int) st.st_ino, st.st_size); } else if (strncmp(key, "articlepart.", 12) == 0) { answer_articleselect(buf, bptr, key + 12, select_article_part, NULL); } else if (strncmp(key, "articlehead.", 12) == 0) { answer_articleselect(buf, bptr, key + 12, select_article_head, NULL); } else if (strncmp(key, "articletail.", 12) == 0) { answer_articleselect(buf, bptr, key + 12, select_article_tail, NULL); } else return; } else if (strncmp(key, "tobid.", 6) == 0) { bid = getbnum(key + 6); bptr = getbcache(bid); if (!bptr->brdname[0] || BOARD_HIDDEN(bptr)) return; evbuffer_add_printf(buf, "%d", bid); #if HOTBOARDCACHE } else if (strncmp(key, "hotboards", 9) == 0) { for (bid = 0; bid < SHM->nHOTs; bid++) { bptr = getbcache(SHM->HBcache[bid] + 1); if (BOARD_HIDDEN(bptr)) continue; evbuffer_add_printf(buf, "%d,", SHM->HBcache[bid] + 1); } #endif } }