static int undo_mail(struct userec* user, void* arg) { char fname[256], buf[64]; struct _mail_list ml; int i; if((user == NULL) || (user->userid[0] == '\0')) return 0; if(strcmp(user->userid, "SYSOP") != 0) { setmailfile(fname, user->userid, ".DIR"); undo_index(fname); setmailfile(fname, user->userid, ".DELETED"); undo_index(fname); } setmailfile(fname, user->userid, ".SENT"); undo_index(fname); bzero(&ml, sizeof(ml)); load_mail_list(user, &ml); for(i=0; i<ml.mail_list_t; i++) { sprintf(buf, ".%s", ml.mail_list[i] + 30); setmailfile(fname, user->userid, buf); undo_index(fname); } printf("mail %s is undone.\n", user->userid); return 0; }
static void strip_mail_index_file(const char *username, 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; setmailfile(old_dir_path, username, dir); if ((old_fd = open(old_dir_path, O_RDONLY, 0644)) < 0) { fprintf(stderr, "Warning: maildir %s/%s not found.\n", username, dir); return; } sprintf(buf, "%s.NEW", dir); setmailfile(dir_path, username, 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_mail_fileheader(ptr + i, &fh, username, 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); } }
int delete_all_mail(int dfd, char *touser, char *filename, int size, RECORD_FUNC_ARG fptr, void *farg) { int i; char *buf, *buf1; off_t filesize; char *fname; char buf2[80]; char from[256]; char to[256]; struct stat st; int subspace = 0; struct userec *to_userec; printf("Deleting mails of %s... \n", touser); BBS_TRY { if (safe_mmapfile(filename, O_RDONLY, PROT_READ, MAP_SHARED, &buf, &filesize, NULL) == 0) BBS_RETURN(0); for (i = 0, buf1 = buf; i < filesize / size; i++, buf1 += size) { if ((*fptr)(buf1, farg)) { fname = ((struct fileheader *)buf1)->filename; sprintf(buf2, "SMTH.DM%s", fname); setmailfile(from, touser, fname); setmailfile(to, touser, buf2); rename(from, to); printf("found one %s...\n",fname); if (lstat(to, &st) == 0 && S_ISREG(st.st_mode) && st.st_nlink == 1) { subspace += st.st_size; } continue; } write(dfd, buf1, size); } end_mmapfile((void *) buf, filesize, -1); if (getuser(touser, &to_userec) != 0) { if (to_userec->usedspace > subspace) to_userec->usedspace -= subspace; else to_userec->usedspace = 0; } BBS_RETURN(0); } BBS_CATCH { } BBS_END; end_mmapfile((void *) buf, filesize, -1); return 0; }
void call_mail(chatcontext * pthis, const char *arg) { /* added by Luzi, 1997/12/22 */ fileheader mailheader; FILE *fpin; char b2[STRLEN]; char *t; char direct[PATHLEN]; if (chkmail() == 0) { /* check mail */ printchatline(pthis, "\033[32m*** 没有新的信件 ***\033[m"); return; } setmailfile(direct, getCurrentUser()->userid, DOT_DIR); fpin = fopen(direct, "rb"); if (fpin == NULL) return; printchatline(pthis, "\033[32m【当前新的信件如下】\033[m"); while (fread(&mailheader, sizeof(fileheader), 1, fpin)) { if ((mailheader.accessed[0] & FILE_READ) == 0) { strcpy(b2, mailheader.owner); if ((t = strchr(b2, ' ')) != NULL) *t = '\0'; sprintf(genbuf, "\033[31m %-20.20s ★ %.46s \033[m", b2, mailheader.title); printchatline(pthis, genbuf); } } fclose(fpin); }
static void rollback_mail_file(const char *username, const char *dir) { char dir_path[256]; char old_dir_path[256]; setmailfile(dir_path, username, dir); sprintf(old_dir_path, "%s.v1.2", dir_path); if (dashf(old_dir_path)) rename(old_dir_path, dir_path); }
/*********************************************************** * 轉寄文章檔案 * * 一般區、精華區、信件區通用 ************************************************************/ 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; }
/******************************************************************* * 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; }
/******************************************************************* * 查 userid 有沒有還沒讀的信 * 只檢查最後 CHK_MAIL_NUM 篇 * * return TRUE if user has mail unread *******************************************************************/ BOOL chk_newmail(char *userid) { int fd; register int idx = 0; register long numfiles; struct stat st; FILEHEADER fhGol; char mailfile[PATHLEN]; if(request_rec->URLParaType != UserQuery && PSCorrect != Correct) return FALSE; setmailfile(mailfile, userid, DIR_REC); if (stat(mailfile, &st) == -1) { return FALSE; } numfiles = st.st_size / FH_SIZE; if (numfiles > 0) { if ((fd = open(mailfile, O_RDONLY)) > 0) { lseek(fd, (off_t) (st.st_size - FH_SIZE), SEEK_SET); while (numfiles-- > 0 && idx++ < CHK_MAIL_NUM) { read(fd, &fhGol, sizeof(fhGol)); if (!(fhGol.accessed & FILE_READ) && !(fhGol.accessed & FILE_DELE)) { close(fd); return TRUE; } lseek(fd, -((off_t) (2 * FH_SIZE)), SEEK_CUR); } close(fd); } } return FALSE; }
int main(int argc, char **argv) { char mdir[256]; char mdir_bak[256]; char mdir_new[256]; struct stat st; int fd; char touser[20]; int len; if (argc != 2) { fprintf(stderr, "Usage: %s fromuser\n", argv[0]); return -1; } chdir(BBSHOME); resolve_ucache(); while (!feof(stdin)) { if (fgets(touser, sizeof(touser) - 1, stdin) == NULL) return -1; touser[sizeof(touser) - 1] = '\0'; len = strlen(touser); if (touser[len - 1] == '\n') touser[len - 1] = '\0'; setmailfile(mdir, touser, ".DIR"); if (stat(mdir, &st) < 0) { fprintf(stderr, "User '%s' not found.\n", touser); continue; } sprintf(mdir_bak, "%s.BAK", mdir); f_cp(mdir, mdir_bak, 0); sprintf(mdir_new, "%s.NEW", mdir); if ((fd = open(mdir_new, O_RDWR | O_CREAT, 0644)) > 0) { delete_all_mail(fd, touser, mdir, sizeof(struct fileheader), (RECORD_FUNC_ARG)cmpauthor, argv[1]); close(fd); f_mv(mdir_new, mdir); } } 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; }
static int get_user_mail_size(char * userid) { int currsize = 0; char currmaildir[STRLEN], tmpmail[STRLEN]; struct fileheader tmpfh; FILE *fp; time_t t; sethomefile(tmpmail, userid, "msgindex"); if(file_time(tmpmail)) currsize += file_size_s(tmpmail); sethomefile(tmpmail, userid, "msgindex2"); if(file_time(tmpmail)) currsize += file_size_s(tmpmail); sethomefile(tmpmail, userid, "msgcontent"); if(file_time(tmpmail)) currsize += file_size_s(tmpmail); sprintf(currmaildir, "mail/%c/%s/%s", mytoupper(userid[0]), userid, DOT_DIR); t = file_time(currmaildir); if(!t) return (currsize/1024); fp = fopen(currmaildir, "r"); if(!fp) return (currsize/1024); while(fread(&tmpfh, 1, sizeof(tmpfh), fp) == sizeof(tmpfh)) { setmailfile(tmpmail, userid, fh2fname(&tmpfh)); currsize += file_size_s(tmpmail); } fclose(fp); return (currsize/1024); }
static void query_user(chatcontext * pthis, const char *userid) { int tuid = 0; char qry_mail_dir[STRLEN], inbuf[STRLEN * 2]; char *newline; time_t exit_time, temp; struct userec *lookupuser; if (!(tuid = getuser(userid, &lookupuser))) { printchatline(pthis, "\033[32m这个ID不存在!\033[m"); return; } setmailfile(qry_mail_dir, lookupuser->userid, DOT_DIR); /*--- modified by period 2000-11-02 hide posts/logins ---*/ sprintf(genbuf, "%s (%s): %s", lookupuser->userid, lookupuser->username, (check_query_mail(qry_mail_dir, NULL)) ? "有新信" : " "); printchatline(pthis, genbuf); sprintf(genbuf, "共上站 %d 次,发表过 %d 篇文章,生命力[%d]%s", lookupuser->numlogins, lookupuser->numposts, compute_user_value(lookupuser), (lookupuser->userlevel & PERM_SUICIDE) ? " (自杀中)" : " "); printchatline(pthis, genbuf); strcpy(inbuf, ctime(&(lookupuser->lastlogin))); if ((newline = strchr(genbuf, '\n')) != NULL) *newline = '\0'; strcpy(genbuf, "当前状态:"); if (apply_utmpuid((APPLY_UTMP_FUNC) chat_status, tuid, (char *) pthis)) { char buf[1024]; lookupuser->lasthost[IPLEN-1] = '\0'; sprintf(buf, "目前正在线上: 来自 %s 上线时间 %s" /*\n" */ , (lookupuser->lasthost[0] == '\0' /* || DEFINE(getCurrentUser(),DEF_HIDEIP) */ ? "(不详)" : SHOW_USERIP(lookupuser, lookupuser->lasthost)), inbuf); /*Haohmaru.99.12.18 */ printchatline(pthis, buf); printchatline(pthis, genbuf); } else { lookupuser->lasthost[IPLEN-1] = '\0'; sprintf(genbuf, "上次上线来自 %s 时间为 %s " /*\n" */ , (lookupuser->lasthost[0] == '\0' /* || DEFINE(getCurrentUser(),DEF_HIDEIP) */ ? "(不详)" : SHOW_USERIP(lookupuser, lookupuser->lasthost)), inbuf); /* Haohmaru.99.12.18 */ printchatline(pthis, genbuf); /* 获得离线时间 Luzi 1998/10/23 */ exit_time = get_exit_time(lookupuser, genbuf); if ((newline = strchr(genbuf, '\n')) != NULL) *newline = '\0'; if (exit_time > lookupuser->lastlogin) strcpy(inbuf, genbuf); /*Haohmaru.98.12.04.和菜单查询结果一致 */ if (exit_time <= lookupuser->lastlogin) /* || (uin.active && uin.pid && (!uin.invisible || (uin.invisible && HAS_PERM(getCurrentUser(),PERM_SEECLOAK))))) */ strcpy(inbuf, "因在线上或非常断线不详"); if (exit_time <= lookupuser->lastlogin) { /* && (uin.invisible&& !HAS_PERM(getCurrentUser(),PERM_SEECLOAK))) */ temp = lookupuser->lastlogin + (lookupuser->numlogins % 7) + 5; strcpy(inbuf, ctime(&temp)); /*Haohmaru.98.12.04.让隐身用户看上去离线时间比上线时间晚5秒钟 */ if ((newline = strchr(inbuf, '\n')) != NULL) *newline = '\0'; } /* else strcpy(inbuf,"[因非常断线不详]"); */ sprintf(genbuf, "离线时间为 %s " /*\n" */ , inbuf); printchatline(pthis, genbuf); } #ifdef DEBUG if (HAS_PERM(getCurrentUser(), PERM_SYSOP)) { sprintf(genbuf, "%d", tuid); printchatline(pthis, genbuf); } #endif /* */ }
int CheckNewmail(char *name, BOOL force_chk) #endif { static long lasttime = 0; static BOOL ismail = FALSE; struct stat st; int fd; size_t numfiles; char fnameTmp[PATHLEN]; BOOL isme = 0; FILEHEADER fhGol; int i; #ifdef GUEST if (!strcmp(name, GUEST)) return FALSE; #endif if (!force_chk) isme = TRUE; setmailfile(fnameTmp, name, DIR_REC); if (stat(fnameTmp, &st) == -1) return FALSE; if (isme) { if (lasttime >= st.st_mtime) return ismail; lasttime = st.st_mtime; } numfiles = st.st_size / FH_SIZE; if (numfiles > 0) { if ((fd = open(fnameTmp, O_RDONLY)) > 0) { #if 0 time_t now = time(0), timestamp; #endif lseek(fd, (off_t) (st.st_size - FH_SIZE), SEEK_SET); i = 0; while (numfiles-- > 0 && i++ < CHK_MAIL_NUM) { read(fd, &fhGol, sizeof(fhGol)); if (!(fhGol.accessed & FILE_READ) && !(fhGol.accessed & FILE_DELE)) { close(fd); if (isme) ismail = TRUE; return TRUE; } #if 0 timestamp = atoi(fhGol.filename+2); if (timestamp && now - timestamp > (86400*14)) break; if (!isme) /* lthuang: only check the last one mail */ break; #endif lseek(fd, -((off_t) (2 * FH_SIZE)), SEEK_CUR); } close(fd); } } if (isme) ismail = FALSE; return FALSE; }
int api_mail_list(ONION_FUNC_PROTO_STR) { const char * str_startnum = onion_request_get_query(req, "startnum"); const char * str_count = onion_request_get_query(req, "count"); const char * userid = onion_request_get_query(req, "userid"); const char * appkey = onion_request_get_query(req, "appkey"); const char * sessid = onion_request_get_query(req, "sessid"); const char * box_type = onion_request_get_query(req, "box_type"); if(!userid || !appkey || !sessid) return api_error(p, req, res, API_RT_WRONGPARAM); struct userec *ue = getuser(userid); if(!ue) return api_error(p, req, res, API_RT_NOSUCHUSER); int r = check_user_session(ue, sessid, appkey); if(r != API_RT_SUCCESSFUL) { free(ue); return api_error(p, req, res, r); } int startnum = (str_startnum) ? atoi(str_startnum) : 999999; int count = (str_count) ? atoi(str_count) : 20; char mail_dir[80]; int box_type_i = (box_type != NULL && box_type[0] == '1') ? API_MAIL_SENT_BOX : API_MAIL_RECIEVE_BOX; if(box_type_i == API_MAIL_RECIEVE_BOX) setmailfile(mail_dir, ue->userid, ".DIR"); else setsentmailfile(mail_dir, ue->userid, ".DIR"); int total = file_size_s(mail_dir) / sizeof(struct fileheader); if(!total) { free(ue); return api_error(p, req, res, API_RT_MAILEMPTY); } FILE *fp = fopen(mail_dir, "r"); if(fp==0) { free(ue); return api_error(p, req, res, API_RT_MAILDIRERR); } if(startnum == 0 || startnum > total-count+1) startnum = total - count + 1; if(startnum <= 0) startnum = 1; struct fileheader x; int i; struct bmy_article mail_list[count]; memset(mail_list, 0, sizeof(struct bmy_article) * count); fseek(fp, (startnum - 1) * sizeof(struct fileheader), SEEK_SET); for(i=0; i<count; ++i) { if(fread(&x, sizeof(x), 1, fp) <= 0) break; mail_list[i].sequence_num = i + startnum; mail_list[i].mark = x.accessed; strncpy(mail_list[i].author, fh2owner(&x), sizeof(mail_list[i].author)); mail_list[i].filetime = x.filetime; g2u(x.title, strlen(x.title), mail_list[i].title, sizeof(mail_list[i].title)); } fclose(fp); char *s = bmy_mail_array_to_json_string(mail_list, count, 0, ue); api_set_json_header(res); onion_response_write0(res, s); free(s); free(ue); return OCS_PROCESSED; }
static int api_mail_get_content(ONION_FUNC_PROTO_STR, int mode) { const char * userid = onion_request_get_query(req, "userid"); const char * sessid = onion_request_get_query(req, "sessid"); const char * appkey = onion_request_get_query(req, "appkey"); const char * str_num = onion_request_get_query(req, "num"); const char * box_type = onion_request_get_query(req, "box_type"); if(!userid || !sessid || !appkey || !str_num) return api_error(p, req, res, API_RT_WRONGPARAM); struct userec * ue = getuser(userid); if(ue == 0) return api_error(p, req, res, API_RT_WRONGPARAM); if(check_user_session(ue, sessid, appkey) != API_RT_SUCCESSFUL) { free(ue); return api_error(p, req, res, API_RT_WRONGSESS); } char mail_dir[80]; struct fileheader fh; int box_type_i = (box_type != NULL && box_type[0] == '1') ? API_MAIL_SENT_BOX : API_MAIL_RECIEVE_BOX; if(box_type_i == API_MAIL_RECIEVE_BOX) setmailfile(mail_dir, ue->userid, ".DIR"); else setsentmailfile(mail_dir, ue->userid, ".DIR"); FILE *fp = fopen(mail_dir, "r"); if(fp==0) { free(ue); return api_error(p, req, res, API_RT_MAILINNERR); } int total = file_size_s(mail_dir) / sizeof(struct fileheader); int num = atoi(str_num); if(num<=0) num = 1; if(num>total) num = total; fseek(fp, (num-1)*sizeof(struct fileheader), SEEK_SET); if(fread(&fh, sizeof(fh), 1, fp) <= 0) { fclose(fp); free(ue); return api_error(p, req, res, API_RT_MAILINNERR); } fclose(fp); char title_utf[240]; g2u(fh.title, strlen(fh.title), title_utf, 240); struct attach_link *attach_link_list = NULL; char * mail_content_utf8 = parse_mail(ue->userid, fh.filetime, mode, &attach_link_list); if(!mail_content_utf8) { // 文件不存在 free(ue); free_attach_link_list(attach_link_list); return api_error(p, req, res, API_RT_MAILEMPTY); } char * mail_json_str = (char *)malloc(strlen(mail_content_utf8) + 512); if(!mail_json_str) { free(ue); free(mail_content_utf8); free_attach_link_list(attach_link_list); return api_error(p, req, res, API_RT_NOTENGMEM); } memset(mail_json_str, 0, strlen(mail_content_utf8)+512); sprintf(mail_json_str, "{\"errcode\": 0, \"attach\":[]}"); struct json_object * jp = json_tokener_parse(mail_json_str); if(!jp) { free(ue); free(mail_content_utf8); free_attach_link_list(attach_link_list); free(mail_json_str); return api_error(p, req, res, API_RT_NOTENGMEM); } json_object_object_add(jp, "content", json_object_new_string(mail_content_utf8)); json_object_object_add(jp, "title", json_object_new_string(title_utf)); if(attach_link_list) { struct json_object * attach_array = json_object_object_get(jp, "attach"); char at_buf[320]; struct attach_link * alp = attach_link_list; while(alp) { memset(at_buf, 0, 320); sprintf(at_buf, "{\"link\": \"%s\", \"size\": %d}", alp->link, alp->size); json_object_array_add(attach_array, json_tokener_parse(at_buf)); alp=alp->next; } } char * api_output = strdup(json_object_to_json_string(jp)); free(ue); free(mail_content_utf8); free_attach_link_list(attach_link_list); free(mail_json_str); json_object_put(jp); api_set_json_header(res); onion_response_write0(res, api_output); free(api_output); return OCS_PROCESSED; }
/************************************************************** * 寄信給站上使用者 **************************************************************/ 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; }
/* return total size */ int calc_mailsize(char *userid, char *dirname) { char fn[256]; int fd, total, i; struct stat buf; struct flock ldata; struct fileheader * ptr1; char * ptr; int totalsize = 0; int size=sizeof(struct fileheader); setmailfile(fn, userid, dirname); if ((fd = open(fn, O_RDWR, 0664)) == -1) { /* bbslog("user", "%s", "recopen err"); */ return 0; /* 创建文件发生错误*/ } fstat(fd, &buf); total = buf.st_size / size; if (total == 0) { close(fd); return 0; } ldata.l_type = F_RDLCK; ldata.l_whence = 0; ldata.l_len = 0; ldata.l_start = 0; fcntl(fd, F_SETLKW, &ldata); if((i=safe_mmapfile_handle(fd,PROT_READ|PROT_WRITE,MAP_SHARED, &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 ffn[256]; #ifndef FORCE_SYNC if (ptr1->eff_size > 0) { totalsize += ptr1->eff_size; ptr1++; continue; } #endif setmailfile(ffn, userid, ptr1->filename); if (lstat(ffn, &st) == -1 || !S_ISREG(st.st_mode)) ptr1->eff_size = 0; else { ptr1->eff_size = st.st_size; totalsize += ptr1->eff_size; } ptr1++; } end_mmapfile((void *) ptr, buf.st_size, -1); ldata.l_type = F_UNLCK; fcntl(fd, F_SETLKW, &ldata); close(fd); return totalsize; }
int bbsdelmail_main() { int fd; struct fileheader f; struct fileheader *fhmw, *fhw; char path[80], file[80], *ptr, list[40][20], fullpath[256]; int num, ndelfile = 0; struct stat st; int count; int wcount, wstart; int spam; struct yspam_ctx *yctx; html_header(1); //check_msg(); if (!loginok || isguest) http_fatal("您尚未登录"); changemode(RMAIL); spam=atoi(getparm("spam")); strsncpy(list[ndelfile], getparm("file"), 20); if (list[ndelfile][0] == 'M') ndelfile++; for (num = 0; num < 40 && ndelfile < 40; num++) { sprintf(file, "F%d", num); strsncpy(list[ndelfile], getparm(file), 20); if (list[ndelfile][0] == 'M' || list[ndelfile][0] == 'G') ndelfile++; } if(-2==get_mailsize(currentuser)){ errlog("strange user %s",currentuser->userid); http_fatal("邮箱内部错误! 请联系系统维护!"); } setmailfile(path, currentuser->userid, ".DIR"); fd = open(path, O_RDWR); if (fd < 0) http_fatal("错误的参数2"); flock(fd, LOCK_EX); fstat(fd, &st); if (st.st_size % sizeof (struct fileheader) != 0) { flock(fd, LOCK_UN); close(fd); return -1; } fhmw = malloc(st.st_size); if (fhmw == NULL) { flock(fd, LOCK_UN); close(fd); return -1; } fhw = fhmw; count = 0; wstart = -1; wcount = 0; yctx = yspam_init("127.0.0.1"); while (read(fd, &f, sizeof (struct fileheader)) == sizeof (struct fileheader)) { count++; ptr = fh2fname(&f); for (num = 0; num < ndelfile; num++) { if (!strcmp(ptr, list[num])) break; } if (num == ndelfile) { if (wstart == -1) continue; memcpy(fhw, &f, sizeof (struct fileheader)); wcount++; fhw++; } else { if (wstart == -1) wstart = count - 1; if (!f.filetime) continue; setmailfile(fullpath, currentuser->userid, fh2fname(&f)); update_mailsize_down(&f, currentuser->userid); if (spam && yspam_feed_spam(yctx, currentuser->userid, fh2fname(&f)) == 0) { unlink(fullpath); continue; } deltree(fullpath); } } yspam_fini(yctx); if (wstart != -1) { ftruncate(fd, (wstart + wcount) * sizeof (struct fileheader)); if (wcount > 0) { lseek(fd, wstart * sizeof (struct fileheader), SEEK_SET); write(fd, fhmw, wcount * sizeof (struct fileheader)); } } free(fhmw); flock(fd, LOCK_UN); close(fd); printf("信件已删除.<br><a href=bbsmail>返回所有信件列表</a>\n"); printf("<script>top.f4.location.reload();</script>"); http_quit(); return 0; }
/******************************************************************* * 從 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; } }