minor fix to multiline pages
[citadel.git] / citadel / client_chat.c
1 /*
2  * Citadel/UX
3  *
4  * client_chat.c  --  front end for chat mode
5  *                    (the "single process" version - no more fork() anymore)
6  *
7  * $Id$
8  *
9  */
10
11 #include "sysdep.h"
12 #include <stdlib.h>
13 #include <unistd.h>
14 #include <stdio.h>
15 #include <fcntl.h>
16 #include <ctype.h>
17 #include <string.h>
18 #include <signal.h>
19 #include <errno.h>
20 #include <sys/time.h>
21 #include <sys/types.h>
22 #ifdef HAVE_SYS_SELECT_H
23 #include <sys/select.h>
24 #endif
25 #include "citadel.h"
26 #include "client_chat.h"
27 #include "commands.h"
28 #include "routines.h"
29 #include "ipc.h"
30 #include "citadel_decls.h"
31 #include "tools.h"
32
33 #define MIN(a, b) ((a) < (b) ? (a) : (b))
34
35 extern struct CtdlServInfo serv_info;
36 extern char temp[];
37 void citedit(FILE *fp, long int base_pos);
38
39 void chatmode(void) {
40         char wbuf[256];
41         char buf[256];
42         char c_user[256];
43         char c_text[256];
44         char c_room[256];
45         char last_user[256];
46         int send_complete_line;
47         int recv_complete_line;
48         char ch;
49         int a,pos;
50         
51         fd_set rfds;
52         struct timeval tv;
53         int retval;
54
55         serv_puts("CHAT");
56         serv_gets(buf);
57         if (buf[0]!='8') {
58                 printf("%s\n",&buf[4]);
59                 return;
60                 }
61
62         printf("Entering chat mode (type /quit to exit, /help for other cmds)\n");
63         set_keepalives(KA_CHAT);
64
65         strcpy(buf,"");
66         strcpy(wbuf,"");
67         color(3);
68         printf("> ");
69         send_complete_line = 0;
70         recv_complete_line = 0;
71
72         while(1) {
73             fflush(stdout);
74             FD_ZERO(&rfds);
75             FD_SET(0,&rfds);
76             FD_SET(getsockfd(),&rfds);
77             tv.tv_sec = S_KEEPALIVE;
78             tv.tv_usec = 0;
79             retval = select(getsockfd()+1, &rfds, NULL, NULL, &tv);
80
81             if (FD_ISSET(getsockfd(), &rfds)) {
82                 ch = serv_getc();
83                 if (ch == 10) {
84                         recv_complete_line = 1;
85                         goto RCL; /* ugly, but we've gotta get out! */
86                         }
87                 else {
88                         buf[strlen(buf) + 1] = 0;
89                         buf[strlen(buf)] = ch;
90                         }
91                 goto RCL;
92                 }
93
94             if (FD_ISSET(0, &rfds)) {
95                 ch = inkey();
96                 if ((ch == 10) || (ch == 13)) {
97                         send_complete_line = 1;
98                         }
99                 else if ((ch == 8) || (ch == 127)) {
100                         if (strlen(wbuf) > 0) {
101                                 wbuf[strlen(wbuf)-1] = 0;
102                                 printf("%c %c",8,8);
103                                 }
104                         }
105                 else {
106                         putc(ch,stdout);
107                         wbuf[strlen(wbuf) + 1] = 0;
108                         wbuf[strlen(wbuf)] = ch;
109                         }
110                 }
111
112
113         /* if the user hit return, send the line */
114 RCL:        if (send_complete_line) {
115                 serv_puts(wbuf);
116                 strcpy(wbuf,"");
117                 send_complete_line = 0;
118                 }
119
120         /* if it's time to word wrap, send a partial line */
121             if ( strlen(wbuf) >= (77-strlen(fullname)) ) {
122                 pos = 0;
123                 for (a=0; a<strlen(wbuf); ++a) {
124                         if (wbuf[a] == 32) pos = a;
125                         }
126                 if (pos == 0) {
127                         serv_puts(wbuf);
128                         strcpy(wbuf, "");
129                         send_complete_line = 0;
130                         }
131                 else {
132                         wbuf[pos] = 0;
133                         serv_puts(wbuf);
134                         strcpy(wbuf,&wbuf[pos+1]);
135                         }
136                 }
137
138             if (recv_complete_line) {   
139                 printf("\r%79s\r","");
140                 if (!strcmp(buf,"000")) {
141                         color(7);
142                         printf("Exiting chat mode\n");
143
144                         fflush(stdout);
145                         set_keepalives(KA_YES);
146                         return;
147                         }
148                 if (num_parms(buf)>=2) {
149                         extract(c_user,buf,0);
150                         extract(c_text,buf,1);
151                         if (num_parms(buf)>2)
152                         {
153                            extract(c_room,buf,2);
154                            printf("Got room %s\n", c_room);
155                         }
156                            
157                         if (strucmp(c_text,"NOOP")) {
158                                 if (!strcmp(c_user, fullname)) {
159                                         color(3);
160                                         }
161                                 else if (!strcmp(c_user,":")) {
162                                         color(1);
163                                         }
164                                 else {
165                                         color(2);
166                                         }
167                                 if (strcmp(c_user,last_user)) {
168                                         snprintf(buf,sizeof buf,"%s: %s",c_user,c_text);
169                                         }
170                                 else {
171                                         size_t i = MIN(sizeof buf - 1,
172                                                        strlen(c_user) + 2);
173
174                                         memset(buf, ' ', i);
175                                         safestrncpy(&buf[i], c_text,
176                                                     sizeof buf - i);
177                                         }
178                                 while (strlen(buf)<79) strcat(buf," ");
179                                 if (strcmp(c_user,last_user)) {
180                                         printf("\r%79s\n","");
181                                         strcpy(last_user,c_user);
182                                         }
183                                 printf("\r%s\n",buf);
184                                 fflush(stdout);
185                                 }
186                         }
187                 color(3);
188                 printf("> %s",wbuf);
189                 recv_complete_line = 0;
190                 strcpy(buf,"");
191                 }
192             }
193         }
194
195 /*
196  * send an express message
197  */
198 void page_user() {
199         static char last_paged[32] = "";
200         char buf[256], touser[256], msg[256];
201         FILE *fp;
202
203         strcpy(touser, last_paged);
204         strprompt("Page who", touser, 30);
205
206         /* old server -- use inline paging */
207         if (serv_info.serv_paging_level == 0) {
208                 newprompt("Message:  ",msg,69);
209                 snprintf(buf,sizeof buf,"SEXP %s|%s",touser,msg);
210                 serv_puts(buf);
211                 serv_gets(buf);
212                 if (!strncmp(buf, "200", 3)) {
213                         strcpy(last_paged, touser);
214                         }
215                 printf("%s\n", &buf[4]);
216                 return;
217         }
218
219         /* new server -- use extended paging */ 
220         else if (serv_info.serv_paging_level >= 1) {
221                 snprintf(buf, sizeof buf, "SEXP %s||", touser);
222                 serv_puts(buf);
223                 serv_gets(buf);
224                 if (buf[0] != '2') {
225                         printf("%s\n", &buf[4]);
226                         return;
227                         }
228                 fp = fopen(temp, "w");
229                 fp = freopen(temp, "rb+", fp);
230                 if (fp==NULL) printf("Error: %s\n", strerror(errno));
231                 unlink(temp);
232                 printf("Type message to send.  Enter a blank line when finished.\n");
233                 citedit(fp, 0);
234                 snprintf(buf, sizeof buf, "SEXP %s|-", touser);
235                 serv_puts(buf);
236                 serv_gets(buf);
237                 if (buf[0]=='4') {
238                         strcpy(last_paged, touser);
239                         rewind(fp);
240                         while (fgets(buf, sizeof buf, fp) != NULL) {
241                                 buf[strlen(buf)-1] = 0;
242                                 if (strcmp(buf, "000")) serv_puts(buf);
243                         unlink(temp);
244                         }
245                         serv_puts("000");
246                         printf("Message sent.\n");
247                 }
248                 else {
249                         printf("%s\n", &buf[4]);
250                 }
251                 fclose(fp);
252         }
253 }
254
255
256