summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2010-11-05 17:47:18 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2010-11-05 17:47:18 +0800
commitaae80fce2c6c58d993ea524a12b7a0b8286d6f67 (patch)
tree0b4a767ca75aa0dfe566bcd376630197d80c8baa
parent85fdef5e6ad85d0228b830e58beebaf756f02b42 (diff)
downloadpttbbs-aae80fce2c6c58d993ea524a12b7a0b8286d6f67.tar
pttbbs-aae80fce2c6c58d993ea524a12b7a0b8286d6f67.tar.gz
pttbbs-aae80fce2c6c58d993ea524a12b7a0b8286d6f67.tar.bz2
pttbbs-aae80fce2c6c58d993ea524a12b7a0b8286d6f67.tar.lz
pttbbs-aae80fce2c6c58d993ea524a12b7a0b8286d6f67.tar.xz
pttbbs-aae80fce2c6c58d993ea524a12b7a0b8286d6f67.tar.zst
pttbbs-aae80fce2c6c58d993ea524a12b7a0b8286d6f67.zip
add source-safe fileheaeder utility functions
git-svn-id: http://opensvn.csie.org/pttbbs/trunk@5205 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
-rw-r--r--pttbbs/common/bbs/Makefile3
-rw-r--r--pttbbs/common/bbs/fhdr_stamp.c2
-rw-r--r--pttbbs/common/bbs/filehdr.c24
-rw-r--r--pttbbs/common/bbs/passwd.c2
-rw-r--r--pttbbs/common/sys/record.c119
-rw-r--r--pttbbs/include/cmbbs.h5
-rw-r--r--pttbbs/include/cmsys.h23
7 files changed, 165 insertions, 13 deletions
diff --git a/pttbbs/common/bbs/Makefile b/pttbbs/common/bbs/Makefile
index 5e051079..a6c85f65 100644
--- a/pttbbs/common/bbs/Makefile
+++ b/pttbbs/common/bbs/Makefile
@@ -3,7 +3,8 @@
SRCROOT:= ../..
.include "$(SRCROOT)/pttbbs.mk"
-SRCS:= log.c money.c names.c path.c time.c string.c fhdr_stamp.c cache.c passwd.c
+SRCS:= log.c money.c names.c path.c time.c string.c fhdr_stamp.c cache.c \
+ passwd.c filehdr.c
LIB:= cmbbs
install:
diff --git a/pttbbs/common/bbs/fhdr_stamp.c b/pttbbs/common/bbs/fhdr_stamp.c
index 82c6a1ee..64e3429a 100644
--- a/pttbbs/common/bbs/fhdr_stamp.c
+++ b/pttbbs/common/bbs/fhdr_stamp.c
@@ -28,7 +28,7 @@ int stamplink(char *fpath, fileheader_t * fh) GCC_WEAK;
#define STAMP_DIR 1
#define STAMP_LINK 2
-/* mail / post 時,依據時間建立檔案或目錄,加上郵戳 */
+/* mail / post ɡA̾ڮɶإɮשΥؿA[WlW */
/* @param[in,out] fpath input as dirname, output as filename */
static inline int
fhdr_stamp(char *fpath, fileheader_t *fh, int type)
diff --git a/pttbbs/common/bbs/filehdr.c b/pttbbs/common/bbs/filehdr.c
new file mode 100644
index 00000000..41d4d27a
--- /dev/null
+++ b/pttbbs/common/bbs/filehdr.c
@@ -0,0 +1,24 @@
+#include <string.h>
+#include "cmsys.h"
+#include "cmbbs.h"
+
+static int
+_is_same_fhdr_filename(const void *ptr1, const void *ptr2) {
+ return strcmp(((const fileheader_t*)ptr1)->filename,
+ ((const fileheader_t*)ptr2)->filename) == 0;
+}
+
+int
+substitute_fileheader(const char *dir_path,
+ const void *srcptr, const void *destptr, int id)
+{
+ return substitute_record2(dir_path, srcptr, destptr, sizeof(fileheader_t),
+ id, _is_same_fhdr_filename);
+}
+
+int
+delete_fileheader(const char *dir_path, const void *rptr, int id)
+{
+ return delete_record2(dir_path, rptr, sizeof(fileheader_t),
+ id, _is_same_fhdr_filename);
+}
diff --git a/pttbbs/common/bbs/passwd.c b/pttbbs/common/bbs/passwd.c
index 6b80fe22..e2370386 100644
--- a/pttbbs/common/bbs/passwd.c
+++ b/pttbbs/common/bbs/passwd.c
@@ -11,9 +11,9 @@
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
+#include "cmbbs.h"
#include "common.h"
#include "var.h"
-#include "cmbbs.h"
//////////////////////////////////////////////////////////////////////////
// This is shared by utility library and core BBS,
diff --git a/pttbbs/common/sys/record.c b/pttbbs/common/sys/record.c
index ee417dac..b0badd12 100644
--- a/pttbbs/common/sys/record.c
+++ b/pttbbs/common/sys/record.c
@@ -4,6 +4,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
+#include <stdlib.h>
#include "cmsys.h"
#define BUFSIZE 512
@@ -76,7 +77,7 @@ substitute_record(const char *fpath, const void *rptr, size_t size, int id)
off_t offset = size * (id - 1);
if (id < 1 || (fd = OpenCreate(fpath, O_WRONLY)) == -1)
- return -1;
+ return -1;
lseek(fd, offset, SEEK_SET);
PttLock(fd, offset, size, F_WRLCK);
@@ -113,6 +114,119 @@ out:
}
int
+substitute_record2(const char *fpath, const void *srcptr, const void *destptr,
+ size_t size, int id, record_callback_t cb_can_substitue)
+{
+ int fd;
+ int err = 0;
+ off_t offset = size * (id - 1);
+ void *p = NULL;
+
+ if (id < 1 || (fd = OpenCreate(fpath, O_RDWR)) == -1)
+ return -1;
+ if (lseek(fd, offset, SEEK_SET) != offset ||
+ (cb_can_substitue && !(p = malloc(size)))) {
+ close(fd);
+ return -1;
+ }
+ PttLock(fd, offset, size, F_WRLCK);
+ while(cb_can_substitue) {
+ err = -1;
+ if (read(fd, p, size) != size)
+ break;
+ if (!cb_can_substitue(p, srcptr))
+ break;
+ if (lseek(fd, offset, SEEK_SET) != offset)
+ break;
+ err = 0;
+ break;
+ }
+ if (err == 0) {
+ if (write(fd, destptr, size) != size)
+ err = -1;
+ }
+ PttLock(fd, offset, size, F_UNLCK);
+ close(fd);
+ if (p) free(p);
+
+ return err;
+}
+
+int
+delete_record2(const char *fpath, const void *rptr, size_t size,
+ int id, record_callback_t cb_can_delete)
+{
+ char buf[BUFSIZE];
+ int fi = -1, fo = -1;
+ int locksize, readsize, c, d=0;
+ struct stat st;
+ off_t offset = size * (id - 1);
+ int err = 0;
+ void *p = NULL;
+ const int num = 1;
+
+ do {
+ err = -1;
+ fi = open(fpath, O_RDONLY, 0);
+ if (fi < 0)
+ break;
+ if (fstat(fi, &st) != 0)
+ break;
+ locksize = st.st_size - offset;
+ if (locksize < 0)
+ break;
+ fo = open(fpath, O_WRONLY, 0);
+ if (fo < 0)
+ break;
+ if (cb_can_delete && (p = malloc(size)) == NULL)
+ break;
+ err = 0;
+ } while (0);
+
+ if (err != 0) {
+ // clean up on error exit
+ if (fi >= 0) close(fi);
+ if (fo >= 0) close(fo);
+ return err;
+ }
+
+ readsize = locksize - size*num;
+ PttLock(fo, offset, locksize, F_WRLCK);
+
+ while (cb_can_delete) {
+ err = -1;
+ if (lseek(fi, offset, SEEK_SET) != offset)
+ break;
+ if (read(fi, p, size) != size)
+ break;
+ if (!cb_can_delete(p, rptr))
+ break;
+ err = 0;
+ break;
+ }
+ if (!cb_can_delete) {
+ if (lseek(fi, offset+size*num, SEEK_SET) != offset)
+ err = -1;
+ }
+
+ if (lseek(fo, offset, SEEK_SET) != offset)
+ err = -1;
+ while (err == 0 && d < readsize && (c = read(fi, buf, BUFSIZE)) > 0) {
+ // when entering loop, never stop even if error
+ write(fo, buf, c);
+ d += c;
+ }
+ close(fi);
+ if (err == 0)
+ ftruncate(fo, st.st_size - size*num);
+ PttLock(fo, offset, locksize, F_UNLCK);
+ close(fo);
+ if (p) free(p);
+
+ return err;
+}
+
+int
delete_records(const char *fpath, size_t size, int id, size_t num)
{
char buf[BUFSIZE];
@@ -172,7 +286,8 @@ int delete_record(const char *fpath, size_t size, int id)
#endif
int
-apply_record(const char *fpath, int (*fptr) (void *item, void *optarg), size_t size, void *arg)
+apply_record(const char *fpath, int (*fptr) (void *item, void *optarg),
+ size_t size, void *arg)
{
char buf[BUFSIZE];
int fd;
diff --git a/pttbbs/include/cmbbs.h b/pttbbs/include/cmbbs.h
index 3b501138..08278cea 100644
--- a/pttbbs/include/cmbbs.h
+++ b/pttbbs/include/cmbbs.h
@@ -99,4 +99,9 @@ extern int checkpasswd (const char *passwd, char *test); // test will be dest
extern void logattempt (const char *uid, char type, time4_t now, const char *fromhost);
extern char*genpasswd (char *pw);
+/* record */
+extern int substitute_fileheader(const char *dir_path, const void *srcptr, const void *destptr, int id);
+extern int delete_fileheader(const char *dir_path, const void *rptr, int id);
+
+
#endif
diff --git a/pttbbs/include/cmsys.h b/pttbbs/include/cmsys.h
index 78fb641d..1d129493 100644
--- a/pttbbs/include/cmsys.h
+++ b/pttbbs/include/cmsys.h
@@ -42,7 +42,7 @@ typedef time_t time4_t;
#endif
/* crypt.c */
-char *fcrypt(const char *key, const char *salt);
+extern char *fcrypt(const char *key, const char *salt);
/* daemon.c */
extern int daemonize(const char * pidfile, const char * logfile);
@@ -150,16 +150,23 @@ extern int log_filef(const char *fn, int flag, const char *fmt,...) GCC_CHECK_FO
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);
+extern int get_num_records(const char *fpath, size_t size);
+extern int get_records_keep(const char *fpath, void *rptr, size_t size, int id, size_t number, int *fd);
+extern 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);
+extern int apply_record(const char *fpath, int (*fptr) (void *item, void *optarg), size_t size, void *arg);
+extern int append_record(const char *fpath, const void *record, size_t size);
+extern int delete_records(const char *fpath, size_t size, int id, size_t num);
+extern int substitute_record(const char *fpath, const void *rptr, size_t size, int id);
#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);
+typedef int (*record_callback_t)(const void *ptr1, const void *ptr2);
+extern int substitute_record2(const char *fpath,
+ const void *srcptr, const void *destptr,
+ size_t size, int id,
+ record_callback_t cb_can_substitue);
+extern int delete_record2(const char *fpath, const void *rptr, size_t size,
+ int id, record_callback_t cb_can_substitue);
/* vector.c */
struct Vector {