static int _iter_delete_tagged(void *ptr, void *opt) { fileheader_t *fh = (fileheader_t*) ptr; const char *direct = (const char*)opt; if ((fh->filemode & FILE_MARKED) || (fh->filemode & FILE_DIGEST)) return 0; if (!FindTaggedItem(fh)) return 0; // only called by home or board, no need for man. // so backup_direct can be same as direct. delete_file_content(direct, fh, direct, NULL, 0); return IsEmptyTagList(); }
static void a_delete(menu_t * pm, const char *backup_dir) { char fpath[PATHLEN], buf[PATHLEN], cmd[PATHLEN]; char ans[4]; fileheader_t backup, *fhdr = &(pm->header[pm->now - pm->page]); const char *msg_errsync = "刪除檔案失敗,請退回上層目錄後再重試一次", *msg_errsync2 = "檔案可能已被它人刪除,請退回上層目錄再重進確認", *msg_errbackup = "檔案已刪除但無法備份。請至 " BN_BUGREPORT "報告您試圖刪除檔案的位置。"; snprintf(fpath, sizeof(fpath), "%s/%s", pm->path, fhdr->filename); setadir(buf, pm->path); if (fhdr->filename[0] == 'H' && fhdr->filename[1] == '.') { getdata(b_lines - 1, 1, "您確定要刪除此精華區連線嗎(Y/N)?[N] ", ans, sizeof(ans), LCECHO); if (ans[0] != 'y') return; if (delete_fileheader(buf, fhdr, pm->now + 1) == -1) { vmsg(msg_errsync); return; } } else if (dashl(fpath)) { getdata(b_lines - 1, 1, "您確定要刪除此 symbolic link 嗎(Y/N)?[N] ", ans, sizeof(ans), LCECHO); if (ans[0] != 'y') return; if (delete_fileheader(buf, fhdr, pm->now + 1) == -1) { vmsg(msg_errsync); return; } unlink(fpath); } else if (dashf(fpath)) { getdata(b_lines - 1, 1, "您確定要刪除此檔案嗎(Y/N)?[N] ", ans, sizeof(ans), LCECHO); if (ans[0] != 'y') return; if (delete_fileheader(buf, fhdr, pm->now + 1) == -1) { vmsg(msg_errsync); return; } switch(delete_file_content(buf, fhdr, backup_dir, NULL, 0)) { case DELETE_FILE_CONTENT_BACKUP_FAILED: vmsg(msg_errbackup); break; case DELETE_FILE_CONTENT_FAILED: vmsg(msg_errsync2); break; default: #ifndef USE_TIME_CAPSULE // When not using time capsule, .DIR content may be changed in // board (BN_DELETE/BN_JUNK) and need to be changed. However // since that's going to be deprecated in future, let's have a // simple workaround here. if (backup_dir) { const char *bn = NULL; if (strstr(backup_dir, "/" BN_JUNK "/")) bn = BN_JUNK; else if (strstr(backup_dir, "/" BN_DELETED "/")) bn = BN_DELETED; if (bn) setbtotal(getbnum(bn)); } #endif break; } } else if (dashd(fpath)) { // TODO(hungte) We should create a top level folder and move everything // inside. // XXX we also check PERM_MAILLIMIT here because RMAIL // may be not trusted... const char *save_bn = ( HasUserPerm(PERM_MAILLIMIT) && (currstat & RMAIL) ) ? BN_JUNK : BN_DELETED; getdata(b_lines - 1, 1, "您確定要刪除整個目錄嗎(Y/N)?[N] ", ans, sizeof(ans), LCECHO); if (ans[0] != 'y') return; if (delete_fileheader(buf, fhdr, pm->now + 1) == -1) { vmsg(msg_errsync); return; } setapath(buf, save_bn); // XXX because this directory will hold folders from entire site, // let's allow it to use a large set of file names. if (stampadir(buf, &backup, 1) != 0) { vmsg("抱歉,系統目前無法刪除資料,請通知站務人員"); return; } snprintf(cmd, sizeof(cmd), "rm -rf %s;/bin/mv -f %s %s", buf, fpath, buf); system(cmd); strlcpy(backup.owner, cuser.userid, sizeof(backup.owner)); strcpy(backup.title, "◆"); strlcpy(backup.title + 2, fhdr->title + 2, sizeof(backup.title) - 3); // restrict access if source is hidden if ((fhdr->filemode & FILE_BM) || (fhdr->filemode & FILE_HIDE)) backup.filemode |= FILE_BM; /* merge setapath(buf, save_bn); setadir(buf, buf); */ snprintf(buf, sizeof(buf), "man/boards/%c/%s/" FN_DIR, *save_bn, save_bn); append_record(buf, &backup, sizeof(backup)); } else { /* Ptt 損毀的項目 */ getdata(b_lines - 1, 1, "您確定要刪除此損毀的項目嗎(Y/N)?[N] ", ans, sizeof(ans), LCECHO); if (ans[0] != 'y') return; if (delete_fileheader(buf, fhdr, pm->now + 1) == -1) return; } pm->num--; }