Updated the boilerplate on each file
[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 are 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 {
22         char wbuf[SIZ];
23         char buf[SIZ];
24         char response[SIZ];
25         char c_user[SIZ];
26         char c_text[SIZ];
27         char last_user[SIZ];
28         int send_complete_line;
29         char ch;
30         int a, pos;
31         int seq = 0;
32
33         fd_set rfds;
34         struct timeval tv;
35         int retval;
36
37         CtdlIPC_chat_send(ipc, "RCHT enter");
38         CtdlIPC_chat_recv(ipc, buf);
39         if (buf[0] != '2') {
40                 scr_printf("%s\n", &buf[4]);
41                 return;
42         }
43         scr_printf("Entering chat mode (type /quit to exit)\n");
44
45         strcpy(buf, "");
46         strcpy(wbuf, "");
47         strcpy(last_user, "");
48         color(BRIGHT_YELLOW);
49         scr_printf("\n");
50         scr_printf("> ");
51         send_complete_line = 0;
52
53         while (1) {
54                 scr_flush();
55                 FD_ZERO(&rfds);
56                 FD_SET(0, &rfds);
57                 tv.tv_sec = 1;
58                 tv.tv_usec = 0;
59                 retval = select(1, &rfds, NULL, NULL, &tv);
60
61                 if (retval < 0) {
62                         color(BRIGHT_WHITE);
63                         scr_printf("Server gone Exiting chat mode\n");
64                         scr_flush();
65                         return;
66                 }
67
68                 /* If there's data from the keyboard... */
69                 if (FD_ISSET(0, &rfds)) {
70                         ch = scr_getc(SCR_BLOCK);
71                         if ((ch == 10) || (ch == 13)) {
72                                 send_complete_line = 1;
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                         } else {
79                                 scr_putc(ch);
80                                 wbuf[strlen(wbuf) + 1] = 0;
81                                 wbuf[strlen(wbuf)] = ch;
82                         }
83                 }
84
85                 /* if the user hit return, send the line */
86                 if (send_complete_line) {
87
88                         if (!strcasecmp(wbuf, "/quit")) {
89                                 CtdlIPC_chat_send(ipc, "RCHT exit");
90                                 CtdlIPC_chat_recv(ipc, response);       /* don't care about the result */
91                                 color(BRIGHT_WHITE);
92                                 scr_printf("\rExiting chat mode\n");
93                                 scr_flush();
94                                 return;
95                         }
96
97                         CtdlIPC_chat_send(ipc, "RCHT send");
98                         CtdlIPC_chat_recv(ipc, response);
99                         if (response[0] == '4') {
100                                 CtdlIPC_chat_send(ipc, wbuf);
101                                 CtdlIPC_chat_send(ipc, "000");
102                         }
103                         strcpy(wbuf, "");
104                         send_complete_line = 0;
105                 }
106
107                 /* if it's time to word wrap, send a partial line */
108                 if (strlen(wbuf) >= (77 - strlen(fullname))) {
109                         pos = 0;
110                         for (a = 0; !IsEmptyStr(&wbuf[a]); ++a) {
111                                 if (wbuf[a] == 32)
112                                         pos = a;
113                         }
114                         if (pos == 0) {
115                                 CtdlIPC_chat_send(ipc, "RCHT send");
116                                 CtdlIPC_chat_recv(ipc, response);
117                                 if (response[0] == '4') {
118                                         CtdlIPC_chat_send(ipc, wbuf);
119                                         CtdlIPC_chat_send(ipc, "000");
120                                 }
121                                 strcpy(wbuf, "");
122                                 send_complete_line = 0;
123                         } else {
124                                 wbuf[pos] = 0;
125                                 CtdlIPC_chat_send(ipc, "RCHT send");
126                                 CtdlIPC_chat_recv(ipc, response);
127                                 if (response[0] == '4') {
128                                         CtdlIPC_chat_send(ipc, wbuf);
129                                         CtdlIPC_chat_send(ipc, "000");
130                                 }
131                                 strcpy(wbuf, &wbuf[pos + 1]);
132                         }
133                 }
134
135                 /* poll for incoming chat messages */
136                 snprintf(buf, sizeof buf, "RCHT poll|%d", seq);
137                 CtdlIPC_chat_send(ipc, buf);
138                 CtdlIPC_chat_recv(ipc, response);
139
140                 if (response[0] == '1') {
141                         seq = extract_int(&response[4], 0);
142                         extract_token(c_user, &response[4], 2, '|', sizeof c_user);
143                         while (CtdlIPC_chat_recv(ipc, c_text), strcmp(c_text, "000")) {
144                                 scr_printf("\r%79s\r", "");
145                                 if (!strcmp(c_user, fullname)) {
146                                         color(BRIGHT_YELLOW);
147                                 } else if (!strcmp(c_user, ":")) {
148                                         color(BRIGHT_RED);
149                                 } else {
150                                         color(BRIGHT_GREEN);
151                                 }
152                                 if (strcmp(c_user, last_user)) {
153                                         snprintf(buf, sizeof buf, "%s: %s", c_user, c_text);
154                                 } else {
155                                         size_t i = MIN(sizeof buf - 1, strlen(c_user) + 2);
156                                         memset(buf, ' ', i);
157                                         safestrncpy(&buf[i], c_text, sizeof buf - i);
158                                 }
159                                 while (strlen(buf) < 79) {
160                                         strcat(buf, " ");
161                                 }
162                                 if (strcmp(c_user, last_user)) {
163                                         scr_printf("\r%79s\n", "");
164                                         strcpy(last_user, c_user);
165                                 }
166                                 scr_printf("\r%s\n", buf);
167                                 scr_flush();
168                         }
169                 }
170                 color(BRIGHT_YELLOW);
171                 scr_printf("\r> %s", wbuf);
172                 scr_flush();
173                 strcpy(buf, "");
174         }
175 }
176
177
178 /*
179  * send an instant message
180  */
181 void page_user(CtdlIPC * ipc)
182 {
183         char buf[SIZ], touser[SIZ], msg[SIZ];
184         FILE *pagefp;
185
186         strcpy(touser, last_paged);
187         strprompt("Page who", touser, 30);
188
189         /* old server -- use inline paging */
190         if (ipc->ServInfo.paging_level == 0) {
191                 newprompt("Message: ", msg, 69);
192                 snprintf(buf, sizeof buf, "SEXP %s|%s", touser, msg);
193                 CtdlIPC_chat_send(ipc, buf);
194                 CtdlIPC_chat_recv(ipc, buf);
195                 if (!strncmp(buf, "200", 3)) {
196                         strcpy(last_paged, touser);
197                 }
198                 scr_printf("%s\n", &buf[4]);
199                 return;
200         }
201         /* new server -- use extended paging */
202         else if (ipc->ServInfo.paging_level >= 1) {
203                 snprintf(buf, sizeof buf, "SEXP %s||", touser);
204                 CtdlIPC_chat_send(ipc, buf);
205                 CtdlIPC_chat_recv(ipc, buf);
206                 if (buf[0] != '2') {
207                         scr_printf("%s\n", &buf[4]);
208                         return;
209                 }
210                 if (client_make_message(ipc, temp, touser, 0, 0, 0, NULL, 0) != 0) {
211                         scr_printf("No message sent.\n");
212                         return;
213                 }
214                 pagefp = fopen(temp, "r");
215                 unlink(temp);
216                 snprintf(buf, sizeof buf, "SEXP %s|-", touser);
217                 CtdlIPC_chat_send(ipc, buf);
218                 CtdlIPC_chat_recv(ipc, buf);
219                 if (buf[0] == '4') {
220                         strcpy(last_paged, touser);
221                         while (fgets(buf, sizeof buf, pagefp) != NULL) {
222                                 buf[strlen(buf) - 1] = 0;
223                                 CtdlIPC_chat_send(ipc, buf);
224                         }
225                         fclose(pagefp);
226                         CtdlIPC_chat_send(ipc, "000");
227                         scr_printf("Message sent.\n");
228                 } else {
229                         scr_printf("%s\n", &buf[4]);
230                 }
231         }
232 }
233
234
235 void quiet_mode(CtdlIPC * ipc)
236 {
237         static int quiet = 0;
238         char cret[SIZ];
239         int r;
240
241         r = CtdlIPCEnableInstantMessageReceipt(ipc, !quiet, cret);
242         if (r / 100 == 2) {
243                 quiet = !quiet;
244                 scr_printf("Quiet mode %sabled (%sother users may page you)\n", (quiet) ? "en" : "dis", (quiet) ? "no " : "");
245         } else {
246                 scr_printf("Unable to change quiet mode: %s\n", cret);
247         }
248 }
249
250
251 void stealth_mode(CtdlIPC * ipc)
252 {
253         static int stealth = 0;
254         char cret[SIZ];
255         int r;
256
257         r = CtdlIPCStealthMode(ipc, !stealth, cret);
258         if (r / 100 == 2) {
259                 stealth = !stealth;
260                 scr_printf("Stealth mode %sabled (you are %s)\n",
261                            (stealth) ? "en" : "dis", (stealth) ? "invisible" : "listed as online");
262         } else {
263                 scr_printf("Unable to change stealth mode: %s\n", cret);
264         }
265 }