Back to index

citadel  8.12
client_chat.c
Go to the documentation of this file.
00001 /*
00002  * front end for multiuser chat
00003  *
00004  * Copyright (c) 1987-2012 by the citadel.org team
00005  *
00006  * This program is open source software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License version 3.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  */
00014 
00015 #include "sysdep.h"
00016 #include <stdlib.h>
00017 #include <unistd.h>
00018 #include <stdio.h>
00019 #include <fcntl.h>
00020 #include <ctype.h>
00021 #include <string.h>
00022 #include <signal.h>
00023 #include <errno.h>
00024 
00025 #if TIME_WITH_SYS_TIME
00026 # include <sys/time.h>
00027 # include <time.h>
00028 #else
00029 # if HAVE_SYS_TIME_H
00030 #  include <sys/time.h>
00031 # else
00032 #  include <time.h>
00033 # endif
00034 #endif
00035 
00036 #include <sys/types.h>
00037 #ifdef HAVE_SYS_SELECT_H
00038 #include <sys/select.h>
00039 #endif
00040 #include <stdarg.h>
00041 #include <libcitadel.h>
00042 #include "citadel.h"
00043 #include "citadel_ipc.h"
00044 #include "client_chat.h"
00045 #include "commands.h"
00046 #include "routines.h"
00047 #include "citadel_decls.h"
00048 #include "rooms.h"
00049 #include "messages.h"
00050 #ifndef HAVE_SNPRINTF
00051 #include "snprintf.h"
00052 #endif
00053 #include "screen.h"
00054 
00055 #define MIN(a, b) ((a) < (b) ? (a) : (b))
00056 
00057 extern char temp[];
00058 char last_paged[SIZ] = "";
00059 
00060 void chatmode(CtdlIPC *ipc)
00061 {
00062        char wbuf[SIZ];
00063        char buf[SIZ];
00064        char response[SIZ];
00065        char c_user[SIZ];
00066        char c_text[SIZ];
00067        char last_user[SIZ];
00068        int send_complete_line;
00069        char ch;
00070        int a, pos;
00071        int seq = 0;
00072 
00073        fd_set rfds;
00074        struct timeval tv;
00075        int retval;
00076 
00077        CtdlIPC_chat_send(ipc, "RCHT enter");
00078        CtdlIPC_chat_recv(ipc, buf);
00079        if (buf[0] != '2') {
00080               scr_printf("%s\n", &buf[4]);
00081               return;
00082        }
00083        scr_printf("Entering chat mode (type /quit to exit)\n");
00084 
00085        strcpy(buf, "");
00086        strcpy(wbuf, "");
00087        strcpy(last_user, ""); 
00088        color(BRIGHT_YELLOW);
00089        scr_printf("\n");
00090        scr_printf("> ");
00091        send_complete_line = 0;
00092 
00093        while (1) {
00094               scr_flush();
00095               FD_ZERO(&rfds);
00096               FD_SET(0, &rfds);
00097               tv.tv_sec = 1;
00098               tv.tv_usec = 0;
00099               retval = select(1, &rfds, NULL, NULL, &tv);
00100 
00101               if (retval < 0) {
00102                      color(BRIGHT_WHITE);
00103                      scr_printf("Server gone Exiting chat mode\n");
00104                      scr_flush();
00105                      return;
00106               }
00107 
00108               /* If there's data from the keyboard... */
00109               if (FD_ISSET(0, &rfds)) {
00110                      ch = scr_getc(SCR_BLOCK);
00111                      if ((ch == 10) || (ch == 13)) {
00112                             send_complete_line = 1;
00113                      } else if ((ch == 8) || (ch == 127)) {
00114                             if (!IsEmptyStr(wbuf)) {
00115                                    wbuf[strlen(wbuf) - 1] = 0;
00116                                    scr_printf("%c %c", 8, 8);
00117                             }
00118                      } else {
00119                             scr_putc(ch);
00120                             wbuf[strlen(wbuf) + 1] = 0;
00121                             wbuf[strlen(wbuf)] = ch;
00122                      }
00123               }
00124 
00125               /* if the user hit return, send the line */
00126               if (send_complete_line) {
00127 
00128                      if (!strcasecmp(wbuf, "/quit")) {
00129                             CtdlIPC_chat_send(ipc, "RCHT exit");
00130                             CtdlIPC_chat_recv(ipc, response);  /* don't care about the result */
00131                             color(BRIGHT_WHITE);
00132                             scr_printf("\rExiting chat mode\n");
00133                             scr_flush();
00134                             return;
00135                      }
00136 
00137                      CtdlIPC_chat_send(ipc, "RCHT send");
00138                      CtdlIPC_chat_recv(ipc, response);
00139                      if (response[0] == '4') {
00140                             CtdlIPC_chat_send(ipc, wbuf);
00141                             CtdlIPC_chat_send(ipc, "000");
00142                      }
00143                      strcpy(wbuf, "");
00144                      send_complete_line = 0;
00145               }
00146 
00147               /* if it's time to word wrap, send a partial line */
00148               if (strlen(wbuf) >= (77 - strlen(fullname))) {
00149                      pos = 0;
00150                      for (a = 0; !IsEmptyStr(&wbuf[a]); ++a) {
00151                             if (wbuf[a] == 32)
00152                                    pos = a;
00153                      }
00154                      if (pos == 0) {
00155                             CtdlIPC_chat_send(ipc, "RCHT send");
00156                             CtdlIPC_chat_recv(ipc, response);
00157                             if (response[0] == '4') {
00158                                    CtdlIPC_chat_send(ipc, wbuf);
00159                                    CtdlIPC_chat_send(ipc, "000");
00160                             }
00161                             strcpy(wbuf, "");
00162                             send_complete_line = 0;
00163                      } else {
00164                             wbuf[pos] = 0;
00165                             CtdlIPC_chat_send(ipc, "RCHT send");
00166                             CtdlIPC_chat_recv(ipc, response);
00167                             if (response[0] == '4') {
00168                                    CtdlIPC_chat_send(ipc, wbuf);
00169                                    CtdlIPC_chat_send(ipc, "000");
00170                             }
00171                             strcpy(wbuf, &wbuf[pos + 1]);
00172                      }
00173               }
00174 
00175               /* poll for incoming chat messages */
00176               snprintf(buf, sizeof buf, "RCHT poll|%d", seq);
00177               CtdlIPC_chat_send(ipc, buf);
00178               CtdlIPC_chat_recv(ipc, response);
00179        
00180               if (response[0] == '1') {
00181                      seq = extract_int(&response[4], 0);
00182                      extract_token(c_user, &response[4], 2, '|', sizeof c_user);
00183                      while (CtdlIPC_chat_recv(ipc, c_text), strcmp(c_text, "000")) {
00184                             scr_printf("\r%79s\r", "");
00185                             if (!strcmp(c_user, fullname)) {
00186                                    color(BRIGHT_YELLOW);
00187                             } else if (!strcmp(c_user, ":")) {
00188                                    color(BRIGHT_RED);
00189                             } else {
00190                                    color(BRIGHT_GREEN);
00191                             }
00192                             if (strcmp(c_user, last_user)) {
00193                                    snprintf(buf, sizeof buf, "%s: %s", c_user, c_text);
00194                             } else {
00195                                    size_t i = MIN(sizeof buf - 1, strlen(c_user) + 2);
00196                                    memset(buf, ' ', i);
00197                                    safestrncpy(&buf[i], c_text, sizeof buf - i);
00198                             }
00199                             while (strlen(buf) < 79) {
00200                                    strcat(buf, " ");
00201                             }
00202                             if (strcmp(c_user, last_user)) {
00203                                    scr_printf("\r%79s\n", "");
00204                                    strcpy(last_user, c_user);
00205                             }
00206                             scr_printf("\r%s\n", buf);
00207                             scr_flush();
00208                      }
00209               }
00210               color(BRIGHT_YELLOW);
00211               scr_printf("\r> %s", wbuf);
00212               scr_flush();
00213               strcpy(buf, "");
00214        }
00215 }
00216 
00217 
00218 /*
00219  * send an instant message
00220  */
00221 void page_user(CtdlIPC *ipc)
00222 {
00223        char buf[SIZ], touser[SIZ], msg[SIZ];
00224        FILE *pagefp;
00225 
00226        strcpy(touser, last_paged);
00227        strprompt("Page who", touser, 30);
00228 
00229        /* old server -- use inline paging */
00230        if (ipc->ServInfo.paging_level == 0) {
00231               newprompt("Message: ", msg, 69);
00232               snprintf(buf, sizeof buf, "SEXP %s|%s", touser, msg);
00233               CtdlIPC_chat_send(ipc, buf);
00234               CtdlIPC_chat_recv(ipc, buf);
00235               if (!strncmp(buf, "200", 3)) {
00236                      strcpy(last_paged, touser);
00237               }
00238               scr_printf("%s\n", &buf[4]);
00239               return;
00240        }
00241        /* new server -- use extended paging */
00242        else if (ipc->ServInfo.paging_level >= 1) {
00243               snprintf(buf, sizeof buf, "SEXP %s||", touser);
00244               CtdlIPC_chat_send(ipc, buf);
00245               CtdlIPC_chat_recv(ipc, buf);
00246               if (buf[0] != '2') {
00247                      scr_printf("%s\n", &buf[4]);
00248                      return;
00249               }
00250               if (client_make_message(ipc, temp, touser, 0, 0, 0, NULL, 0) != 0) {
00251                      scr_printf("No message sent.\n");
00252                      return;
00253               }
00254               pagefp = fopen(temp, "r");
00255               unlink(temp);
00256               snprintf(buf, sizeof buf, "SEXP %s|-", touser);
00257               CtdlIPC_chat_send(ipc, buf);
00258               CtdlIPC_chat_recv(ipc, buf);
00259               if (buf[0] == '4') {
00260                      strcpy(last_paged, touser);
00261                      while (fgets(buf, sizeof buf, pagefp) != NULL) {
00262                             buf[strlen(buf) - 1] = 0;
00263                             CtdlIPC_chat_send(ipc, buf);
00264                      }
00265                      fclose(pagefp);
00266                      CtdlIPC_chat_send(ipc, "000");
00267                      scr_printf("Message sent.\n");
00268               } else {
00269                      scr_printf("%s\n", &buf[4]);
00270               }
00271        }
00272 }
00273 
00274 
00275 void quiet_mode(CtdlIPC *ipc)
00276 {
00277        static int quiet = 0;
00278        char cret[SIZ];
00279        int r;
00280 
00281        r = CtdlIPCEnableInstantMessageReceipt(ipc, !quiet, cret);
00282        if (r / 100 == 2) {
00283               quiet = !quiet;
00284               scr_printf("Quiet mode %sabled (%sother users may page you)\n",
00285                             (quiet) ? "en" : "dis",
00286                             (quiet) ? "no " : "");
00287        } else {
00288               scr_printf("Unable to change quiet mode: %s\n", cret);
00289        }
00290 }
00291 
00292 
00293 void stealth_mode(CtdlIPC *ipc)
00294 {
00295        static int stealth = 0;
00296        char cret[SIZ];
00297        int r;
00298 
00299        r = CtdlIPCStealthMode(ipc, !stealth, cret);
00300        if (r / 100 == 2) {
00301               stealth = !stealth;
00302               scr_printf("Stealth mode %sabled (you are %s)\n",
00303                             (stealth) ? "en" : "dis",
00304                             (stealth) ? "invisible" : "listed as online");
00305        } else {
00306               scr_printf("Unable to change stealth mode: %s\n", cret);
00307        }
00308 }