summaryrefslogtreecommitdiffstats
path: root/mbbsd
diff options
context:
space:
mode:
authormhsin <mhsin@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-17 16:14:27 +0800
committermhsin <mhsin@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-17 16:14:27 +0800
commitd023f75854cf77c29a1d2b52635bab90dc370fa1 (patch)
treebbdf07c2b6e1b80750f611588d433adb1e32a509 /mbbsd
parentec4a554115d214ba754951deb570742a5c0bb2e2 (diff)
downloadpttbbs-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.c50
-rw-r--r--mbbsd/read.c128
-rw-r--r--mbbsd/stuff.c154
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));
+}
+