* Changed the comments at the beginning of each file to a consistent format
[citadel.git] / citadel / client_chat.c
1 /*
2  * $Id$
3  *
4  * front end for chat mode
5  * (the "single process" version - no more fork() anymore)
6  *
7  */
8
9 #include "sysdep.h"
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <ctype.h>
15 #include <string.h>
16 #include <signal.h>
17 #include <errno.h>
18 #include <sys/time.h>
19 #include <sys/types.h>
20 #ifdef HAVE_SYS_SELECT_H
21 #include <sys/select.h>
22 #endif
23 #include <stdarg.h>
24 #include "citadel.h"
25 #include "client_chat.h"
26 #include "commands.h"
27 #include "routines.h"
28 #include "ipc.h"
29 #include "citadel_decls.h"
30 #include "tools.h"
31 #include "rooms.h"
32 #include "messages.h"
33 #ifndef HAVE_SNPRINTF
34 #include "snprintf.h"
35 #endif
36
37 #define MIN(a, b) ((a) < (b) ? (a) : (b))
38
39 extern struct CtdlServInfo serv_info;
40 extern char temp[];
41 void getline(char *, int);
42
43 void chatmode(void) {
44         char wbuf[256];
45         char buf[256];
46         char c_user[256];
47         char c_text[256];
48         char c_room[256];
49         char last_user[256];
50         int send_complete_line;
51         int recv_complete_line;
52         char ch;
53         int a,pos;
54         
55         fd_set rfds;
56         struct timeval tv;
57         int retval;
58
59         serv_puts("CHAT");
60         serv_gets(buf);
61         if (buf[0]!='8') {
62                 printf("%s\n",&buf[4]);
63                 return;
64                 }
65
66         printf("Entering chat mode (type /quit to exit, /help for other cmds)\n");
67         set_keepalives(KA_CHAT);
68
69         strcpy(buf,"");
70         strcpy(wbuf,"");
71         color(BRIGHT_YELLOW);
72         printf("> ");
73         send_complete_line = 0;
74         recv_complete_line = 0;
75
76         while(1) {
77             fflush(stdout);
78             FD_ZERO(&rfds);
79             FD_SET(0,&rfds);
80             FD_SET(getsockfd(),&rfds);
81             tv.tv_sec = S_KEEPALIVE;
82             tv.tv_usec = 0;
83             retval = select(getsockfd()+1, &rfds, NULL, NULL, &tv);
84
85             if (FD_ISSET(getsockfd(), &rfds)) {
86                 ch = serv_getc();
87                 if (ch == 10) {
88                         recv_complete_line = 1;
89                         goto RCL; /* ugly, but we've gotta get out! */
90                         }
91                 else {
92                         buf[strlen(buf) + 1] = 0;
93                         buf[strlen(buf)] = ch;
94                         }
95                 goto RCL;
96                 }
97
98             if (FD_ISSET(0, &rfds)) {
99                 ch = inkey();
100                 if ((ch == 10) || (ch == 13)) {
101                         send_complete_line = 1;
102                         }
103                 else if ((ch == 8) || (ch == 127)) {
104                         if (strlen(wbuf) > 0) {
105                                 wbuf[strlen(wbuf)-1] = 0;
106                                 printf("%c %c",8,8);
107                                 }
108                         }
109                 else {
110                         putc(ch,stdout);
111                         wbuf[strlen(wbuf) + 1] = 0;
112                         wbuf[strlen(wbuf)] = ch;
113                         }
114                 }
115
116
117         /* if the user hit return, send the line */
118 RCL:        if (send_complete_line) {
119                 serv_puts(wbuf);
120                 strcpy(wbuf,"");
121                 send_complete_line = 0;
122                 }
123
124         /* if it's time to word wrap, send a partial line */
125             if ( strlen(wbuf) >= (77-strlen(fullname)) ) {
126                 pos = 0;
127                 for (a=0; a<strlen(wbuf); ++a) {
128                         if (wbuf[a] == 32) pos = a;
129                         }
130                 if (pos == 0) {
131                         serv_puts(wbuf);
132                         strcpy(wbuf, "");
133                         send_complete_line = 0;
134                         }
135                 else {
136                         wbuf[pos] = 0;
137                         serv_puts(wbuf);
138                         strcpy(wbuf,&wbuf[pos+1]);
139                         }
140                 }
141
142             if (recv_complete_line) {   
143                 printf("\r%79s\r","");
144                 if (!strcmp(buf,"000")) {
145                         color(BRIGHT_WHITE);
146                         printf("Exiting chat mode\n");
147
148                         fflush(stdout);
149                         set_keepalives(KA_YES);
150
151
152                         /* Some users complained about the client and server
153                          * losing protocol synchronization when exiting chat.
154                          * This little dialog forces everything to be
155                          * hunky-dory.
156                          */
157                         serv_puts("ECHO __ExitingChat__");
158                         do {
159                                 serv_gets(buf);
160                         } while (strcmp(buf, "200 __ExitingChat__"));
161
162
163                         return;
164                         }
165                 if (num_parms(buf)>=2) {
166                         extract(c_user,buf,0);
167                         extract(c_text,buf,1);
168                         if (num_parms(buf)>2)
169                         {
170                            extract(c_room,buf,2);
171                            printf("Got room %s\n", c_room);
172                         }
173                            
174                         if (strcasecmp(c_text,"NOOP")) {
175                                 if (!strcmp(c_user, fullname)) {
176                                         color(BRIGHT_YELLOW);
177                                         }
178                                 else if (!strcmp(c_user,":")) {
179                                         color(BRIGHT_RED);
180                                         }
181                                 else {
182                                         color(BRIGHT_GREEN);
183                                         }
184                                 if (strcmp(c_user,last_user)) {
185                                         snprintf(buf,sizeof buf,"%s: %s",c_user,c_text);
186                                         }
187                                 else {
188                                         size_t i = MIN(sizeof buf - 1,
189                                                        strlen(c_user) + 2);
190
191                                         memset(buf, ' ', i);
192                                         safestrncpy(&buf[i], c_text,
193                                                     sizeof buf - i);
194                                         }
195                                 while (strlen(buf)<79) strcat(buf," ");
196                                 if (strcmp(c_user,last_user)) {
197                                         printf("\r%79s\n","");
198                                         strcpy(last_user,c_user);
199                                         }
200                                 printf("\r%s\n",buf);
201                                 fflush(stdout);
202                                 }
203                         }
204                 color(BRIGHT_YELLOW);
205                 printf("> %s",wbuf);
206                 recv_complete_line = 0;
207                 strcpy(buf,"");
208                 }
209             }
210         }
211
212 /*
213  * send an express message
214  */
215 void page_user() {
216         static char last_paged[32] = "";
217         char buf[256], touser[256], msg[256];
218         FILE *pagefp;
219
220         strcpy(touser, last_paged);
221         strprompt("Page who", touser, 30);
222
223         /* old server -- use inline paging */
224         if (serv_info.serv_paging_level == 0) {
225                 newprompt("Message:  ", msg, 69);
226                 snprintf(buf,sizeof buf,"SEXP %s|%s",touser,msg);
227                 serv_puts(buf);
228                 serv_gets(buf);
229                 if (!strncmp(buf, "200", 3)) {
230                         strcpy(last_paged, touser);
231                         }
232                 printf("%s\n", &buf[4]);
233                 return;
234         }
235
236         /* new server -- use extended paging */ 
237         else if (serv_info.serv_paging_level >= 1) {
238                 snprintf(buf, sizeof buf, "SEXP %s||", touser);
239                 serv_puts(buf);
240                 serv_gets(buf);
241                 if (buf[0] != '2') {
242                         printf("%s\n", &buf[4]);
243                         return;
244                         }
245
246                 if ( make_message(temp, touser, 0, 0, 0) != 0 ) {
247                         printf("No message sent.\n");
248                         return;
249                 }
250
251                 pagefp = fopen(temp, "r");
252                 unlink(temp);
253                 snprintf(buf, sizeof buf, "SEXP %s|-", touser);
254                 serv_puts(buf);
255                 serv_gets(buf);
256                 if (buf[0]=='4') {
257                         strcpy(last_paged, touser);
258                         while (fgets(buf, 256, pagefp) != NULL) {
259                                 buf[strlen(buf)-1] = 0;
260                                 serv_puts(buf);
261                                 }
262                         fclose(pagefp);
263                         serv_puts("000");
264                         printf("Message sent.\n");
265                 }
266                 else {
267                         printf("%s\n", &buf[4]);
268                 }
269         }
270 }
271
272
273
274
275 void quiet_mode(void) {
276         int qstate;
277         char buf[256];
278
279         serv_puts("DEXP 2");
280         serv_gets(buf);
281         if (buf[0]!='2') {
282                 printf("%s\n", &buf[4]);
283                 return;
284         }
285         qstate = atoi(&buf[4]);
286         if (qstate == 0) qstate = 1;
287         else qstate = 0;
288         sprintf(buf, "DEXP %d", qstate);
289         serv_puts(buf);
290         serv_gets(buf);
291         if (buf[0]!='2') {
292                 printf("%s\n", &buf[4]);
293                 return;
294         }
295         qstate = atoi(&buf[4]);
296         if (qstate) {
297                 printf("Quiet mode enabled (no other users may page you)\n");
298         }
299         else {
300                 printf("Quiet mode disabled (other users may page you)\n");
301         }
302 }