From d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a Mon Sep 17 00:00:00 2001 From: wens Date: Fri, 13 Jun 2008 09:45:10 +0000 Subject: Move BBS non-related functions to independent library git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4350 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- common/sys/Makefile | 2 +- common/sys/record.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++ include/cmsys.h | 12 ++++ include/proto.h | 11 --- mbbsd/record.c | 186 +------------------------------------------------ 5 files changed, 208 insertions(+), 197 deletions(-) create mode 100644 common/sys/record.c diff --git a/common/sys/Makefile b/common/sys/Makefile index 39598f86..e0fec71f 100644 --- a/common/sys/Makefile +++ b/common/sys/Makefile @@ -5,7 +5,7 @@ MKPIC:=no SRCROOT= ../.. .include "$(SRCROOT)/pttbbs.mk" -SRCS:= file.c lock.c log.c net.c sort.c string.c time.c crypt.c osdep.c +SRCS:= file.c lock.c log.c net.c sort.c string.c time.c crypt.c record.c osdep.c LIB:= cmsys install: diff --git a/common/sys/record.c b/common/sys/record.c new file mode 100644 index 00000000..e1b74402 --- /dev/null +++ b/common/sys/record.c @@ -0,0 +1,194 @@ +/* $Id$ */ + +#include +#include +#include +#include +#include "cmsys.h" + +#define BUFSIZE 512 + +/* Functions for fixed size record operations */ + +int +get_num_records(const char *fpath, size_t size) +{ + struct stat st; + + if (stat(fpath, &st) == -1) + return 0; + + return st.st_size / size; +} + +int +get_records_keep(const char *fpath, void *rptr, size_t size, int id, size_t number, int *fd) +{ + assert(fpath); + assert(fd); + + if (id < 1) + return -1; + + if (*fd < 0 && (*fd = open(fpath, O_RDONLY, 0)) == -1) + return -1; + + if (lseek(*fd, (off_t) (size * (id - 1)), SEEK_SET) == -1) + return 0; + + if ((id = read(*fd, rptr, size * number)) == -1) + return -1; + + return id / size; +} + +int +get_records(const char *fpath, void *rptr, size_t size, int id, size_t number) +{ + int res, fd = -1; + + res = get_records_keep(fpath, rptr, size, id, number, &fd); + close(fd); + + return res; +} + +#ifndef get_record +int +get_record(const char *fpath, void *rptr, size_t size, int id) +{ + return get_records(fpath, rptr, size, id, 1); +} +#endif + +#ifndef get_record_keep +int +get_record_keep(const char *fpath, void *rptr, size_t size, int id, int *fd) +{ + return get_records_keep(fpath, rptr, size, id, 1, fd); +} +#endif + +int +substitute_record(const char *fpath, const void *rptr, size_t size, int id) +{ + int fd; + off_t offset = size * (id - 1); + + if (id < 1 || (fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) + return -1; + + lseek(fd, offset, SEEK_SET); + PttLock(fd, offset, size, F_WRLCK); + write(fd, rptr, size); + PttLock(fd, offset, size, F_UNLCK); + close(fd); + + return 0; +} + +int +append_record(const char *fpath, const void *record, size_t size) +{ + int fd, index = -2, fsize = 0; + + if ((fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) + return -1; + + flock(fd, LOCK_EX); + + if ((fsize = lseek(fd, 0, SEEK_END)) < 0) + goto out; + + index = fsize / size; + lseek(fd, index * size, SEEK_SET); // avoid offset + + write(fd, record, size); + +out: + flock(fd, LOCK_UN); + close(fd); + + return index + 1; +} + +int +delete_records(const char *fpath, size_t size, int id, size_t num) +{ + char buf[BUFSIZE]; + int fi, fo, locksize, readsize, c, d=0; + struct stat st; + off_t offset = size * (id - 1); + + if ((fi=open(fpath, O_RDONLY, 0)) == -1) + return -1; + + if ((fo=open(fpath, O_WRONLY, 0)) == -1) { + close(fi); + return -1; + } + + if (fstat(fi, &st)==-1) { + close(fo); + close(fi); + return -1; + } + + locksize = st.st_size - offset; + readsize = locksize - size*num; + + if (locksize < 0 ) { + close(fo); + close(fi); + return -1; + } + + PttLock(fo, offset, locksize, F_WRLCK); + + if (readsize > 0) { + lseek(fi, offset+size, SEEK_SET); + lseek(fo, offset, SEEK_SET); + while (d < readsize && (c = read(fi, buf, BUFSIZE)) > 0) { + write(fo, buf, c); + d += c; + } + } + close(fi); + + ftruncate(fo, st.st_size - size*num); + + PttLock(fo, offset, locksize, F_UNLCK); + + close(fo); + + return 0; +} + +#ifndef delete_record +int delete_record(const char *fpath, size_t size, int id) +{ + return delete_records(fpath, size, id, 1); +} +#endif + +int +apply_record(const char *fpath, int (*fptr) (void *item, void *optarg), size_t size, void *arg) +{ + char buf[BUFSIZE]; + int fd; + + assert(size <= sizeof(buf)); + + if ((fd = open(fpath, O_RDONLY, 0)) == -1) + return -1; + + while (read(fd, buf, size) == size) + if ((*fptr) (buf, arg) == 1) { + close(fd); + return 1; + } + + close(fd); + + return 0; +} diff --git a/include/cmsys.h b/include/cmsys.h index 458281e9..1e866630 100644 --- a/include/cmsys.h +++ b/include/cmsys.h @@ -135,4 +135,16 @@ extern struct tm localtime4r(const time4_t *t); extern int log_filef(const char *fn, int flag, const char *fmt,...) GCC_CHECK_FORMAT(3,4); extern int log_file(const char *fn, int flag, const char *msg); +/* record.c */ +int get_num_records(const char *fpath, size_t size); +int get_records_keep(const char *fpath, void *rptr, size_t size, int id, size_t number, int *fd); +int get_records(const char *fpath, void *rptr, size_t size, int id, size_t number); +#define get_record(fpath, rptr, size, id) get_records(fpath, rptr, size, id, 1) +#define get_record_keep(fpath, rptr, size, id, fd) get_records_keep(fpath, rptr, size, id, 1, fd) +int substitute_record(const char *fpath, const void *rptr, size_t size, int id); +int append_record(const char *fpath, const void *record, size_t size); +int delete_records(const char *fpath, size_t size, int id, size_t num); +#define delete_record(fpath, size, id) delete_records(fpath, size, id, 1) +int apply_record(const char *fpath, int (*fptr) (void *item, void *optarg), size_t size, void *arg); + #endif diff --git a/include/proto.h b/include/proto.h index 70274b94..76f284b0 100644 --- a/include/proto.h +++ b/include/proto.h @@ -494,20 +494,10 @@ int Tagger(time4_t chrono, int recno, int mode); void EnumTagFhdr(fileheader_t *fhdr, char *direct, int locus); void UnTagger (int locus); /* record */ -int substitute_record(const char *fpath, const void *rptr, int size, int id); -int lock_substitute_record(const char *fpath, void *rptr, int size, int id, int); -int get_record(const char *fpath, void *rptr, int size, int id); -int get_record_keep(const char *fpath, void *rptr, int size, int id, int *fd); -int get_record_keep_seek(const char *fpath, void *rptr, int size, int id, int *fd, int toseek); -int append_record(const char *fpath, const fileheader_t *record, int size); int stampfile_u(char *fpath, fileheader_t *fh); inline int stampfile(char *fpath, fileheader_t *fh); void stampdir(char *fpath, fileheader_t *fh); -int get_num_records(const char *fpath, int size); -int get_records(const char *fpath, void *rptr, int size, int id, int number); -int get_records_fd(const char *fpath, void *rptr, int size, int id, int number, int *use_fd); void stamplink(char *fpath, fileheader_t *fh); -int delete_record(const char fpath[], int size, int id); int delete_files(const char* dirname, int (*filecheck)(), int record); void set_safedel_fhdr(fileheader_t *fhdr); #ifdef SAFE_ARTICLE_DELETE @@ -519,7 +509,6 @@ int safe_article_delete_range(const char *direct, int from, int to); #endif int delete_file(const char *dirname, int size, int ent, int (*filecheck)()); int delete_range(const char *fpath, int id1, int id2); -int apply_record(const char *fpath, int (*fptr)(void*,void*), int size,void *arg); int search_rec(const char* dirname, int (*filecheck)()); int append_record_forward(char *fpath, fileheader_t *record, int size, const char *origid); int get_sum_records(const char* fpath, int size); diff --git a/mbbsd/record.c b/mbbsd/record.c index e0b22adc..89304604 100644 --- a/mbbsd/record.c +++ b/mbbsd/record.c @@ -6,18 +6,6 @@ #define safewrite write -int -get_num_records(const char *fpath, int size) -{ - struct stat st; - if (stat(fpath, &st) == -1) - { - /* TODO: delete this entry, or mark as read */ - return 0; - } - return st.st_size / size; -} - int get_sum_records(const char *fpath, int size) { @@ -45,77 +33,6 @@ get_sum_records(const char *fpath, int size) return ans / 1024; } -int -get_record_keep(const char *fpath, void *rptr, int size, int id, int *fd) -{ - /* 和 get_record() 一樣. 不過藉由 *fd, 可使同一個檔案不要一直重複開關 */ - if (id >= 1 && - (*fd > 0 || - ((*fd = open(fpath, O_RDONLY, 0)) > 0))){ // FIXME leak if *fd==0 - if (lseek(*fd, (off_t) (size * (id - 1)), SEEK_SET) != -1) { - if (read(*fd, rptr, size) == size) { - return 0; - } - } - } - return -1; -} - -int -get_record(const char *fpath, void *rptr, int size, int id) -{ - int fd = -1; - /* TODO merge with get_records() */ - - if (id >= 1 && (fd = open(fpath, O_RDONLY, 0)) != -1) { - if (lseek(fd, (off_t) (size * (id - 1)), SEEK_SET) != -1) { - if (read(fd, rptr, size) == size) { - close(fd); - return 0; - } - } - close(fd); - } - return -1; -} - -int -get_records(const char *fpath, void *rptr, int size, int id, int number) -{ - int fd; - - if (id < 1 || (fd = open(fpath, O_RDONLY, 0)) == -1) - return -1; - - if (lseek(fd, (off_t) (size * (id - 1)), SEEK_SET) == -1) { - close(fd); - return 0; - } - if ((id = read(fd, rptr, size * number)) == -1) { - close(fd); - return -1; - } - close(fd); - return id / size; -} - -int -substitute_record(const char *fpath, const void *rptr, int size, int id) -{ - int fd; - int offset=size * (id - 1); - if (id < 1 || (fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) - return -1; - - lseek(fd, (off_t) (offset), SEEK_SET); - PttLock(fd, offset, size, F_WRLCK); - write(fd, rptr, size); - PttLock(fd, offset, size, F_UNLCK); - close(fd); - - return 0; -} - /* return index>0 if thisstamp==stamp[index], * return -index<0 if stamp[index-1]? stamp[index] * or XXX filename[index]="" @@ -212,7 +129,6 @@ force_open(const char *fname) return fd; } -#endif /* new/old/lock file processing */ typedef struct nol_t { @@ -221,7 +137,6 @@ typedef struct nol_t { char lockfn[PATHLEN]; } nol_t; -#ifndef _BBS_UTIL_C_ static void nolfilename(nol_t * n, const char *fpath) { @@ -229,60 +144,7 @@ nolfilename(nol_t * n, const char *fpath) snprintf(n->oldfn, sizeof(n->oldfn), "%s.old", fpath); snprintf(n->lockfn, sizeof(n->lockfn), "%s.lock", fpath); } -#endif - -int -delete_records(const char *fpath, int size, int id, int num) -{ - char abuf[BUFSIZE]; - int fi, fo, locksize=0, readsize=0, offset = size * (id - 1), c, d=0; - struct stat st; - - - if ((fi=open(fpath, O_RDONLY, 0)) == -1) - return -1; - - if ((fo=open(fpath, O_WRONLY, 0)) == -1) - { - close(fi); - return -1; - } - - if(fstat(fi, &st)==-1) - { close(fo); close(fi); return -1;} - - locksize = st.st_size - offset; - readsize = locksize - size*num; - if (locksize < 0 ) - { close(fo); close(fi); return -1;} - - PttLock(fo, offset, locksize, F_WRLCK); - if(readsize>0) - { - lseek(fi, offset+size, SEEK_SET); - lseek(fo, offset, SEEK_SET); - while( d0) - { - write(fo, abuf, c); - d=d+c; - } - } - close(fi); - ftruncate(fo, st.st_size - size*num); - PttLock(fo, offset, locksize, F_UNLCK); - close(fo); - return 0; - -} - -int delete_record(const char *fpath, int size, int id) -{ - return delete_records(fpath, size, id, 1); -} - - -#ifndef _BBS_UTIL_C_ #ifdef SAFE_ARTICLE_DELETE void safe_delete_range(const char *fpath, int id1, int id2) { @@ -380,7 +242,7 @@ delete_range(const char *fpath, int id1, int id2) close(fd); return dcount; } -#endif +#endif // _BBS_UTIL_C_ void set_safedel_fhdr(fileheader_t *fhdr) @@ -459,24 +321,6 @@ safe_article_delete_range(const char *direct, int from, int to) #endif -int -apply_record(const char *fpath, int (*fptr) (void *item, void *optarg), int size, void *arg){ - char abuf[BUFSIZE]; - int fp; - - if((fp=open(fpath, O_RDONLY, 0)) == -1) - return -1; - - assert(size<=sizeof(abuf)); - while (read(fp, abuf, size) == (size_t)size) - if ((*fptr) (abuf, arg) == QUIT) { - close(fp); - return QUIT; - } - close(fp); - return 0; -} - /* mail / post 時,依據時間建立檔案,加上郵戳 */ int stampfile_u(char *fpath, fileheader_t * fh) @@ -564,34 +408,6 @@ stamplink(char *fpath, fileheader_t * fh) "%2d/%02d", ptime.tm_mon + 1, ptime.tm_mday); } -int -append_record(const char *fpath, const fileheader_t * record, int size) -{ - int fd, fsize=0, index; - struct stat st; - - if ((fd = open(fpath, O_WRONLY | O_CREAT, 0644)) == -1) { - char buf[STRLEN]; - assert(errno != EISDIR); - sprintf(buf, "id(%s), open(%s)", cuser.userid, fpath); - perror(buf); - return -1; - } - flock(fd, LOCK_EX); - - if(fstat(fd, &st)!=-1) - fsize = st.st_size; - - index = fsize / size; - lseek(fd, index * size, SEEK_SET); // avoid offset - - safewrite(fd, record, size); - - flock(fd, LOCK_UN); - close(fd); - return index + 1; -} - int append_record_forward(char *fpath, fileheader_t * record, int size, const char *origid) { -- cgit v1.2.3