SEXP setOption(SEXP tag, SEXP value) { SEXP opt, old, t; t = opt = SYMVALUE(Rf_install(".Options")); if (!Rf_isList(opt)) Rf_error("corrupted options list"); opt = FindTaggedItem(opt, tag); /* The option is being removed. */ if (value == R_NilValue) { for ( ; t != R_NilValue ; t = CDR(t)) if (TAG(CDR(t)) == tag) { old = CAR(t); SETCDR(t, CDDR(t)); return old; } return R_NilValue; } /* If the option is new, a new slot */ /* is added to the end of .Options */ if (opt == R_NilValue) { while (CDR(t) != R_NilValue) t = CDR(t); PROTECT(value); SETCDR(t, Rf_allocList(1)); UNPROTECT(1); opt = CDR(t); SET_TAG(opt, tag); } old = CAR(opt); SETCAR(opt, value); return old; }
TagItem *RemoveTagItem(const fileheader_t *fh) { TagItem *tag = IsEmptyTagList() ? NULL : FindTaggedItem(fh); if (!tag) return tag; TagNum--; memmove(tag, tag + 1, (TagNum - (tag - TagList)) * sizeof(TagItem)); return tag; }
static int _iter_tag_match_title(void *ptr, void *opt) { fileheader_t *fh = (fileheader_t*) ptr; char *pattern = (char*) opt; const char *title = subject(fh->title); if (strncmp(pattern, title, TTLEN) != 0) return 0; if (FindTaggedItem(fh)) return 0; if (!AddTagItem(fh)) return -1; return 0; }
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(); }
TagItem *AddTagItem(const fileheader_t *fh) { if (TagNum == MAXTAGS) return NULL; if(TagList == NULL) { const size_t sz = sizeof(TagItem) * (MAXTAGS + 1); TagList = (TagItem*) malloc(sz); memset(TagList, 0, sz); } else { memset(TagList+TagNum, 0, sizeof(TagItem)); } // assert(!FindTaggedItem(fh)); strlcpy(TagList[TagNum++].filename, fh->filename, sizeof(fh->filename)); qsort(TagList, TagNum, sizeof(TagItem), compare_tagitem); return FindTaggedItem(fh); }
static int _iter_paste_tag(void *item, void *optarg) { char buf[PATHLEN]; char title[TTLEN + 1] = "◇ "; fileheader_t *fhdr = (fileheader_t*) item; _iter_paste_tag_param *param = (_iter_paste_tag_param*) optarg; param->item ++; // XXX many process crashed here as fhdr.filename[0] == 0 // let's workaround it? or trace? if (!fhdr->filename[0]) { grayout(0, b_lines-2, GRAYOUT_DARK); move(b_lines-1, 0); clrtobot(); prints("處理 #%d 項發生錯誤。 請把你剛剛進行的完整步驟貼到 " BN_BUGREPORT " 板。\n", param->item); vmsg("忽略錯誤並繼續進行。"); return 0; } if (!FindTaggedItem(fhdr)) return 0; if (TagBoard == 0) sethomefile(buf, cuser.userid, fhdr->filename); else { setbfile(buf, param->bh->brdname, fhdr->filename); } if (!dashf(buf)) return 0; strlcpy(title + 3, fhdr->title, sizeof(title) - 3); a_copyitem(buf, title, 0, 0); if (param->mode) { param->mode--; a_pasteitem(param->pm, 0); } else a_appenditem(param->pm, 0); param->copied++; RemoveTagItem(fhdr); return IsEmptyTagList(); }
void safe_delete_range(const char *fpath, int id1, int id2) { int fd, i; fileheader_t fhdr; char fullpath[STRLEN], *t; strlcpy(fullpath, fpath, sizeof(fullpath)); t = strrchr(fullpath, '/'); assert(t); t++; if( (fd = open(fpath, O_RDONLY)) == -1 ) return; for( i = 1 ; (read(fd, &fhdr, sizeof(fileheader_t)) == sizeof(fileheader_t)) ; ++i ){ strcpy(t, fhdr.filename); /* rocker.011018: add new tag delete */ if (!((fhdr.filemode & FILE_MARKED) || /* 標記 */ (fhdr.filemode & FILE_DIGEST) || /* 文摘 */ (id1 && (i < id1 || i > id2)) || /* range */ (!id1 && !FindTaggedItem(&fhdr)))) /* TagList */ safe_article_delete(i, &fhdr, fpath, NULL); } close(fd); }
int delete_range(const char *fpath, int id1, int id2) { fileheader_t fhdr; nol_t my; char fullpath[STRLEN], *t; int fdr, fdw, fd; int count, dcount=0; nolfilename(&my, fpath); if ((fd = OpenCreate(my.lockfn, O_RDWR | O_APPEND)) == -1) return -1; flock(fd, LOCK_EX); if ((fdr = open(fpath, O_RDONLY)) == -1) { flock(fd, LOCK_UN); close(fd); return -1; } if ( ((fdw = OpenCreate(my.newfn, O_WRONLY | O_EXCL)) == -1) && ((fdw = force_open(my.newfn)) == -1)) { close(fdr); flock(fd, LOCK_UN); close(fd); return -1; } count = 1; strlcpy(fullpath, fpath, sizeof(fullpath)); t = strrchr(fullpath, '/'); assert(t); t++; while (read(fdr, &fhdr, sizeof(fileheader_t)) == sizeof(fileheader_t)) { strcpy(t, fhdr.filename); /* rocker.011018: add new tag delete */ if ( (fhdr.filemode & FILE_MARKED) || /* 標記 */ ((fhdr.filemode & FILE_DIGEST) && (currstat != RMAIL) )|| /* 文摘 , FILE_DIGEST is used as REPLIED in mail menu.*/ (id1 && (count < id1 || count > id2)) || /* range */ (!id1 && !FindTaggedItem(&fhdr))) { /* TagList */ if ((safewrite(fdw, &fhdr, sizeof(fileheader_t)) == -1)) { close(fdr); close(fdw); unlink(my.newfn); flock(fd, LOCK_UN); close(fd); return -1; } } else { unlink(fullpath); dcount++; RemoveTagItem(&fhdr); } ++count; } close(fdr); close(fdw); if (Rename(fpath, my.oldfn) == -1 || Rename(my.newfn, fpath) == -1) { flock(fd, LOCK_UN); close(fd); return -1; } flock(fd, LOCK_UN); close(fd); return dcount; }