Fixed the vertical float issue by specifying the height of the text div and letting...
[citadel] / 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         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                         } else if ((ch == 8) || (ch == 127)) {
73                                 if (!IsEmptyStr(wbuf)) {
74                                         wbuf[strlen(wbuf) - 1] = 0;
75                                         scr_printf("%c %c", 8, 8);
76                                 }
77                         } else {
78                                 scr_putc(ch);
79                                 wbuf[strlen(wbuf) + 1] = 0;
80                                 wbuf[strlen(wbuf)] = ch;
81                         }
82                 }
83
84                 /* if the user hit return, send the line */
85                 if (send_complete_line) {
86
87                         if (!strcasecmp(wbuf, "/quit")) {
88                                 CtdlIPC_chat_send(ipc, "RCHT exit");
89                                 CtdlIPC_chat_recv(ipc, response);       /* don't care about the result */
90                                 color(BRIGHT_WHITE);
91                                 scr_printf("\rExiting chat mode\n");
92                                 scr_flush();
93                                 return;
94                         }
95
96                         CtdlIPC_chat_send(ipc, "RCHT send");
97                         CtdlIPC_chat_recv(ipc, response);
98                         if (response[0] == '4') {
99                                 CtdlIPC_chat_send(ipc, wbuf);
100                                 CtdlIPC_chat_send(ipc, "000");
101                         }
102                         strcpy(wbuf, "");
103                         send_complete_line = 0;
104                 }
105
106                 /* if it's time to word wrap, send a partial line */
107                 if (strlen(wbuf) >= (77 - strlen(fullname))) {
108                         pos = 0;
109                         for (a = 0; !IsEmptyStr(&wbuf[a]); ++a) {
110                                 if (wbuf[a] == 32)
111                                         pos = a;
112                         }
113                         if (pos == 0) {
114                                 CtdlIPC_chat_send(ipc, "RCHT send");
115                                 CtdlIPC_chat_recv(ipc, response);
116                                 if (response[0] == '4') {
117                                         CtdlIPC_chat_send(ipc, wbuf);
118                                         CtdlIPC_chat_send(ipc, "000");
119                                 }
120                                 strcpy(wbuf, "");
121                                 send_complete_line = 0;
122                         } else {
123                                 wbuf[pos] = 0;
124                                 CtdlIPC_chat_send(ipc, "RCHT send");
125                                 CtdlIPC_chat_recv(ipc, response);
126                                 if (response[0] == '4') {
127                                         CtdlIPC_chat_send(ipc, wbuf);
128                                         CtdlIPC_chat_send(ipc, "000");
129                                 }
130                                 strcpy(wbuf, &wbuf[pos + 1]);
131                         }
132                 }
133
134                 /* poll for incoming chat messages */
135                 snprintf(buf, sizeof buf, "RCHT poll|%d", seq);
136                 CtdlIPC_chat_send(ipc, buf);
137                 CtdlIPC_chat_recv(ipc, response);
138
139                 if (response[0] == '1') {
140                         seq = extract_int(&response[4], 0);
141                         extract_token(c_user, &response[4], 2, '|', sizeof c_user);
142                         while (CtdlIPC_chat_recv(ipc, c_text), strcmp(c_text, "000")) {
143                                 scr_printf("\r%79s\r", "");
144                                 if (!strcmp(c_user, fullname)) {
145                                         color(BRIGHT_YELLOW);
146                                 } else if (!strcmp(c_user, ":")) {
147                                         color(BRIGHT_RED);
148                                 } else {
149                                         color(BRIGHT_GREEN);
150                                 }
151                                 if (strcmp(c_user, last_user)) {
152                                         snprintf(buf, sizeof buf, "%s: %s", c_user, c_text);
153                                 } else {
154                                         size_t i = MIN(sizeof buf - 1, strlen(c_user) + 2);
155                                         memset(buf, ' ', i);
156                                         strncpy(&buf[i], c_text, sizeof buf - i);
157                                 }
158                                 while (strlen(buf) < 79) {
159                                         strcat(buf, " ");
160                                 }
161                                 if (strcmp(c_user, last_user)) {
162                                         scr_printf("\r%79s\n", "");
163                                         strcpy(last_user, c_user);
164                                 }
165                                 scr_printf("\r%s\n", buf);
166                                 scr_flush();
167                         }
168                 }
169                 color(BRIGHT_YELLOW);
170                 scr_printf("\r> %s", wbuf);
171                 scr_flush();
172                 strcpy(buf, "");
173         }
174 }
175
176
177 // send an instant message
178 void page_user(CtdlIPC * ipc) {
179         char buf[SIZ], touser[SIZ], msg[SIZ];
180         FILE *pagefp;
181
182         strcpy(touser, last_paged);
183         strprompt("Page who", touser, 30);
184
185         snprintf(buf, sizeof buf, "SEXP %s||", touser);
186         CtdlIPC_chat_send(ipc, buf);
187         CtdlIPC_chat_recv(ipc, buf);
188         if (buf[0] != '2') {
189                 scr_printf("%s\n", &buf[4]);
190                 return;
191         }
192         if (client_make_message(ipc, temp, touser, 0, 0, 0, NULL, 0) != 0) {
193                 scr_printf("No message sent.\n");
194                 return;
195         }
196         pagefp = fopen(temp, "r");
197         unlink(temp);
198         snprintf(buf, sizeof buf, "SEXP %s|-", touser);
199         CtdlIPC_chat_send(ipc, buf);
200         CtdlIPC_chat_recv(ipc, buf);
201         if (buf[0] == '4') {
202                 strcpy(last_paged, touser);
203                 while (fgets(buf, sizeof buf, pagefp) != NULL) {
204                         buf[strlen(buf) - 1] = 0;
205                         CtdlIPC_chat_send(ipc, buf);
206                 }
207                 fclose(pagefp);
208                 CtdlIPC_chat_send(ipc, "000");
209                 scr_printf("Message sent.\n");
210         }
211         else {
212                 scr_printf("%s\n", &buf[4]);
213         }
214 }
215
216
217 void quiet_mode(CtdlIPC * ipc)
218 {
219         static int quiet = 0;
220         char cret[SIZ];
221         int r;
222
223         r = CtdlIPCEnableInstantMessageReceipt(ipc, !quiet, cret);
224         if (r / 100 == 2) {
225                 quiet = !quiet;
226                 scr_printf("Quiet mode %sabled (%sother users may page you)\n", (quiet) ? "en" : "dis", (quiet) ? "no " : "");
227         } else {
228                 scr_printf("Unable to change quiet mode: %s\n", cret);
229         }
230 }
231
232
233 void stealth_mode(CtdlIPC * ipc)
234 {
235         static int stealth = 0;
236         char cret[SIZ];
237         int r;
238
239         r = CtdlIPCStealthMode(ipc, !stealth, cret);
240         if (r / 100 == 2) {
241                 stealth = !stealth;
242                 scr_printf("Stealth mode %sabled (you are %s)\n",
243                            (stealth) ? "en" : "dis", (stealth) ? "invisible" : "listed as online");
244         } else {
245                 scr_printf("Unable to change stealth mode: %s\n", cret);
246         }
247 }