Grammar change in the license declaration.
[citadel.git] / textclient / client_chat.c
1 // front end for multiuser chat
2 //
3 // Copyright (c) 1987-2016 by the citadel.org team
4 //
5 // This program is open source software.  Use, duplication, and/or
6 // disclosure is subject to the GNU General Purpose License version 3.
7 //
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 // GNU General Public License for more details.
12
13 #include "textclient.h"
14
15 #define MIN(a, b) ((a) < (b) ? (a) : (b))
16
17 extern char temp[];
18 char last_paged[SIZ] = "";
19
20 void chatmode(CtdlIPC * ipc) {
21         char wbuf[SIZ];
22         char buf[SIZ];
23         char response[SIZ];
24         char c_user[SIZ];
25         char c_text[SIZ];
26         char last_user[SIZ];
27         int send_complete_line;
28         char ch;
29         int a, pos;
30         int seq = 0;
31
32         fd_set rfds;
33         struct timeval tv;
34         int retval;
35
36         CtdlIPC_chat_send(ipc, "RCHT enter");
37         CtdlIPC_chat_recv(ipc, buf);
38         if (buf[0] != '2') {
39                 scr_printf("%s\n", &buf[4]);
40                 return;
41         }
42         scr_printf("Entering chat mode (type /quit to exit)\n");
43
44         strcpy(buf, "");
45         strcpy(wbuf, "");
46         strcpy(last_user, "");
47         color(BRIGHT_YELLOW);
48         scr_printf("\n");
49         scr_printf("> ");
50         send_complete_line = 0;
51
52         while (1) {
53                 scr_flush();
54                 FD_ZERO(&rfds);
55                 FD_SET(0, &rfds);
56                 tv.tv_sec = 1;
57                 tv.tv_usec = 0;
58                 retval = select(1, &rfds, NULL, NULL, &tv);
59
60                 if (retval < 0) {
61                         color(BRIGHT_WHITE);
62                         scr_printf("Server gone Exiting chat mode\n");
63                         scr_flush();
64                         return;
65                 }
66
67                 /* If there's data from the keyboard... */
68                 if (FD_ISSET(0, &rfds)) {
69                         ch = scr_getc(SCR_BLOCK);
70                         if ((ch == 10) || (ch == 13)) {
71                                 send_complete_line = 1;
72                         }
73                         else if ((ch == 8) || (ch == 127)) {
74                                 if (!IsEmptyStr(wbuf)) {
75                                         wbuf[strlen(wbuf) - 1] = 0;
76                                         scr_printf("%c %c", 8, 8);
77                                 }
78                         }
79                         else {
80                                 scr_putc(ch);
81                                 wbuf[strlen(wbuf) + 1] = 0;
82                                 wbuf[strlen(wbuf)] = ch;
83                         }
84                 }
85
86                 /* if the user hit return, send the line */
87                 if (send_complete_line) {
88
89                         if (!strcasecmp(wbuf, "/quit")) {
90                                 CtdlIPC_chat_send(ipc, "RCHT exit");
91                                 CtdlIPC_chat_recv(ipc, response);       /* don't care about the result */
92                                 color(BRIGHT_WHITE);
93                                 scr_printf("\rExiting chat mode\n");
94                                 scr_flush();
95                                 return;
96                         }
97
98                         CtdlIPC_chat_send(ipc, "RCHT send");
99                         CtdlIPC_chat_recv(ipc, response);
100                         if (response[0] == '4') {
101                                 CtdlIPC_chat_send(ipc, wbuf);
102                                 CtdlIPC_chat_send(ipc, "000");
103                         }
104                         strcpy(wbuf, "");
105                         send_complete_line = 0;
106                 }
107
108                 /* if it's time to word wrap, send a partial line */
109                 if (strlen(wbuf) >= (77 - strlen(fullname))) {
110                         pos = 0;
111                         for (a = 0; !IsEmptyStr(&wbuf[a]); ++a) {
112                                 if (wbuf[a] == 32)
113                                         pos = a;
114                         }
115                         if (pos == 0) {
116                                 CtdlIPC_chat_send(ipc, "RCHT send");
117                                 CtdlIPC_chat_recv(ipc, response);
118                                 if (response[0] == '4') {
119                                         CtdlIPC_chat_send(ipc, wbuf);
120                                         CtdlIPC_chat_send(ipc, "000");
121                                 }
122                                 strcpy(wbuf, "");
123                                 send_complete_line = 0;
124                         }
125                         else {
126                                 wbuf[pos] = 0;
127                                 CtdlIPC_chat_send(ipc, "RCHT send");
128                                 CtdlIPC_chat_recv(ipc, response);
129                                 if (response[0] == '4') {
130                                         CtdlIPC_chat_send(ipc, wbuf);
131                                         CtdlIPC_chat_send(ipc, "000");
132                                 }
133                                 strcpy(wbuf, &wbuf[pos + 1]);
134                         }
135                 }
136
137                 /* poll for incoming chat messages */
138                 snprintf(buf, sizeof buf, "RCHT poll|%d", seq);
139                 CtdlIPC_chat_send(ipc, buf);
140                 CtdlIPC_chat_recv(ipc, response);
141
142                 if (response[0] == '1') {
143                         seq = extract_int(&response[4], 0);
144                         extract_token(c_user, &response[4], 2, '|', sizeof c_user);
145                         while (CtdlIPC_chat_recv(ipc, c_text), strcmp(c_text, "000")) {
146                                 scr_printf("\r%79s\r", "");
147                                 if (!strcmp(c_user, fullname)) {
148                                         color(BRIGHT_YELLOW);
149                                 }
150                                 else if (!strcmp(c_user, ":")) {
151                                         color(BRIGHT_RED);
152                                 }
153                                 else {
154                                         color(BRIGHT_GREEN);
155                                 }
156                                 if (strcmp(c_user, last_user)) {
157                                         snprintf(buf, sizeof buf, "%s: %s", c_user, c_text);
158                                 }
159                                 else {
160                                         size_t i = MIN(sizeof buf - 1, strlen(c_user) + 2);
161                                         memset(buf, ' ', i);
162                                         strncpy(&buf[i], c_text, sizeof buf - i);
163                                 }
164                                 while (strlen(buf) < 79) {
165                                         strcat(buf, " ");
166                                 }
167                                 if (strcmp(c_user, last_user)) {
168                                         scr_printf("\r%79s\n", "");
169                                         strcpy(last_user, c_user);
170                                 }
171                                 scr_printf("\r%s\n", buf);
172                                 scr_flush();
173                         }
174                 }
175                 color(BRIGHT_YELLOW);
176                 scr_printf("\r> %s", wbuf);
177                 scr_flush();
178                 strcpy(buf, "");
179         }
180 }
181
182
183 // send an instant message
184 void page_user(CtdlIPC * ipc) {
185         char buf[SIZ], touser[SIZ], msg[SIZ];
186         FILE *pagefp;
187
188         strcpy(touser, last_paged);
189         strprompt("Page who", touser, 30);
190
191         snprintf(buf, sizeof buf, "SEXP %s||", touser);
192         CtdlIPC_chat_send(ipc, buf);
193         CtdlIPC_chat_recv(ipc, buf);
194         if (buf[0] != '2') {
195                 scr_printf("%s\n", &buf[4]);
196                 return;
197         }
198         if (client_make_message(ipc, temp, touser, 0, 0, 0, NULL, 0) != 0) {
199                 scr_printf("No message sent.\n");
200                 return;
201         }
202         pagefp = fopen(temp, "r");
203         unlink(temp);
204         snprintf(buf, sizeof buf, "SEXP %s|-", touser);
205         CtdlIPC_chat_send(ipc, buf);
206         CtdlIPC_chat_recv(ipc, buf);
207         if (buf[0] == '4') {
208                 strcpy(last_paged, touser);
209                 while (fgets(buf, sizeof buf, pagefp) != NULL) {
210                         buf[strlen(buf) - 1] = 0;
211                         CtdlIPC_chat_send(ipc, buf);
212                 }
213                 fclose(pagefp);
214                 CtdlIPC_chat_send(ipc, "000");
215                 scr_printf("Message sent.\n");
216         }
217         else {
218                 scr_printf("%s\n", &buf[4]);
219         }
220 }
221
222
223 void quiet_mode(CtdlIPC * ipc) {
224         static int quiet = 0;
225         char cret[SIZ];
226         int r;
227
228         r = CtdlIPCEnableInstantMessageReceipt(ipc, !quiet, cret);
229         if (r / 100 == 2) {
230                 quiet = !quiet;
231                 scr_printf("Quiet mode %sabled (%sother users may page you)\n", (quiet) ? "en" : "dis", (quiet) ? "no " : "");
232         }
233         else {
234                 scr_printf("Unable to change quiet mode: %s\n", cret);
235         }
236 }
237
238
239 void stealth_mode(CtdlIPC * ipc) {
240         static int stealth = 0;
241         char cret[SIZ];
242         int r;
243
244         r = CtdlIPCStealthMode(ipc, !stealth, cret);
245         if (r / 100 == 2) {
246                 stealth = !stealth;
247                 scr_printf("Stealth mode %sabled (you are %s)\n",
248                            (stealth) ? "en" : "dis", (stealth) ? "invisible" : "listed as online");
249         }
250         else {
251                 scr_printf("Unable to change stealth mode: %s\n", cret);
252         }
253 }