summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--common/sys/Makefile2
-rw-r--r--common/sys/record.c194
-rw-r--r--include/cmsys.h12
-rw-r--r--include/proto.h11
-rw-r--r--mbbsd/record.c186
5 files changed, 208 insertions, 197 deletions
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 <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#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
@@ -7,18 +7,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)
{
struct stat st;
@@ -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]<thisstamp<stamp[index+1], XXX thisstamp ?<>? 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( d<readsize && (c = read(fi, abuf, BUFSIZE))>0)
- {
- 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)
@@ -565,34 +409,6 @@ stamplink(char *fpath, fileheader_t * fh)
}
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)
{
// #ifdef USE_MAIL_AUTO_FORWARD