Works a bit more
[erwise] / Cl / ClConnection.c
1 /*
2  * ClConnection.c --
3  *
4  * Author: Teemu Rantanen <tvr@cs.hut.fi>
5  * Copyright (c) 1992 Teemu Rantanen
6  *                    All rights reserved
7  *
8  * Created: Mon Apr 20 19:29:14 1992 tvr
9  * Last modified: Wed May 13 00:53:24 1992 tvr
10  *
11  */
12
13 #include <stdio.h>
14 #include <sys/types.h>
15 #include <errno.h>
16
17 #include "Cl.h"
18
19 #include "HTParse.h"
20 #include "HTFormat.h"
21 #include "HTAnchor.h"
22 #include "tcp.h"
23
24 #include "../HText/HText.h"
25
26 extern HText_t *HtLocalText;
27
28
29 /*
30  * Poll connecting until connection completes.
31  */
32 void
33 WWWErwiseConnect ()
34 {
35   int status;
36
37   CL_DEBUG (("Poll connect\n"));
38
39   status = connect (WWWErwiseConnection->fd,
40                     (struct sockaddr *) WWWErwiseConnection->addr,
41                     WWWErwiseConnection->addr_size);
42   if (status < 0 && (errno != EISCONN))
43     {
44       if ((errno == EALREADY) || (errno == EINPROGRESS))
45         {
46           /*
47            * Would block
48            */
49           return;
50         }
51
52       CL_DEBUG (("Cannot connect(%d)\n", errno));
53
54       /*
55        * Cannot connect
56        */
57       WWWErwiseStatus = CL_FAILED;
58
59       return;
60     }
61
62   /*
63    * Connected. Get next function from the list of things to do.
64    * Also, stop polling.
65    */
66
67   free (WWWErwiseConnection->addr);
68
69   WWWErwiseConnection->addr = NULL;
70
71   WWWErwiseConnection->function++;
72 }
73
74
75
76 /*
77  * Instead of connect, this function is called. Store needed data to
78  * poll connecting later.
79  */
80 int
81 erwise_connect (fd, addr, size)
82      int fd;
83      struct sockaddr *addr;
84      int size;
85 {
86   int status;
87
88   CL_DEBUG (("Try to Connect\n"));
89
90   status = connect (fd, addr, size);
91
92   if (status < 0)
93     {
94       switch (errno)
95         {
96         case EINPROGRESS:
97         case EISCONN:
98         case EALREADY:
99           break;
100
101         default:
102           CL_DEBUG (("Cannot connect (first try %d)\n", errno));
103           return -1;
104         }
105     }
106
107   /*
108    * Duplicate what to connect
109    */
110   WWWErwiseConnection->addr = (void *) malloc (size);
111
112   memcpy (WWWErwiseConnection->addr, addr, size);
113
114   WWWErwiseConnection->addr_size = size;
115
116   /*
117    * OK
118    */
119   return 0;
120 }
121
122
123
124
125
126 /*
127  * Send command to net
128  */
129
130 void
131 WWWErwiseSendCommand ()
132 {
133   int status;
134
135   CL_DEBUG (("Send Command\n"));
136
137   status = NETWRITE (WWWErwiseConnection->fd,
138                      WWWErwiseConnection->command,
139                      (int) strlen (WWWErwiseConnection->command));
140
141   if (status == strlen (WWWErwiseConnection->command))
142     {
143       /*
144        * Succeeded
145        */
146       free (WWWErwiseConnection->command);
147       WWWErwiseConnection->command = 0;
148
149       WWWErwiseConnection->function++;
150
151     }
152   else if (status < 0)
153     {
154       /*
155        * Failed
156        */
157       CL_DEBUG (("SendCommand failed\n"));
158
159       WWWErwiseStatus = CL_FAILED;
160       return;
161     }
162   else
163     {
164       /*
165        * Partial read
166        */
167       char *tmp = WWWErwiseConnection->command;
168
169       WWWErwiseConnection->command = (char *) strdup (tmp + status);
170       free (tmp);
171     }
172 }
173
174
175 #define ERWISE_BLOCK 8192
176
177 /*
178  * Read data until all data is read
179  */
180
181 void
182 WWWErwiseReadData ()
183 {
184   char tmp[ERWISE_BLOCK];
185
186   int i;
187
188   i = read (WWWErwiseConnection->fd,
189             tmp,
190             ERWISE_BLOCK);
191
192   CL_DEBUG (("got %d bytes\n", i));
193
194   /*
195    * Append data to (memory) buffer or to file.
196    */
197   if (i > 0)
198     {
199
200       /*
201        * Load directly to file ?
202        */
203
204       if (WWWErwiseConnection->load_to_file)
205         {
206           int st;
207
208           st = write (WWWErwiseConnection->load_to_file_fd,
209                       tmp,
210                       i);
211
212           if (st != i)
213             {
214               WWWErwiseStatus = CL_FAILED;
215             }
216
217           return;
218         }
219
220       if (!WWWErwiseConnection->buffer_first)
221         {
222
223           WWWErwiseConnection->buffer_first =
224             WWWErwiseConnection->buffer_last =
225             (cl_data_t *) malloc (sizeof (cl_data_t));
226
227           memset (WWWErwiseConnection->buffer_first, 0, sizeof (cl_data_t));
228
229           WWWErwiseConnection->buffer_first->data =
230             WWWErwiseConnection->buffer_first->freeptr =
231             (void *) malloc (i);
232
233           WWWErwiseConnection->buffer_first->size = i;
234
235           memcpy (WWWErwiseConnection->buffer_first->data, tmp, i);
236
237         }
238       else
239         {
240
241           cl_data_t *p = (cl_data_t *) malloc (sizeof (cl_data_t));
242
243           memset (p, 0, sizeof (cl_data_t));
244
245           p->data = p->freeptr = (void *) malloc (i);
246
247           p->size = i;
248
249           memcpy (p->data, tmp, i);
250
251           p->prev = WWWErwiseConnection->buffer_last;
252
253           WWWErwiseConnection->buffer_last->next = p;
254
255           WWWErwiseConnection->buffer_last = p;
256         }
257
258       return;
259     }
260
261   if (i < 0 && (errno != EWOULDBLOCK))
262     {
263       CL_DEBUG (("ReadData failed\n"));
264       WWWErwiseStatus = CL_FAILED;
265     }
266
267   if (i == 0)
268     {
269       WWWErwiseConnection->function++;
270       return;
271     }
272 }
273
274
275
276 /*
277  * Parse data that has been read
278  */
279
280 void
281 WWWErwiseParse ()
282 {
283   /*
284    * XXXXXX If saving to file, don't parse
285    */
286
287   HTParseFormat (WWWErwiseConnection->diag ? WWW_PLAINTEXT : WWW_HTML,
288                  WWWErwiseConnection->anAnchor,
289                  WWWErwiseConnection->fd);
290
291   (void) HTClose (WWWErwiseConnection->fd);
292
293   /*
294    * XXXXX free connection structure
295    */
296   WWWErwiseStatus = CL_COMPLETED;
297   WWWErwiseConnection->function++;
298 }
299
300
301
302 /*
303  * If we are loading to file, nothing else needs to be done ...
304  */
305 void
306 WWWErwiseTerminateIfLoadToFile ()
307 {
308   if (WWWErwiseConnection->load_to_file)
309     {
310       HtLocalText = 0;
311
312       while (*WWWErwiseConnection->function)
313         {
314           WWWErwiseConnection->function++;
315         }
316
317       WWWErwiseStatus = CL_COMPLETED;
318
319     }
320   else
321     {
322       WWWErwiseConnection->function++;
323     }
324 }