Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
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();
}
Example #5
0
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);
}
Example #6
0
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();
}
Example #7
0
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);
}
Example #8
0
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;
}