summaryrefslogtreecommitdiffstats
path: root/mbbsd/aids.c
diff options
context:
space:
mode:
authormhsin <mhsin@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-01-26 22:01:15 +0800
committermhsin <mhsin@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2008-01-26 22:01:15 +0800
commit0454427012fc548d888d7318ba78eea8e9de78fb (patch)
treea4305deddb82d34aca6161fdd97d538d01c7680a /mbbsd/aids.c
parent689674475e60a570a7ba2bf66249fdfbc8752edc (diff)
downloadpttbbs-0454427012fc548d888d7318ba78eea8e9de78fb.tar
pttbbs-0454427012fc548d888d7318ba78eea8e9de78fb.tar.gz
pttbbs-0454427012fc548d888d7318ba78eea8e9de78fb.tar.bz2
pttbbs-0454427012fc548d888d7318ba78eea8e9de78fb.tar.lz
pttbbs-0454427012fc548d888d7318ba78eea8e9de78fb.tar.xz
pttbbs-0454427012fc548d888d7318ba78eea8e9de78fb.tar.zst
pttbbs-0454427012fc548d888d7318ba78eea8e9de78fb.zip
Temporary version of aids.c
git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3872 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/aids.c')
-rw-r--r--mbbsd/aids.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/mbbsd/aids.c b/mbbsd/aids.c
new file mode 100644
index 00000000..53bca85b
--- /dev/null
+++ b/mbbsd/aids.c
@@ -0,0 +1,291 @@
+/* $Id$ */
+#include "bbs.h"
+
+#error "Not complete yet"
+
+aidu_t fn2aidu(char *fn)
+{
+ aidu_t aidu = 0;
+ aidu_t type = 0;
+ aidu_t v1 = 0;
+ aidu_t 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, aidu_t aidu)
+{
+ const char aidu2aidc_table[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_";
+ const int aidu2aidc_tablesize = sizeof(aidu2aidc_table) - 1;
+ char *sp = buf + 8;
+ aidu_t 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, aidu_t aidu)
+{
+ aidu_t type = ((aidu >> 44) & 0xf);
+ aidu_t v1 = ((aidu >> 12) & 0xffffffff);
+ aidu_t v2 = (aidu & 0xfff);
+
+ if(fn == NULL)
+ return NULL;
+ snprintf(fn, FNLEN - 1, "%c.%d.A.%03X", ((type == 0) ? 'M' : 'G'), (unsigned int)v1, (unsigned int)v2);
+ fn[FNLEN - 1] = '\0';
+ return fn;
+}
+
+aidu_t aidc2aidu(char *aidc)
+{
+ char *sp = aidc;
+ aidu_t aidu = 0;
+
+ if(aidc == NULL)
+ return 0;
+
+ while(*sp != '\0' && /* ignore trailing spaces */ *sp != ' ')
+ {
+ aidu_t 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 if(*sp == '@')
+ break;
+ else
+ return 0;
+ aidu <<= 6;
+ aidu |= (v & 0x3f);
+ sp ++;
+ }
+
+ return aidu;
+}
+
+int search_aidu_in_bfile(char *bfile, aidu_t 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;
+ if(strcmp(fhs[i].filename, fn) == 0 ||
+ ((aidu & 0xfff) == 0 && (l = strlen(fhs[i].filename)) > 6 &&
+ 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));
+}
+
+SearchAIDResult_t search_aidu_in_board(char *bname, aidu_t aidu)
+{
+ SearchAIDResult_t r = {AIDR_BOARD, -1}:
+ int n = -1;
+ char dirfile[PATHLEN];
+
+ {
+ char bf[FNLEN];
+
+ snprintf(bf, FNLEN, "%s.bottom", FN_DIR);
+ setbfile(dirfile, bname, bf);
+ if((n = search_aidu_in_bfile(dirfile, aidu)) >= 0)
+ {
+ r.where = AIDR_BOTTOM;
+ r.n = n;
+ }
+ }
+ if(r.n < 0)
+ {
+ setbfile(dirfile, bname, FN_DIR);
+ if((n = search_aidu_in_bfile(dirfile, aidu)) >= 0)
+ {
+ r.where = AIDR_BOARD;
+ r.n = n;
+ }
+ }
+ if(r.n < 0)
+ {
+ setbfile(dirfile, bname, fn_mandex);
+ if((n = search_aidu_in_bfile(dirfile, aidu)) >= 0)
+ {
+ r.where = AIDR_DIGEST;
+ r.n = n;
+ }
+ }
+ return r;
+}
+
+SearchAIDResult_t do_search_aid(void)
+{
+ SearchAIDResult_t r = {AIDR_BOARD, -1};
+ char aidc[100];
+ char bname[IDLEN + 1] = "";
+ aidu_t aidu = 0;
+ char *sp;
+ char *sp2;
+ char *emsg = NULL;
+
+ if(!getdata(b_lines, 0, "搜尋" AID_DISPLAYNAME ": #", aidc, 15 + IDLEN, LCECHO))
+ {
+ move(b_lines, 0);
+ clrtorol();
+ r.n = -1;
+ return r;
+ }
+
+ if(currstat == RMAIL)
+ {
+ move(21, 0);
+ clrtobot();
+ move(22, 0);
+ prints("此狀態下無法搜尋" AID_DISPLAYNAME);
+ pressanykey();
+ r.n = -1;
+ return r;
+ }
+
+ sp = aidc;
+ while(*sp == ' ')
+ sp ++;
+ while(*sp == '#')
+ sp ++;
+ aidu = aidc2aidu(sp);
+ if((sp2 = strchr(sp, '@')) != NULL)
+ {
+ strncpy(bname, sp2 + 1, IDLEN);
+ bname[IDLEN] = '\0';
+ *sp2 = '\0';
+ }
+ else
+ bname[0] = '\0';
+
+ if(aidu > 0)
+ {
+ if(bname[0] != '\0')
+ {
+ if(!HasBoardPerm_bn(bname))
+ return FULLUPDATE;
+ r = search_aidu_in_board(bname, aidu);
+ if(r.n >= 0)
+ {
+ if(enter_board(bname) < 0)
+ {
+ r.n = -1;
+ emsg = "錯誤:無法進入指定的看板 %s";
+ }
+ }
+ }
+ else
+ {
+ r = search_aidu_in_board(currboard, aidu);
+ }
+ }
+
+ if(r.n < 0)
+ {
+ if(aidu == 0)
+ emsg = "不合法的" AID_DISPLAYNAME ",請確定輸入是正確的";
+ else if(emsg == NULL)
+ {
+ if(bname[0] != '\0')
+ emsg = "看板 %s 內找不到這個" AID_DISPLAYNAME ",可能是文章已經消失,或是找錯看板了";
+ else
+ emsg = "找不到這個" AID_DISPLAYNAME ",可能是文章已經消失,或是找錯看板了";
+ }
+ move(21, 0);
+ clrtoeol();
+ move(22, 0);
+ prints(emsg, bname);
+ pressanykey();
+ r.n = -1;
+ return r;
+ }
+ else
+ {
+ return r;
+ }
+}