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