diff options
author | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-03-08 00:01:56 +0800 |
---|---|---|
committer | piaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2008-03-08 00:01:56 +0800 |
commit | 1812d5521f71bf6726cd959308cb4628c5a1951c (patch) | |
tree | f61c5be32e335668ddddeca1e28459605a220b6c /mbbsd/file.c | |
parent | 80d861dff5d757ef5827054a0633fdbe56ff356a (diff) | |
download | pttbbs-1812d5521f71bf6726cd959308cb4628c5a1951c.tar pttbbs-1812d5521f71bf6726cd959308cb4628c5a1951c.tar.gz pttbbs-1812d5521f71bf6726cd959308cb4628c5a1951c.tar.bz2 pttbbs-1812d5521f71bf6726cd959308cb4628c5a1951c.tar.lz pttbbs-1812d5521f71bf6726cd959308cb4628c5a1951c.tar.xz pttbbs-1812d5521f71bf6726cd959308cb4628c5a1951c.tar.zst pttbbs-1812d5521f71bf6726cd959308cb4628c5a1951c.zip |
- register: Regform2 API prototype (for concurrent registration form validation) [not applied yet]
- file/passwd/assess: API finetune
- menu: menu item finetune
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3975 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/file.c')
-rw-r--r-- | mbbsd/file.c | 105 |
1 files changed, 100 insertions, 5 deletions
diff --git a/mbbsd/file.c b/mbbsd/file.c index 34af866a..3b657acc 100644 --- a/mbbsd/file.c +++ b/mbbsd/file.c @@ -28,7 +28,7 @@ int file_count_line(const char *file) } /** - * 將 string append 到檔案 file 後端 + * 將 string append 到檔案 file 後端 (不加換行) * @param file 要被 append 的檔 * @param string * @return 成功傳回 0,失敗傳回 -1。 @@ -46,21 +46,43 @@ int file_append_line(const char *file, const char *string) } /** - * 傳回檔案 file 中是否有 string 這個字串。 + * 將 "$key\n" append 到檔案 file 後端 + * @param file 要被 append 的檔 + * @param key 沒有換行的字串 + * @return 成功傳回 0,失敗傳回 -1。 */ -int file_exist_record(const char *file, const char *string) +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; - if ((ptr = strtok_r(buf, str_space, &strtok_pos)) && !strcasecmp(ptr, string)) { + i++; + if ((ptr = strtok_r(buf, str_space, &strtok_pos)) && !strcasecmp(ptr, key)) { fclose(fp); - return 1; + return i; } } fclose(fp); @@ -68,6 +90,79 @@ int file_exist_record(const char *file, const char *string) } /** + * 傳回檔案 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。 |