diff options
-rw-r--r-- | include/libbbsutil.h | 14 | ||||
-rw-r--r-- | include/osdep.h | 2 | ||||
-rw-r--r-- | include/proto.h | 10 | ||||
-rw-r--r-- | innbbsd/Makefile | 4 | ||||
-rw-r--r-- | innbbsd/str_decode.c | 6 | ||||
-rw-r--r-- | mbbsd/Makefile | 4 | ||||
-rw-r--r-- | mbbsd/file.c | 186 | ||||
-rw-r--r-- | mbbsd/register.c | 7 | ||||
-rw-r--r-- | src/libbbsutil/Makefile | 2 | ||||
-rw-r--r-- | src/libbbsutil/crypt.c (renamed from mbbsd/crypt.c) | 2 | ||||
-rw-r--r-- | src/libbbsutil/file.c | 192 | ||||
-rw-r--r-- | src/libbbsutil/string.c | 8 |
12 files changed, 221 insertions, 216 deletions
diff --git a/include/libbbsutil.h b/include/libbbsutil.h index 3acebdfc..aa892beb 100644 --- a/include/libbbsutil.h +++ b/include/libbbsutil.h @@ -30,10 +30,13 @@ typedef int32_t time4_t; typedef time_t time4_t; #endif +/* crypt.c */ +char *fcrypt(const char *key, const char *salt); + /* file.c */ extern off_t dashs(const char *fname); -time4_t dasht(const char *fname); -time4_t dashc(const char *fname); +extern time4_t dasht(const char *fname); +extern time4_t dashc(const char *fname); extern int dashl(const char *fname); extern int dashf(const char *fname); extern int dashd(const char *fname); @@ -46,6 +49,13 @@ extern int Copy(const char *src, const char *dst); extern int CopyN(const char *src, const char *dst, int n); extern int AppendTail(const char *src, const char *dst, int off); extern int Link(const char *src, const char *dst); +extern int file_count_line(const char *file); +extern int file_append_line(const char *file, const char *string); // does not append "\n" +extern int file_append_record(const char *file, const char *key); // will append "\n" +extern int file_exist_record(const char *file, const char *key); +extern int file_find_record(const char *file, const char *key); +extern int file_delete_record(const char *file, const char *key, int case_sensitive); + /* lock.c */ extern void PttLock(int fd, int start, int size, int mode); diff --git a/include/osdep.h b/include/osdep.h index 3aa93e7b..351d55af 100644 --- a/include/osdep.h +++ b/include/osdep.h @@ -16,7 +16,9 @@ #elif defined(__linux__) +#ifndef _GNU_SOURCE #define _GNU_SOURCE /* for strcasestr */ +#endif #include <sys/ioctl.h> #include <sys/file.h> /* for flock() */ #include <strings.h> /* for strcasecmp() */ diff --git a/include/proto.h b/include/proto.h index a69288f4..c51afb43 100644 --- a/include/proto.h +++ b/include/proto.h @@ -46,8 +46,6 @@ int Announce(void); void BlogMain(int); #endif -/* args */ - /* assess */ int inc_goodpost(const char *, int num); int inc_badpost(const char *, int num); @@ -284,14 +282,6 @@ int updatenewfav(int mode); void subscribe_newfav(void); void reginit_fav(void); -/* file */ -int file_count_line(const char *file); -int file_append_line(const char *file, const char *string); // does not append "\n" -int file_append_record(const char *file, const char *key); // will append "\n" -int file_exist_record(const char *file, const char *key); -int file_find_record(const char *file, const char *key); -int file_delete_record(const char *file, const char *key, int case_sensitive); - /* friend */ void friend_edit(int type); void friend_load(int); diff --git a/innbbsd/Makefile b/innbbsd/Makefile index 3365e9c8..c8021368 100644 --- a/innbbsd/Makefile +++ b/innbbsd/Makefile @@ -7,7 +7,7 @@ ADMINUSER?= root@your.domain.name # FreeBSD為了 innbbsd額外需加的參數 inn_CFLAGS_FreeBSD= -DBSD44 -DMMAP -DGETRUSAGE -inn_LDFLAGS_FreeBSD= -L/usr/local/lib -lcrypt -liconv +inn_LDFLAGS_FreeBSD= -L/usr/local/lib -liconv # Linux為了 innbbsd額外需加的參數 inn_CFLAGS_Linux= -DLINUX -DGETRUSAGE @@ -33,7 +33,7 @@ all: ${PROGS} UTIL_DIR= $(SRCROOT)/util UTIL_OBJS= \ util_cache.o util_record.o util_passwd.o util_var.o \ - util_stuff.o util_osdep.o util_args.o util_file.o + util_stuff.o util_osdep.o .for fn in ${UTIL_OBJS} LINK_UTIL_OBJS+= ${UTIL_DIR}/${fn} diff --git a/innbbsd/str_decode.c b/innbbsd/str_decode.c index 72a1f225..7a58439d 100644 --- a/innbbsd/str_decode.c +++ b/innbbsd/str_decode.c @@ -179,7 +179,7 @@ str_iconv( } /* Start translation */ while (srclen > 0 && dstlen > 0) { - iconv_ret = iconv(iconv_descriptor, (const char **)&src, &srclen, + iconv_ret = iconv(iconv_descriptor, &src, &srclen, &dst, &dstlen); if (iconv_ret != 0) { switch (errno) { @@ -260,7 +260,7 @@ str_decode_M3(unsigned char *str) if (*tmp && tmp[1] && tmp[2] == '?') { /* Thor: *tmp == '?' */ #ifdef USE_ICONV int i = mmdecode(tmp + 3, tmp[1], dst1); - i = str_iconv(charset, "big5", dst1, i, dst, + i = str_iconv((char*)charset, "big5", (char*)dst1, i, (char*)dst, sizeof(buf) - ((int)(dst - buf))); #else int i = mmdecode(tmp + 3, tmp[1], dst); @@ -287,5 +287,5 @@ str_decode_M3(unsigned char *str) } } *dst = 0; - strcpy(str, buf); + strcpy((char*)str, (char*)buf); } diff --git a/mbbsd/Makefile b/mbbsd/Makefile index 883a2200..56cc71cd 100644 --- a/mbbsd/Makefile +++ b/mbbsd/Makefile @@ -10,12 +10,12 @@ SRCROOT= .. PROG= mbbsd CHESSOBJS= chc.o chc_tab.o chess.o go.o gomo.o dark.o reversi.o GAMEOBJS = card.o guess.o chicken.o othello.o -SYSOBJS = crypt.o osdep.o +SYSOBJS = osdep.o COREOBJS = bbs.o announce.o read.o board.o cache.o brc.o mail.o record.o fav.o ACCOBJS = user.o register.o passwd.o TALKOBJS = talk.o chat.o friend.o NETOBJS = mbbsd.o io.o term.o -UTILOBJS = stuff.o file.o kaede.o convert.o name.o +UTILOBJS = stuff.o kaede.o convert.o name.o PLUGOBJS = lovepaper.o calendar.o topsong.o vice.o OBJS= admin.o assess.o cal.o edit.o menu.o more.o gamble.o \ xyz.o syspost.o vote.o var.o voteboard.o \ diff --git a/mbbsd/file.c b/mbbsd/file.c deleted file mode 100644 index 3b657acc..00000000 --- a/mbbsd/file.c +++ /dev/null @@ -1,186 +0,0 @@ -/* $Id$ */ - -#include "bbs.h" - -/** - * file.c 是針對以"行"為單位的檔案所定義的一些 operation。 - */ - -/** - * 傳回 file 檔的行數 - * @param file - */ -int file_count_line(const char *file) -{ - FILE *fp; - int count = 0; - char buf[200]; - - if ((fp = fopen(file, "r"))) { - while (fgets(buf, sizeof(buf), fp)) { - if (strchr(buf, '\n') == NULL) - continue; - count++; - } - fclose(fp); - } - return count; -} - -/** - * 將 string append 到檔案 file 後端 (不加換行) - * @param file 要被 append 的檔 - * @param string - * @return 成功傳回 0,失敗傳回 -1。 - */ -int file_append_line(const char *file, const char *string) -{ - FILE *fp; - if ((fp = fopen(file, "a")) == NULL) - return -1; - flock(fileno(fp), LOCK_EX); - fputs(string, fp); - flock(fileno(fp), LOCK_UN); - fclose(fp); - return 0; -} - -/** - * 將 "$key\n" append 到檔案 file 後端 - * @param file 要被 append 的檔 - * @param key 沒有換行的字串 - * @return 成功傳回 0,失敗傳回 -1。 - */ -int file_append_record(const char *file, const char *key) -{ - FILE *fp; - if (!key || !*key) return -1; - if ((fp = fopen(file, "a")) == NULL) - return -1; - flock(fileno(fp), LOCK_EX); - fputs(key, fp); - fputs("\n", fp); - flock(fileno(fp), LOCK_UN); - fclose(fp); - return 0; -} - -/** - * 傳回檔案 file 中 key 所在行數 - */ -int file_find_record(const char *file, const char *key) -{ - FILE *fp; - char buf[STRLEN], *ptr; - int i = 0; - - if ((fp = fopen(file, "r")) == NULL) - return 0; - - while (fgets(buf, STRLEN, fp)) { - char *strtok_pos; - i++; - if ((ptr = strtok_r(buf, str_space, &strtok_pos)) && !strcasecmp(ptr, key)) { - fclose(fp); - return i; - } - } - fclose(fp); - return 0; -} - -/** - * 傳回檔案 file 中是否有 key - */ -int file_exist_record(const char *file, const char *key) -{ - return file_find_record(file, key) > 0 ? 1 : 0; -} - -/** - * 刪除檔案 file 中以 string 開頭的行 - * @param file 要處理的檔案 - * @param string 尋找的 key name - * @param case_sensitive 是否要處理大小寫 - * @return 成功傳回 0,失敗傳回 -1。 - */ -int -file_delete_record(const char *file, const char *string, int case_sensitive) -{ - // TODO nfp 用 tmpfile() 比較好? 不過 Rename 會變慢... - FILE *fp = NULL, *nfp = NULL; - char fnew[PATHLEN]; - char buf[STRLEN + 1]; - int ret = -1, i = 0; - const size_t toklen = strlen(string); - - if (!toklen) - return 0; - - do { - snprintf(fnew, sizeof(fnew), "%s.%3.3X", file, (unsigned int)(random() & 0xFFF)); - if (access(fnew, 0) != 0) - break; - } while (i++ < 10); // max tries = 10 - - if (access(fnew, 0) == 0) return -1; // cannot create temp file. - - i = 0; - if ((fp = fopen(file, "r")) && (nfp = fopen(fnew, "w"))) { - while (fgets(buf, sizeof(buf), fp)) - { - size_t klen = strcspn(buf, str_space); - if (toklen == klen) - { - if (((case_sensitive && strncmp(buf, string, toklen) == 0) || - (!case_sensitive && strncasecmp(buf, string, toklen) == 0))) - { - // found line. skip it. - i++; - continue; - } - } - // other wise, keep the line. - fputs(buf, nfp); - } - fclose(nfp); nfp = NULL; - if (i > 0) - { - if(Rename(fnew, file) < 0) - ret = -1; - else - ret = 0; - } else { - unlink(fnew); - ret = 0; - } - } - if(fp) - fclose(fp); - if(nfp) - fclose(nfp); - return ret; -} - -/** - * 對每一筆 record 做 func 這件事。 - * @param file - * @param func 處理每筆 record 的 handler,為一 function pointer。 - * 第一個參數是檔案中的一行,第二個參數為 info。 - * @param info 一個額外的參數。 - */ -int file_foreach_entry(const char *file, int (*func)(char *, int), int info) -{ - char line[80]; - FILE *fp; - - if ((fp = fopen(file, "r")) == NULL) - return -1; - - while (fgets(line, sizeof(line), fp)) { - (*func)(line, info); - } - - fclose(fp); - return 0; -} diff --git a/mbbsd/register.c b/mbbsd/register.c index 43ade453..db0211e4 100644 --- a/mbbsd/register.c +++ b/mbbsd/register.c @@ -15,9 +15,6 @@ // Password Hash //////////////////////////////////////////////////////////////////////////// -// prototype of crypt() -char *crypt(const char *key, const char *salt); - char * genpasswd(char *pw) { @@ -37,7 +34,7 @@ genpasswd(char *pw) c += 6; saltc[i] = c; } - return crypt(pw, saltc); + return fcrypt(pw, saltc); } return ""; } @@ -50,7 +47,7 @@ checkpasswd(const char *passwd, char *plain) char *pw; ok = 0; - pw = crypt(plain, passwd); + pw = fcrypt(plain, passwd); if(pw && strcmp(pw, passwd)==0) ok = 1; memset(plain, 0, strlen(plain)); diff --git a/src/libbbsutil/Makefile b/src/libbbsutil/Makefile index 99cd6143..d5b20637 100644 --- a/src/libbbsutil/Makefile +++ b/src/libbbsutil/Makefile @@ -4,7 +4,7 @@ SRCROOT= ../.. CFLAGS+= -I$(SRCROOT)/include -OBJS= file.o lock.o log.o net.o sort.o string.o time.o +OBJS= file.o lock.o log.o net.o sort.o string.o time.o crypt.o TARGET= libbbsutil.a diff --git a/mbbsd/crypt.c b/src/libbbsutil/crypt.c index 7283c8a6..8353132a 100644 --- a/mbbsd/crypt.c +++ b/src/libbbsutil/crypt.c @@ -525,7 +525,7 @@ static unsigned const char cov_2char[64]={ #ifdef PERL5 char *des_crypt(buf,salt) #else -char *crypt(buf, salt) +char *fcrypt(buf, salt) char *buf; char *salt; diff --git a/src/libbbsutil/file.c b/src/libbbsutil/file.c index 21313283..5b891598 100644 --- a/src/libbbsutil/file.c +++ b/src/libbbsutil/file.c @@ -1,4 +1,6 @@ #include <stdio.h> +#include <stdlib.h> // random +#include <sys/file.h> // flock #include <unistd.h> #include <fcntl.h> #include <sys/types.h> @@ -97,6 +99,10 @@ dashd(const char *fname) return (stat(fname, &st) == 0 && S_ISDIR(st.st_mode)); } +/* ----------------------------------------------------- */ +/* 檔案操作函數:複製、搬移、附加 */ +/* ----------------------------------------------------- */ + #define BUFFER_SIZE 8192 int copy_file_to_file(const char *src, const char *dst) { @@ -295,3 +301,189 @@ Link(const char *src, const char *dst) return Copy(src, dst); } +/* ----------------------------------------------------- */ +/* 檔案內容處理函數:以「行」為單位 */ +/* ----------------------------------------------------- */ + +#define LINEBUFSZ (PATH_MAX) +#define STR_SPACE " \t\n\r" + + +/** + * 傳回 file 檔的行數 + * @param file + */ +int file_count_line(const char *file) +{ + FILE *fp; + int count = 0; + char buf[LINEBUFSZ]; + + if ((fp = fopen(file, "r"))) { + while (fgets(buf, sizeof(buf), fp)) { + if (strchr(buf, '\n') == NULL) + continue; + count++; + } + fclose(fp); + } + return count; +} + +/** + * 將 string append 到檔案 file 後端 (不加換行) + * @param file 要被 append 的檔 + * @param string + * @return 成功傳回 0,失敗傳回 -1。 + */ +int file_append_line(const char *file, const char *string) +{ + FILE *fp; + if ((fp = fopen(file, "a")) == NULL) + return -1; + flock(fileno(fp), LOCK_EX); + fputs(string, fp); + flock(fileno(fp), LOCK_UN); + fclose(fp); + return 0; +} + +/** + * 將 "$key\n" append 到檔案 file 後端 + * @param file 要被 append 的檔 + * @param key 沒有換行的字串 + * @return 成功傳回 0,失敗傳回 -1。 + */ +int file_append_record(const char *file, const char *key) +{ + FILE *fp; + if (!key || !*key) return -1; + if ((fp = fopen(file, "a")) == NULL) + return -1; + flock(fileno(fp), LOCK_EX); + fputs(key, fp); + fputs("\n", fp); + flock(fileno(fp), LOCK_UN); + fclose(fp); + return 0; +} + +/** + * 傳回檔案 file 中 key 所在行數 + */ +int file_find_record(const char *file, const char *key) +{ + FILE *fp; + char buf[LINEBUFSZ], *ptr; + int i = 0; + + if ((fp = fopen(file, "r")) == NULL) + return 0; + + while (fgets(buf, LINEBUFSZ, fp)) { + char *strtok_pos; + i++; + if ((ptr = strtok_r(buf, STR_SPACE, &strtok_pos)) && !strcasecmp(ptr, key)) { + fclose(fp); + return i; + } + } + fclose(fp); + return 0; +} + +/** + * 傳回檔案 file 中是否有 key + */ +int file_exist_record(const char *file, const char *key) +{ + return file_find_record(file, key) > 0 ? 1 : 0; +} + +/** + * 刪除檔案 file 中以 string 開頭的行 + * @param file 要處理的檔案 + * @param string 尋找的 key name + * @param case_sensitive 是否要處理大小寫 + * @return 成功傳回 0,失敗傳回 -1。 + */ +int +file_delete_record(const char *file, const char *string, int case_sensitive) +{ + // TODO nfp 用 tmpfile() 比較好? 不過 Rename 會變慢... + FILE *fp = NULL, *nfp = NULL; + char fnew[PATH_MAX]; + char buf[LINEBUFSZ + 1]; + int ret = -1, i = 0; + const size_t toklen = strlen(string); + + if (!toklen) + return 0; + + do { + snprintf(fnew, sizeof(fnew), "%s.%3.3X", file, (unsigned int)(random() & 0xFFF)); + if (access(fnew, 0) != 0) + break; + } while (i++ < 10); // max tries = 10 + + if (access(fnew, 0) == 0) return -1; // cannot create temp file. + + i = 0; + if ((fp = fopen(file, "r")) && (nfp = fopen(fnew, "w"))) { + while (fgets(buf, sizeof(buf), fp)) + { + size_t klen = strcspn(buf, STR_SPACE); + if (toklen == klen) + { + if (((case_sensitive && strncmp(buf, string, toklen) == 0) || + (!case_sensitive && strncasecmp(buf, string, toklen) == 0))) + { + // found line. skip it. + i++; + continue; + } + } + // other wise, keep the line. + fputs(buf, nfp); + } + fclose(nfp); nfp = NULL; + if (i > 0) + { + if(Rename(fnew, file) < 0) + ret = -1; + else + ret = 0; + } else { + unlink(fnew); + ret = 0; + } + } + if(fp) + fclose(fp); + if(nfp) + fclose(nfp); + return ret; +} + +/** + * 對每一筆 record 做 func 這件事。 + * @param file + * @param func 處理每筆 record 的 handler,為一 function pointer。 + * 第一個參數是檔案中的一行,第二個參數為 info。 + * @param info 一個額外的參數。 + */ +int file_foreach_entry(const char *file, int (*func)(char *, int), int info) +{ + char line[80]; + FILE *fp; + + if ((fp = fopen(file, "r")) == NULL) + return -1; + + while (fgets(line, sizeof(line), fp)) { + (*func)(line, info); + } + + fclose(fp); + return 0; +} diff --git a/src/libbbsutil/string.c b/src/libbbsutil/string.c index b2e7612e..37d05eeb 100644 --- a/src/libbbsutil/string.c +++ b/src/libbbsutil/string.c @@ -90,11 +90,11 @@ static const char EscapeFlag[] = { /** * 根據 mode 來 strip 字串 src,並把結果存到 dst * @param dst - * @param src + * @param src (if NULL then only return length) * @param mode enum {STRIP_ALL = 0, ONLY_COLOR, NO_RELOAD}; * STRIP_ALL: 全部吃掉 - * ONLY_COLOR: 吃掉所有跟顏色無關的 (ESC[*m) - * NO_RELOAD: 不 strip (?) + * ONLY_COLOR: 只留跟顏色有關的 (ESC[*m) + * NO_RELOAD: 只留上面認識的(移位+色彩) * @return strip 後的長度 */ int @@ -121,7 +121,7 @@ strip_ansi(char *dst, const char *src, enum STRIP_FLAG mode) (mode == ONLY_COLOR && *p == 'm' )){ register int len = p - src + 1; if( dst ){ - strncpy(dst, src, len); + memmove(dst, src, len); dst += len; } count += len; |