diff options
author | mhsin <mhsin@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2007-12-17 16:14:27 +0800 |
---|---|---|
committer | mhsin <mhsin@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2007-12-17 16:14:27 +0800 |
commit | d023f75854cf77c29a1d2b52635bab90dc370fa1 (patch) | |
tree | bbdf07c2b6e1b80750f611588d433adb1e32a509 /mbbsd | |
parent | ec4a554115d214ba754951deb570742a5c0bb2e2 (diff) | |
download | pttbbs-d023f75854cf77c29a1d2b52635bab90dc370fa1.tar pttbbs-d023f75854cf77c29a1d2b52635bab90dc370fa1.tar.gz pttbbs-d023f75854cf77c29a1d2b52635bab90dc370fa1.tar.bz2 pttbbs-d023f75854cf77c29a1d2b52635bab90dc370fa1.tar.lz pttbbs-d023f75854cf77c29a1d2b52635bab90dc370fa1.tar.xz pttbbs-d023f75854cf77c29a1d2b52635bab90dc370fa1.tar.zst pttbbs-d023f75854cf77c29a1d2b52635bab90dc370fa1.zip |
* Add Article IDentification System(AIDS)
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3700 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd')
-rw-r--r-- | mbbsd/bbs.c | 50 | ||||
-rw-r--r-- | mbbsd/read.c | 128 | ||||
-rw-r--r-- | mbbsd/stuff.c | 154 |
3 files changed, 324 insertions, 8 deletions
diff --git a/mbbsd/bbs.c b/mbbsd/bbs.c index 44415c46..8056ae55 100644 --- a/mbbsd/bbs.c +++ b/mbbsd/bbs.c @@ -3108,30 +3108,64 @@ lock_post(int ent, fileheader_t * fhdr, const char *direct) } static int -view_postmoney(int ent, const fileheader_t * fhdr, const char *direct) +view_postinfo(int ent, const fileheader_t * fhdr, const char *direct) { + unsigned long aidu = 0; + + if(fhdr->filename[0] == '.') + return DONOTHING; + + move(17, 0); + clrtobot(); + prints("-------------------------------------------------------------------------------\n"); + prints("\n%7d", ent); + prints(" %-13.12s", fhdr->owner); + prints(" %s\n\n", fhdr->title); + + aidu = fn2aidu(fhdr->filename); + if(aidu > 0) + { + char aidc[10]; + + aidu2aidc(aidc, aidu); +#ifdef DEBUG + prints(" fn: %s\n", fhdr->filename); + prints("AIDu: %012lX\n", aidu); + prints("AIDc: %s\n", aidc); +#endif + prints(" 此篇文章的" AID_DISPLAYNAME "為: " ANSI_COLOR(1) "#%s" ANSI_RESET "\n", aidc); + } + else + { + prints("\n"); + } + if(fhdr->filemode & FILE_ANONYMOUS) /* When the file is anonymous posted, fhdr->multi.anon_uid is author. * see do_general() */ - vmsgf("匿名管理編號: %d (同一人號碼會一樣)", - fhdr->multi.anon_uid + (int)currutmp->pid); + prints(" 匿名管理編號: %d (同一人號碼會一樣)", + fhdr->multi.anon_uid + (int)currutmp->pid); else { int m = query_file_money(fhdr); if(m < 0) - m = vmsgf("特殊文章,無價格記錄。"); + prints(" 特殊文章,無價格記錄。"); else - m = vmsgf("這一篇文章值 %d 銀", m); + prints(" 這一篇文章值 %d 銀", m); + } + { + int r = pressanykey(); + /* TODO: 多加一個 LISTMODE_AID? */ /* QQ: enable money listing mode */ - if (m == 'Q') + if (r == 'Q') { currlistmode = (currlistmode == LISTMODE_MONEY) ? LISTMODE_DATE : LISTMODE_MONEY; vmsg((currlistmode == LISTMODE_MONEY) ? "開啟文章價格列表模式" : "停止列出文章價格"); } - } + } return FULLUPDATE; } @@ -3573,7 +3607,7 @@ const onekey_t read_comms[] = { { 0, NULL }, // 'N' { 0, b_moved_to_config }, // 'O' { 0, NULL }, // 'P' - { 1, view_postmoney }, // 'Q' + { 1, view_postinfo }, // 'Q' { 0, b_results }, // 'R' { 0, NULL }, // 'S' { 1, edit_title }, // 'T' diff --git a/mbbsd/read.c b/mbbsd/read.c index 9137d304..883f75d5 100644 --- a/mbbsd/read.c +++ b/mbbsd/read.c @@ -677,6 +677,8 @@ select_read(const keeploc_t * locmem, int sr_mode) return READ_REDRAW; } +static int newdirect_new_ln = -1; + static int i_read_key(const onekey_t * rcmdlist, keeploc_t * locmem, int bid, int bottom_line) @@ -726,6 +728,127 @@ i_read_key(const onekey_t * rcmdlist, keeploc_t * locmem, mode = (currmode & MODE_DIGEST) ? board_digest() : DOQUIT; break; + case '#': + { + char aidc[100]; + unsigned long aidu = 0; + char dirfile[PATHLEN]; + char *sp; + int n = -1; + + if(!getdata(b_lines, 0, "搜尋" AID_DISPLAYNAME ": #", aidc, 20, LCECHO)) + { + move(b_lines, 0); + clrtoeol(); + mode = FULLUPDATE; + break; + } + + if((currmode & MODE_SELECT) || + (currstat == RMAIL)) + { + move(21, 0); + clrtobot(); + move(22, 0); + prints("此狀態下無法使用搜尋" AID_DISPLAYNAME "功\能"); + pressanykey(); + mode = FULLUPDATE; + break; + } + + /* strip leading spaces and '#' */ + sp = aidc; + while(*sp == ' ') + sp ++; + if(*sp == '#') + sp ++; + + if((aidu = aidc2aidu(sp)) > 0) + { + /* search bottom */ + /* FIXME: 置底文但沒列在 .DIR.bottom 的在這段會搜不到, + 在下一段 search board 時才會搜到本體。難解。 */ + { + char buf[FNLEN]; + + snprintf(buf, FNLEN, "%s.bottom", FN_DIR); + setbfile(dirfile, currboard, buf); + if((n = search_aidu(dirfile, aidu)) >= 0) + { + n += getbtotal(currbid); + /* 不可用 bottom_line,因為如果是在 digest mode, + bottom_line 會是文摘的數目,而不是真正的文章數 */ + if(currmode & MODE_DIGEST) + { + newdirect_new_ln = n; + + new_ln = locmem->crs_ln; + /* dirty hack for crs_ln = 1, then HOME pressed */ + + default_ch = KEY_TAB; + mode = DONOTHING; + break; + } + } + } + if(n < 0) + /* search board */ + { + setbfile(dirfile, currboard, FN_DIR); + n = search_aidu(dirfile, aidu); + if(n >= 0 && (currmode & MODE_DIGEST)) + /* switch to normal read mode */ + { + newdirect_new_ln = n; + + new_ln = locmem->crs_ln; + /* dirty hack for crs_ln = 1, then HOME pressed */ + + default_ch = KEY_TAB; + mode = DONOTHING; + break; + } + } + if(n < 0) + /* search digest */ + { + setbfile(dirfile, currboard, fn_mandex); + n = search_aidu(dirfile, aidu); + if(n >= 0 && !(currmode & MODE_DIGEST)) + /* switch to digest mode */ + { + newdirect_new_ln = n; + + new_ln = locmem->crs_ln; + /* dirty hack for crs_ln = 1, then HOME pressed */ + + default_ch = KEY_TAB; + mode = DONOTHING; + break; + } + } + } /* if(aidu > 0) */ + if(n < 0) + { + move(21, 0); + clrtobot(); + move(22, 0); + if(aidu <= 0) + prints("不合法的" AID_DISPLAYNAME ",請確定輸入是正確的"); + else + prints("找不到這個" AID_DISPLAYNAME ",可能是文章已消失,或是你找錯看板了"); + pressanykey(); + mode = FULLUPDATE; + } /* if(n < 0) */ + else + { + new_ln = n + 1; + move(b_lines, 0); + clrtoeol(); + mode = DONOTHING; + } + } + break; case Ctrl('L'): redoscr(); break; @@ -1082,6 +1205,11 @@ i_read(int cmdmode, const char *direct, void (*dotitle) (), int num; num = last_line - p_lines + 1; locmem = getkeep(currdirect, num < 1 ? 1 : num, last_line); + if(newdirect_new_ln >= 0) + { + locmem->crs_ln = newdirect_new_ln + 1; + newdirect_new_ln = -1; + } } recbase = -1; /* no break */ diff --git a/mbbsd/stuff.c b/mbbsd/stuff.c index fa4c424a..af55ca01 100644 --- a/mbbsd/stuff.c +++ b/mbbsd/stuff.c @@ -663,3 +663,157 @@ uintbsearch(const unsigned int key, const unsigned int *base0, const int nmemb) return (NULL); } +unsigned long fn2aidu(char *fn) +{ + unsigned long aidu = 0; + unsigned long type = 0; + unsigned long v1 = 0; + unsigned long v2 = 0; + char *sp = fn; + + if(fn == NULL) + return 0; + + switch(*(sp ++)) + { + case 'M': + type = 0; + break; + case 'G': + type = 1; + break; + default: + return 0; + break; + } + + if(*(sp ++) != '.') + return 0; + v1 = strtoul(sp, &sp, 10); + if(sp == NULL) + return 0; + if(*sp != '.' || *(sp + 1) != 'A') + return 0; + sp += 2; + if(*(sp ++) == '.') + { + v2 = strtoul(sp, &sp, 16); + if(sp == NULL) + return 0; + } + aidu = ((type & 0xf) << 44) | ((v1 & 0xffffffff) << 12) | (v2 & 0xfff); + + return aidu; +} + +/* IMPORTANT: + * size of buf must be at least 8+1 bytes + */ +char *aidu2aidc(char *buf, unsigned long aidu) +{ + const char aidu2aidc_table[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_"; + const int aidu2aidc_tablesize = sizeof(aidu2aidc_table) - 1; + char *sp = buf + 8; + unsigned long v; + + *(sp --) = '\0'; + while(sp >= buf) + { + /* FIXME: 能保證 aidu2aidc_tablesize 是 2 的冪次的話, + 這裡可以改用 bitwise operation 做 */ + v = aidu % aidu2aidc_tablesize; + aidu = aidu / aidu2aidc_tablesize; + *(sp --) = aidu2aidc_table[v]; + } + return buf; +} + +/* IMPORTANT: + * size of fn must be at least FNLEN bytes + */ +char *aidu2fn(char *fn, unsigned long aidu) +{ + unsigned long type = ((aidu >> 44) & 0xf); + unsigned long v1 = ((aidu >> 12) & 0xffffffff); + unsigned long v2 = (aidu & 0xfff); + + if(fn == NULL) + return NULL; + snprintf(fn, FNLEN - 1, "%c.%ld.A.%03lX", ((type == 0) ? 'M' : 'G'), v1, v2); + fn[FNLEN - 1] = '\0'; + return fn; +} + +unsigned long aidc2aidu(char *aidc) +{ + char *sp = aidc; + unsigned long aidu = 0; + + if(aidc == NULL) + return 0; + + while(*sp != '\0' && /* ignore trailing spaces */ *sp != ' ') + { + unsigned long v = 0; + /* FIXME: 查表法會不會比較快? */ + if(*sp >= '0' && *sp <= '9') + v = *sp - '0'; + else if(*sp >= 'A' && *sp <= 'Z') + v = *sp - 'A' + 10; + else if(*sp >= 'a' && *sp <= 'z') + v = *sp - 'a' + 36; + else if(*sp == '-') + v = 62; + else if(*sp == '_') + v = 63; + else + return 0; + aidu <<= 6; + aidu |= (v & 0x3f); + sp ++; + } + + return aidu; +} + +int search_aidu(char *bfile, unsigned long aidu) +{ + char fn[FNLEN]; + int fd; + fileheader_t fhs[64]; + int len, i; + int pos = 0; + int found = 0; + int lastpos = 0; + + if(aidu2fn(fn, aidu) == NULL) + return -1; + if((fd = open(bfile, O_RDONLY, 0)) < 0) + return -1; + + while(!found && (len = read(fd, fhs, sizeof(fhs))) > 0) + { + len /= sizeof(fileheader_t); + for(i = 0; i < len; i ++) + { + int l = strlen(fhs[i].filename); + if(strncmp(fhs[i].filename, fn, l) == 0) + { + if(fhs[i].filemode & FILE_BOTTOM) + { + lastpos = pos; + } + else + { + found = 1; + break; + } + } + pos ++; + } + } + close(fd); + + return (found ? pos : (lastpos ? lastpos : -1)); +} + |