Esempio n. 1
0
File: chat.c Progetto: wyat/kbs
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);
}
Esempio n. 2
0
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));
                }
            }
        //}
    }
}
Esempio n. 4
0
File: chat.c Progetto: wyat/kbs
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;
}
Esempio n. 5
0
File: chat.c Progetto: wyat/kbs
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 ***");
            }
        }
    }
}
Esempio n. 6
0
File: chat.c Progetto: AoLaD/rtems
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 );
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}
Esempio n. 9
0
/*
 * 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;
}
Esempio n. 10
0
File: chat.c Progetto: wyat/kbs
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;
}
Esempio n. 11
0
File: chat.c Progetto: wyat/kbs
/* 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;
}
Esempio n. 12
0
File: chat.c Progetto: wyat/kbs
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, "*** 系统错误 ***");
            }
        }
    }
}
Esempio n. 13
0
File: chat.c Progetto: wyat/kbs
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);
                }
            }
        }
    }
}
Esempio n. 14
0
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;
}
Esempio n. 15
0
/* 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);
	}
}
Esempio n. 16
0
/*
 * 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;
    }
  }
}