summaryrefslogtreecommitdiffstats
path: root/mbbsd/chat.c
diff options
context:
space:
mode:
authorin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
committerin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
commitae31e19f92e717919ac8e3db9039eb38d2b89aae (patch)
treec70164d6a1852344f44b04a653ae2815043512af /mbbsd/chat.c
downloadpttbbs-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/chat.c')
-rw-r--r--mbbsd/chat.c623
1 files changed, 623 insertions, 0 deletions
diff --git a/mbbsd/chat.c b/mbbsd/chat.c
new file mode 100644
index 00000000..f75383a8
--- /dev/null
+++ b/mbbsd/chat.c
@@ -0,0 +1,623 @@
+/* $Id: chat.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include "config.h"
+#include "pttstruct.h"
+#include "perm.h"
+#include "common.h"
+#include "modes.h"
+#include "proto.h"
+
+extern userinfo_t *currutmp;
+static int chatline;
+static int stop_line; /* next line of bottom of message window area */
+static FILE *flog;
+
+static void printchatline(char *str) {
+ move(chatline, 0);
+ if(*str == '>' && !PERM_HIDE(currutmp))
+ return;
+ else if(chatline < stop_line - 1)
+ chatline++;
+ else {
+ region_scroll_up(2, stop_line - 2);
+ move(stop_line - 2, 0);
+ }
+ outs(str);
+ outc('\n');
+ outs("→");
+
+ if(flog)
+ fprintf(flog, "%s\n", str);
+}
+
+extern int b_lines; /* Screen bottom line number: t_lines-1 */
+
+static void chat_clear() {
+ for(chatline = 2; chatline < stop_line; chatline++) {
+ move(chatline, 0);
+ clrtoeol();
+ }
+ move(b_lines, 0);
+ clrtoeol();
+ move(chatline = 2, 0);
+ outs("→");
+}
+
+static void print_chatid(char *chatid) {
+ move(b_lines - 1, 0);
+ clrtoeol();
+ outs(chatid);
+ outc(':');
+}
+
+static int chat_send(int fd, char *buf) {
+ int len;
+ char genbuf[200];
+
+ sprintf(genbuf, "%s\n", buf);
+ len = strlen(genbuf);
+ return (send(fd, genbuf, len, 0) == len);
+}
+
+static char chatroom[IDLEN]; /* Chat-Room Name */
+
+static int chat_recv(int fd, char *chatid) {
+ static char buf[512];
+ static int bufstart = 0;
+ char genbuf[200];
+ int c, len;
+ char *bptr;
+
+ len = sizeof(buf) - bufstart - 1;
+ if((c = recv(fd, buf + bufstart, len, 0)) <= 0)
+ return -1;
+ c += bufstart;
+
+ bptr = buf;
+ while(c > 0) {
+ len = strlen(bptr) + 1;
+ if(len > c && len < (sizeof buf / 2))
+ break;
+
+ if(*bptr == '/') {
+ switch(bptr[1]) {
+ case 'c':
+ chat_clear();
+ break;
+ case 'n':
+ strncpy(chatid, bptr + 2, 8);
+ print_chatid(chatid);
+ clrtoeol();
+ break;
+ case 'r':
+ strncpy(chatroom, bptr + 2, IDLEN - 1);
+ break;
+ case 't':
+ move(0, 0);
+ clrtoeol();
+ sprintf(genbuf, "談天室 [%s]", chatroom);
+ prints("\033[1;37;46m %-21s \033[45m 話題:%-48s\033[m",
+ genbuf, bptr + 2);
+ }
+ } else
+ printchatline(bptr);
+
+ c -= len;
+ bptr += len;
+ }
+
+ if(c > 0) {
+ strcpy(genbuf, bptr);
+ strcpy(buf, genbuf);
+ bufstart = len - 1;
+ } else
+ bufstart = 0;
+ return 0;
+}
+
+extern userec_t cuser;
+
+static int printuserent(userinfo_t *uentp) {
+ static char uline[80];
+ static int cnt;
+ char pline[30];
+
+ if(!uentp) {
+ if(cnt)
+ printchatline(uline);
+ bzero(uline, 80);
+ cnt = 0;
+ return 0;
+ }
+ if(!HAS_PERM(PERM_SYSOP) && !HAS_PERM(PERM_SEECLOAK) && uentp->invisible)
+ return 0;
+
+ sprintf(pline, "%-13s%c%-10s ", uentp->userid,
+ uentp->invisible ? '#' : ' ',
+ modestring(uentp, 1));
+ if(cnt < 2)
+ strcat(pline, "│");
+ strcat(uline, pline);
+ if(++cnt == 3) {
+ printchatline(uline);
+ memset(uline, 0, 80);
+ cnt = 0;
+ }
+ return 0;
+}
+
+static void chathelp(char *cmd, char *desc) {
+ char buf[STRLEN];
+
+ sprintf(buf, " %-20s- %s", cmd, desc);
+ printchatline(buf);
+}
+
+static void chat_help(char *arg) {
+ if(strstr(arg, " op")) {
+ printchatline("談天室管理員專用指令");
+ chathelp("[/f]lag [+-][ls]", "設定鎖定、秘密狀態");
+ chathelp("[/i]nvite <id>", "邀請 <id> 加入談天室");
+ chathelp("[/k]ick <id>", "將 <id> 踢出談天室");
+ chathelp("[/o]p <id>", "將 Op 的權力轉移給 <id>");
+ chathelp("[/t]opic <text>", "換個話題");
+ chathelp("[/w]all", "廣播 (站長專用)");
+ } else {
+ chathelp("[//]help", "MUD-like 社交動詞");
+ chathelp("[/.]help", "chicken 鬥雞用指令");
+ chathelp("[/h]elp op", "談天室管理員專用指令");
+ chathelp("[/a]ct <msg>", "做一個動作");
+ chathelp("[/b]ye [msg]", "道別");
+ chathelp("[/c]lear", "清除螢幕");
+ chathelp("[/j]oin <room>", "建立或加入談天室");
+ chathelp("[/l]ist [room]", "列出談天室使用者");
+ chathelp("[/m]sg <id> <msg>", "跟 <id> 說悄悄話");
+ chathelp("[/n]ick <id>", "將談天代號換成 <id>");
+ chathelp("[/p]ager", "切換呼叫器");
+ chathelp("[/q]uery", "查詢網友");
+ chathelp("[/r]oom", "列出一般談天室");
+ chathelp("[/u]sers", "列出站上使用者");
+ chathelp("[/w]ho", "列出本談天室使用者");
+ chathelp("[/w]hoin <room>", "列出談天室<room> 的使用者");
+ }
+}
+
+static void chat_date() {
+ time_t thetime;
+ char genbuf[200];
+
+ time(&thetime);
+ sprintf(genbuf, "◆ " BBSNAME "標準時間: %s", Cdate(&thetime));
+ printchatline(genbuf);
+}
+
+static void chat_pager() {
+ char genbuf[200];
+
+ char *msgs[] = {"關閉", "打開", "拔掉", "防水","好友"};
+ sprintf(genbuf, "◆ 您的呼叫器:[%s]",
+ msgs[currutmp->pager = (currutmp->pager+1)%5]);
+ printchatline(genbuf);
+}
+
+extern char *str_space;
+extern userec_t xuser;
+extern char *fn_plans;
+extern char *err_uid;
+
+static void chat_query(char *arg) {
+ char *uid;
+ int tuid;
+
+ printchatline("");
+ strtok(arg, str_space);
+ if((uid = strtok(NULL, str_space)) && (tuid = getuser(uid))) {
+ char buf[128], *ptr;
+ FILE *fp;
+
+ sprintf(buf, "%s(%s) 共上站 %d 次,發表過 %d 篇文章",
+ xuser.userid, xuser.username, xuser.numlogins, xuser.numposts);
+ printchatline(buf);
+
+ sprintf(buf, "最近(%s)從[%s]上站", Cdate(&xuser.lastlogin),
+ (xuser.lasthost[0] ? xuser.lasthost : "(不詳)"));
+ printchatline(buf);
+
+ sethomefile(buf, xuser.userid, fn_plans);
+ if((fp = fopen(buf, "r"))) {
+ tuid = 0;
+ while(tuid++ < MAX_QUERYLINES && fgets(buf, 128, fp)) {
+ if((ptr = strchr(buf, '\n')))
+ ptr[0] = '\0';
+ printchatline(buf);
+ }
+ fclose(fp);
+ }
+ } else
+ printchatline(err_uid);
+}
+
+extern char *msg_shortulist;
+
+static void chat_users() {
+ printchatline("");
+ printchatline("【 " BBSNAME "的遊客列表 】");
+ printchatline(msg_shortulist);
+
+ if(apply_ulist(printuserent) == -1)
+ printchatline("空無一人");
+ printuserent(NULL);
+}
+
+typedef struct chat_command_t {
+ char *cmdname; /* Chatroom command length */
+ void (*cmdfunc) (); /* Pointer to function */
+} chat_command_t;
+
+static chat_command_t chat_cmdtbl[] = {
+ {"help", chat_help},
+ {"clear", chat_clear},
+ {"date", chat_date},
+ {"pager", chat_pager},
+ {"query", chat_query},
+ {"users", chat_users},
+ {NULL, NULL}
+};
+
+static int chat_cmd_match(char *buf, char *str) {
+ while(*str && *buf && !isspace(*buf))
+ if(tolower(*buf++) != *str++)
+ return 0;
+ return 1;
+}
+
+static int chat_cmd(char *buf, int fd) {
+ int i;
+
+ if(*buf++ != '/')
+ return 0;
+
+ for(i = 0; chat_cmdtbl[i].cmdname; i++) {
+ if(chat_cmd_match(buf, chat_cmdtbl[i].cmdname)) {
+ chat_cmdtbl[i].cmdfunc(buf);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+extern char trans_buffer[256]; /* 一般傳遞變數 add by Ptt */
+
+#if 0
+static char *select_address() {
+ int c;
+ FILE *fp;
+ char nametab[25][90];
+ char iptab[25][18], buf[80];
+
+ move(1, 0);
+ clrtobot();
+ outs("\n \033[36m【找個地方抬抬槓吧!】\033[m "
+ "◎ 【以下為本站登記有案的茶樓】 \n");
+ trans_buffer[0]=0;
+ if((fp = fopen("etc/teashop", "r"))) {
+ for(c = 0; fscanf(fp, "%s%s", iptab[c], nametab[c]) != EOF; c++) {
+ sprintf(buf,"\n (\033[36m%d\033[0m) %-30s [%s]",
+ c + 1, nametab[c], iptab[c]);
+ outs(buf);
+ }
+ getdata(20, 10, "★\033[32m 請選擇,[0]離開:\033[0m", buf, 3,
+ LCECHO);
+ if(buf[1])
+ buf[0] = (buf[0] + 1) * 10 + (buf[1] - '1');
+ else
+ buf[0] -= '1';
+ if(buf[0] >= 0 && buf[0] < c)
+ strcpy(trans_buffer,iptab[(int)buf[0]]);
+ } else {
+ outs("本站沒有登記任何合格茶樓");
+ pressanykey();
+ }
+ return trans_buffer;
+}
+#endif
+
+extern int usernum;
+extern int t_lines;
+extern char *msg_seperator;
+#define MAXLASTCMD 6
+static int chatid_len = 10;
+
+int t_chat() {
+ char inbuf[80], chatid[20], lastcmd[MAXLASTCMD][80], *ptr = "";
+ struct sockaddr_in sin;
+ struct hostent *h;
+ int cfd, cmdpos, ch;
+ int currchar;
+ int newmail;
+ int chatting = YEA;
+ char fpath[80];
+ char genbuf[200];
+ char roomtype;
+
+ if(inbuf[0] == 0)
+ return -1;
+
+ outs(" 驅車前往 請梢候........ ");
+ if(!(h = gethostbyname("localhost"))) {
+ perror("gethostbyname");
+ return -1;
+ }
+ memset(&sin, 0, sizeof sin);
+#ifdef FreeBSD
+ sin.sin_len = sizeof(sin);
+#endif
+ sin.sin_family = PF_INET;
+ memcpy(&sin.sin_addr, h->h_addr, h->h_length);
+ sin.sin_port = htons(NEW_CHATPORT);
+ cfd = socket(sin.sin_family, SOCK_STREAM, 0);
+ if(!(connect(cfd, (struct sockaddr *) & sin, sizeof sin)))
+ roomtype = 1;
+ else {
+ sin.sin_port = CHATPORT;
+ cfd = socket(sin.sin_family, SOCK_STREAM, 0);
+ if(!(connect(cfd, (struct sockaddr *) & sin, sizeof sin)))
+ roomtype = 2;
+ else {
+ outs("\n "
+ "哇! 沒人在那邊耶...要有那地方的人先去開門啦!...");
+ system("bin/xchatd");
+ pressanykey();
+ return -1;
+ }
+ }
+
+ while(1) {
+ getdata(b_lines - 1, 0, "請輸入聊天代號:", inbuf, 9, DOECHO);
+ sprintf(chatid, "%s", (inbuf[0] ? inbuf : cuser.userid));
+ chatid[8] = '\0';
+/*
+ 舊格式: /! 使用者編號 使用者等級 UserID ChatID
+ 新格式: /! UserID ChatID Password
+*/
+ if(roomtype == 1)
+ sprintf(inbuf, "/! %s %s %s",
+ cuser.userid, chatid, cuser.passwd);
+ else
+ sprintf(inbuf, "/! %d %d %s %s",
+ usernum, cuser.userlevel, cuser.userid, chatid);
+ chat_send(cfd, inbuf);
+ if(recv(cfd, inbuf, 3, 0) != 3)
+ return 0;
+ if(!strcmp(inbuf, CHAT_LOGIN_OK))
+ break;
+ else if(!strcmp(inbuf, CHAT_LOGIN_EXISTS))
+ ptr = "這個代號已經有人用了";
+ else if(!strcmp(inbuf, CHAT_LOGIN_INVALID))
+ ptr = "這個代號是錯誤的";
+ else if(!strcmp(inbuf, CHAT_LOGIN_BOGUS))
+ ptr = "請勿派遣分身進入聊天室 !!";
+
+ move(b_lines - 2, 0);
+ outs(ptr);
+ clrtoeol();
+ bell();
+ }
+
+ add_io(cfd, 0);
+
+ newmail = currchar = 0;
+ cmdpos = -1;
+ memset(lastcmd, 0, MAXLASTCMD * 80);
+
+ setutmpmode(CHATING);
+ currutmp->in_chat = YEA;
+ strcpy(currutmp->chatid, chatid);
+
+ clear();
+ chatline = 2;
+ strcpy(inbuf, chatid);
+ stop_line = t_lines - 3;
+
+ move(stop_line, 0);
+ outs(msg_seperator);
+ move(1, 0);
+ outs(msg_seperator);
+ print_chatid(chatid);
+ memset(inbuf, 0, 80);
+
+ sethomepath(fpath, cuser.userid);
+ strcpy(fpath, tempnam(fpath, "chat_"));
+ flog = fopen(fpath, "w");
+
+ while(chatting) {
+ move(b_lines - 1, currchar + chatid_len);
+ ch = igetkey();
+
+ switch(ch) {
+ case KEY_DOWN:
+ cmdpos += MAXLASTCMD - 2;
+ case KEY_UP:
+ cmdpos++;
+ cmdpos %= MAXLASTCMD;
+ strcpy(inbuf, lastcmd[cmdpos]);
+ move(b_lines - 1, chatid_len);
+ clrtoeol();
+ outs(inbuf);
+ currchar = strlen(inbuf);
+ continue;
+ case KEY_LEFT:
+ if(currchar)
+ --currchar;
+ continue;
+ case KEY_RIGHT:
+ if(inbuf[currchar])
+ ++currchar;
+ continue;
+ }
+
+ if(!newmail && currutmp->mailalert ) {
+ newmail = 1;
+ printchatline("◆ 噹!郵差又來了...");
+ }
+
+ if(ch == I_OTHERDATA) { /* incoming */
+ if(chat_recv(cfd, chatid) == -1) {
+ chatting = chat_send(cfd, "/b");
+ break;
+ }
+ continue;
+ }
+ if(isprint2(ch)) {
+ if(currchar < 68) {
+ if(inbuf[currchar]) { /* insert */
+ int i;
+
+ for(i = currchar; inbuf[i] && i < 68; i++);
+ inbuf[i + 1 ] = '\0';
+ for(; i > currchar; i--)
+ inbuf[i] = inbuf[i - 1];
+ } else /* append */
+ inbuf[currchar + 1] = '\0';
+ inbuf[currchar] = ch;
+ move(b_lines - 1, currchar + chatid_len);
+ outs(&inbuf[currchar++]);
+ }
+ continue;
+ }
+
+ if(ch == '\n' || ch == '\r') {
+ if(*inbuf) {
+ chatting = chat_cmd(inbuf, cfd);
+ if(chatting == 0)
+ chatting = chat_send(cfd, inbuf);
+ if(!strncmp(inbuf, "/b", 2))
+ break;
+
+ for(cmdpos = MAXLASTCMD - 1; cmdpos; cmdpos--)
+ strcpy(lastcmd[cmdpos], lastcmd[cmdpos - 1]);
+ strcpy(lastcmd[0], inbuf);
+
+ inbuf[0] = '\0';
+ currchar = 0;
+ cmdpos = -1;
+ }
+ print_chatid(chatid);
+ move(b_lines - 1, chatid_len);
+ continue;
+ }
+
+ if(ch == Ctrl('H') || ch == '\177') {
+ if(currchar) {
+ currchar--;
+ inbuf[69] = '\0';
+ memcpy(&inbuf[currchar], &inbuf[currchar + 1], 69 - currchar);
+ move(b_lines - 1, currchar + chatid_len);
+ clrtoeol();
+ outs(&inbuf[currchar]);
+ }
+ continue;
+ }
+ if(ch == Ctrl('Z') || ch == Ctrl('Y')) {
+ inbuf[0] = '\0';
+ currchar = 0;
+ print_chatid(chatid);
+ move(b_lines - 1, chatid_len);
+ continue;
+ }
+
+ if(ch == Ctrl('C')) {
+ chat_send(cfd, "/b");
+ break;
+ }
+ if(ch == Ctrl('D')) {
+ if(currchar < strlen(inbuf)) {
+ inbuf[69] = '\0';
+ memcpy(&inbuf[currchar], &inbuf[currchar + 1], 69 - currchar);
+ move(b_lines - 1, currchar + chatid_len);
+ clrtoeol();
+ outs(&inbuf[currchar]);
+ }
+ continue;
+ }
+ if(ch == Ctrl('K')) {
+ inbuf[currchar] = 0;
+ move(b_lines - 1, currchar + chatid_len);
+ clrtoeol();
+ continue;
+ }
+ if(ch == Ctrl('A')) {
+ currchar = 0;
+ continue;
+ }
+ if(ch == Ctrl('E')) {
+ currchar = strlen(inbuf);
+ continue;
+ }
+ if(ch == Ctrl('I')) {
+ extern screenline_t *big_picture;
+ screenline_t *screen0 = calloc(t_lines, sizeof(screenline_t));
+
+ memcpy(screen0, big_picture, t_lines * sizeof(screenline_t));
+ add_io(0, 0);
+ t_idle();
+ memcpy(big_picture, screen0, t_lines * sizeof(screenline_t));
+ free(screen0);
+ redoscr();
+ add_io(cfd, 0);
+ continue;
+ }
+ if(ch == Ctrl('Q')) {
+ print_chatid(chatid);
+ move(b_lines - 1, chatid_len);
+ outs(inbuf);
+ continue;
+ }
+ }
+
+ close(cfd);
+ add_io(0, 0);
+ currutmp->in_chat = currutmp->chatid[0] = 0;
+
+ if(flog) {
+ char ans[4];
+
+ fclose(flog);
+ more(fpath, NA);
+ getdata(b_lines - 1, 0, "清除(C) 移至備忘錄(M) (C/M)?[C]",
+ ans, 4, LCECHO);
+ if (*ans == 'm') {
+ fileheader_t mymail;
+ char title[128];
+
+ sethomepath(genbuf, cuser.userid);
+ stampfile(genbuf, &mymail);
+ mymail.savemode = 'H'; /* hold-mail flag */
+ mymail.filemode = FILE_READ;
+ strcpy(mymail.owner, "[備.忘.錄]");
+ strcpy(mymail.title, "會議\033[1;33m記錄\033[m");
+ sethomedir(title, cuser.userid);
+ append_record(title, &mymail, sizeof(mymail));
+ Rename(fpath, genbuf);
+ } else
+ unlink(fpath);
+ }
+
+ return 0;
+}
+/* -------------------------------------------------- */
+#if 0
+
+extern char page_requestor[];
+extern userinfo_t *currutmp;
+
+#endif