void call_query_ByChatid(chatcontext * pthis, const char *arg) { /* add by dong, 1998.9.12 */ char uident[32]; char tmpstr[40]; int res; if (!*arg) { printchatline(pthis, "*** 请输入要查询的chat ID ***"); return; } strncpy(uident, arg, 32); uident[31] = '\0'; /* get user id from the chat id */ sprintf(tmpstr, "/qc %s", uident); chat_send(pthis, tmpstr); res = chat_recv(pthis, tmpstr, 40); if (res <= 0) return; tmpstr[res] = '\0'; if (tmpstr[0] == '1') { sprintf(uident, "%s", tmpstr + 1); } else { sprintf(genbuf, "\033[32m这个chat ID不存在!\033[m"); printchatline(pthis, genbuf); return; } query_user(pthis, uident); }
int getty_chat(char *scrstr, int timeout, int debug) { int r = -1; chat_alarm = timeout ? timeout : CHAT_DEFAULT_TIMEOUT; chat_debug = debug; if (scrstr != NULL) { char **script; if (chat_debug & CHATDEBUG_MISC) syslog(LOG_DEBUG, "getty_chat script='%s'", scrstr); if ((script = read_chat(&scrstr)) != NULL) { int i = r = 0; int off = 0; sig_t old_alarm; /* * We need to be in raw mode for all this * Rely on caller... */ old_alarm = signal(SIGALRM, chat_alrm); chat_unalarm(); /* Force blocking mode at start */ /* * This is the send/expect loop */ while (r == 0 && script[i] != NULL) if ((r = chat_expect(script[i++])) == 0 && script[i] != NULL) r = chat_send(script[i++]); signal(SIGALRM, old_alarm); free(script); free(scrstr); /* * Ensure stdin is in blocking mode */ ioctl(STDIN_FILENO, FIONBIO, &off); } if (chat_debug & CHATDEBUG_MISC) syslog(LOG_DEBUG, "getty_chat %s", result(r)); } return r; }
void chat_forward_msg(uint8_t sender_id, char msg[129], linked_list_t *clients) { if (clients->count == 0){ return; } printf("[CHAT_SERVER] Forwarding message from ID %d: %.*s\n", sender_id, 128, msg); for (node_t *i = clients->head->next; i != clients->tail; i = i->next){ player_info_t *player = (player_info_t *)i->data; //if (player->playerID != sender_id){ if (player->chat_descriptor > 0){ if (chat_send(player->chat_descriptor, sender_id, msg) <= 0){ printf("[CHAT SERVER] Error sending to client %"SCNu8": %s\n", sender_id, strerror(errno)); } } //} } }
int chat_status(struct user_info *uentp, chatcontext * pthis) { char tmpstr[31],buf[80],buf2[80]; char *lpTmp; if (strlen(genbuf)>t_columns) return QUIT; if (uentp->invisible == 1) { if (HAS_PERM(getCurrentUser(), PERM_SEECLOAK)) { sprintf(genbuf + strlen(genbuf), "\x1b[32m#\x1b[m"); } else return 0; } lpTmp = (char *) idle_str(buf,uentp); if (uentp->in_chat) { /* add by Luzi 1997.11.18 */ int res; sprintf(tmpstr, "/q %s", uentp->userid); chat_send(pthis, tmpstr); res = chat_recv(pthis, tmpstr, 30); if (res <= 0) return -1; tmpstr[res] = '\0'; if (tmpstr[0] == '1') { sprintf(genbuf + strlen(genbuf), "'%s' room as '%s'", tmpstr + 1, uentp->chatid); if (lpTmp[0] != ' ') sprintf(genbuf + strlen(genbuf), "[%s];", lpTmp); else strcat(genbuf, " ;"); return COUNT; } } sprintf(genbuf, "%s%-8s", genbuf, modestring(buf2,uentp->mode, uentp->destuid, 0, /* 1->0 不显示聊天对象等 modified by dong 1996.10.26 */ (uentp->in_chat ? uentp-> chatid : NULL))); if (lpTmp[0] != ' ') sprintf(genbuf + strlen(genbuf), "[%s];", lpTmp); else strcat(genbuf, " ;"); return COUNT; }
void call_listen(chatcontext * pthis, const char *arg) { /* added by Luzi 1997.11.28 */ char path[40]; char uident[IDLEN + 1]; char ignoreuser[IDLEN + 1]; int nIdx; if (!*arg) { printchatline(pthis, "*** 请输入用户的ID ***"); } else if (!strcasecmp(arg, getCurrentUser()->userid)) printchatline(pthis, "*** 这是你自己的ID ***"); else { strncpy(uident, arg, IDLEN + 1); uident[IDLEN] = 0; if (!searchuser(uident)) /* change getuser -> searchuser, by dong, 1999.10.26 */ printchatline(pthis, "*** 没有这个ID ***"); else { sethomefile(path, getCurrentUser()->userid, "/ignores"); nIdx = search_record(path, ignoreuser, IDLEN + 1, (RECORD_FUNC_ARG) cmpinames, uident); if (nIdx <= 0) printchatline(pthis, "*** 该用户的聊天讯息没有被忽略啊 ***"); else if (delete_record(path, IDLEN + 1, nIdx, NULL, NULL) == 0) { bbslog("user", "listen %s", uident); printchatline(pthis, "*** 已恢复对该用户聊天讯息的接收 ***"); sprintf(uident, "/listen %s\n", uident); chat_send(pthis, uident); } else { bbslog("3error", "listen %s failed", uident); printchatline(pthis, "*** system error ***"); } } } }
int chatmain(int fd, int mode, char *pScript) { char arg[80]; char *script; /* initialize exit code */ exit_code = 0; ttyfd = fd; script=pScript; if ( debug ) { dbglog("chat_main: %s\n", script); } /* get first expect string */ script = getnextcommand(script,arg); while (( script != NULL ) && ( exit_code == 0 )) { /* process the expect string */ chat_expect(arg); if ( exit_code == 0 ) { /* get the next send string */ script = getnextcommand(script,arg); if ( script != NULL ) { /* process the send string */ chat_send(arg); /* get the next expect string */ script = getnextcommand(script,arg); } } } ttyfd = (int)-1; return ( exit_code ); }
void chat_expect(char *s) { char *expect; char *reply; if (strcmp(s, "HANGUP") == 0) { ++hup_next; return; } if (strcmp(s, "ABORT") == 0) { ++abort_next; return; } if (strcmp(s, "CLR_ABORT") == 0) { ++clear_abort_next; return; } if (strcmp(s, "REPORT") == 0) { ++report_next; return; } if (strcmp(s, "CLR_REPORT") == 0) { ++clear_report_next; return; } if (strcmp(s, "TIMEOUT") == 0) { ++timeout_next; return; } if (strcmp(s, "ECHO") == 0) { ++echo_next; return; } if (strcmp(s, "SAY") == 0) { ++say_next; return; } /* * Fetch the expect and reply string. */ for (;;) { expect = expect_strtok (s, "-"); s = (char *) 0; if (expect == (char *) 0) return; reply = expect_strtok (s, "-"); /* * Handle the expect string. If successful then exit. */ if (get_string (expect)) return; /* * If there is a sub-reply string then send it. Otherwise any condition * is terminal. */ if (reply == (char *) 0 || exit_code != 3) break; chat_send (reply); } /* * The expectation did not occur. This is terminal. */ if (fail_reason) chat_logf("Failed (%s)", fail_reason); else chat_logf("Failed"); terminate(exit_code); }
void do_file(char *chatfile) { int linect, sendflg; char *sp, *arg, quote; char buf [STR_LEN]; FILE *cfp; cfp = fopen (chatfile, "r"); if (cfp == NULL) fatal(1, "%s -- open failed: %m", chatfile); linect = 0; sendflg = 0; while (fgets(buf, STR_LEN, cfp) != NULL) { sp = strchr (buf, '\n'); if (sp) *sp = '\0'; linect++; sp = buf; /* lines starting with '#' are comments. If a real '#' is to be expected, it should be quoted .... */ if ( *sp == '#' ) continue; while (*sp != '\0') { if (*sp == ' ' || *sp == '\t') { ++sp; continue; } if (*sp == '"' || *sp == '\'') { quote = *sp++; arg = sp; while (*sp != quote) { if (*sp == '\0') fatal(1, "unterminated quote (line %d)", linect); if (*sp++ == '\\') { if (*sp != '\0') ++sp; } } } else { arg = sp; while (*sp != '\0' && *sp != ' ' && *sp != '\t') ++sp; } if (*sp != '\0') *sp++ = '\0'; if (sendflg) chat_send (arg); else chat_expect (arg); sendflg = !sendflg; } } fclose (cfp); }
/* * chat [-esSvV] [-f chat-file] [-r report-file] [-t timeout] * [-T phone-number] [-U phone-number2] [chat-script] * where chat-script has the form: * [...[[expect[-send[-expect...]] send expect[-send[-expect]] ...]]] * * Perform a UUCP-dialer-like chat script on stdin and stdout. */ int main(int argc, char *argv[]) { int option; tzset(); while ((option = getopt(argc, argv, "ef:r:sSt:T:U:vV")) != -1) { switch (option) { case 'e': ++echo; break; case 'f': if (chat_file != NULL) free(chat_file); chat_file = copy_of(optarg); break; case 'r': if (report_fp != NULL) fclose(report_fp); if (report_file != NULL) free(report_file); report_file = copy_of(optarg); report_fp = fopen(report_file, "a"); if (report_fp != NULL) { if (verbose) fprintf(report_fp, "Opening \"%s\"...\n", report_file); } else fatal(2, "cannot open \"%s\" for appending", report_file); break; case 's': ++to_stderr; break; case 'S': to_log = 0; break; case 't': timeout = atoi(optarg); break; case 'T': if (phone_num != NULL) free(phone_num); phone_num = copy_of(optarg); break; case 'U': if (phone_num2 != NULL) free(phone_num2); phone_num2 = copy_of(optarg); break; case 'v': ++verbose; break; case 'V': ++Verbose; break; default: usage(); break; } } argc -= optind; argv += optind; /* * Default the report file to the stderr location */ if (report_fp == NULL) report_fp = stderr; if (to_log) { openlog("chat", LOG_PID | LOG_NDELAY, LOG_LOCAL2); if (verbose) setlogmask(LOG_UPTO(LOG_INFO)); else setlogmask(LOG_UPTO(LOG_WARNING)); } if (chat_file != NULL) { if (*argv != NULL) usage(); else { init(); do_file(chat_file); } } else { init(); while (*argv != NULL && argc > 0) { chat_expect(*argv); argv++; argc--; if (*argv != NULL && argc > 0) { chat_send(*argv); argv++; argc--; } } } terminate(0); return 0; }
static int ent_chat(int chatnum) { /* 进入聊天室 */ chatcontext *pthis; char inbuf[128]; int ch, cmdpos; int currchar; int modified; /* the line is modified? -- wwj */ int newmail; int page_pending = false; int chatting = true; #ifdef NEW_HELP int oldhelpmode=helpmode; #endif if (!strcmp(getCurrentUser()->userid, "guest")) return -1; pthis = (chatcontext *) malloc(sizeof(chatcontext)); bzero(pthis, sizeof(chatcontext)); if (!pthis) return -1; modify_user_mode(CHAT1); ch = ent_chat_conn(pthis, chatnum); if (ch != 1) { free(pthis); return ch; } #ifdef NEW_HELP helpmode=HELP_CHAT; #endif add_io(pthis->cfd, 0); modified = newmail = cmdpos = currchar = 0; /* update uinfo */ uinfo.in_chat = true; strcpy(uinfo.chatid, pthis->chatid); UPDATE_UTMP(in_chat, uinfo); UPDATE_UTMP_STR(chatid, uinfo); /* initiate screen */ clear(); pthis->chatline = 2; move(s_lines, 0); outs(msg_seperator); move(1, 0); outs(msg_seperator); print_chatid(pthis); memset(inbuf, 0, 80); /* chat begin */ while (chatting) { if (chat_checkparse(pthis) == 0) break; move(b_lines, currchar + 10); pthis->outputcount = 0; ch = igetkey(); if (ch==KEY_TALK) { int talkpage = servicepage(0, pthis->buf); if (talkpage != page_pending) { bell(); oflush(); printchatline(pthis, pthis->buf); page_pending = talkpage; } } if (chat_checkparse(pthis) == 0) break; if (ch == I_OTHERDATA) continue; switch (ch) { case KEY_UP: case KEY_DOWN: if (cmdpos == pthis->cmdpos) { strcpy(pthis->lastcmd[cmdpos], inbuf); modified = 0; } if (ch == KEY_UP) { if (cmdpos != (pthis->cmdpos + 1) % MAXLASTCMD) { int i = (cmdpos + MAXLASTCMD - 1) % MAXLASTCMD; if (pthis->lastcmd[i][0]) cmdpos = i; } } if (ch == KEY_DOWN) { if (cmdpos != pthis->cmdpos) cmdpos = (cmdpos + 1) % MAXLASTCMD; } strcpy(inbuf, pthis->lastcmd[cmdpos]); if (cmdpos == pthis->cmdpos) { modified = 1; } move(b_lines, 10); clrtoeol(); ch = inbuf[69]; inbuf[69] = 0; outs(inbuf); inbuf[69] = ch; currchar = strlen(inbuf); continue; #ifdef CHINESE_CHARACTER case Ctrl('R'): SET_CHANGEDEFINE(getCurrentUser(), DEF_CHCHAR); continue; #endif case KEY_LEFT: if (currchar) --currchar; #ifdef CHINESE_CHARACTER if (DEFINE(getCurrentUser(), DEF_CHCHAR)) { int i,j=0; for (i=0;i<currchar;i++) if (j) j=0; else if (inbuf[i]<0) j=1; if (j) { currchar--; } } #endif continue; case KEY_RIGHT: if (inbuf[currchar]) ++currchar; #ifdef CHINESE_CHARACTER if (DEFINE(getCurrentUser(), DEF_CHCHAR)) { int i,j=0; for (i=0;i<currchar;i++) if (j) j=0; else if (inbuf[i]<0) j=1; if (j) { if (inbuf[currchar]) ++currchar; } } #endif continue; case KEY_ESC: case Ctrl('X'): inbuf[0] = 0; currchar = 0; move(b_lines, currchar + 10); clrtoeol(); modified = 1; continue; case Ctrl('A'): currchar = 0; continue; case Ctrl('E'): currchar = strlen(inbuf); continue; } if (!newmail && chkmail(0)) { /* check mail */ newmail = 1; printchatline(pthis, "\033[32m*** \033[31m当!你有新信来啦...\033[m"); } if (isprint2(ch)) { if (currchar < 126) { /* 未满一行,print it */ modified = 1; if (inbuf[currchar]) { /* insert */ int i; for (i = currchar; inbuf[i] && i < 127; i++); inbuf[i + 1] = '\0'; for (; i > currchar; i--) inbuf[i] = inbuf[i - 1]; } else { /* append */ inbuf[currchar + 1] = '\0'; } inbuf[currchar] = ch; ch = inbuf[69]; /* save the end of line */ inbuf[69] = 0; move(b_lines, currchar + 10); outs(&inbuf[currchar++]); inbuf[69] = ch; } continue; } if (ch == '\n' || ch == '\r') { if (currchar) { if (modified) { /* add to command history */ ch = sizeof(pthis->lastcmd[pthis->cmdpos]) - 1; strncpy(pthis->lastcmd[pthis->cmdpos], inbuf, ch); pthis->lastcmd[pthis->cmdpos][ch] = 0; pthis->cmdpos = (pthis->cmdpos + 1) % MAXLASTCMD; cmdpos = pthis->cmdpos; } else { /* use history, so can +1 */ cmdpos = (cmdpos + 1) % MAXLASTCMD; } if (inbuf[0] == '/' && Isspace(inbuf[1])) { /* discard / b */ printchatline(pthis, "\x1b[37m*** \x1b[32m请输入正确的指令,使用/h寻求帮助\x1b[37m ***\x1b[m"); } else { chatting = chat_cmd(pthis, inbuf); /*local命令处理 */ if (chatting == 0) chatting = chat_send(pthis, inbuf); if (inbuf[0] == '/') { ch = 1; while (inbuf[ch] != '\0' && inbuf[ch] != ' ') ch++; if (ch > 1) { if (!strncasecmp(inbuf, "/bye", ch)) break; if (!strncasecmp(inbuf, "/exit", ch)) break; /*added by alex, 96.9.5 */ } } } modified = 0; inbuf[0] = '\0'; currchar = 0; move(b_lines, 10); clrtoeol(); } continue; } if (ch == Ctrl('H') || ch == '\177') { /*Backspace */ if (currchar) { currchar--; inbuf[127] = '\0'; memcpy(&inbuf[currchar], &inbuf[currchar + 1], 127 - currchar); move(b_lines, currchar + 10); clrtoeol(); ch = inbuf[69]; /* save the end of line */ inbuf[69] = 0; outs(&inbuf[currchar]); inbuf[69] = ch; } #ifdef CHINESE_CHARACTER if (DEFINE(getCurrentUser(), DEF_CHCHAR)) { int i,j=0; for (i=0;i<currchar;i++) if (j) j=0; else if (inbuf[i]<0) j=1; if (j) { currchar--; inbuf[127] = '\0'; memcpy(&inbuf[currchar], &inbuf[currchar + 1], 127 - currchar); move(b_lines, currchar + 10); clrtoeol(); ch = inbuf[69]; /* save the end of line */ inbuf[69] = 0; outs(&inbuf[currchar]); inbuf[69] = ch; } } #endif continue; } if (ch == Ctrl('Z')) { r_lastmsg(); /* Leeward 98.07.30 support msgX */ inbuf[0] = '\0'; currchar = 0; move(b_lines, 10); clrtoeol(); continue; } if (ch == Ctrl('C') /*|| ch == Ctrl('D') */) { /* ^C 退出 */ chat_send(pthis, "/b"); if (pthis->rec) set_rec(pthis,NULL); break; } } /* chat end */ if (pthis->rec)set_rec(pthis,NULL); close(pthis->cfd); add_io(0, 0); uinfo.in_chat = false; uinfo.chatid[0] = '\0'; UPDATE_UTMP(in_chat, uinfo); UPDATE_UTMP(chatid[0], uinfo); clear(); free(pthis); #ifdef NEW_HELP helpmode=oldhelpmode; #endif return 0; }
/* 2001/5/6 --wwj, 修改 ent_chat 函数 */ int ent_chat_conn(chatcontext * pthis, int chatnum) { struct sockaddr_in sin; int ch; char inbuf[128], *ptr; memset(&sin, 0, sizeof sin); sin.sin_family = PF_INET; sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); /* sin.sin_addr.s_addr = inet_addr("166.111.8.237"); */ if (chatnum == 1) sin.sin_port = htons(CHATPORT3); else sin.sin_port = htons(CHATPORT2); pthis->cfd = socket(sin.sin_family, SOCK_STREAM, 0); if (connect(pthis->cfd, (struct sockaddr *) &sin, sizeof sin)) { /*如果连接 chatd 失败,则启动chatd */ close(pthis->cfd); switch (ch = fork()) { case -1 /*fork failure */ : bbslog("chatd", "fork error"); break; case 0 /*fork success */ : bbslog("chatd", "fork success"); prints("开启聊天室..."); if (chatnum == 1) system("bin/chatd"); else system("bin/chatd 2"); exit(1); default: bbslog("chatd", "fork par-proc"); /* The chat daemon forks so we can wait on it here. */ waitpid(ch, NULL, 0); } pthis->cfd = socket(sin.sin_family, SOCK_STREAM, 0); if ((connect(pthis->cfd, (struct sockaddr *) &sin, sizeof sin))) { close(pthis->cfd); bbslog("chatd", "connect2 failed %d", errno); return -1; } } /* Leeward 98.04.26 */ move(3, 0); clrtoeol(); move(4, 0); /* Leave line 3 for error message while entering chat room */ prints ("输入字符 \033[1m\033[37m*\033[m 再按 \033[1m\033[37mEnter\033[m 可以取消进入聊天室。 "); clrtoeol(); move(5, 0); clrtoeol(); /* Clear line 5 for good looking */ while (1) { int gdataret; gdataret = getdata(2, 0, "请输入聊天代号:", inbuf, 9, DOECHO, NULL, true); if (gdataret == -1 || '*' == inbuf[0]) { /* Leeward 98.04.26 */ close(pthis->cfd); return 0; } if (inbuf[0] != '\0' && inbuf[0] != '\n' && inbuf[0] != '/') { strncpy(pthis->chatid, inbuf, 8); } else { strncpy(pthis->chatid, getCurrentUser()->userid, 8); } pthis->chatid[8] = '\0'; sprintf(inbuf, "/! %d %d %s %s", uinfo.uid, getCurrentUser()->userlevel, getCurrentUser()->userid, pthis->chatid); chat_send(pthis, inbuf); /* send user info to chatd , and chatd will check it */ if (chat_recv(pthis, inbuf, 3) != 3) { close(pthis->cfd); 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 ptr = "已经有一个窗口在聊天室里了(若非如此请退出BBS重新登录;若还不行再找在线站长)"; move(3, 0); prints(ptr); clrtoeol(); bell(); } return 1; }
void call_alias(chatcontext * pthis, const char *arg) { /* added by Luzi 1998.01.25 */ char buf[128], buf2[200]; FILE *fp; char path[40]; char emoteid[40]; int nIdx; nextword(&arg, emoteid, sizeof(emoteid)); sethomefile(path, getCurrentUser()->userid, "/emotes"); if (!emoteid[0]) { if ((fp = fopen(path, "r")) == NULL) { printchatline(pthis, "*** 还没有自定义的emote ***"); return; } nIdx = 0; printchatline(pthis, "〖用户自定义emote列表〗"); while (fread(buf, 128, 1, fp) > 0) { printchatline(pthis, buf); } fclose(fp); } else { nIdx = 0; if ((fp = fopen(path, "r")) != NULL) { while (1) { const char *tmpbuf; char tmpemote[40]; if (fread(buf, 128, 1, fp) == 0) { nIdx = 0; break; } tmpbuf = buf; nextword(&tmpbuf, tmpemote, sizeof(tmpemote)); nIdx++; if (strcasecmp(emoteid, tmpemote) == 0) break; } fclose(fp); } if (nIdx > 0) { if (*arg) { printchatline(pthis, "*** 该emote已经被定义过了 ***"); return; } if (delete_record(path, 128, nIdx, NULL, NULL) == 0) { printchatline(pthis, "*** 该自定义emote已经被删除了 ***"); sprintf(buf, "/alias_del %s", emoteid); chat_send(pthis, buf); } else { bbslog("3error", "delete alias %s fail", emoteid); printchatline(pthis, "*** system error ***"); } } else if (!*arg) printchatline(pthis, "*** 请指定emote对应的字串 ***"); else { fp = fopen(path, "r"); if (fp != NULL) { fseek(fp, 0, SEEK_END); if (ftell(fp) >= 128 * MAX_EMOTES) { fclose(fp); printchatline(pthis, "*** 用户自定义emote的列表已满 ***"); return; } fclose(fp); } sprintf(buf, "%s %s", emoteid, arg); if (append_record(path, buf, 128) == 0) { printchatline(pthis, "*** 自定义emote已经设定 ***"); sprintf(buf2, "/alias_add %s", buf); chat_send(pthis, buf2); } else { bbslog("3error", "add alias %s fail", emoteid); printchatline(pthis, "*** 系统错误 ***"); } } } }
void call_ignore(chatcontext * pthis, const char *arg) { /* added by Luzi 1997.11.28 */ char buf[STRLEN], buf2[76]; FILE *fp; char uident[IDLEN + 1]; char path[40]; char ignoreuser[IDLEN + 1]; int nIdx; sethomefile(path, getCurrentUser()->userid, "/ignores"); if (!*arg) { nIdx = 0; if ((fp = fopen(path, "r")) != NULL) { strcpy(buf2, "【忽略其讯息的用户ID列表】"); while (fread(buf, IDLEN + 1, 1, fp) > -0) { if (nIdx % 4 == 0) { printchatline(pthis, buf2); *buf2 = '\0'; } nIdx++; sprintf(buf2 + strlen(buf2), " %-13s", buf); } fclose(fp); } if (nIdx > 0) printchatline(pthis, buf2); else printchatline(pthis, "*** 尚未设定忽略用户的名单 ***"); } else if (!strcasecmp(arg, getCurrentUser()->userid)) printchatline(pthis, "*** 无法忽略自己的信息 ***"); else { strncpy(uident, arg, IDLEN + 1); uident[IDLEN] = 0; if (!searchuser(uident)) /* change getuser -> searchuser, by dong, 1999.10.26 */ printchatline(pthis, "*** 没有这个 ID ***"); else { nIdx = search_record(path, ignoreuser, IDLEN + 1, (RECORD_FUNC_ARG) cmpinames, uident); if (nIdx > 0) printchatline(pthis, "*** 该ID已经被忽略了 ***"); else { fp = fopen(path, "r"); if (fp != NULL) { fseek(fp, 0, SEEK_END); if (ftell(fp) >= (IDLEN + 1) * MAX_IGNORE) { fclose(fp); printchatline(pthis, "*** 忽略用户名单已满 ***"); return; } fclose(fp); } if (append_record(path, uident, IDLEN + 1) == 0) { printchatline(pthis, "*** 忽略已经设定 ***"); bbslog("user", "ignore %s", uident); sprintf(buf, "/ignore %s", uident); chat_send(pthis, buf); } else { printchatline(pthis, "*** 系统错误 ***"); bbslog("3error", "ignore %s failed", uident); } } } } }
static int chat_line_run(FAR struct chat* priv, FAR const struct chat_line* line) { int ret = 0; int numarg; vdbg("type %d, rhs %s\n", line->type, line->rhs); switch (line->type) { case CHAT_LINE_TYPE_COMMAND: if (priv->ctl.verbose) { fprintf(stderr, "chat: cmd %d, arg %s\n", line->lhs.command, line->rhs); } switch (line->lhs.command) { case CHAT_COMMAND_ABORT: /* TODO */ break; case CHAT_COMMAND_ECHO: if (strcmp(line->rhs, "ON")) { priv->ctl.echo = true; } else { priv->ctl.echo = false; } break; case CHAT_COMMAND_PAUSE: numarg = atoi(line->rhs); if (numarg < 0) { numarg = 0; } sleep(numarg); break; case CHAT_COMMAND_SAY: fprintf(stderr, "%s\n", line->rhs); break; case CHAT_COMMAND_TIMEOUT: numarg = atoi(line->rhs); if (numarg < 0) { vdbg("invalid timeout string %s\n", line->rhs); } else { vdbg("timeout is %d s\n", numarg); priv->ctl.timeout = numarg; } break; default: break; } break; case CHAT_LINE_TYPE_EXPECT_SEND: if (priv->ctl.verbose) { fprintf(stderr, "chat: %s %s\n", line->lhs.expect, line->rhs); } ret = chat_expect(priv, line->lhs.expect); if (!ret) { /* Discard anything after the confirmed expectation */ chat_flush(priv); ret = chat_send(priv, line->rhs); } break; default: ret = -EINVAL; break; } return ret; }
/* NB. this starts the input thread after some initial setup for the call leg */ void conference_loop_output(conference_member_t *member) { switch_channel_t *channel; switch_frame_t write_frame = { 0 }; uint8_t *data = NULL; switch_timer_t timer = { 0 }; uint32_t interval; uint32_t samples; //uint32_t csamples; uint32_t tsamples; uint32_t flush_len; uint32_t low_count, bytes; call_list_t *call_list, *cp; switch_codec_implementation_t read_impl = { 0 }; int sanity; switch_status_t st; switch_core_session_get_read_impl(member->session, &read_impl); channel = switch_core_session_get_channel(member->session); interval = read_impl.microseconds_per_packet / 1000; samples = switch_samples_per_packet(member->conference->rate, interval); //csamples = samples; tsamples = member->orig_read_impl.samples_per_packet; low_count = 0; bytes = samples * 2 * member->conference->channels; call_list = NULL; cp = NULL; member->loop_loop = 0; switch_assert(member->conference != NULL); flush_len = switch_samples_per_packet(member->conference->rate, member->conference->interval) * 2 * member->conference->channels * (500 / member->conference->interval); if (switch_core_timer_init(&timer, member->conference->timer_name, interval, tsamples, NULL) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_ERROR, "Timer Setup Failed. Conference Cannot Start\n"); return; } switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Setup timer %s success interval: %u samples: %u\n", member->conference->timer_name, interval, tsamples); write_frame.data = data = switch_core_session_alloc(member->session, SWITCH_RECOMMENDED_BUFFER_SIZE); write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; write_frame.codec = &member->write_codec; /* Start the input thread */ conference_loop_launch_input(member, switch_core_session_get_pool(member->session)); if ((call_list = switch_channel_get_private(channel, "_conference_autocall_list_"))) { const char *cid_name = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_name"); const char *cid_num = switch_channel_get_variable(channel, "conference_auto_outcall_caller_id_number"); const char *toval = switch_channel_get_variable(channel, "conference_auto_outcall_timeout"); const char *flags = switch_channel_get_variable(channel, "conference_utils_auto_outcall_flags"); const char *profile = switch_channel_get_variable(channel, "conference_auto_outcall_profile"); const char *ann = switch_channel_get_variable(channel, "conference_auto_outcall_announce"); const char *prefix = switch_channel_get_variable(channel, "conference_auto_outcall_prefix"); const char *maxwait = switch_channel_get_variable(channel, "conference_auto_outcall_maxwait"); const char *delimiter_val = switch_channel_get_variable(channel, "conference_auto_outcall_delimiter"); int to = 60; int wait_sec = 2; int loops = 0; if (ann && !switch_channel_test_app_flag_key("conference_silent", channel, CONF_SILENT_REQ)) { member->conference->special_announce = switch_core_strdup(member->conference->pool, ann); } switch_channel_set_private(channel, "_conference_autocall_list_", NULL); conference_utils_set_flag(member->conference, CFLAG_OUTCALL); if (toval) { to = atoi(toval); if (to < 10 || to > 500) { to = 60; } } for (cp = call_list; cp; cp = cp->next) { int argc; char *argv[512] = { 0 }; char *cpstr = strdup(cp->string); int x = 0; switch_assert(cpstr); if (!zstr(delimiter_val) && strlen(delimiter_val) == 1) { char delimiter = *delimiter_val; argc = switch_separate_string(cpstr, delimiter, argv, (sizeof(argv) / sizeof(argv[0]))); } else { argc = switch_separate_string(cpstr, ',', argv, (sizeof(argv) / sizeof(argv[0]))); } for (x = 0; x < argc; x++) { char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); switch_assert(dial_str); conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL, profile, &member->conference->cancel_cause, NULL); switch_safe_free(dial_str); } switch_safe_free(cpstr); } if (maxwait) { int tmp = atoi(maxwait); if (tmp > 0) { wait_sec = tmp; } } loops = wait_sec * 10; switch_channel_set_app_flag(channel, CF_APP_TAGGED); do { switch_ivr_sleep(member->session, 100, SWITCH_TRUE, NULL); } while(switch_channel_up(channel) && (member->conference->originating && --loops)); switch_channel_clear_app_flag(channel, CF_APP_TAGGED); if (!switch_channel_ready(channel)) { member->conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; goto end; } conference_member_play_file(member, "tone_stream://%(500,0,640)", 0, SWITCH_TRUE); } if (!conference_utils_test_flag(member->conference, CFLAG_ANSWERED)) { switch_channel_answer(channel); } sanity = 2000; while(!conference_utils_member_test_flag(member, MFLAG_ITHREAD) && sanity > 0) { switch_cond_next(); sanity--; } /* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed, */ /* you better not block this thread loop for more than the duration of member->conference->timer_name! */ while (!member->loop_loop && conference_utils_member_test_flag(member, MFLAG_RUNNING) && conference_utils_member_test_flag(member, MFLAG_ITHREAD) && switch_channel_ready(channel)) { switch_event_t *event; int use_timer = 0; switch_buffer_t *use_buffer = NULL; uint32_t mux_used = 0; //if (member->reset_media || switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) { // switch_cond_next(); // continue; //} switch_mutex_lock(member->write_mutex); if (switch_channel_test_flag(member->channel, CF_CONFERENCE_ADV)) { if (member->conference->la) { conference_event_adv_la(member->conference, member, SWITCH_TRUE); } switch_channel_clear_flag(member->channel, CF_CONFERENCE_ADV); } if (switch_core_session_dequeue_event(member->session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { if (event->event_id == SWITCH_EVENT_MESSAGE) { char *from = switch_event_get_header(event, "from"); char *to = switch_event_get_header(event, "to"); char *body = switch_event_get_body(event); if (to && from && body) { if (strchr(to, '+') && strncmp(to, CONF_CHAT_PROTO, strlen(CONF_CHAT_PROTO))) { switch_event_del_header(event, "to"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s+%s@%s", CONF_CHAT_PROTO, member->conference->name, member->conference->domain); } else { switch_event_del_header(event, "to"); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "to", "%s", member->conference->name); } chat_send(event); } } switch_event_destroy(&event); } if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { /* test to see if outbound channel has answered */ if (switch_channel_test_flag(channel, CF_ANSWERED) && !conference_utils_test_flag(member->conference, CFLAG_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "Outbound conference channel answered, setting CFLAG_ANSWERED\n"); conference_utils_set_flag(member->conference, CFLAG_ANSWERED); } } else { if (conference_utils_test_flag(member->conference, CFLAG_ANSWERED) && !switch_channel_test_flag(channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(member->session), SWITCH_LOG_DEBUG, "CLFAG_ANSWERED set, answering inbound channel\n"); switch_channel_answer(channel); } } use_buffer = NULL; mux_used = (uint32_t) switch_buffer_inuse(member->mux_buffer); use_timer = 1; if (mux_used) { if (mux_used < bytes) { if (++low_count >= 5) { /* partial frame sitting around this long is useless and builds delay */ conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER); } } else if (mux_used > flush_len) { /* getting behind, clear the buffer */ conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER); } } if (switch_channel_test_app_flag(channel, CF_APP_TAGGED)) { conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER); } else if (mux_used >= bytes) { /* Flush the output buffer and write all the data (presumably muxed) back to the channel */ switch_mutex_lock(member->audio_out_mutex); write_frame.data = data; use_buffer = member->mux_buffer; low_count = 0; if ((write_frame.datalen = (uint32_t) switch_buffer_read(use_buffer, write_frame.data, bytes))) { if (write_frame.datalen) { write_frame.samples = write_frame.datalen / 2 / member->conference->channels; if( !conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)) { memset(write_frame.data, 255, write_frame.datalen); } else if (member->volume_out_level) { /* Check for output volume adjustments */ switch_change_sln_volume(write_frame.data, write_frame.samples * member->conference->channels, member->volume_out_level); } write_frame.timestamp = timer.samplecount; if (member->fnode) { conference_member_add_file_data(member, write_frame.data, write_frame.datalen); } conference_member_check_channels(&write_frame, member, SWITCH_FALSE); if (switch_core_session_write_frame(member->session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { switch_mutex_unlock(member->audio_out_mutex); break; } } } switch_mutex_unlock(member->audio_out_mutex); } if (conference_utils_member_test_flag(member, MFLAG_FLUSH_BUFFER)) { if (switch_buffer_inuse(member->mux_buffer)) { switch_mutex_lock(member->audio_out_mutex); switch_buffer_zero(member->mux_buffer); switch_mutex_unlock(member->audio_out_mutex); } conference_utils_member_clear_flag_locked(member, MFLAG_FLUSH_BUFFER); } switch_mutex_unlock(member->write_mutex); if (conference_utils_member_test_flag(member, MFLAG_INDICATE_MUTE)) { if (!zstr(member->conference->muted_sound)) { conference_member_play_file(member, member->conference->muted_sound, 0, SWITCH_TRUE); } else { char msg[512]; switch_snprintf(msg, sizeof(msg), "Muted"); conference_member_say(member, msg, 0); } conference_utils_member_clear_flag(member, MFLAG_INDICATE_MUTE); } if (conference_utils_member_test_flag(member, MFLAG_INDICATE_MUTE_DETECT)) { if (!zstr(member->conference->mute_detect_sound)) { conference_member_play_file(member, member->conference->mute_detect_sound, 0, SWITCH_TRUE); } else { char msg[512]; switch_snprintf(msg, sizeof(msg), "Currently Muted"); conference_member_say(member, msg, 0); } conference_utils_member_clear_flag(member, MFLAG_INDICATE_MUTE_DETECT); } if (conference_utils_member_test_flag(member, MFLAG_INDICATE_UNMUTE)) { if (!zstr(member->conference->unmuted_sound)) { conference_member_play_file(member, member->conference->unmuted_sound, 0, SWITCH_TRUE); } else { char msg[512]; switch_snprintf(msg, sizeof(msg), "Un-Muted"); conference_member_say(member, msg, 0); } conference_utils_member_clear_flag(member, MFLAG_INDICATE_UNMUTE); } if (switch_core_session_private_event_count(member->session)) { switch_channel_set_app_flag(channel, CF_APP_TAGGED); switch_ivr_parse_all_events(member->session); switch_channel_clear_app_flag(channel, CF_APP_TAGGED); conference_utils_member_set_flag_locked(member, MFLAG_FLUSH_BUFFER); switch_core_session_set_read_codec(member->session, &member->read_codec); } else { switch_ivr_parse_all_messages(member->session); } if (use_timer) { switch_core_timer_next(&timer); } else { switch_cond_next(); } } /* Rinse ... Repeat */ end: if (!member->loop_loop) { conference_utils_member_clear_flag_locked(member, MFLAG_RUNNING); /* Wait for the input thread to end */ if (member->input_thread) { switch_thread_join(&st, member->input_thread); member->input_thread = NULL; } } switch_core_timer_destroy(&timer); if (member->loop_loop) { return; } switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_INFO, "Channel leaving conference, cause: %s\n", switch_channel_cause2str(switch_channel_get_cause(channel))); /* if it's an outbound channel, store the release cause in the conference struct, we might need it */ if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) { member->conference->bridge_hangup_cause = switch_channel_get_cause(channel); } }
/* * Processes the chat. This needs to be called iteratively until the chat_cb() * callback function posts success or an error. */ void chat_poll(struct chat *chat) { int done = 0; int err; LWIP_ASSERT("chat_poll: chat != NULL", chat != NULL); while (!done) { switch (chat->state) { case STATE_INITIAL: /* Check item command */ switch (chat->item->cmd) { case CHAT_ABORT: chat->state = STATE_NEXT_ITEM; break; case CHAT_SAY: LWIP_DEBUGF(PPP_DEBUG, ("chat_poll: SAY '%s'\n", chat->item->arg)); chat->state = STATE_NEXT_ITEM; break; case CHAT_SEND: LWIP_DEBUGF(PPP_DEBUG, ("chat_poll: SEND '%s'\n", chat->item->arg)); chat_send(chat, chat->item); chat->state = STATE_NEXT_ITEM; break; case CHAT_SEND_CB: LWIP_DEBUGF(PPP_DEBUG, ("chat_poll: SEND_CB '%d'\n", (int) chat->item->arg)); chat_send_cb(chat, chat->item); chat->state = STATE_NEXT_ITEM; break; case CHAT_WAIT: LWIP_DEBUGF(PPP_DEBUG, ("chat_poll: WAIT '%s'\n", chat->item->arg)); chat->timeleft = chat->timeout; chat->state = STATE_WAIT; break; case CHAT_SLEEP: LWIP_DEBUGF(PPP_DEBUG, ("chat_poll: SLEEP\n")); chat->timeleft = 1000 + 1; if (chat->item->arg) chat->timeleft = (int) chat->item->arg + 1; chat->state = STATE_SLEEP; break; case CHAT_LAST: LWIP_DEBUGF(PPP_DEBUG, ("chat_poll: SUCCESS\n")); chat->chat_cb(chat, CHAT_ERR_OK, chat->arg); chat->state = STATE_IDLE; break; } break; case STATE_WAIT: err = chat_wait(chat, chat->item); if (err == -1) { done = 1; } else if (err == CHAT_ERR_OK) { chat->state = STATE_NEXT_ITEM; } else { chat->chat_cb(chat, err, chat->arg); chat->state = STATE_IDLE; } break; case STATE_SLEEP: if (chat->timeleft == 0) chat->state = STATE_NEXT_ITEM; else done = 1; break; case STATE_NEXT_ITEM: chat->item++; chat->state = STATE_INITIAL; break; case STATE_IDLE: done = 1; break; } } }