예제 #1
0
static int load_highrecord(int level,struct high_record* hr,int myrecord)
{
    int fd,ret;

    bzero(hr,sizeof(*hr));
    if (level==-1) {
    	hr->shortest=-1;
    	return 0;
    }
    if (myrecord!=-1) 
        fd=open(RECORD_FILE,O_RDWR|O_CREAT,0644);
    else
        fd=open(RECORD_FILE,O_RDONLY|O_CREAT,0644);
    	
    if (fd==-1) {
    	bbslog("3error","Box:can't open %s:%s",RECORD_FILE,strerror(errno));
    	return -1;
    }
    
    lseek(fd,sizeof(*hr)*(level-1),SEEK_SET);
    if (myrecord!=-1) 
        readw_lock(fd,0,SEEK_SET,sizeof(*hr)*MAXDATA);
    else
        readw_lock(fd,sizeof(*hr)*(level-1),SEEK_SET,sizeof(*hr));
    read(fd,hr,sizeof(*hr));
    ret=0;
    if (myrecord!=-1) {
    	if (hr->shortest>myrecord||hr->shortest<=0) {
		int i;
		int count;
		struct high_record allrecord[MAXDATA];
		count=0;
		lseek(fd,0,SEEK_SET);
		read(fd,&allrecord,sizeof(*hr)*MAXDATA);
		for (i=0;i<MAXDATA;i++) {
			if (!strcasecmp(allrecord[i].userid,getCurrentUser()->userid))
				count++;
		}
		if (count>20) 
			ret = count;
		else {
    		strcpy(hr->userid,getCurrentUser()->userid);
    		hr->shortest=myrecord;
    		lseek(fd,sizeof(*hr)*(level-1),SEEK_SET);
    		write(fd,hr,sizeof(*hr));
    		ret=1;
		}
    	}
    }
    if (myrecord!=-1) 
        un_lock(fd,0,SEEK_SET,sizeof(*hr)*MAXDATA);
    else
        un_lock(fd,sizeof(*hr)*(level-1),SEEK_SET,sizeof(*hr));
    close(fd);
    return ret;
}
예제 #2
0
char *
db_nextrec(DB *db, char *key)
{
    char    c, *ptr;

        /* We read lock the free list so that we don't read
           a record in the middle of its being deleted. */
    if (readw_lock(db->idxfd, FREE_OFF, SEEK_SET, 1) < 0)
        err_dump("readw_lock error");

    do {
            /* read next sequential index record */
        if (_db_readidx(db, 0) < 0) {
            ptr = NULL;        /* end of index file, EOF */
            goto doreturn;
        }
            /* check if key is all blank (empty record) */
        ptr = db->idxbuf;
        while ( (c = *ptr++) != 0  &&  c == ' ')
            ;    /* skip until null byte or nonblank */
    } while (c == 0);    /* loop until a nonblank key is found */

    if (key != NULL)
        strcpy(key, db->idxbuf);    /* return key */
    ptr = _db_readdat(db);    /* return pointer to data buffer */

    db->cnt_nextrec++;
doreturn:
    if (un_lock(db->idxfd, FREE_OFF, SEEK_SET, 1) < 0)
        err_dump("un_lock error");

    return(ptr);
}
/* Returning the sequential record...
Just gotta step ahead through the index file where we gotta ignore deleted records.
db_rewind() essential to be called before this function at initial stage itself */
char *db_nextrec(DB *db, char *key)
{
	char c, *ptr;
	/* Locking the free list where we don't actually read a record in the mid of deletion*/
	if(readw_lock(db->idxfd, FREE_OFF, SEEK_SET, 1) < 0)
		err_dump("error");
	do
	{
		/* read next sequential index record */
		if(_db_readidx(db, 0) < 0)
		{
			ptr = NULL; /* end of index file --- EOF */
			goto doreturn;
		}
		/* Checking if the key is still blank or empty record */
		ptr = db->idxbuf;
		while((c = *ptr++) != 0 && c = ' ');
		/* skip if it's not blank */
	}
	while(c == 0) /* loop untill a non-empty key is found*/
		if(key != NULL)
			strcpy(key, db->idxbuf); /* return key */
	ptr = _db_readdat(db); /* return pointer to data buffer */
	db->cnt_nextrec++;
doreturn:
	if(un_lock(db->idxfd, FREE_OFF, SEEK_SET, 1) < 0)
		err_dump("error");
}
/* Find specified record.
Called by db_delete(), db_fetch() and db_store() */
int _db_find(DB *db, const char *key, int writelock)
{
    off_t offset, nextoffset;
    /* calculate hash value for this key, then calculate byte offset of corresponding chain ptr in hash table.
    */
    /* calculate offset in hash table for this key */
    db->chainoff = (_db_hash(db, key) * PTR_SZ) + db->hashoff;
    db->ptroff = db->chainoff;
    /* here's where we lock this hash chain. It's the caller responsibility to unlock it when done.
    Note that we lock and unlock only the first byte. */
    if(writelock)
    {
        if(writew_lock(db->idxfd, db->chainoff, SEEK_SET, 1) < 0)
            err_dump("error");
    }
    else
    {
        if(readw_lock(db->idxfd, db->chainoff, SEEK_SET, 1) < 0)
            err_dump("error");
    }
    /* Get the offset in the index file of first record on the bash chain (it can be 0 too) */
    offset = _db_readptr(db, db->ptroff);
    while(offset!=0)
    {
        nextoffset = _db_readidx(db, offset);
        if(strcmp(db->idxbuf, key) == 0)
            break; /* found a match */
        db->ptroff = offset; /* offset of this (unequal) record */
        offset = nextoffset; /* next one to compare */
    }
    if(offset == 0)
        return(-1); /* error -- record not found */
    return(0); /* if not error */
}
예제 #5
0
static char * get_file_info(char *boardname, int threadid, char *title, char *userid, char *filename, int pic)
{

    char dirfile[256];
    int fd;
    struct fileheader fh;

    setbdir(DIR_MODE_NORMAL, dirfile, boardname);
    if ((fd = open(dirfile, O_RDWR, 0644)) < 0)
        return NULL;

    if (get_records_from_id(fd, threadid, &fh, 1, NULL) == 0) {
        close(fd);
        return NULL;
    }
    close(fd);

#ifdef NEWSMTH
    // pig2532 Feb 2008: ignore topic with FEN flag in top10
    if (fh.accessed[1] & FILE_FEN) {
        printf("skip:%s/%d/%s/%s\n", boardname, fh.id, fh.owner, fh.title);
        return NULL;
    }
#endif /* NEWSMTH */

    if (pic) {
        if (!fh.attachment) {
            return NULL;
        } else {
            // 读取楼主的第一个附件,判断是否为图片,是则输出该图以备缩略之用,否则返回NULL
            char fn[PATHLEN];
            int fd_pic;
            char *src, *dst, *dot;
            off_t size_src, size_dst;
            char *aname, *start;
            long asize;

            setbfile(fn, boardname, fh.filename);
            if ((fd = open(fn, O_RDONLY)) == -1)
                return NULL;
            if (readw_lock(fd, 0, SEEK_SET, 0) == -1) {
                close(fd);
                return NULL;
            }
            if (safe_mmapfile_handle(fd, PROT_READ, MAP_PRIVATE, &src, &size_src) == 0) {
                un_lock(fd, 0, SEEK_SET, 0);
                close(fd);
                return NULL;
            }
            if (!(aname = checkattach(src + fh.attachment, size_src - fh.attachment, &asize, &start)))
                return NULL;

            dot = strrchr(aname, '.');
            // 是否图片?
            if (get_attachment_type_from_ext(dot) != ATTACH_IMG) {
                end_mmapfile(src, size_src, -1);
                un_lock(fd, 0, SEEK_SET, 0);
                close(fd);
                return NULL;
            }
            sprintf(fn, "hotpic/%s_%d", boardname, threadid);
            if ((fd_pic = open(fn, O_RDWR | O_CREAT, 0600)) == -1) {
                end_mmapfile(src, size_src, -1);
                un_lock(fd, 0, SEEK_SET, 0);
                close(fd);
                return NULL;
            }
            ftruncate(fd_pic, asize);
            if (safe_mmapfile_handle(fd_pic, PROT_WRITE, MAP_SHARED, &dst, &size_dst) == 0) {
                close(fd_pic);
                un_lock(fd, 0, SEEK_SET, 0);
                close(fd);
                return NULL;
            }
            printf("HOTPIC: %s_%d\n", boardname, threadid);
            memcpy(dst, start, asize);
            end_mmapfile(dst, size_dst, -1);
            end_mmapfile(src, size_src, -1);
            close(fd_pic);
            un_lock(fd, 0, SEEK_SET, 0);
            close(fd);
        }
    }

    strncpy(title, fh.title, 80);
    title[80]=0;

    strncpy(userid, fh.owner, IDLEN);
    userid[IDLEN]='\0';

    strncpy(filename, fh.filename, FILENAME_LEN);
    filename[FILENAME_LEN]='\0';

    return title;
}