summaryrefslogtreecommitdiffstats
path: root/common/sys
diff options
context:
space:
mode:
authorwens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-06-13 17:45:10 +0800
committerwens <wens@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-06-13 17:45:10 +0800
commitd3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a (patch)
tree0086302d5dbe8fd2e44c13c5aed7791723529c1f /common/sys
parentf076301f829cd83641259802d5bb9ef04f527946 (diff)
downloadpttbbs-d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a.tar
pttbbs-d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a.tar.gz
pttbbs-d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a.tar.bz2
pttbbs-d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a.tar.lz
pttbbs-d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a.tar.xz
pttbbs-d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a.tar.zst
pttbbs-d3e4bc1b6c4c5bfe8b2db6706fa8e8665465421a.zip
Move BBS non-related functions to independent library
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@4350 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'common/sys')
-rw-r--r--common/sys/Makefile2
-rw-r--r--common/sys/record.c194
2 files changed, 195 insertions, 1 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;
+}