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 ForwardArticle(char *pbuf, BOARDHEADER *board, POST_FILE *pf) { int result; char address[STRLEN], fname[PATHLEN]; strcpy(fname, pf->POST_NAME); if(request_rec->URLParaType == PostForward) setboardfile(pf->POST_NAME, board->filename, fname); else if(request_rec->URLParaType == TreaForward) settreafile(pf->POST_NAME, board->filename, fname); else if(request_rec->URLParaType == MailForward) setmailfile(pf->POST_NAME, username, fname); else return WEB_ERROR; GetPara2(address, "NUM", pbuf, 3, "-1"); pf->num = atoi(address); GetPara2(address, "ADDRESS", pbuf, STRLEN, ""); if((result = MailCheck(address)) != WEB_OK) return result; if(GetPostInfo(board, pf) != WEB_OK) { return WEB_FILE_NOT_FOUND; } if(!isfile(pf->POST_NAME)) { sprintf(WEBBBS_ERROR_MESSAGE, "開啟轉寄檔案失敗 %s", fname); return WEB_ERROR; } if(SendMail(-1, pf->POST_NAME, username, address, pf->fh.title, curuser.ident)) { strcpy(WEBBBS_ERROR_MESSAGE, "SendMail Error"); return WEB_ERROR; } #ifdef WEB_EVENT_LOG if(request_rec->URLParaType == MailForward) sprintf(log, "%s FROM=\"%s\" TO=\"%s\" SJT=\"%s\" UA=\"%s\"", POST_MailForward, username, address, pf->fh.title, request_rec->user_agent); else sprintf(log, "%s FROM=\"%s\" TO=\"%s\" SJT=\"%s\" UA=\"%s\"", POST_PostForward, username, address, pf->fh.title, request_rec->user_agent); #endif return WEB_OK_REDIRECT; }
/**1 output_file = new file() 2 dict = new hash() 3 while (free memory available) 4 do token = next_token() 5 if token not in dict 6 postinglist = addtodict(dict, token) 7 else postinglist = getpostinglist(dict, token) 8 if full(postinglist) 9 postinglist = doublepostinglist(dict, token) 10 addtopostinglist(postinglist, docid(token)) 11 sorted_terms = sortterm(dict) // for merge purpose *12 writeblock(sorted_terms, dict, output_file) */ int build_board_index(char *bname) { char *word; char dirfile[PATH_MAX], docid2path[PATH_MAX], indexfile[PATH_MAX]; char filepath[PATH_MAX]; /* article file path */ char filename[20]; char cachedir[PATH_MAX]; char cachefile[PATH_MAX]; char ndocsfile[PATH_MAX]; DB *dbp; DBT key, data; int ret; int result = -1; FILE *filelist, *fp; struct postinglist *p; unsigned int docid = 1; gzFile cachefp; int gzerr; setboardfile(dirfile, bname, bname); set_brddocid2path_file(docid2path, bname); set_brdindex_file(indexfile, bname); /* Initialize the DB structure.*/ ret = db_create(&dbp, NULL, 0); if (ret != 0) { ERROR("create db hanldle failed"); goto RETURN; } if (dbopen(dbp, docid2path, 1) != 0) { ERROR1("open db %s failed", docid2path); goto RETURN; } if (!(filelist = fopen(dirfile, "r"))) { ERROR1("open file %s failed", dirfile); goto CLEAN_DB; } size_t size = 300000; /* TODO: define this constant */ struct dict_t **bucket = new_postinglist_bucket(size); if (bucket == NULL) { ERROR1("new_dict size=%u failed", size); goto CLEAN_FP; } g_text = malloc(MAX_FILE_SIZE); if (g_text == NULL) { ERROR("malloc failed"); goto CLEAN_MEM; } /* Zero out the DBTs before using them. */ memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); key.size = sizeof(unsigned int); key.data = &docid; /* ensure the cache directory exists */ setcachepath(cachedir, bname); f_mkdir(cachedir, 0755); while (fgets(filename, sizeof(filename), filelist)) { filename[strlen(filename) - 1] = '\0'; data.size = strlen(filename) + 1; data.data = filename; setboardfile(filepath, bname, filename); ansi_filter(filepath); if (g_len != 0) { fprintf(stderr, "%d indexing %s\n", docid, filename); /* save to cache file */ setcachefile(cachefile, bname, filename); cachefp = gzopen(cachefile, "wb"); if (cachefp != NULL) { if (gzwrite(cachefp, g_text, g_len) != g_len) ERROR(gzerror(cachefp, &gzerr)); gzclose(cachefp); } g_pos = 0; while ((word = next_token())) { //DEBUG1("%s", word); p = get_postinglist(bucket, size, word); if (p->freq == p->size) /* is full */ double_postinglist(p); addto_postinglist(p, docid); } /* write_docid2path */ dbp->put(dbp, NULL, &key, &data, 0); docid++; } } write_index_file(bucket, size, indexfile); calc_doc_weight(bname, BOARD, docid - 1); set_brdndocs_file(ndocsfile, bname); fp = fopen(ndocsfile, "w"); if (fp == NULL) { ERROR1("fopen %s failed", ndocsfile); goto CLEAN; } fprintf(fp, "%u", docid - 1); fclose(fp); /* it's ok */ result = 0; CLEAN: free(g_text); CLEAN_MEM: free(bucket); CLEAN_FP: fclose(filelist); CLEAN_DB: if (dbp != NULL) dbp->close(dbp, 0); RETURN: return result; }
/******************************************************************* * 從 URI 判斷要求及抓出有用的資訊 * set BOARDNAME, POST_NAME, SKIN_FILE * * return URLParaType *******************************************************************/ int ParseURI(const char *curi, REQUEST_REC *r, BOARDHEADER *board, POST_FILE *pf) { char *p, *boardname; int HttpRequestType; char skin[PATHLEN], post[PATHLEN]; *skin = 0x00; *post = 0x00; *BBS_SUBDIR = 0x00; boardname = board->filename; HttpRequestType = r->HttpRequestType; if(curi[strlen(curi)-1] == '\\') { strncat(skin_file->filename, curi, strlen(curi)-1); return Redirect; } else if((p = strstr(curi, "/treasure/")) != NULL) { /* subdir/treasure/bname/ subdir/treasure/bname/start-end subdir/treasure/bname/treadir/treapost */ xstrncpy(BBS_SUBDIR, curi+1, p-curi+1); curi = p + 10; #if 0 if(curi[strlen(curi)-1] == '\\') { sprintf(skin_file->filename, "/%streasure/", BBS_SUBDIR); strncat(skin_file->filename, curi, strlen(curi)-1); return Redirect; } #endif GetURIToken(boardname, post, skin, curi); #if 0 fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]<br>", boardname, post, skin); fflush(fp_out); #endif if(HttpRequestType == POST) { xstrncpy(pf->POST_NAME, post, PATHLEN); if(!strcmp(skin, POST_PostSend)) return TreaSend; else if(!strcmp(skin, POST_PostEdit)) return TreaEdit; else if(!strcmp(skin, POST_PostForward)) return TreaForward; else if(!strcmp(skin, POST_PostDelete)) return TreaDelete; else return Board; } if(strlen(boardname)==0) /* no BOARDNAME assigned , list all boards */ { if(strlen(skin)==0) { sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaBoardList); return TreaBoardList; } else { /* skin is boardname */ sprintf(skin_file->filename, "/%streasure/%s/", BBS_SUBDIR, skin); return Redirect; } } if(strlen(skin)==0) /* must be treasure dir */ { if(strlen(post)==0) { settreafile(pf->POST_NAME, board->filename, DIR_REC); } else { settreafile(pf->POST_NAME, board->filename, post); strcat(pf->POST_NAME, "/"); strcat(pf->POST_NAME, DIR_REC); } sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaList); return TreaList; } if(strlen(post)) /* has treasure sub-dir*/ { settreafile(pf->POST_NAME, boardname, post); strcat(pf->POST_NAME, "/"); strcat(pf->POST_NAME, skin); } else { settreafile(pf->POST_NAME, boardname, skin); } if(isPost(skin)) { strip_html(pf->POST_NAME); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaPost); return TreaRead; } if(isdir(pf->POST_NAME)) /* check isdir before isPost */ { sprintf(skin_file->filename, "/%s%s/", BBS_SUBDIR, pf->POST_NAME); return Redirect; } sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin); if(CacheState(skin_file->filename, NULL) >=0 || isfile(skin_file->filename)) { if(strlen(post)==0) return TreaList; settreafile(pf->POST_NAME, board->filename, post); return TreaRead; } if(isList(skin, &(pf->list_start), &(pf->list_end))) { if(strlen(post)==0) settreafile(pf->POST_NAME, board->filename, DIR_REC); else sprintf(pf->POST_NAME, "treasure/%s/%s/%s", boardname, post, DIR_REC); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_TreaList); return TreaList; } else { settreafile(skin_file->filename, boardname, skin); return Board; } } else if((p = strstr(curi, "/boards/")) != NULL) { /* subdir/board/bname/ subdir/board/bname/start-end subdir/board/bname/post */ xstrncpy(BBS_SUBDIR, curi+1, p-curi+1); curi = p + 8; GetURIToken(boardname, post, skin, curi); #if 0 fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]<br>", boardname, post, skin); fflush(fp_out); #endif if(HttpRequestType == POST) { xstrncpy(pf->POST_NAME, post, PATHLEN); if(!strcmp(skin, POST_PostSend)) return PostSend; else if(!strcmp(skin, POST_PostEdit)) return PostEdit; else if(!strcmp(skin, POST_PostForward)) return PostForward; else if(!strcmp(skin, POST_PostDelete)) return PostDelete; else if(!strcmp(skin, POST_BoardModify)) return BoardModify; else if(!strcmp(skin, POST_SkinModify)) return SkinModify; else if(!strcmp(skin, POST_AccessListModify)) return AccessListModify; else return Board; } if(strlen(boardname)==0) { /* case: /boards/ /boards/boardname */ if(strlen(skin)==0) { sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_BoardList); return BoardList; } else { /* skin is boardname */ sprintf(skin_file->filename, "/%sboards/%s/", BBS_SUBDIR, skin); return Redirect; } } if(strlen(skin)==0) { /* case: /boards/boardname/ */ sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_PostList); setboardfile(pf->POST_NAME, boardname, DIR_REC); return PostList; } if(isList(skin, &(pf->list_start), &(pf->list_end))) { setboardfile(pf->POST_NAME, board->filename, DIR_REC); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_PostList); return PostList; } if(isPost(skin)) { strip_html(skin); setboardfile(pf->POST_NAME, boardname, skin); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_Post); return PostRead; } sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin); if(CacheState(skin_file->filename, NULL) >=0 || isfile(skin_file->filename)) { if(strlen(post)==0) /* is DIR_REC skin */ { if(!strcmp(skin, HTML_SkinModify)) { *(pf->POST_NAME) = '\0'; return SkinModify; } else { setboardfile(pf->POST_NAME, boardname, DIR_REC); return PostList; } } else /* is post skin */ { sprintf(pf->POST_NAME, "%s%s%s", HTML_PATH, BBS_SUBDIR, post); if(isfile(pf->POST_NAME)) { sprintf(pf->POST_NAME, "%s%s%s", HTML_PATH, BBS_SUBDIR, post); return SkinModify; } else { setboardfile(pf->POST_NAME, board->filename, post); return PostRead; } } } setboardfile(skin_file->filename, boardname, skin); return Board; } else if((p = strstr(curi, "/mail/")) != NULL) { xstrncpy(BBS_SUBDIR, curi+1, p-curi+1); curi = p + 6; GetURIToken(boardname, post, skin, curi); #if 0 fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]<br>", boardname, post, skin); fflush(fp_out); #endif if(HttpRequestType == POST) { xstrncpy(pf->POST_NAME, boardname, PATHLEN); if(!strcmp(skin, POST_MailSend)) return MailSend; else if(!strcmp(skin, POST_MailForward)) return MailForward; else if(!strcmp(skin, POST_MailDelete)) return MailDelete; else return OtherFile; } /* !! 'BOARDNAME' is 'post' in this section !! */ #if 0 if(strlen(boardname)==0 && strlen(skin)==0) { sprintf(skin_file->filename, "%s%s", BBS_SUBDIR, HTML_MailList); setmailfile(pf->POST_NAME, username, DIR_REC); return MailList; } #endif if(strlen(skin)==0) { sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_MailList); setmailfile(pf->POST_NAME, username, DIR_REC); return MailList; } if(isList(skin, &(pf->list_start), &(pf->list_end))) { setmailfile(pf->POST_NAME, username, DIR_REC); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_MailList); return MailList; } if(isPost(skin)) { strip_html(skin); setmailfile(pf->POST_NAME, username, skin); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_Mail); return MailRead; } sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin); if(CacheState(skin_file->filename, NULL) >=0 || isfile(skin_file->filename)) { if(strlen(board->filename) != 0) { setmailfile(pf->POST_NAME, username, boardname); return MailRead; } else { setmailfile(pf->POST_NAME, username, DIR_REC); return MailList; } } setmailfile(skin_file->filename, username, skin); return Mail; } else if((p = strstr(curi, "/users/")) != NULL) { xstrncpy(BBS_SUBDIR, curi+1, p-curi+1); curi = p + 7; GetURIToken(board->filename, post, skin, curi); #if 0 fprintf(fp_out, "[BOARDNAME=%s, post=%s, skin=%s]", board->filename, post, skin); fflush(fp_out); #endif if(HttpRequestType == POST) { if(!strcmp(skin, POST_UserNew)) return UserNew; else if(!strcmp(skin, POST_UserIdent)) return UserIdent; else if(!strcmp(skin, POST_UserData)) return UserData; else if(!strcmp(skin, POST_UserPlan)) return UserPlan; else if(!strcmp(skin, POST_UserSign)) return UserSign; else if(!strcmp(skin, POST_UserFriend)) return UserFriend; else return OtherFile; } if(strlen(skin)==0) { if(strlen(board->filename)!=0) { xstrncpy(username, board->filename, IDLEN); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserQuery); return UserQuery; } else { sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserList); return UserList; } } if(isList(skin, &(pf->list_start), &(pf->list_end))) { sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserList); return UserList; } sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, skin); if(CacheState(skin_file->filename, NULL) >=0 || isfile(skin_file->filename)) return UserData; xstrncpy(username, skin, IDLEN); sprintf(skin_file->filename, "%s%s%s", HTML_PATH, BBS_SUBDIR, HTML_UserQuery); return UserQuery; } else if(!strncmp(curi, "/~", 2)) /* want user planfile only */ { curi+=2; #if 0 fprintf(fp_out, "userplan name=%s ", curi); fflush(fp_out); #endif xstrncpy(username, curi, IDLEN); strtok(username, " /\t\r\n"); sprintf(skin_file->filename, "%s%s", HTML_PATH, HTML_UserPlanShow); return UserQuery; } else { #if 0 fprintf(fp_out, "[other file=%s]", curi); fflush(fp_out); #endif #ifdef NSYSUBBS /* for compatiable with old URL parameter ================== */ if((p = strstr(curi, "BoardName=")) != NULL || (p = strstr(curi, "boardname=")) != NULL) { p+=10; strtok(p, "?&/"); sprintf(skin_file->filename, "/txtVersion/boards/%s/", p); return Redirect; } /* ========================================================= */ #endif xstrncpy(skin_file->filename, curi, PATHLEN); xstrncpy(BBS_SUBDIR, curi+1, PATHLEN); if((p = strrchr(BBS_SUBDIR, '/')) != NULL) *(p+1) = 0x00; else BBS_SUBDIR[0] = 0x00; return OtherFile; } }