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; }
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 */ }
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; }