diff options
author | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
---|---|---|
committer | in2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204> | 2002-03-07 23:13:44 +0800 |
commit | ae31e19f92e717919ac8e3db9039eb38d2b89aae (patch) | |
tree | c70164d6a1852344f44b04a653ae2815043512af /mbbsd/name.c | |
download | pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2 pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip |
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/name.c')
-rw-r--r-- | mbbsd/name.c | 473 |
1 files changed, 473 insertions, 0 deletions
diff --git a/mbbsd/name.c b/mbbsd/name.c new file mode 100644 index 00000000..2f84a1fe --- /dev/null +++ b/mbbsd/name.c @@ -0,0 +1,473 @@ +/* $Id: name.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <signal.h> +#include <sys/types.h> +#include "config.h" +#include "pttstruct.h" +#include "common.h" +#include "proto.h" + +extern char *str_space; +extern int p_lines; /* a Page of Screen line numbers: tlines-4 */ +extern int b_lines; /* Screen bottom line number: t_lines-1 */ + +word_t *toplev = NULL; +static word_t *current = NULL; +static char *msg_more = "\033[7m-- More --\033[m"; + +typedef char (*arrptr)[]; +/* name complete for user ID */ + +static int UserMaxLen(char cwlist[][IDLEN + 1], int cwnum, int morenum, + int count) { + int len, max = 0; + + while(count-- > 0 && morenum < cwnum) { + len = strlen(cwlist[morenum++]); + if (len > max) + max = len; + } + return max; +} + +static int UserSubArray(char cwbuf[][IDLEN + 1], char cwlist[][IDLEN + 1], + int cwnum, int key, int pos) { + int key2, num = 0; + int n, ch; + + key = chartoupper(key); + if(key >= 'A' && key <= 'Z') + key2 = key | 0x20; + else + key2 = key ; + + for(n = 0; n < cwnum; n++) { + ch = cwlist[n][pos]; + if(ch == key || ch == key2) + strcpy(cwbuf[num++], cwlist[n]); + } + return num; +} + +static void FreeNameList() { + word_t *p, *temp; + + for(p = toplev; p; p = temp) { + temp = p->next; + free(p->word); + free(p); + } +} + +void CreateNameList() { + if(toplev) + FreeNameList(); + toplev = current = NULL; +} + +void AddNameList(char *name) { + word_t *node; + + node = (word_t *)malloc(sizeof(word_t)); + node->next = NULL; + node->word = (char *)malloc(strlen(name) + 1); + strcpy(node->word, name); + + if(toplev) + current = current->next = node; + else + current = toplev = node; +} + +int RemoveNameList(char *name) { + word_t *curr, *prev = NULL; + + for(curr = toplev; curr; curr = curr->next) { + if(!strcmp(curr->word, name)) { + if(prev == NULL) + toplev = curr->next; + else + prev->next = curr->next; + + if(curr == current) + current = prev; + free(curr->word); + free(curr); + return 1; + } + prev = curr; + } + return 0; +} + +int InNameList(char *name) { + word_t *p; + + for(p = toplev; p; p = p->next) + if(!strcmp(p->word, name)) + return 1; + return 0; +} + +void ShowNameList(int row, int column, char *prompt) { + word_t *p; + + move(row, column); + clrtobot(); + outs(prompt); + + column = 80; + for(p = toplev; p; p = p->next) { + row = strlen(p->word) + 1; + if(column + row > 76) { + column = row; + outc('\n'); + } else { + column += row; + outc(' '); + } + outs(p->word); + } +} + +void ToggleNameList(int *reciper, char *listfile, char *msg) { + FILE *fp; + char genbuf[200]; + + if((fp = fopen(listfile, "r"))) { + while(fgets(genbuf, STRLEN, fp)) { + strtok(genbuf, str_space); + if(!InNameList(genbuf)) { + AddNameList(genbuf); + (*reciper)++; + } else { + RemoveNameList(genbuf); + (*reciper)--; + } + } + fclose(fp); + ShowNameList(3, 0, msg); + } +} + +static int NumInList(word_t *list) { + register int i; + + for(i = 0; list; i++) + list = list->next; + return i; +} + +int chkstr(char *otag, char *tag, char *name) { + char ch, *oname = name; + + while(*tag) { + ch = *name++; + if(*tag != chartoupper(ch)) + return 0; + tag++; + } + if(*tag && *name == '\0') + strcpy(otag, oname); + return 1; +} + +static word_t *GetSubList(char *tag, word_t *list) { + word_t *wlist, *wcurr; + char tagbuf[STRLEN]; + int n; + + wlist = wcurr = NULL; + for(n = 0; tag[n]; n++) + tagbuf[n] = chartoupper(tag[n]); + tagbuf[n] = '\0'; + + while(list) { + if(chkstr(tag, tagbuf, list->word)) { + register word_t *node; + + node = (word_t *)malloc(sizeof(word_t)); + node->word = list->word; + node->next = NULL; + if(wlist) + wcurr->next = node; + else + wlist = node; + wcurr = node; + } + list = list->next; + } + return wlist; +} + +static void ClearSubList(word_t *list) { + struct word_t *tmp_list; + + while(list) { + tmp_list = list->next; + free(list); + list = tmp_list; + } +} + +static int MaxLen(word_t *list, int count) { + int len = strlen(list->word); + int t; + + while(list && count) { + if((t = strlen(list->word)) > len) + len = t; + list = list->next; + count--; + } + return len; +} + +void namecomplete(char *prompt, char *data) { + char *temp; + word_t *cwlist, *morelist; + int x, y, origx, origy; + int ch; + int count = 0; + int clearbot = NA; + + if(toplev == NULL) + AddNameList(""); + cwlist = GetSubList("", toplev); + morelist = NULL; + temp = data; + + outs(prompt); + clrtoeol(); + getyx(&y, &x); + getyx(&origy, &origx); + standout(); + prints("%*s", IDLEN + 1, ""); + standend(); + move(y, x); + refresh(); + + while((ch = igetch()) != EOF) { + if(ch == '\n' || ch == '\r') { + *temp = '\0'; + outc('\n'); + if(NumInList(cwlist) == 1) + strcpy(data, cwlist->word); + ClearSubList(cwlist); + break; + } + if(ch == ' ') { + int col, len; + + if(NumInList(cwlist) == 1) { + strcpy(data, cwlist->word); + move(y, x); + outs(data + count); + count = strlen(data); + temp = data + count; + getyx(&y, &x); + continue; + } + clearbot = YEA; + col = 0; + if(!morelist) + morelist = cwlist; + len = MaxLen(morelist, p_lines); + move(2, 0); + clrtobot(); + printdash("相關資訊一覽表"); + while(len + col < 80) { + int i; + + for(i = p_lines; (morelist) && (i > 0); i--) { + move(3 + (p_lines - i), col); + outs(morelist->word); + morelist = morelist->next; + } + col += len + 2; + if(!morelist) + break; + len = MaxLen(morelist, p_lines); + } + if(morelist) { + move(b_lines, 0); + outs(msg_more); + } + move(y, x); + continue; + } + if(ch == '\177' || ch == '\010') { + if(temp == data) + continue; + temp--; + count--; + *temp = '\0'; + ClearSubList(cwlist); + cwlist = GetSubList(data, toplev); + morelist = NULL; + x--; + move(y, x); + outc(' '); + move(y, x); + continue; + } + + if(count < STRLEN && isprint(ch)) { + word_t *node; + + *temp++ = ch; + count++; + *temp = '\0'; + node = GetSubList(data, cwlist); + if(node == NULL) { + temp--; + *temp = '\0'; + count--; + continue; + } + ClearSubList(cwlist); + cwlist = node; + morelist = NULL; + move(y, x); + outc(ch); + x++; + } + } + if(ch == EOF) + /* longjmp(byebye, -1); */ + raise(SIGHUP); /* jochang: don't know if this is necessary... */ + outc('\n'); + refresh(); + if(clearbot) { + move(2, 0); + clrtobot(); + } + if(*data) { + move(origy, origx); + outs(data); + outc('\n'); + } +} + +void usercomplete(char *prompt, char *data) { + char *temp; + char *cwbuf, *cwlist; + int cwnum, x, y, origx, origy; + int clearbot = NA, count = 0, morenum = 0; + char ch; + + cwbuf = malloc(MAX_USERS * (IDLEN + 1)); + cwlist = u_namearray((arrptr)cwbuf, &cwnum, ""); + temp = data; + + outs(prompt); + clrtoeol(); + getyx(&y, &x); + getyx(&origy, &origx); + standout(); + prints("%*s", IDLEN + 1, ""); + standend(); + move(y, x); + while((ch = igetch()) != EOF) { + if(ch == '\n' || ch == '\r') { + int i; + char *ptr; + + *temp = '\0'; + outc('\n'); + ptr = (char *)cwlist; + for(i = 0; i < cwnum; i++) { + if(strncasecmp(data, ptr, IDLEN + 1) == 0) + strcpy(data, ptr); + ptr += IDLEN + 1; + } + break; + } else if(ch == ' ') { + int col, len; + + if(cwnum == 1) { + strcpy(data, (char *)cwlist); + move(y, x); + outs(data + count); + count = strlen(data); + temp = data + count; + getyx(&y, &x); + continue; + } + clearbot = YEA; + col = 0; + len = UserMaxLen((arrptr)cwlist, cwnum, morenum, p_lines); + move(2, 0); + clrtobot(); + printdash("使用者代號一覽表"); + while(len + col < 79) { + int i; + + for(i = 0; morenum < cwnum && i < p_lines; i++) { + move(3 + i, col); + prints("%s ", cwlist + (IDLEN + 1) * morenum++); + } + col += len + 2; + if(morenum >= cwnum) + break; + len = UserMaxLen((arrptr)cwlist, cwnum, morenum, p_lines); + } + if(morenum < cwnum) { + move(b_lines, 0); + outs(msg_more); + } else + morenum = 0; + move(y, x); + continue; + } else if(ch == '\177' || ch == '\010') { + if(temp == data) + continue; + temp--; + count--; + *temp = '\0'; + cwlist = u_namearray((arrptr)cwbuf, &cwnum, data); + morenum = 0; + x--; + move(y, x); + outc(' '); + move(y, x); + continue; + } else if(count < STRLEN && isprint(ch)) { + int n; + + *temp++ = ch; + *temp = '\0'; + n = UserSubArray((arrptr)cwbuf, (arrptr)cwlist, cwnum, ch, count); + if(n == 0) { + temp--; + *temp = '\0'; + continue; + } + cwlist = cwbuf; + count++; + cwnum = n; + morenum = 0; + move(y, x); + outc(ch); + x++; + } + } + free(cwbuf); + if(ch == EOF) + /* longjmp(byebye, -1); */ + raise(SIGHUP); /* jochang: don't know if this is necessary */ + outc('\n'); + refresh(); + if(clearbot) { + move(2, 0); + clrtobot(); + } + if(*data) { + move(origy, origx); + outs(data); + outc('\n'); + } +} |