int bbsfadd_main(void) { if (!loginok) return BBS_ELGNREQ; const char *id = getparm("id"); const char *desc = getparm("desc"); if (*id != '\0') { override_t ov; memset(&ov, 0, sizeof(ov)); strlcpy(ov.id, id, sizeof(ov.id)); if (!searchuser(ov.id)) return BBS_ENOUSR; strlcpy(ov.exp, desc, sizeof(ov.exp)); char file[HOMELEN]; sethomefile(file, currentuser.userid, "friends"); if (get_num_records(file, sizeof(ov)) == MAXFRIENDS) return BBS_EFRNDQE; // TODO: be atomic if (!search_record(file, NULL, sizeof(ov), cmpname, ov.id)) append_record(file, &ov, sizeof(ov)); printf("Location: fall\n\n"); return 0; } xml_header("bbs"); printf("<bbsfadd "); print_session(); printf(">%s</bbsfadd>", id); return 0; }
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 void chat_load_alias() { char buf[256]; int i; chat_alias_count = 0; chat_aliases = (struct chatalias *) malloc(sizeof (struct chatalias) * MAXDEFINEALIAS); for (i = 0; i < MAXDEFINEALIAS; i++) chat_aliases[i].cmd[0] = 0; setuserfile(buf, "chatalias"); chat_alias_count = get_num_records(buf, sizeof (struct chatalias)); if (chat_alias_count > MAXDEFINEALIAS) chat_alias_count = MAXDEFINEALIAS; if (chat_alias_count != 0) get_records(buf, chat_aliases, sizeof (struct chatalias), 1, chat_alias_count); for (i = 0; i < chat_alias_count; i++) { if (chat_aliases[i].cmd[0] == 0) { chat_alias_count = i; break; } chat_aliases[i].cmd[8] = 0; chat_aliases[i].action[80] = 0; } }
int fptr(BOARDHEADER *bhentp) { char fname[PATHLEN], *boardname; FILEHEADER *fileinfo; int i, fd, total_rec; boardname = bhentp->filename; if (boardname[0] == '\0') return -1; setboardfile (fname, boardname, DIR_REC); total_rec = get_num_records(fname, FH_SIZE); if(total_rec > 0 && (fd = open(fname, O_RDWR)) > 0) { flock(fd, LOCK_EX); fileinfo = (FILEHEADER *) mmap(NULL, (size_t)(total_rec * FH_SIZE), (PROT_READ | PROT_WRITE), MAP_SHARED, fd, (off_t) 0); printf("Checking %s:\n", boardname); for (i = 0 ; i < total_rec ; ++i) if (fileinfo->filename[0]) fix_old_push(fileinfo + i); munmap(fileinfo, (size_t)(total_rec * FH_SIZE)); flock(fd, LOCK_UN); close(fd); } return 0; }
int main() { init_all(); struct compact p; char board[STRLEN],path[STRLEN]; strsncpy(board, getparm("board"), 20); sprintf(path,"compact/%s/compact",board); int total=get_num_records(path,sizeof(p)); if(total==0) { showinfo("该板尚无过刊."); return 1; } printf("<center>%s 过刊区<br>",board); printf("----------------------------------------------------------"); printf("<table width=80% boarder=0 align=center>"); printf("<tr><td>序号</td><td>名称</td><td>文章总数</td><td>建立日期</td></tr>"); FILE *fp=fopen(path,"r"); if(fp==0) { printf("文件读取错误,请重试."); return 1; } int i=1; while(1) { if(fread(&p, sizeof(p), 1, fp)<=0) break; printf("<tr><td>%d</td><td><a href=bbsdoc?board=%s&&mode=c&&num=%d>%s</a></td><td>%d</td><td>%6.6s</td></tr>\ ",i,board,i,p.name,p.total,ctime(&p.time)+4); i++; } printf("</table>"); fclose(fp); return 0; }
/***************************************************** * Syntax: MAILNUM * 取得信件數目 *****************************************************/ DoGetMailNumber() { int num; num = get_num_records(maildirect, FH_SIZE); inet_printf("%d\t%d\r\n", MAIL_NUM_IS, num); }
static void a_delrange(menu_t * pm, const char *backup_dir) { char fname[PATHLEN]; snprintf(fname, sizeof(fname), "%s/" FN_DIR, pm->path); del_range(0, NULL, fname, backup_dir); pm->num = get_num_records(fname, FHSZ); }
/******************************************************************* * check if user mail-box full * *******************************************************************/ int isExceedMailLimit(USEREC *user) { int num_mail; char fname[PATHLEN]; setmailfile(fname, user->userid, DIR_REC); num_mail = get_num_records(fname, FH_SIZE); if((user->userlevel < PERM_BM && num_mail >= MAX_KEEP_MAIL) || num_mail >= SPEC_MAX_KEEP_MAIL) { sprintf(WEBBBS_ERROR_MESSAGE, "%s 信箱已滿 ( %d 封), 無法再收信...(from %s)", user->userid, num_mail, username); return TRUE; } return FALSE; }
int fixbcache(int argc, char **argv) { int n, fd, bid, changed = 0; boardheader_t bh; (void)argc; (void)argv; if( (fd = open(fn_board, O_RDONLY)) < 0 ){ perror("open .BRD"); return 1; } for( bid = 0 ; (bid < MAX_BOARD && read(fd, &bh, sizeof(bh)) == sizeof(bh)) ; ++bid ){ if( strcmp(bh.brdname, bcache[bid].brdname) != 0 ){ char fn[PATHLEN]; printf("bid: %d, brdname not match(.BRD: %s, bcache: %s). " "fix it!\n", bid + 1, bh.brdname, bcache[bid].brdname); changed = 1; lockbcache(); bcache[bid] = bh; unlockbcache(); sprintf(fn, "boards/%c/%s/.DIR.bottom", bh.brdname[0], bh.brdname); n = get_num_records(fn, sizeof(fileheader_t)); if( n > 5 ) n = 5; SHM->n_bottom[bid] = n; } } close(fd); if( changed ){ puts("re-sort bcache"); sort_bcache(); } return 0; }
/* * include signature: support multiple signatures */ static void do_article_sig(const char *wfile) { int sig_no = 0, avalsig = 0, i; /* default: don't include signature */ FILE *fpr; static BOOL shownote = TRUE; if (curuser.flags[0] & SIG_FLAG) { if (shownote) { outs(_msg_no_use_sig); getkey(); shownote = FALSE; } return; } sethomefile(genbuf, curuser.userid, UFNAME_SIGNATURES); if (!get_num_records(genbuf, sizeof(char))) return; if ((fpr = fopen(genbuf, "r")) == NULL) return; outs("\n"); for (i = 0; i < (MAX_SIG_LINES * MAX_SIG_NUM) && fgets(genbuf, sizeof(genbuf), fpr); i++) { if (i % MAX_SIG_LINES == 0) prints("[1;36m[%s #%d][m\n", _msg_signature, ++avalsig); outs(genbuf); } fclose(fpr); prints("[m\n%s(1-%d,0:%s) ? [1]: ", _msg_include_which_sig, MAX_SIG_NUM, _msg_no_include_sig); sig_no = (getkey() - '0'); if (sig_no > avalsig || sig_no < 0) sig_no = 1; if (sig_no != 0) include_sig(curuser.userid, wfile, sig_no); }
int getfriendstr(struct userec* user,struct user_info* puinfo,session_t * session) { int nf; int i; struct friends *friendsdata; char buf[60]; puinfo->friendsnum=0; if (session->topfriend != NULL) { free(session->topfriend); session->topfriend = NULL; } sethomefile(buf, user->userid, "friends"); nf = get_num_records(buf, sizeof(struct friends)); if (nf <= 0) return 0; if (nf>MAXFRIENDS) nf=MAXFRIENDS; friendsdata = (struct friends *) calloc(nf,sizeof(struct friends)); get_records(buf, friendsdata, sizeof(struct friends), 1, nf); for (i = 0; i < nf; i++) { friendsdata[i].id[IDLEN] = 0; friendsdata[i].exp[LEN_FRIEND_EXP-1] = 0; if (id_invalid(friendsdata[i].id)||(searchuser(friendsdata[i].id)==0)) { memcpy(&friendsdata[i], &friendsdata[nf - 1], sizeof(struct friends)); nf--; } } qsort(friendsdata, nf, sizeof(friendsdata[0]), cmpfuid); /*For Bi_Search */ session->topfriend = (struct friends_info *) calloc(nf,sizeof(struct friends_info)); for (i = 0; i < nf; i++) { puinfo->friends_uid[i] = searchuser(friendsdata[i].id); strcpy(session->topfriend[i].exp, friendsdata[i].exp); } free(friendsdata); puinfo->friendsnum=nf; return 0; }
/* return index>0 if thisstamp==stamp[index], * return -index<0 if stamp[index-1]<thisstamp<stamp[index+1], XXX thisstamp ?<>? stamp[index] * or XXX filename[index]="" * return 0 if error */ int getindex_m(const char *direct, fileheader_t *fhdr, int end, int isloadmoney) { // Ptt: 從前面找很費力 太暴力 int fd = -1, begin = 1, i, s, times, stamp; fileheader_t fh; int n = get_num_records(direct, sizeof(fileheader_t)); if( end > n || end<=0 ) end = n; stamp = atoi(fhdr->filename + 2); for( i = (begin + end ) / 2, times = 0 ; end >= begin && times < 20 ; /* 最多只找 20 次 */ i = (begin + end ) / 2, ++times ){ if( get_record_keep(direct, &fh, sizeof(fileheader_t), i, &fd)==-1 || !fh.filename[0] ) break; s = atoi(fh.filename + 2); if( s > stamp ) end = i - 1; else if( s == stamp ){ close(fd); if(isloadmoney) fhdr->multi.money = fh.multi.money; return i; } else begin = i + 1; } if( times < 20) // Not forever loop. It any because of deletion. { close(fd); return -i; } if( fd != -1 ) close(fd); return 0; }
int CheckMail(USEREC *urc, const char *to, BOOL strict) { char dotdir[PATHLEN]; int total; USEREC urcTmp, *u = (urc) ? urc : &urcTmp; int flexbility = (strict) ? 0 : 10; if (get_passwd(u, to) <= 0) return -1; if (u->userlevel == PERM_SYSOP) return 0; setmailfile(dotdir, to, DIR_REC); total = get_num_records(dotdir, FH_SIZE); if ((u->userlevel >= PERM_BM && total >= SPEC_MAX_KEEP_MAIL+flexbility) || (u->userlevel < PERM_BM && total >= MAX_KEEP_MAIL+flexbility)) { return -2; } return 0; }
int read_max(char *direct, int size) { return get_num_records(direct, size); }
/************************************************************** * 寄信給站上使用者 **************************************************************/ static int SendMail_Local(char *fname,char *from, const char *to, char *title, char ident) { USEREC urcTmp; char pathTmp[PATHLEN]; int retval, fsize; retval = CheckMail(&urcTmp, to, FALSE); if (retval == -1) return -1; /* kmwang:20000610:blacklist */ /* bug fixed by lasehu 2002/05/22 if (in_blacklist(to, from)) return -1; */ if (!is_emailaddr(from) && in_blacklist(to, from)) return -1; else if (retval > 0) { bbslog("SENDMAIL", "from=%s, to=%s, total=%d, stat=ENOSPC", from, to, retval); return -2; } /* Auto-Forward */ if ((urcTmp.flags[0] & FORWARD_FLAG) && is_emailaddr(urcTmp.email)) { #ifdef NSYSUBBS if (strncmp(urcTmp.email, "bbs@", 4) && !strstr(urcTmp.email, "..")) { #endif if (SendMail_Internet(-1, fname, from, urcTmp.email, title, urcTmp.userid) == 0) return 0; #ifdef NSYSUBBS } #endif bbslog("ERR", "auto-forward: %s", urcTmp.email); } setmailfile(pathTmp, to, NULL); if (!isdir(pathTmp)) { if (mkdir(pathTmp, 0700) == -1) return -1; } if (!(fsize = get_num_records(fname, sizeof(char)))) return -2; if (fsize > MAX_MAIL_SIZE) { bbslog("SENDMAIL", "from=%s, to=%s, size=%d, stat=EFBIG", from, to, fsize); return -3; } #ifdef USE_THREADING /* syhu */ if (append_article(fname, pathTmp, from, title, ident, NULL, FALSE, 0, NULL, -1, -1 ) == -1) /* syhu */ #else if (append_article(fname, pathTmp, from, title, ident, NULL, FALSE, 0, NULL) == -1) #endif return -1; 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); }
/******************************************************************* * 根據 URLParaType 執行 GET 的要求 * * * return WebRespondType *******************************************************************/ int DoGetRequest(REQUEST_REC * rc, BOARDHEADER * board, POST_FILE * pf) { char *p, *boardname; int URLParaType = rc->URLParaType; char fname[PATHLEN]; boardname = board->filename; if (URLParaType == Redirect) { /* redirect target must set in ParseURI() */ return WEB_REDIRECT; } if (PSCorrect != Correct && (URLParaType == MailList || URLParaType == MailRead || URLParaType == SkinModify)) { return WEB_USER_NOT_LOGIN; } if (URLParaType == PostList || URLParaType == PostRead || URLParaType == TreaList || URLParaType == TreaRead || URLParaType == SkinModify || URLParaType == Board) { int perm; if (get_board(board, boardname) <= 0 || board->filename[0] == '\0') return WEB_BOARD_NOT_FOUND; if ((perm = CheckBoardPerm(board, &curuser)) != WEB_OK) return perm; if (board->brdtype & BRD_WEBSKIN) /* Board has custom html skin */ { char *skin, web_board_dir[PATHLEN]; if (URLParaType == SkinModify) { if (strlen(pf->POST_NAME) != 0) { xstrncpy(web_board_dir, pf->POST_NAME, PATHLEN); skin = strrchr(web_board_dir, '/') + 1; setskinfile(pf->POST_NAME, boardname, skin); } } else if (!strstr(skin_file->filename, HTML_BoardModify)) { /* set specfic skin file to custom file */ xstrncpy(web_board_dir, skin_file->filename, PATHLEN); skin = strrchr(web_board_dir, '/') + 1; setskinfile(skin_file->filename, boardname, skin); } } else { if (strstr(skin_file->filename, HTML_SkinModify)) return WEB_FILE_NOT_FOUND; } } if (strstr(skin_file->filename, HTML_BoardModify) && (!HAS_PERM(PERM_SYSOP) || PSCorrect != Correct)) { return WEB_FILE_NOT_FOUND; } switch (URLParaType) { case TreaRead: case PostRead: if (GetPostInfo(board, pf) != WEB_OK) return WEB_FILE_NOT_FOUND; break; case TreaList: case PostList: pf->total_rec = get_num_records(pf->POST_NAME, FH_SIZE); break; case MailList: if (PSCorrect == Correct) pf->total_rec = get_num_records(pf->POST_NAME, FH_SIZE); else pf->total_rec = 0; break; case MailRead: if (PSCorrect == Correct) { int RESULT = GetPostInfo(board, pf); if (RESULT != WEB_OK) return RESULT; } break; case UserList: case BoardList: case TreaBoardList: case UserData: case SkinModify: /* do nothing here.. */ break; case UserQuery: /* put USER_REC in curuser for query */ if (!get_passwd(&curuser, username)) { bzero(&curuser, sizeof(USEREC)); return WEB_USER_NOT_FOUND; } break; case Board: /* cuscom webboard */ case Mail: /* ?? */ #if 0 fprintf(fp_out, "DoGetRequest Board,Mail:[%s]", skin_file->filename); fflush(fp_out); #endif if (CacheState(skin_file->filename, NULL) < 0 && !isfile(skin_file->filename)) { return WEB_FILE_NOT_FOUND; } break; default: #if 0 fprintf(fp_out, "DoGetRequest default:[%s]\r\n", skin_file->filename); fflush(fp_out); #endif xstrncpy(fname, skin_file->filename, sizeof(fname)); if (isBadURI(fname)) { BBS_SUBDIR[0] = 0x00; return WEB_BAD_REQUEST; } sprintf(skin_file->filename, "%s%s", HTML_PATH, fname + 1); if (CacheState(skin_file->filename, NULL) == -1) /* file not in cache */ { if (isdir(skin_file->filename)) { p = skin_file->filename + strlen(skin_file->filename) - 1; if (*p == '/') { strcat(skin_file->filename, DEFAULT_HTML); } else { sprintf(skin_file->filename, "%s/", fname); return WEB_REDIRECT; } } else { if ((p = strrchr(fname + 1, '/')) == NULL) p = fname; if (!strcmp(p, "/boards") || !strcmp(p, "/treasure") || !strcmp(p, "/mail") || !strcmp(p, "/users")) { sprintf(skin_file->filename, "%s/", fname); return WEB_REDIRECT; } } if (!isfile(skin_file->filename)) { BBS_SUBDIR[0] = 0x00; return WEB_FILE_NOT_FOUND; } } #ifdef WEB_LOGIN_CHECK return WebLoginCheck(); #endif } return WEB_OK; }
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 } }
/***************************************************** * Syntax: MAILHEAD startnum [endnum] * 取得信件資料 * Respond: MailNum State-Condition Owner Date Title * 取得信件資料 *****************************************************/ DoGetMailHead() { int start, end, num, fd, i; struct fileheader fh; char mail_state, chdate[6], c; time_t date; start = Get_para_number(1); if (start < 1) { RespondProtocol(MAIL_NOT_EXIST); return; } end = Get_para_number(2); if (end < 1) end = start; else if (end < start) { RespondProtocol(SYNTAX_ERROR); return; } num = get_num_records(maildirect, FH_SIZE); /* get mail count */ if (start > num || end > num) { RespondProtocol(MAIL_NOT_EXIST); return; } if ((fd = open(maildirect, O_RDWR)) < 0) { RespondProtocol(WORK_ERROR); return; } if (lseek(fd, FH_SIZE * (start - 1), SEEK_SET) == -1) { RespondProtocol(WORK_ERROR); close(fd); return; } RespondProtocol(OK_CMD); net_cache_init(); for (i = start; i <= end; i++) { if (read(fd, &fh, FH_SIZE) == FH_SIZE) { if (fh.accessed & FILE_DELE) mail_state = 'D'; /* deleted mail */ else if (fh.accessed & FILE_READ) mail_state = 'R'; /* readed mail */ else mail_state = 'N'; /* new mail */ date = atol((fh.filename) + 2); strftime(chdate, 6, "%m/%d", localtime(&date)); chk_str2(fh.owner); chk_str2(fh.title); if (curuser.ident == 7) c = fh.ident + '0'; else c = '*'; if (mail_state != 'D') net_cache_printf("%d\t%c\t%c\t%s\t%s\t%s\r\n", i, mail_state, c, fh.owner, chdate, fh.title); else net_cache_printf("%d\t%c\t%c\t%s\t%s\r\n", i, mail_state, c, fh.owner, chdate); } else break; } close(fd); net_cache_write(".\r\n", 3); /* end */ net_cache_refresh(); }
/******************************************************************* * 從 .DIR 中讀取 POST 相關資訊 * * 佈告區 & 精華區 & 信件 通用 *******************************************************************/ int GetPostInfo(BOARDHEADER *board, POST_FILE *pf) { int fd; time_t date; #ifdef USE_MMAP FILEHEADER *fileinfo; int i; #else FILEHEADER fileinfo; #endif char *p, board_dir[PATHLEN]; /* ====== get post info from DIR_REC ====== */ setdotfile(board_dir, pf->POST_NAME, DIR_REC); pf->total_rec = get_num_records(board_dir, FH_SIZE); if((pf->total_rec == 0) || (p = strrchr(pf->POST_NAME, '/')) == NULL) return WEB_FILE_NOT_FOUND; xstrncpy(pf->fh.filename, p+1, STRLEN-8-12-4-4); #if 0 fprintf(fp_out, "[board_dir=%s, total_post=%d, pf->POST_NAME=%s, pf->fh.filename=%s]\n", board_dir, pf->total_rec, pf->POST_NAME, pf->fh.filename); fflush(fp_out); #endif if ((fd = open(board_dir, O_RDWR)) < 0) return WEB_FILE_NOT_FOUND; /* seek from .DIR back is better */ pf->num = pf->total_rec; #ifdef USE_MMAP fileinfo = (FILEHEADER *) mmap((caddr_t) 0, (size_t)(pf->total_rec*FH_SIZE), (PROT_READ | PROT_WRITE), MAP_SHARED, fd, (off_t) 0); if(fileinfo == MAP_FAILED) { sprintf(WEBBBS_ERROR_MESSAGE, "mmap failed: %s %d", strerror(errno), (int)(pf->total_rec*FH_SIZE)); close(fd); return WEB_ERROR; } close(fd); while(pf->num > 0) { if(!strcmp((fileinfo+pf->num-1)->filename, pf->fh.filename)) { if((fileinfo+pf->num-1)->accessed & FILE_DELE) { munmap((void *)fileinfo, pf->total_rec*FH_SIZE); return WEB_FILE_NOT_FOUND; } break; } pf->num--; } if(pf->num < 1) { munmap((void *)fileinfo, pf->total_rec*FH_SIZE); return WEB_FILE_NOT_FOUND; } memcpy(&(pf->fh), fileinfo+pf->num-1, FH_SIZE); #else if(lseek(fd, (FH_SIZE*(pf->total_rec-1)), SEEK_SET) == -1) return WEB_FILE_NOT_FOUND; while(pf->num >= 0) { if(read(fd, &fileinfo, FH_SIZE)==FH_SIZE) { if(!strcmp(fileinfo.filename, pf->fh.filename)) { if(fileinfo.accessed & FILE_DELE) { close(fd); return WEB_FILE_NOT_FOUND; } break; } pf->num--; lseek(fd, -(FH_SIZE*2), SEEK_CUR); } else { close(fd); return WEB_FILE_NOT_FOUND; } } #if 0 /* search from head */ pf->num = 0; while (read(fd, &fileinfo, FH_SIZE) == FH_SIZE) { pf->num++; if (!strcmp(fileinfo.filename, pf->fh.filename)) { if(fileinfo.accessed & FILE_DELE) { close(fd); return WEB_FILE_NOT_FOUND; } break; } } #endif memcpy(&(pf->fh), &(fileinfo), FH_SIZE); #endif /* USE_MMAP */ date = atol((pf->fh.filename) + 2); /* get date from filename */ xstrncpy(pf->date, ctime(&date), STRLEN); if(request_rec->HttpRequestType != GET) { /* skip find last & next post info if not HTTP_GET */ #ifdef USE_MMAP munmap((void *)fileinfo, pf->total_rec*FH_SIZE); #else close(fd); #endif return WEB_OK; } if(request_rec->URLParaType == MailRead && (pf->fh.accessed & FILE_READ) == FALSE) { int maxkeepmail; if (curuser.userlevel == PERM_BM) maxkeepmail = SPEC_MAX_KEEP_MAIL; else maxkeepmail = MAX_KEEP_MAIL; if(curuser.userlevel != PERM_SYSOP && pf->num > maxkeepmail ) /* lthuang */ { #ifdef USE_MMAP munmap((void *)fileinfo, pf->total_rec*FH_SIZE); #else close(fd); #endif sprintf(WEBBBS_ERROR_MESSAGE, "%s 信箱已滿 ( %d 封), 請刪除舊信後再看新信...", curuser.userid, pf->total_rec); return WEB_ERROR; } /* set fileinfo as readed */ #ifdef USE_MMAP (fileinfo+pf->num-1)->accessed |= FILE_READ; #else if (lseek(fd, -FH_SIZE, SEEK_CUR) == -1) { close(fd); return WEB_FILE_NOT_FOUND; } fileinfo.accessed |= FILE_READ; write(fd, &fileinfo, FH_SIZE); #endif } #ifdef TORNADO_OPTIMIZE #if defined(NSYSUBBS1) || defined(NSYSUBBS3) if(isTORNADO && request_rec->URLParaType == PostRead) { if(pf->total_rec - pf->num > TORNADO_GET_MAXPOST) { strcpy(pf->lfname, "-1"); strcpy(pf->nfname, "-1"); #ifdef USE_MMAP munmap((void *)fileinfo, pf->total_rec*FH_SIZE); #else close(fd); #endif return WEB_OK; } } #endif #endif /* get previous post filename */ #ifdef USE_MMAP for(i=pf->num-1; i>0; i--) { if(*((fileinfo+i-1)->filename) != 0x00 && !((fileinfo+i-1)->accessed & FILE_DELE) && !((fileinfo+i-1)->accessed & FILE_TREA)) { xstrncpy(pf->lfname, (fileinfo+i-1)->filename, STRLEN-8); break; } } if(i <= 0) strcpy(pf->lfname, "-1"); #else while(1) { if(lseek(fd, -(FH_SIZE*2), SEEK_CUR) == -1) { strcpy(pf->lfname, "-1"); break; } if(read(fd, &fileinfo, FH_SIZE)==FH_SIZE) { if( *fileinfo.filename != 0x00 && !(fileinfo.accessed & FILE_DELE) && !(fileinfo.accessed & FILE_TREA)) { xstrncpy(pf->lfname, fileinfo.filename, STRLEN-8); break; } } } #endif /* USE_MMAP */ if(strcmp(pf->lfname, "-1")) #ifdef USE_MMAP if((fileinfo+i-1)->accessed & FILE_HTML) #else if(fileinfo.accessed & FILE_HTML) #endif pf->type |= LAST_POST_IS_HTML; #if 0 fprintf(fp_out, "[file_num=%d, last_filename=%s]", pf->num, pf->lfname); fflush(fp_out); #endif /* get next post filename */ #ifdef USE_MMAP for(i=pf->num+1; i<=pf->total_rec; i++) { if(*((fileinfo+i-1)->filename) != 0x00 && !((fileinfo+i-1)->accessed & FILE_DELE) && !((fileinfo+i-1)->accessed & FILE_TREA)) { xstrncpy(pf->nfname, (fileinfo+i-1)->filename, STRLEN-8); break; } } if(i >= pf->total_rec+1) strcpy(pf->nfname, "-1"); #else if (lseek(fd, (long) (FH_SIZE * (pf->num)), SEEK_SET) == -1) { close(fd); return WEB_FILE_NOT_FOUND; } while(1) { if(read(fd, &fileinfo, FH_SIZE)==FH_SIZE) { if( *fileinfo.filename != 0x00 && !(fileinfo.accessed & FILE_DELE) && !(fileinfo.accessed & FILE_TREA)) { xstrncpy(pf->nfname, fileinfo.filename, STRLEN-8); break; } } else { strcpy(pf->nfname, "-1"); break; } } #endif /* USE_MMAP */ if(strcmp(pf->nfname, "-1")) #ifdef USE_MMAP if((fileinfo+i-1)->accessed & FILE_HTML) #else if(fileinfo.accessed & FILE_HTML) #endif pf->type |= NEXT_POST_IS_HTML; #if 0 fprintf(fp_out, "[next_filename=%s]", pf->nfname); fflush(fp_out); #endif #ifdef USE_MMAP munmap((void *)fileinfo, pf->total_rec*FH_SIZE); #else close(fd); #endif return WEB_OK; }
int append_record_forward(char *fpath, fileheader_t * record, int size, const char *origid) { FILE *fp; char buf[PATHLEN]; char address[64] = ""; char fwd_title[STRLEN] = ""; int r; // No matter what, append it, and return if that failed. r = append_record(fpath, record, size); if (r < 0) return r; // #ifdef USE_MAIL_AUTO_FORWARD if (strlen(fpath) + strlen(FN_FORWARD) >= PATHLEN) { log_filef("log/invalid_append_record_forward", LOG_CREAT, "%s %s %s\n", Cdatelite(&now), cuser.userid, fpath); return -1; } setdirpath(buf, fpath, FN_FORWARD); fp = fopen(buf, "r"); if (!fp) return 0; // Load and setup address address[0] = 0; fscanf(fp, "%63s", address); fclose(fp); chomp(address); strip_blank(address, address); #ifdef UNTRUSTED_FORWARD_TIMEBOMB if (dasht(buf) < UNTRUSTED_FORWARD_TIMEBOMB) { // We may unlink here, but for systems with timebomb, // just leave it alone and let user see it in login screen. // unlink(buf); return 0; } #endif if (get_num_records(fpath, sizeof(fileheader_t)) > MAX_KEEPMAIL_HARDLIMIT) { unlink(buf); // TODO add a mail so that origid knows what happened. LOG_IF(LOG_CONF_INTERNETMAIL, log_filef("log/internet_mail.log", LOG_CREAT, "%s [%s] (%s -> %s) mailbox overflow (%d > %d)\n", Cdatelite(&now), __FUNCTION__, origid, address, get_num_records(fpath, sizeof(fileheader_t)), MAX_KEEPMAIL_HARDLIMIT)); return 0; } if (!*address || strchr(address, '@') == NULL || strcasestr(address, str_mail_address)) { #ifndef UNTRUSTED_FORWARD_TIMEBOMB // delete the setting if we don't have timebombs. unlink(buf); LOG_IF(LOG_CONF_INTERNETMAIL, log_filef("log/internet_mail.log", LOG_CREAT, "%s [%s] Removed bad address: %s (%s)\n", Cdatelite(&now), __FUNCTION__, address, origid)); #endif return 0; } setdirpath(buf, fpath, record->filename); // because too many user set wrong forward address, // let's put their own address instead. // and again because some really stupid user // does not understand they've set auto-forward, // let's mark this in the title. snprintf(fwd_title, sizeof(fwd_title)-1, "[自動轉寄] %s", record->title); bsmtp(buf, fwd_title, address, origid); LOG_IF(LOG_CONF_INTERNETMAIL, log_filef("log/internet_mail.log", LOG_CREAT, "%s [%s] %s -> (%s) %s: %s\n", Cdatelite(&now), __FUNCTION__, cuser.userid, origid, address, fwd_title)); // #endif // USE_MAIL_AUTO_FORWARD return 0; }
int main(void) { FILE *fp, *ftmp; int i = 0, num; // char *currboard[3] = {"CCK-CHUHEN", "CCK-GENERAL", "CCK-FREE"}; // char *kingdom[3] = {"·¡º~¬Ó´Â", "±N«Ó«ÒÁp", "³p»»¤ý´Â"}; char file1[80], file2[80], line[256], str[256]; time_t dtime; boardheader_t brd; int brdfd; setgid(BBSGID); setuid(BBSUID); chdir(BBSHOME); attach_SHM(); time(&dtime); if ((brdfd = open(BBSHOME "/" FN_BOARD, O_RDONLY)) == -1){ perror("open " BBSHOME "/" FN_BOARD); return 0; } while(read(brdfd, &brd, sizeof(brd)) == sizeof(brd)) { const char* photo_fname = 0; const char* chess_name = 0; char kingdom_name[256]; int bid; // struct stat st; switch(brd.chesscountry){ case CHESSCODE_FIVE: photo_fname = "photo_fivechess"; chess_name = "¤¤l´Ñ"; break; case CHESSCODE_CCHESS: photo_fname = "photo_cchess"; chess_name = "¶H´Ñ"; break; case CHESSCODE_GO: photo_fname = "photo_go"; chess_name = "³ò´Ñ"; break; case CHESSCODE_REVERSI: photo_fname = "photo_reversi"; chess_name = "¶Â¥Õ´Ñ"; break; default: continue; } bid = getbnum(brd.brdname); setapath(str, brd.brdname); sprintf(file1, "%s/chess_list", str); printf("apath = %s\n", str); /* if (stat(file1, &st) == 0 && st.st_mtime > (dtime - UPDATE_FREQUENCY * 60)) continue; */ sprintf(file2, "%s/chess_list.tmp", str); if ((ftmp = fopen(file2, "w")) == NULL) continue; if ((fp = fopen(file1, "r"))) { char *p; char userid[IDLEN + 1], buf[256], name[11]; char date[11], other[IDLEN + 1]; int namelen; fgets(kingdom_name, 256, fp); fputs(kingdom_name, ftmp); chomp(kingdom_name); while (fgets(buf, sizeof(buf), fp)) { i = 0; strcpy(line, buf); p = strtok(buf, " "); name[0] = '\0'; if (p && *p != '#' && searchuser(p, userid)) { i = 1; if ((p = strtok(NULL, " "))) strlcpy(name, p, sizeof(name)); else i = 0; if ((p = strtok(NULL, " "))) strlcpy(date, p, sizeof(date)); else i = 0; if ((p = strtok(NULL, " "))) strlcpy(other, p, sizeof(other)); else i = 0; } if (!strcmp("°£¦W", name)) { sethomefile(buf, userid, photo_fname); unlink(buf); continue; } if (i == 0) { fprintf(ftmp, "%s", line); continue; } namelen = strlen(name); setapath(str, brd.brdname); sprintf(buf, "%s/chess_photo/.DIR", str); num = get_num_records(buf, sizeof(fileheader_t)); for (i = 1; i <= num; i++) { fileheader_t item; if (get_record(buf, &item, sizeof item, i) != -1) { FILE *fp1; if (!strncmp(item.title + 3, name, namelen) && (item.title[namelen + 3] == '\0' || item.title[namelen + 3] == ' ') ) { sethomefile(buf, userid, photo_fname); if ((fp1 = fopen(buf, "w"))) { sprintf(buf, "%s/chess_photo/%s", str, item.filename); f_suck6(fp1, buf); fprintf(fp1, "%d\n", bid); if (strcmp("«R¸¸", name)) fprintf(fp1, "<©ÒÄݤý°ê> %s (%s)\n", kingdom_name, chess_name); else fprintf(fp1, "<«R¸¸¤ý°ê> %s\n", kingdom_name); fprintf(fp1, "<²{¦b¶¥¯Å> %s\n", name); fprintf(fp1, "<¥[¤J¤é´Á> %s\n", date); if (strcmp("«R¸¸", name)) { int level; fprintf(fp1, "<¤ý°êµ¥¯Å> "); level = atoi(other); for (i = 0; i < level; i++) fprintf(fp1, "%s", "¡¹"); } else { chomp(other); fprintf(fp1, "<³Q½Ö«R¸¸> %s", other); } fprintf(fp1, "\n<¦Û§Ú»¡©ú> \n"); fclose(fp1); } break; } } } if (i > num) // level photo not found fprintf(ftmp, "%s", line); else fprintf(ftmp, "#%s", line); } fclose(fp); fclose(ftmp); rename(file2, file1); } else { fclose(ftmp); } } return 0; }
main() { /*Declarations*/ tree tr; status_code SC=SUCCESS; int ht,num,option,contnue,num_lo=0,num_hi=0; char dumbo[2]; int number; char name[NAME_LEN]; char dsgn[DSGN_LEN]; char add[ADD_LEN]; long int phone; initialize(&tr); /*Declarations End*/ do { /* Asking for different operations */ puts("ENTER the option as per the operation you want to do. ENTER :-\n"); puts("1- insert/update\n2- delete\n3- Search\n4- getNumRecords\n5- Height\n6- Range Search\n7- Print Database\n\n"); printf("Your Choice is:- "); scanf("%d",&option); printf("\n\n"); switch (option) { /* INSERT/UPDATE */ case 1: { printf("***********INSERT**********\n\n"); /* Data Entering Start */ printf("Enter Employee's Number :-\t"); scanf("%d",&number); printf("Enter Employee Name :-\t"); gets(dumbo); gets(name); remove_space_make_uppercase(name); printf("Enter Employee's Designation :-\t"); gets(dsgn); remove_space_make_uppercase(dsgn); printf("Enter Employee's Address :-\t"); gets(add); remove_space_make_uppercase(add); printf("Enter Employee's Phone Number :-\t"); scanf("%lu",&phone); /* Data Entering End */ /* Inserting/Updating Data */ SC=insert_emp(&tr,number,name,dsgn,add,phone); if(SC==SUCCESS) { puts("\n**********Data inserted**********\n"); } else { puts("\n**********Data insertion failed**********\n"); } break; } /*Search*/ case 3: { printf("Enter Employee's Number :-\t"); scanf("%d",&number); search(&tr,number); break; } /* Get Num Records */ case 4: { num=get_num_records(&tr); printf("Number of records present in the tree is %d",num); break; } /* Height of the tree */ case 5: { ht=height(&tr); printf("Height of the tree is %d",ht); break; } /* Range Search */ case 6: { printf("\nEnter lower bound :- \t"); scanf("%d",&num_lo); printf("\nEnter upper bound :- \t"); scanf("%d",&num_hi); if(num_lo<num_hi) { range_search(&tr,num_lo,num_hi); } else { printf("Please enter valid bounds.\n"); } break; } /* Print Database */ case 7: { print_database(&tr); break; } /* Default */ default: { break; } } /* Asking for CHOICE to Continue */ puts("\n\nIf you want to continue... ? Enter 1 if YES or 0 if NO\n"); printf("Your Choice is:- "); scanf("%d",&contnue); printf("\n\n"); }while(contnue==1); getch(); }
int a_menu_rec(const char *maintitle, const char *path, int lastlevel, int lastbid, char *trans_buffer, a_menu_session_t *sess, const int *preselect, // we don't change root's value (but may change root pointer) // we may change parent's value (but never change parent pointer) const menu_t *root, menu_t* const parent) { menu_t me = {0}; char fname[PATHLEN]; int ch, returnvalue = FULLUPDATE; assert(sess); // prevent deep resursive directories if (strlen(path) + FNLEN >= PATHLEN) { // it is not save to enter such directory. return returnvalue; } if(trans_buffer) trans_buffer[0] = '\0'; if (parent) { parent->next = &me; } else { assert(root == NULL); root = &me; } me.header_size = p_lines; me.header = (fileheader_t *) calloc(me.header_size, FHSZ); me.path = path; strlcpy(me.mtitle, maintitle, sizeof(me.mtitle)); setadir(fname, me.path); me.num = get_num_records(fname, FHSZ); me.bid = lastbid; /* 精華區-tree 中部份結構屬於 cuser ==> BM */ if (!(me.level = lastlevel)) { char *ptr; // warning: this is only valid for me.level. // is_uBM should not do anything except returning test result: // for ex, setting user BM permission automatically. // such extra behavior will result in any sub-op to have PERM_BM // ability, which leads to entering BM board without authority. // Thanks to mtdas@ptt for reporting this exploit. if (HasBasicUserPerm(PERM_LOGINOK) && !HasUserPerm(PERM_NOCITIZEN) && (ptr = strrchr(me.mtitle, '['))) me.level = is_uBM(ptr + 1, cuser.userid); } me.page = A_INVALID_PAGE; if (preselect && !*preselect) preselect = NULL; me.now = preselect ? (*preselect -1) : 0; for (;;) { if (me.now >= me.num) me.now = me.num - 1; if (me.now < 0) me.now = 0; if (me.now < me.page || me.now >= me.page + me.header_size) { me.page = me.now - ((me.page == 10000 && me.now > p_lines / 2) ? (p_lines / 2) : (me.now % p_lines)); if (!a_showmenu(&me)) { // some directories are invalid, restart! sess->bReturnToRoot = 1; break; } } if (preselect && *preselect && preselect[1]) { // if this is not the last preselect entry, enter it ch = KEY_ENTER; } else { ch = cursor_key(2 + me.now - me.page, 0); } if (ch == 'q' || ch == 'Q' || ch == KEY_LEFT) break; // TODO maybe we should let 1-9=simple search and z=tree-search // TODO or let 'z' prefix means 'back to root' if ((ch >= '1' && ch <= '9') || (ch == 'z' || ch == 'Z')) { int n = a_multi_search_num(ch, sess); me.page = A_INVALID_PAGE; if (n > 0) { // simple (single) selection me.now = n-1; me.page = 10000; // I don't know what's the magic value 10000... } else if (n == 0 && sess->z_indexes[0] == 0) { // empty/invalid input } else { // n == 0 with multiple selects preselect = sess->z_indexes; if (*preselect < 0) { // return to root first? if (parent) { sess->bReturnToRoot = 1; return DONOTHING; } // already in root preselect ++; } // handle first preselect (maybe zero due to previous 'already in root') if (*preselect > 0) me.now = *preselect - 1; else preselect = NULL; } continue; } switch (ch) { case KEY_UP: case 'k': if (--me.now < 0) me.now = me.num - 1; break; case KEY_DOWN: case 'j': if (++me.now >= me.num) me.now = 0; break; case KEY_PGUP: case Ctrl('B'): if (me.now >= p_lines) me.now -= p_lines; else if (me.now > 0) me.now = 0; else me.now = me.num - 1; break; case ' ': case KEY_PGDN: case Ctrl('F'): if (me.now < me.num - p_lines) me.now += p_lines; else if (me.now < me.num - 1) me.now = me.num - 1; else me.now = 0; break; case KEY_HOME: case '0': me.now = 0; break; case KEY_END: case '$': me.now = me.num - 1; break; case '?': case '/': if(me.num) { me.now = a_searchtitle(&me, ch == '?'); me.page = A_INVALID_PAGE; } break; case 'h': a_showhelp(me.level); me.page = A_INVALID_PAGE; break; case Ctrl('W'): a_where_am_i(root, me.now, me.header[me.now - me.page].title); vmsg(NULL); me.page = A_INVALID_PAGE; break; case 'e': case 'E': snprintf(fname, sizeof(fname), "%s/%s", path, me.header[me.now - me.page].filename); if (dashf(fname) && me.level >= MANAGER) { int edflags = 0; *quote_file = 0; # ifdef BN_BBSMOVIE if (me.bid && strcmp(getbcache(me.bid)->brdname, BN_BBSMOVIE) == 0) { edflags |= EDITFLAG_UPLOAD; edflags |= EDITFLAG_ALLOWLARGE; } # endif // BN_BBSMOVIE if (vedit2(fname, NA, NULL, edflags) != -1) { char fpath[PATHLEN]; fileheader_t fhdr; strlcpy(fpath, path, sizeof(fpath)); stampfile(fpath, &fhdr); unlink(fpath); strlcpy(fhdr.filename, me.header[me.now - me.page].filename, sizeof(fhdr.filename)); strlcpy(me.header[me.now - me.page].owner, cuser.userid, sizeof(me.header[me.now - me.page].owner)); setadir(fpath, path); substitute_record(fpath, me.header + me.now - me.page, sizeof(fhdr), me.now + 1); } me.page = A_INVALID_PAGE; } break; case 't': case 'c': if (me.now < me.num) { if (!isvisible_man(&me)) break; snprintf(fname, sizeof(fname), "%s/%s", path, me.header[me.now - me.page].filename); /* XXX: dirty fix 應該要改成如果發現該目錄裡面有隱形目錄的話才拒絕. 不過這樣的話須要整個搜一遍, 而且目前判斷該資料是目錄 還是檔案竟然是用 fstat(2) 而不是直接存在 .DIR 內 |||b 須等該資料寫入 .DIR 內再 implement才有效率. */ if( !me.level && !HasUserPerm(PERM_SYSOP) && (me.bid==0 || !is_BM_cache(me.bid)) && dashd(fname) ) vmsg("只有板主才可以拷貝目錄唷!"); else a_copyitem(fname, me.header[me.now - me.page].title, 0, 1); me.page = A_INVALID_PAGE; /* move down */ if (++me.now >= me.num) me.now = 0; break; } case KEY_ENTER: case KEY_RIGHT: case 'r': if (me.now >= me.num || me.now < 0) { preselect = NULL; continue; } else { fileheader_t *fhdr = &me.header[me.now - me.page]; const int *newselect = preselect ? preselect+1 : NULL; preselect = NULL; if (!isvisible_man(&me)) break; #ifdef DEBUG vmsgf("%s/%s", &path[11], fhdr->filename);; #endif snprintf(fname, sizeof(fname), "%s/%s", path, fhdr->filename); if (dashf(fname)) { int more_result; while ((more_result = more(fname, YEA))) { /* Ptt 範本精靈 plugin */ if (trans_buffer && (currstat == EDITEXP || currstat == OSONG)) { char ans[4]; move(22, 0); clrtoeol(); getdata(22, 1, currstat == EDITEXP ? "要把範例加入到文章內嗎?[y/N]" : "確定要選這篇嗎?[y/N]", ans, sizeof(ans), LCECHO); if (ans[0] == 'y') { strlcpy(trans_buffer, fname, PATHLEN); sess->bReturnToRoot = 1; if (currstat == OSONG) { log_filef(FN_USSONG, LOG_CREAT, "%s\n", fhdr->title); } free(me.header); return FULLUPDATE; } } if (more_result == READ_PREV) { if (--me.now < 0) { me.now = 0; break; } } else if (more_result == READ_NEXT) { if (++me.now >= me.num) { me.now = me.num - 1; break; } /* we only load me.header_size pages */ if (me.now - me.page >= me.header_size) break; } else break; if (!isvisible_man(&me)) break; snprintf(fname, sizeof(fname), "%s/%s", path, me.header[me.now - me.page].filename); if (!dashf(fname)) break; } } else if (dashd(fname)) { returnvalue = a_menu_rec(me.header[me.now - me.page].title, fname, me.level, me.bid, trans_buffer, sess, newselect, root, &me); if (returnvalue == DONOTHING) { // DONOTHING will only be caused by previous a_multi_search_num + preselect. assert(sess->bReturnToRoot); if (!parent) { // we've reached root menu! assert(sess->z_indexes[0] == -1); sess->bReturnToRoot = 0; returnvalue = FULLUPDATE; preselect = sess->z_indexes+1; // skip first 'return to root' if (*preselect > 0) me.now = *preselect-1; } } else { returnvalue = FULLUPDATE; } me.next = NULL; /* Ptt 強力跳出recursive */ if (sess->bReturnToRoot) { free(me.header); return returnvalue; } } me.page = A_INVALID_PAGE; } break; case 'F': case 'U': if (me.now < me.num) { fileheader_t *fhdr = &me.header[me.now - me.page]; if (!isvisible_man(&me)) break; snprintf(fname, sizeof(fname), "%s/%s", path, fhdr->filename); if (HasBasicUserPerm(PERM_LOGINOK) && dashf(fname)) { a_forward(path, fhdr, ch /* == 'U' */ ); /* By CharlieL */ } else vmsg("無法轉寄此項目"); me.page = A_INVALID_PAGE; } break; } if (me.level >= MANAGER) { switch (ch) { case 'n': a_newitem(&me, ADDITEM); me.page = A_INVALID_PAGE; break; case 'g': a_newitem(&me, ADDGROUP); me.page = A_INVALID_PAGE; break; case 'p': a_pasteitem(&me, 1); me.page = A_INVALID_PAGE; break; case 'f': a_editsign(&me); me.page = A_INVALID_PAGE; break; case Ctrl('P'): a_pastetagpost(&me, -1); returnvalue = DIRCHANGED; me.page = A_INVALID_PAGE; break; case Ctrl('A'): a_pastetagpost(&me, 1); returnvalue = DIRCHANGED; me.page = A_INVALID_PAGE; break; case 'a': a_appenditem(&me, 1); me.page = A_INVALID_PAGE; break; } if (me.num) switch (ch) { case 'm': a_moveitem(&me); me.page = A_INVALID_PAGE; break; case 'D': /* Ptt me.page = -1; */ a_delrange(&me, sess->backup_dir); me.page = A_INVALID_PAGE; break; case 'd': a_delete(&me, sess->backup_dir); me.page = A_INVALID_PAGE; break; case 'H': a_hideitem(&me); me.page = A_INVALID_PAGE; break; case 'T': a_newtitle(&me); me.page = A_INVALID_PAGE; break; #ifdef CHESSCOUNTRY case 'L': a_setchesslist(&me); break; #endif } } if (me.level >= SYSOP) { switch (ch) { case 'N': a_showname(&me); me.page = A_INVALID_PAGE; break; } } } free(me.header); return returnvalue; }
int list_intersection(struct book_record br1[],struct book_record br2[],struct book_record br3[]) { int num1,num2; int i=0,j=0,k=0; num1=get_num_records(br1); num2=get_num_records(br2); while((i<num1) && (j<num2)) { if(strcmp(br1[i].author_name,br2[j].author_name)>0) { j++; } else if(strcmp(br1[i].author_name,br2[j].author_name)<0) { i++; } else { if(strcmp(br1[i].book_name,br2[j].book_name)>0) { j++; } else if(strcmp(br1[i].book_name,br2[j].book_name)<0) { i++; } else { if(br1[i].copies_available<br2[j].copies_available) { br3[k]=br1[i]; k++; i++; j++; } else if(br1[i].copies_available>br2[j].copies_available) { br3[k]=br2[j]; k++; j++; i++; } else { if(br1[i].publication_year<br2[j].publication_year) { br3[k]=br2[j]; k++; j++; i++; } else { br3[k]=br1[i]; k++; j++; i++; } } } } } return k; }
/* * 搜尋文章 */ int search_article(register char *direct, register int ent, register char *string, register char op, register struct word **srchwtop) { FILEHEADER *fhr = &fhGol; char author[STRLEN], cmps_str[STRLEN]; int fd; register char *takestr; register int cmps_kind = 0; register int total_target = 0; int total; if (string[0] == '\0') return -1; xstrncpy(cmps_str, string, sizeof(cmps_str)); if (strchr(srchbword, op)) cmps_kind = SCMP_BACKWARD; if (strchr(srchauthor, op)) cmps_kind |= SCMP_AUTHOR; else if (strchr(srchassoc, op)) cmps_kind |= SCMP_ASSOC; #if USE_THREAD if (thr_mode) total = num_thrs; else if (art_mode) total = num_arts; else #endif total = get_num_records(direct, FH_SIZE); if (cmps_kind & SCMP_BACKWARD) { if (++ent > total) return -1; } else { if (--ent < 1) return -1; } if ((cmps_kind & SCMP_ASSOC) || srchwtop) { /* make cmps_str as no Re: */ if (!strncmp(cmps_str, STR_REPLY, REPLY_LEN)) strcpy(cmps_str, cmps_str + REPLY_LEN); } #if USE_THREAD if (!thr_mode && !art_mode) { #endif if ((fd = open(direct, O_RDONLY)) < 0) return -1; lseek(fd, (off_t) ((ent - 1) * FH_SIZE), SEEK_SET); #if USE_THREAD } #endif for (;;) { #if USE_THREAD if (thr_mode || art_mode) { if (ent > total) break; if (thr_mode) fhr = all_thrs[ent-1]; else if (art_mode) fhr = &(all_arts[ent-1]); } else { #endif if (read(fd, fhr, FH_SIZE) != FH_SIZE) break; #if USE_THREAD } #endif if (cmps_kind & SCMP_AUTHOR) { xstrncpy(author, fhr->owner, sizeof(author)); strtok(author, ".@"); takestr = author; if (takestr[0] == '#') takestr++; #ifndef IGNORE_CASE if (!strcmp(takestr, cmps_str)) /* compare */ #else if (!strcasecmp(takestr, cmps_str)) #endif { if (srchwtop) { add_wlist(srchwtop, fhr->filename, malloc_str); total_target++; } else { #if USE_THREAD if (!thr_mode && !art_mode) #endif close(fd); return ent; } } } else if (!(fhr->accessed & FILE_DELE)) { takestr = fhr->title; switch (op) { case '-': case '+': if (fhr->accessed & FILE_RESV) { #if USE_THREAD if (!thr_mode && !art_mode) #endif close(fd); return ent; } break; case '[': case ']': if (!strncmp(takestr, STR_REPLY, REPLY_LEN)) takestr += REPLY_LEN; case '=': if (!strcmp(takestr, cmps_str)) { #if USE_THREAD if (!thr_mode && !art_mode) #endif close(fd); return ent; } break; case '/': if (!srchwtop) { if (!strcmp(takestr, cmps_str)) /* compare */ { #if USE_THREAD if (!thr_mode && !art_mode) #endif close(fd); return ent; /* found it */ } } else { if (!strncmp(takestr, STR_REPLY, REPLY_LEN)) takestr += REPLY_LEN; if (!strcmp(takestr, cmps_str)) { add_wlist(srchwtop, fhr->filename, malloc_str); total_target++; } } break; case '<': case '>': if (strstr(takestr, cmps_str)) /* compare */ { if (!srchwtop) /* found it */ { #if USE_THREAD if (!thr_mode && !art_mode) #endif close(fd); return ent; } add_wlist(srchwtop, fhr->filename, malloc_str); total_target++; } break; } /* switch */ } /* else if */ if (cmps_kind & SCMP_BACKWARD) ent++; else { if (--ent < 1) /* abort search */ break; #if USE_THREAD if (!thr_mode && !art_mode) #endif lseek(fd, -2 * ((off_t) FH_SIZE), SEEK_CUR); } } /* while */ #if USE_THREAD if (!thr_mode && !art_mode) #endif close(fd); if (srchwtop) return total_target; return -1; }