summaryrefslogtreecommitdiffstats
path: root/mbbsd/read.c
diff options
context:
space:
mode:
authorjack <jack@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2004-05-03 05:58:08 +0800
committerjack <jack@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2004-05-03 05:58:08 +0800
commite443776eb7025c569df22f801965f0ec84798e35 (patch)
treea6200d5ccc57109dfece0b30180da83a9915785c /mbbsd/read.c
parent886fd091d3cc9e39e342e13e994fb63acb30c34b (diff)
downloadpttbbs-e443776eb7025c569df22f801965f0ec84798e35.tar
pttbbs-e443776eb7025c569df22f801965f0ec84798e35.tar.gz
pttbbs-e443776eb7025c569df22f801965f0ec84798e35.tar.bz2
pttbbs-e443776eb7025c569df22f801965f0ec84798e35.tar.lz
pttbbs-e443776eb7025c569df22f801965f0ec84798e35.tar.xz
pttbbs-e443776eb7025c569df22f801965f0ec84798e35.tar.zst
pttbbs-e443776eb7025c569df22f801965f0ec84798e35.zip
merge trunk to branches and corrected confliction
git-svn-id: http://opensvn.csie.org/pttbbs/branches/Jaky.i18n@1919 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/read.c')
-rw-r--r--mbbsd/read.c1063
1 files changed, 445 insertions, 618 deletions
diff --git a/mbbsd/read.c b/mbbsd/read.c
index 2456fdda..c2c33111 100644
--- a/mbbsd/read.c
+++ b/mbbsd/read.c
@@ -3,7 +3,6 @@
static fileheader_t *headers = NULL;
static int last_line; // PTT: last_line 游標可指的最後一個
-static int hit_thread;
#include <sys/mman.h>
@@ -95,7 +94,7 @@ AskTag(char *msg)
num = TagNum;
snprintf(buf, sizeof(buf), "◆ %s A)文章 T)標記 Q)uit?", msg);
- switch (rget(b_lines - 1, buf)) {
+ switch (getans(buf)) {
case 'q':
num = -1;
break;
@@ -172,7 +171,7 @@ TagPruner(int bid)
if (getans("刪除所有標記[N]?") != 'y')
return READ_REDRAW;
#ifdef SAFE_ARTICLE_DELETE
- if(bp && bp->nuser>20)
+ if(bp && !(currmode & MODE_DIGEST) && bp->nuser>20 )
safe_delete_range(currdirect, 0, 0);
else
#endif
@@ -230,211 +229,77 @@ fixkeep(char *s, int first)
/* calc cursor pos and show cursor correctly */
static int
-cursor_pos(keeploc_t * locmem, int val, int from_top)
+cursor_pos(keeploc_t * locmem, int val, int from_top, int isshow)
{
- int top;
-
- if (val > last_line) {
- bell();
+ int top=locmem->top_ln;
+ if (!last_line){
+ cursor_show(3 , 0);
+ return DONOTHING;
+ }
+ if (val > last_line){
+ bell();
val = last_line;
}
- if (val <= 0) {
- bell();
+ if (val <= 0){
+ bell();
val = 1;
}
- top = locmem->top_ln;
if (val >= top && val < top + p_lines) {
- cursor_clear(3 + locmem->crs_ln - top, 0);
+ if(isshow){
+ cursor_clear(3 + locmem->crs_ln - top, 0);
+ cursor_show(3 + val - top, 0);
+ }
locmem->crs_ln = val;
- cursor_show(3 + val - top, 0);
return DONOTHING;
}
locmem->top_ln = val - from_top;
if (locmem->top_ln <= 0)
locmem->top_ln = 1;
locmem->crs_ln = val;
- return PARTUPDATE;
-}
-
-static int
-move_cursor_line(keeploc_t * locmem, int mode)
-{
- int top, crs;
- int reload = 0;
-
- top = locmem->top_ln;
- crs = locmem->crs_ln;
- if (mode == READ_PREV) {
- if (crs <= top) {
- top -= p_lines - 1;
- if (top < 1)
- top = 1;
- reload = 1;
- }
- if (--crs < 1) {
- crs = 1;
- reload = -1;
- }
- } else if (mode == READ_NEXT) {
- if (crs >= top + p_lines - 1) {
- top += p_lines - 1;
- reload = 1;
- }
- if (++crs > last_line) {
- crs = last_line;
- reload = -1;
- }
- }
- locmem->top_ln = top;
- locmem->crs_ln = crs;
- return reload;
+ return isshow ? PARTUPDATE : HEADERS_RELOAD;
}
static int
-thread(keeploc_t * locmem, int stype)
+thread(keeploc_t * locmem, int stypen)
{
- static char a_ans[32], t_ans[32];
- char ans[32], s_pmt[64];
- register char *tag, *query = NULL;
- register int now, pos, match, near = 0;
- fileheader_t fh;
- int circulate_flag = 1; /* circulate at end or begin */
- int fd = -1;
-
- match = hit_thread = 0;
- now = pos = locmem->crs_ln;
- if (stype == 'A') {
- if (!*currowner)
- return DONOTHING;
- str_lower(a_ans, currowner);
- query = a_ans;
- circulate_flag = 0;
- stype = 0;
- } else if (stype == 'a') {
- if (!*currowner)
- return DONOTHING;
- str_lower(a_ans, currowner);
- query = a_ans;
- circulate_flag = 0;
- stype = RS_FORWARD;
- } else if (stype == '/') {
- if (!*t_ans)
- return DONOTHING;
- query = t_ans;
- circulate_flag = 0;
- stype = RS_TITLE | RS_FORWARD;
- } else if (stype == '?') {
- if (!*t_ans)
- return DONOTHING;
- circulate_flag = 0;
- query = t_ans;
- stype = RS_TITLE;
- } else if (stype & RS_RELATED) {
- tag = headers[pos - locmem->top_ln].title;
- if (stype & RS_CURRENT) {
- if (stype & RS_FIRST) {
- if (!strncmp(currtitle, tag, TTLEN))
- return DONOTHING;
- near = 0;
- }
- query = currtitle;
- } else {
- query = subject(tag);
- if (stype & RS_FIRST) {
- if (query == tag)
- return DONOTHING;
- near = 0;
- }
- }
- } else if (!(stype & RS_THREAD)) {
- query = (stype & RS_TITLE) ? t_ans : a_ans;
- if (!*query && query == a_ans) {
- if (*currowner)
- strlcpy(a_ans, currowner, sizeof(a_ans));
- else if (*currauthor)
- strlcpy(a_ans, currauthor, sizeof(a_ans));
- }
- snprintf(s_pmt, sizeof(s_pmt),
- "%s搜尋%s [%s] ", (stype & RS_FORWARD) ? "往後" : "往前",
- (stype & RS_TITLE) ? "標題" : "作者", query);
- getdata(b_lines - 1, 0, s_pmt, ans, sizeof(ans), DOECHO);
- if (*ans)
- strcpy(query, ans);
- else if (*query == '\0')
- return DONOTHING;
- }
- tag = fh.owner;
-
- do {
- if (!circulate_flag || stype & RS_RELATED) {
- if (stype & RS_FORWARD) {
- if (++now > last_line){
- if( fd != -1 )
- close(fd);
- return DONOTHING;
- }
- } else {
- if (--now <= 0 || now < pos - 200) {
- if( fd )
- close(fd);
- if ((stype & RS_FIRST) && (near)) {
- hit_thread = 1;
- return cursor_pos(locmem, near, 10);
- }
- return DONOTHING;
- }
+ fileheader_t fh;
+ int pos = locmem->crs_ln, jump = 200, new_ln;
+ int fd = -1, step = stypen & RS_FORWARD ? 1 : -1;
+ char *key =
+ (stypen & RS_AUTHOR ? headers[pos - locmem->top_ln].owner :
+ (subject( stypen & RS_CURRENT ?
+ currtitle :
+ headers[pos - locmem->top_ln].title )));
+
+ for(new_ln = pos + step ;
+ new_ln > 0 && new_ln <= last_line && --jump>0;
+ new_ln += step) {
+ get_record_keep(currdirect, &fh, sizeof(fileheader_t), new_ln, &fd);
+ if(stypen & RS_TITLE){
+ if(stypen & RS_FIRST) {
+ if(!strcmp(fh.title, key)) break;
}
- } else {
- if (stype & RS_FORWARD) {
- if (++now > last_line)
- now = 1;
- } else if (--now <= 0)
- now = last_line;
+ else
+ if(!strcmp(subject(fh.title), key)) break;
}
-
- get_record_keep(currdirect, &fh, sizeof(fileheader_t), now, &fd);
-
- if (fh.owner[0] == '-')
- continue;
-
- if (stype & RS_THREAD) {
- if (strncasecmp(fh.title, str_reply, 3)) {
- hit_thread = 1;
- if( fd )
- close(fd);
- return cursor_pos(locmem, now, 10);
- }
- continue;
+ else if(stypen & RS_NEWPOST){
+ if(strncmp(fh.title,"Re:",3)) break;
}
- if (stype & RS_TITLE)
- tag = subject(fh.title);
-
- if (((stype & RS_RELATED) && !strncmp(tag, query, 40)) ||
- (!(stype & RS_RELATED) && ((query == currowner) ?
- !strcmp(tag, query) :
- strstr_lower(tag, query)))) {
- if ((stype & RS_FIRST) && tag != fh.title) {
- near = now;
- continue;
- }
- hit_thread = 1;
- match = cursor_pos(locmem, now, 10);
- if ((!(stype & RS_CURRENT)) &&
- (stype & RS_RELATED) &&
- strncmp(currtitle, query, TTLEN)) {
- strncpy(currtitle, query, TTLEN);
- match = PARTUPDATE;
- }
- break;
+ else{ // RS_AUTHOR
+ if(!strcmp(subject(fh.owner), key)) break;
}
- } while (now != pos);
-
+ }
if( fd != -1 )
close(fd);
- return match;
+ if( jump <=0 || new_ln<=0 || new_ln > last_line )
+ new_ln = pos; //didn't find
+ else{
+ strncpy(currtitle, fh.title, TTLEN);
+ strncpy(currtitle, fh.title, TTLEN);
+ }
+ return new_ln;
}
-
#ifdef INTERNET_EMAIL
static void
mail_forward(fileheader_t * fhdr, char *direct, int mode)
@@ -448,19 +313,17 @@ mail_forward(fileheader_t * fhdr, char *direct, int mode)
*p = '\0';
switch (i = doforward(buf, fhdr, mode)) {
case 0:
- outmsg(msg_fwd_ok);
+ vmsg(msg_fwd_ok);
break;
case -1:
- outmsg(msg_fwd_err1);
+ vmsg(msg_fwd_err1);
break;
case -2:
- outmsg(msg_fwd_err2);
+ vmsg(msg_fwd_err2);
break;
default:
break;
}
- refresh();
- sleep(1);
}
#endif
@@ -468,311 +331,312 @@ static int
select_read(keeploc_t * locmem, int sr_mode)
{
#define READSIZE 64 // 8192 / sizeof(fileheader_t)
- char *tag, *query = NULL, *temp;
- fileheader_t fhs[READSIZE];
- char fpath[80], genbuf[MAXPATHLEN], buf3[5];
- static char t_ans[TTLEN + 1] = "";
- static char a_ans[TTLEN + 1] = "";
- int fd, fr, size = sizeof(fileheader_t), i, len;
- struct stat st;
- /* rocker.011018: make a reference number for process article */
- int reference = 0;
-
- if ((currmode & MODE_SELECT))
- return -1;
- if (sr_mode == RS_TITLE)
- query = subject(headers[locmem->crs_ln - locmem->top_ln].title);
- else if (sr_mode == RS_NEWPOST) {
- strlcpy(buf3, "Re: ", sizeof(buf3));
- query = buf3;
- }
- else if (sr_mode == RS_THREAD) {
-
- } else {
- char buff[80];
- char newdata[35];
-
- query = (sr_mode == RS_RELATED) ? t_ans : a_ans;
- snprintf(buff, sizeof(buff), "搜尋%s [%s] ",
- (sr_mode == RS_RELATED) ? "標題" : "作者", query);
- getdata(b_lines, 0, buff, newdata, sizeof(newdata), DOECHO);
- if (newdata[0])
- strcpy(query, newdata);
- if (!(*query))
- return DONOTHING;
+ fileheader_t fhs[READSIZE];
+ char newdirect[MAXPATHLEN];
+ char keyword[TTLEN + 1] = "";
+ char genbuf[MAXPATHLEN], *p = strstr(currdirect, "SR");
+ static int _mode = 0;
+ int len, fd, fr, i, count=0, reference = 0;
+
+ fileheader_t *fh = &headers[locmem->crs_ln - locmem->top_ln];
+ if(sr_mode & RS_AUTHOR)
+ {
+ if(!getdata(b_lines, 0,
+ currmode & MODE_SELECT ? "增加條件 作者:":"搜尋作者:",
+ keyword, IDLEN+1, LCECHO))
+ return READ_REDRAW;
+ }
+ else if(sr_mode & RS_KEYWORD)
+ {
+ if(!getdata(b_lines, 0,
+ currmode & MODE_SELECT ? "增加條件 標題:":"搜尋標題:",
+ keyword, TTLEN, DOECHO))
+ return READ_REDRAW;
+#ifdef KEYWORD_LOG
+ log_file("keyword_search_log", 1, "%s:%s\n", currboard, keyword);
+#endif
+ }
+ else
+ {
+ if(p && _mode & sr_mode & (RS_TITLE | RS_NEWPOST | RS_MARK))
+ return DONOTHING;
+ // Ptt: only once for these modes.
+ if(sr_mode & RS_TITLE)
+ strcpy(keyword, subject(fh->title));
}
- if ((fd = open(currdirect, O_RDONLY, 0)) != -1) {
- snprintf(genbuf, sizeof(genbuf), "SR.%s", cuser.userid);
- if (currstat == RMAIL)
- sethomefile(fpath, cuser.userid, genbuf);
- else
- setbfile(fpath, currboard, genbuf);
- if (((fr = open(fpath, O_WRONLY | O_CREAT | O_TRUNC, 0600)) != -1)) {
- switch (sr_mode) {
- case RS_TITLE:
- while( (len = read(fd, fhs, sizeof(fhs))) > 0 ){
- len /= sizeof(fileheader_t);
- for( i = 0 ; i < len ; ++i ){
- ++reference;
- tag = subject(fhs[i].title);
- if (!strncmp(tag, query, 40)) {
- fhs[i].money = reference | FHR_REFERENCE;
- write(fr, &fhs[i], size);
- }
- }
- }
- break;
- case RS_RELATED:
- while( (len = read(fd, fhs, sizeof(fhs))) > 0 ){
- len /= sizeof(fileheader_t);
- for( i = 0 ; i < len ; ++i ){
- ++reference;
- tag = fhs[i].title;
- if (strcasestr(tag, query)) {
- fhs[i].money = reference | FHR_REFERENCE;
- write(fr, &fhs[i], size);
- }
- }
- }
- break;
- case RS_NEWPOST:
- while( (len = read(fd, fhs, sizeof(fhs))) > 0 ){
- len /= sizeof(fileheader_t);
- for( i = 0 ; i < len ; ++i ){
- ++reference;
- tag = fhs[i].title;
- temp = strstr(tag, query);
- if (temp == NULL || temp != tag) {
- fhs[i].money = reference | FHR_REFERENCE;
- write(fr, &fhs[i], size);
- }
- }
- }
- break;
- case RS_AUTHOR:
- while( (len = read(fd, fhs, sizeof(fhs))) > 0 ){
- len /= sizeof(fileheader_t);
- for( i = 0 ; i < len ; ++i ){
- ++reference;
- tag = fhs[i].owner;
- if (strcasestr(tag, query)) {
- fhs[i].money = reference | FHR_REFERENCE;
- write(fr, &fhs[i], size);
- }
- }
- }
- break;
- case RS_THREAD:
- while( (len = read(fd, fhs, sizeof(fhs))) > 0 ){
- len /= sizeof(fileheader_t);
- for( i = 0 ; i < len ; ++i ){
- ++reference;
- if (fhs[i].filemode & FILE_MARKED) {
- fhs[i].money = reference | FHR_REFERENCE;
- write(fr, &fhs[i], size);
- }
- }
- }
- break;
- }
- fstat(fr, &st);
- close(fr);
- }
- close(fd);
- if (st.st_size) {
- currmode |= MODE_SELECT;
- strlcpy(currdirect, fpath, sizeof(currdirect));
- }
- }
- return READ_REDRAW;
+ if(p == NULL)
+ _mode = sr_mode;
+ else
+ _mode |= sr_mode;
+
+ snprintf(genbuf, sizeof(genbuf), "%s.%X.%X.%X",
+ p ? p : "SR",
+ sr_mode, strlen(keyword), StringHash(keyword));
+ if( strlen(genbuf) > MAXPATHLEN - 50 )
+ return READ_REDRAW; // avoid overflow
+
+ if (currstat == RMAIL)
+ sethomefile(newdirect, cuser.userid, genbuf);
+ else
+ setbfile(newdirect, currboard, genbuf);
+
+ if( now - dasht(newdirect) < 3600 )
+ count = dashs(newdirect);
+ else {
+ if( (fd = open(newdirect, O_CREAT | O_RDWR, 0600)) == -1 )
+ return READ_REDRAW;
+ if( (fr = open(currdirect, O_RDONLY, 0)) != -1 ) {
+ while( (len = read(fr, fhs, sizeof(fhs))) > 0 ){
+ len /= sizeof(fileheader_t);
+ for( i = 0 ; i < len ; ++i ){
+ reference++;
+ if( sr_mode & RS_MARK &&
+ !(fhs[i].filemode & FILE_MARKED) )
+ continue;
+ else if(sr_mode & RS_NEWPOST &&
+ !strncmp(fhs[i].title, "Re:", 3))
+ continue;
+ else if(sr_mode & RS_AUTHOR &&
+ !strcasestr(fhs[i].owner, keyword))
+ continue;
+ else if(sr_mode & RS_KEYWORD &&
+ !strcasestr(fhs[i].title, keyword))
+ continue;
+ else if(sr_mode & RS_TITLE &&
+ strcmp(subject(fhs[i].title), keyword))
+ continue;
+ ++count;
+ if(p == NULL)
+ fhs[i].money = reference | FHR_REFERENCE;
+ write(fd, &fhs[i], sizeof(fileheader_t));
+ }
+ } // end while
+ close(fr);
+ }
+ close(fd);
+ }
+
+ if(count) {
+ strlcpy(currdirect, newdirect, sizeof(currdirect));
+ currmode |= MODE_SELECT;
+ return NEWDIRECT;
+ }
+ return READ_REDRAW;
}
static int
-i_read_key(onekey_t * rcmdlist, keeploc_t * locmem, int ch, int bid, int bottom_line)
+i_read_key(onekey_t * rcmdlist, keeploc_t * locmem,
+ int bid, int bottom_line)
{
- int mode = DONOTHING;
- int num;
- char direct[60];
- switch (ch) {
- case 'q':
- case 'e':
- case KEY_LEFT:
- if(currmode & MODE_SELECT){
- char genbuf[256];
- fileheader_t *fhdr = &headers[locmem->crs_ln - locmem->top_ln];
- board_select();
- setbdir(genbuf, currboard);
- locmem = getkeep(genbuf, 0, 1);
- locmem->crs_ln = getindex(genbuf, fhdr->filename, sizeof(fileheader_t));
- num = locmem->crs_ln - p_lines + 1;
- locmem->top_ln = num < 1 ? 1 : num;
-
- return NEWDIRECT;
+ int mode = DONOTHING, num, new_top=10;
+ int ch, new_ln = locmem->crs_ln, lastmode=0;
+ char direct[60];
+ static char default_ch = 0;
+
+ do {
+ if( (mode = cursor_pos(locmem, new_ln, new_top, default_ch ? 0 : 1))
+ != DONOTHING )
+ return mode;
+
+ if( !default_ch )
+ ch = igetch();
+ else{
+ if(new_ln != locmem->crs_ln) {// move fault
+ default_ch=0;
+ return FULLUPDATE;
+ }
+ ch = default_ch;
}
- return (currmode & MODE_ETC) ? board_etc() :
- (currmode & MODE_DIGEST) ? board_digest() : DOQUIT;
- case Ctrl('L'):
- redoscr();
- break;
- case Ctrl('H'):
- if (select_read(locmem, RS_NEWPOST))
- return NEWDIRECT;
- else
- return READ_REDRAW;
- case 'a':
- case 'A':
- if (select_read(locmem, RS_AUTHOR))
- return NEWDIRECT;
- else
- return READ_REDRAW;
- case 'G':
- if (select_read(locmem,RS_THREAD)) /* marked articles */
- return NEWDIRECT;
- else
- return READ_REDRAW;
-
- case '/':
- case '?':
- if (select_read(locmem, RS_RELATED))
- return NEWDIRECT;
- else
- return READ_REDRAW;
- case 'S':
- if (select_read(locmem, RS_TITLE))
- return NEWDIRECT;
- else
- return READ_REDRAW;
- /* quick search title first */
- case '=':
- return thread(locmem, RELATE_FIRST);
- case '\\':
- return thread(locmem, CURSOR_FIRST);
- /* quick search title forword */
- case ']':
- return thread(locmem, RELATE_NEXT);
- case '+':
- return thread(locmem, CURSOR_NEXT);
- /* quick search title backword */
- case '[':
- return thread(locmem, RELATE_PREV);
- case '-':
- return thread(locmem, CURSOR_PREV);
- case '<':
- case ',':
- return thread(locmem, THREAD_PREV);
- case '.':
- case '>':
- return thread(locmem, THREAD_NEXT);
- case 'p':
- case 'k':
- case KEY_UP:
- return cursor_pos(locmem, locmem->crs_ln - 1, p_lines - 2);
- case 'n':
- case 'j':
- case KEY_DOWN:
- return cursor_pos(locmem, locmem->crs_ln + 1, 1);
- case ' ':
- case KEY_PGDN:
- case 'N':
- case Ctrl('F'):
- if (last_line >= locmem->top_ln + p_lines) {
- if (last_line > locmem->top_ln + p_lines)
- locmem->top_ln += p_lines;
+ new_top = 10; // default 10
+ switch (ch) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if( (num = search_num(ch, last_line)) != -1 )
+ new_ln = num + 1;
+ break;
+ case 'q':
+ case 'e':
+ case KEY_LEFT:
+ if(currmode & MODE_SELECT){
+ char genbuf[256];
+ fileheader_t *fhdr = &headers[locmem->crs_ln - locmem->top_ln];
+ board_select();
+ setbdir(genbuf, currboard);
+ locmem = getkeep(genbuf, 0, 1);
+ locmem->crs_ln = fhdr->money & ~FHR_REFERENCE;
+ num = locmem->crs_ln - p_lines + 1;
+ locmem->top_ln = num < 1 ? 1 : num;
+ mode = NEWDIRECT;
+ }
else
- locmem->top_ln += p_lines - 1;
- locmem->crs_ln = locmem->top_ln;
- return PARTUPDATE;
- }
- cursor_clear(3 + locmem->crs_ln - locmem->top_ln, 0);
- locmem->crs_ln = last_line;
- cursor_show(3 + locmem->crs_ln - locmem->top_ln, 0);
- break;
- case KEY_PGUP:
- case Ctrl('B'):
- case 'P':
- if (locmem->top_ln > 1) {
- locmem->top_ln -= p_lines;
- if (locmem->top_ln <= 0)
- locmem->top_ln = 1;
- locmem->crs_ln = locmem->top_ln;
- return PARTUPDATE;
- }
- break;
- case KEY_END:
- case '$':
- if (last_line >= locmem->top_ln + p_lines) {
- locmem->top_ln = last_line - p_lines + 1;
- if (locmem->top_ln <= 0)
- locmem->top_ln = 1;
- locmem->crs_ln = last_line;
- return PARTUPDATE;
- }
- cursor_clear(3 + locmem->crs_ln - locmem->top_ln, 0);
- locmem->crs_ln = last_line;
- cursor_show(3 + locmem->crs_ln - locmem->top_ln, 0);
- break;
- case 'F':
- case 'U':
- if (HAS_PERM(PERM_FORWARD)) {
- mail_forward(&headers[locmem->crs_ln - locmem->top_ln],
- currdirect, ch /* == 'U' */ );
- /* by CharlieL */
- return READ_REDRAW;
- }
- break;
- case Ctrl('Q'):
- return my_query(headers[locmem->crs_ln - locmem->top_ln].owner);
- case Ctrl('S'):
- if (HAS_PERM(PERM_ACCOUNTS)) {
- int id;
- userec_t muser;
-
- strlcpy(currauthor,
- headers[locmem->crs_ln - locmem->top_ln].owner,
- sizeof(currauthor));
- stand_title("使用者設定");
- move(1, 0);
- if ((id = getuser(headers[locmem->crs_ln - locmem->top_ln].owner))) {
- memcpy(&muser, &xuser, sizeof(muser));
- user_display(&muser, 1);
- uinfo_query(&muser, 1, id);
+ mode = (currmode & MODE_ETC) ? board_etc() :
+ (currmode & MODE_DIGEST) ? board_digest() : DOQUIT;
+ break;
+ case Ctrl('L'):
+ redoscr();
+ break;
+
+ case Ctrl('H'):
+ mode = select_read(locmem, RS_NEWPOST);
+ break;
+
+ case 'a':
+ case 'A':
+ mode = select_read(locmem, RS_AUTHOR);
+ break;
+
+ case 'G':
+ mode = select_read(locmem, RS_MARK);
+ break;
+
+ case '/':
+ case '?':
+ mode = select_read(locmem, RS_KEYWORD);
+ break;
+
+ case 'S':
+ mode = select_read(locmem, RS_TITLE);
+ break;
+
+ case '=':
+ new_ln = thread(locmem, RELATE_FIRST);
+ break;
+
+ case '\\':
+ new_ln = thread(locmem, CURSOR_FIRST);
+ break;
+
+ case ']':
+ new_ln = thread(locmem, RELATE_NEXT);
+ break;
+
+ case '+':
+ new_ln = thread(locmem, CURSOR_NEXT);
+ break;
+
+ case '[':
+ new_ln = thread(locmem, RELATE_PREV);
+ break;
+
+ case '-':
+ new_ln = thread(locmem, CURSOR_PREV);
+ break;
+
+ case '<':
+ case ',':
+ new_ln = thread(locmem, NEWPOST_PREV);
+ break;
+
+ case '.':
+ case '>':
+ new_ln = thread(locmem, NEWPOST_NEXT);
+ break;
+
+ case 'p':
+ case 'k':
+ case KEY_UP:
+ new_ln = locmem->crs_ln - 1;
+ new_top = p_lines - 2;
+ break;
+
+ case 'n':
+ case 'j':
+ case KEY_DOWN:
+ new_ln = locmem->crs_ln + 1;
+ new_top = 1;
+ break;
+
+ case ' ':
+ case KEY_PGDN:
+ case 'N':
+ case Ctrl('F'):
+ new_ln = locmem->top_ln + p_lines;
+ new_top = 0;
+ break;
+
+ case KEY_PGUP:
+ case Ctrl('B'):
+ case 'P':
+ new_ln = locmem->top_ln - p_lines;
+ new_top = 0;
+ break;
+
+ case KEY_END:
+ case '$':
+ new_ln = last_line;
+ new_top = p_lines-1;
+ break;
+
+ case 'F':
+ case 'U':
+ if (HAS_PERM(PERM_FORWARD)) {
+ mail_forward(&headers[locmem->crs_ln - locmem->top_ln],
+ currdirect, ch /* == 'U' */ );
+ /* by CharlieL */
+ mode = READ_REDRAW;
}
- return FULLUPDATE;
- }
- break;
+ break;
+
+ case Ctrl('Q'):
+ mode = my_query(headers[locmem->crs_ln - locmem->top_ln].owner);
+ break;
- /* rocker.011018: 採用新的tag模式 */
- case 't':
- /* 將原本在 Read() 裡面的 "TagNum = 0" 移至此處 */
- if ((currstat & RMAIL && TagBoard != 0) ||
+ case Ctrl('S'):
+ if (HAS_PERM(PERM_ACCOUNTS)) {
+ int id;
+ userec_t muser;
+
+ strlcpy(currauthor,
+ headers[locmem->crs_ln - locmem->top_ln].owner,
+ sizeof(currauthor));
+ stand_title("使用者設定");
+ move(1, 0);
+ if ((id = getuser(headers[locmem->crs_ln - locmem->top_ln].owner))) {
+ memcpy(&muser, &xuser, sizeof(muser));
+ user_display(&muser, 1);
+ uinfo_query(&muser, 1, id);
+ }
+ mode = FULLUPDATE;
+ }
+ break;
+
+ /* rocker.011018: 採用新的tag模式 */
+ case 't':
+ /* 將原本在 Read() 裡面的 "TagNum = 0" 移至此處 */
+ if ((currstat & RMAIL && TagBoard != 0) ||
(!(currstat & RMAIL) && TagBoard != bid)) {
- if (currstat & RMAIL)
- TagBoard = 0;
- else
- TagBoard = bid;
- TagNum = 0;
- }
- /* rocker.011112: 解決再select mode標記文章的問題 */
- if (Tagger(atoi(headers[locmem->crs_ln - locmem->top_ln].filename + 2),
- (currmode & MODE_SELECT) ?
- (headers[locmem->crs_ln - locmem->top_ln].money & ~FHR_REFERENCE) :
- locmem->crs_ln, TAG_TOGGLE))
- return POS_NEXT;
- return DONOTHING;
+ if (currstat & RMAIL)
+ TagBoard = 0;
+ else
+ TagBoard = bid;
+ TagNum = 0;
+ }
+ /* rocker.011112: 解決再select mode標記文章的問題 */
+ if (Tagger(atoi(headers[locmem->crs_ln - locmem->top_ln].filename + 2),
+ (currmode & MODE_SELECT) ?
+ (headers[locmem->crs_ln - locmem->top_ln].money & ~FHR_REFERENCE) :
+ locmem->crs_ln, TAG_TOGGLE))
+ locmem->crs_ln = locmem->crs_ln + 1;
+ mode = PART_REDRAW;
+ break;
case Ctrl('C'):
if (TagNum) {
TagNum = 0;
- return FULLUPDATE;
+ mode = FULLUPDATE;
}
- return DONOTHING;
+ break;
case Ctrl('T'):
- return TagThread(currdirect);
+ mode = TagThread(currdirect);
+ break;
+
case Ctrl('D'):
- return TagPruner(bid);
+ mode = TagPruner(bid);
+ break;
+
case '\n':
case '\r':
case 'l':
@@ -780,25 +644,70 @@ i_read_key(onekey_t * rcmdlist, keeploc_t * locmem, int ch, int bid, int bottom_
ch = 'r';
default:
if( ch == 'h' && currmode & (MODE_ETC | MODE_DIGEST) )
- return DONOTHING;
+ break;
if (ch > 0 && ch <= onekey_size) {
int (*func)() = rcmdlist[ch - 1];
- if (func != NULL)
- {
- num = locmem->crs_ln - bottom_line;
- if (num>0)
- {
- sprintf(direct,"%s.bottom", currdirect);
- mode = (*func)(num, &headers[locmem->crs_ln-locmem->top_ln],
- direct);
- }
- else
- mode = (*func)(locmem->crs_ln,
- &headers[locmem->crs_ln - locmem->top_ln], currdirect);
- }
- break;
- }
- }
+ if (func != NULL){
+ num = locmem->crs_ln - bottom_line;
+
+ if( num > 0 ){
+ sprintf(direct,"%s.bottom", currdirect);
+ mode= (*func)(num, &headers[locmem->crs_ln-locmem->top_ln],
+ direct);
+ }
+ else
+ mode = (*func)(locmem->crs_ln,
+ &headers[locmem->crs_ln - locmem->top_ln],
+ currdirect);
+ if(mode == READ_SKIP)
+ mode = lastmode;
+
+ // 以下這幾種 mode 要再處理游標
+ if(mode == READ_PREV || mode == READ_NEXT ||
+ mode == RELATE_PREV || mode == RELATE_FIRST ||
+ mode == AUTHOR_NEXT || mode == AUTHOR_PREV ||
+ mode == RELATE_NEXT){
+ lastmode = mode;
+
+ switch(mode){
+ case READ_PREV:
+ new_ln = locmem->crs_ln - 1;
+ break;
+ case READ_NEXT:
+ new_ln = locmem->crs_ln + 1;
+ break;
+ case RELATE_PREV:
+ new_ln = thread(locmem, RELATE_PREV);
+ break;
+ case RELATE_NEXT:
+ new_ln = thread(locmem, RELATE_NEXT);
+ /* XXX: 讀到最後一篇要跳出來 */
+ if( new_ln == locmem->crs_ln ){
+ default_ch = 0;
+ return FULLUPDATE;
+ }
+ break;
+ case RELATE_FIRST:
+ new_ln = thread(locmem, RELATE_FIRST);
+ break;
+ case AUTHOR_PREV:
+ new_ln = thread(locmem, AUTHOR_PREV);
+ break;
+ case AUTHOR_NEXT:
+ new_ln = thread(locmem, AUTHOR_NEXT);
+ break;
+ }
+ mode = DONOTHING; default_ch = 'r';
+ }
+ else {
+ default_ch = 0;
+ lastmode = 0;
+ }
+ } //end if (func != NULL)
+ } // ch > 0 && ch <= onekey_size
+ break;
+ } // end switch
+ } while (mode == DONOTHING);
return mode;
}
@@ -806,38 +715,39 @@ int
get_records_and_bottom(char *direct, fileheader_t* headers,
int recbase, int p_lines, int last_line, int bottom_line)
{
- int n = bottom_line - recbase + 1, rv;
- char directbottom[60];
+ int n = bottom_line - recbase + 1, rv;
+ char directbottom[60];
- if(n>=p_lines || (currmode & (MODE_SELECT | MODE_DIGEST)))
- return get_records(direct, headers, sizeof(fileheader_t), recbase,
- p_lines);
+ if( !last_line )
+ return 0;
+ if( n >= p_lines || (currmode & (MODE_SELECT | MODE_DIGEST)) )
+ return get_records(direct, headers, sizeof(fileheader_t), recbase,
+ p_lines);
sprintf(directbottom, "%s.bottom", direct);
- if (n<=0)
- return get_records(directbottom, headers, sizeof(fileheader_t), 1-n,
- last_line-recbase + 1);
+ if( n <= 0 )
+ return get_records(directbottom, headers, sizeof(fileheader_t), 1-n,
+ last_line-recbase + 1);
- rv = get_records(direct, headers, sizeof(fileheader_t), recbase, n);
+ rv = get_records(direct, headers, sizeof(fileheader_t), recbase, n);
+
+ if( bottom_line < last_line )
+ rv += get_records(directbottom, headers+n, sizeof(fileheader_t), 1,
+ p_lines - n );
+ return rv;
+}
- if(bottom_line<last_line)
- rv += get_records(directbottom, headers+n, sizeof(fileheader_t), 1,
- p_lines - n );
- return rv;
-}
void
-i_read(int cmdmode, char *direct, void (*dotitle) (), void (*doentry) (), onekey_t * rcmdlist, int bidcache)
+i_read(int cmdmode, char *direct, void (*dotitle) (),
+ void (*doentry) (), onekey_t * rcmdlist, int bidcache)
{
keeploc_t *locmem = NULL;
- int recbase = 0, mode, ch;
+ int recbase = 0, mode;
int num = 0, entries = 0, n_bottom=0;
int i;
- int jump = 0;
- char genbuf[4];
char currdirect0[64];
int last_line0 = last_line;
int bottom_line = 0;
- int hit_thread0 = hit_thread;
fileheader_t *headers0 = headers;
strlcpy(currdirect0, currdirect, sizeof(currdirect0));
@@ -866,36 +776,6 @@ i_read(int cmdmode, char *direct, void (*dotitle) (), void (*doentry) (), onekey
bottom_line = last_line = get_num_records(currdirect, FHSZ);
if (mode == NEWDIRECT) {
- if (last_line == 0) {
- if (curredit & EDIT_ITEM) {
- outs("沒有物品");
- refresh();
- goto return_i_read;
- } else if (curredit & EDIT_MAIL) {
- outs("沒有來信");
- refresh();
- goto return_i_read;
- } else if (currmode & MODE_ETC) {
- board_etc(); /* Kaede */
- outmsg("尚未收錄其它文章");
- refresh();
- } else if (currmode & MODE_DIGEST) {
- board_digest(); /* Kaede */
- outmsg("尚未收錄文摘");
- refresh();
- } else if (currmode & MODE_SELECT) {
- board_select(); /* Leeym */
- outmsg("沒有此系列的文章");
- refresh();
- } else {
- getdata(b_lines - 1, 0,
- "看板新成立 (P)發表文章 (Q)離開?[Q] ",
- genbuf, 4, LCECHO);
- if (genbuf[0] == 'p')
- do_post();
- goto return_i_read;
- }
- }
num = last_line - p_lines + 1;
locmem = getkeep(currdirect, num < 1 ? 1 : num, last_line);
}
@@ -906,11 +786,10 @@ i_read(int cmdmode, char *direct, void (*dotitle) (), void (*doentry) (), onekey
case PARTUPDATE:
if (last_line < locmem->top_ln + p_lines) {
- if (bidcache > 0 && !(currmode & (MODE_SELECT | MODE_DIGEST)))
- {
- bottom_line = getbtotal(currbid);
- num = bottom_line+getbottomtotal(currbid);
- }
+ if (bidcache > 0 && !(currmode & (MODE_SELECT | MODE_DIGEST))){
+ bottom_line = getbtotal(currbid);
+ num = bottom_line+getbottomtotal(currbid);
+ }
else
num = get_num_records(currdirect, FHSZ);
@@ -919,9 +798,7 @@ i_read(int cmdmode, char *direct, void (*dotitle) (), void (*doentry) (), onekey
recbase = -1;
}
}
- if (last_line == 0)
- goto return_i_read;
- else if (recbase != locmem->top_ln) {
+ if (recbase != locmem->top_ln) { //headers reload
recbase = locmem->top_ln;
if (recbase > last_line) {
recbase = last_line - p_lines + 1;
@@ -938,8 +815,11 @@ i_read(int cmdmode, char *direct, void (*dotitle) (), void (*doentry) (), onekey
clrtobot();
case PART_REDRAW:
move(3, 0);
- for (i = 0; i < entries; i++)
- (*doentry) (locmem->top_ln + i, &headers[i]);
+ if( last_line == 0 )
+ outs(" 沒有文章...");
+ else
+ for( i = 0; i < entries ; i++ )
+ (*doentry) (locmem->top_ln + i, &headers[i]);
case READ_REDRAW:
outmsg(curredit & EDIT_ITEM ?
"\033[44m 私人收藏 \033[30;47m 繼續? \033[m" :
@@ -947,82 +827,29 @@ i_read(int cmdmode, char *direct, void (*dotitle) (), void (*doentry) (), onekey
break;
case TITLE_REDRAW:
(*dotitle) ();
- break;
- case READ_PREV:
- case READ_NEXT:
- case RELATE_PREV:
- case RELATE_NEXT:
- case RELATE_FIRST:
- case POS_NEXT:
- case 'A':
- case 'a':
- case '/':
- case '?':
- jump = 1;
- break;
- }
-
- /* 讀取鍵盤,加以處理,設定 mode */
- if (!jump) {
- assert(3 + locmem->crs_ln - locmem->top_ln>=0); // FIXME dunno why
- cursor_show(3 + locmem->crs_ln - locmem->top_ln, 0);
- ch = egetch();
- mode = DONOTHING;
- } else
- ch = ' ';
-
- if (mode == POS_NEXT) {
- mode = cursor_pos(locmem, locmem->crs_ln + 1, 1);
- if (mode == DONOTHING)
- mode = PART_REDRAW;
- jump = 0;
- } else if (ch >= '0' && ch <= '9') {
- if ((i = search_num(ch, last_line)) != -1)
- mode = cursor_pos(locmem, i + 1, 10);
- } else {
- if (!jump)
- mode = i_read_key(rcmdlist, locmem, ch, currbid,
- bottom_line);
- while (mode == READ_NEXT || mode == READ_PREV ||
- mode == RELATE_FIRST || mode == RELATE_NEXT ||
- mode == RELATE_PREV || mode == THREAD_NEXT ||
- mode == THREAD_PREV || mode == 'A' || mode == 'a' ||
- mode == '/' || mode == '?') {
- int reload;
-
- if (mode == READ_NEXT || mode == READ_PREV)
- reload = move_cursor_line(locmem, mode);
- else {
- reload = thread(locmem, mode);
- if (!hit_thread) {
- mode = FULLUPDATE;
- break;
- }
- }
-
- if (reload == -1) {
- mode = FULLUPDATE;
- break;
- } else if (reload) {
- recbase = locmem->top_ln;
-
- entries=get_records_and_bottom(currdirect,
- headers, recbase, p_lines, last_line, bottom_line);
-
+ break;
+
+ case HEADERS_RELOAD:
+ if (recbase != locmem->top_ln) {
+ recbase = locmem->top_ln;
+ if (recbase > last_line) {
+ recbase = last_line - p_lines + 1;
+ if (recbase < 1)
+ recbase = 1;
+ locmem->top_ln = recbase;
}
- num = locmem->crs_ln - locmem->top_ln;
- if (headers[num].owner[0] != '-')
- mode = i_read_key(rcmdlist, locmem, ch, currbid,
- bottom_line);
+ entries =
+ get_records_and_bottom(currdirect, headers, recbase,
+ p_lines, last_line, bottom_line);
}
- }
+ break;
+ } //end switch
+ mode = i_read_key(rcmdlist, locmem, currbid, bottom_line);
} while (mode != DOQUIT);
#undef FHSZ
-return_i_read:
free(headers);
last_line = last_line0;
- hit_thread = hit_thread0;
headers = headers0;
strlcpy(currdirect, currdirect0, sizeof(currdirect));
return;