Initial commit of pristine erwise source
[erwise] / Cl / Cl.c
1 /*
2  * Cl.c --
3  *
4  * Author: Teemu Rantanen <tvr@cs.hut.fi>
5  * Copyright (c) 1992 Teemu Rantanen
6  *                    All rights reserved
7  *
8  * Created: Thu Apr 16 22:08:27 1992 tvr
9  * Last modified: Wed May 13 13:27:58 1992 tvr
10  *
11  */
12
13 #include <stdio.h>
14
15 #include "Cl.h"
16
17 #include "HTStyle.h"
18 #include "HTParse.h"
19 #include "HText.h"
20 #include "tcp.h"
21
22 #include "../HText/HText.h"
23
24 extern HText_t *HtLocalText;
25
26 int WWWErwiseStatus;
27 ClConnection_t *WWWErwiseConnection;
28
29 void cl_free_connection ();
30
31 /*
32  * Where to load this file ?
33  */
34
35 char *WWWErwiseFileLoadName = 0;
36
37 /*
38  * Open connection. Allocate strutures.
39  */
40
41 ClConnection_t *
42 ClOpenConnection (address)
43      char *address;
44 {
45   int status;
46   ClConnection_t *p = (ClConnection_t *) malloc (sizeof (*p));
47
48   /*
49    * Some validation checks
50    */
51
52   if (!p)
53     return p;
54
55   if (!address)
56     return NULL;
57
58   memset (p, 0, sizeof (*p));
59
60   p->address = (char *) strdup (address);
61
62   /*
63    * If we wish to load to file, open fd here
64    */
65
66   if (WWWErwiseFileLoadName)
67     {
68
69       p->load_to_file_fd =
70         open (WWWErwiseFileLoadName, O_WRONLY | O_CREAT, 0666);
71
72       free (WWWErwiseFileLoadName);
73
74       WWWErwiseFileLoadName = 0;
75
76       if (p->load_to_file_fd < 0)
77         {
78
79           printf ("ClOpenConnection: Cannot load to file '%s'\n",
80                   WWWErwiseFileLoadName);
81
82           ClCloseConnection (p);
83
84           return 0;
85         }
86
87       p->load_to_file = 1;
88     }
89
90
91   /*
92    * Kludge #1:
93    * Call common code to get socket fd. Also set state to some value so
94    * that ReadData calls some function that makes sense.
95    */
96
97   WWWErwiseConnection = p;
98
99   WWWErwiseStatus = CL_CONTINUES;
100
101   p->status = HTLoadAbsolute (address, 0);
102
103   if ((WWWErwiseStatus == CL_FAILED) ||
104       (WWWErwiseStatus == CL_ALREADY_LOADED))
105     {
106
107       ClCloseConnection (p);
108
109       return NULL;
110     }
111
112   return p;
113 }
114
115
116 /*
117  * Read data or poll connection opening
118  */
119 struct HText *
120 ClReadData (connection, how_done, fd)
121      ClConnection_t *connection;
122      int *how_done;
123      int *fd;
124 {
125   int continues;
126
127   void (*tmpf) ();
128
129   WWWErwiseStatus = CL_CONTINUES;
130
131   WWWErwiseConnection = connection;
132
133   /*
134    * If loading was on non-blocking mode ?
135    */
136   if (!connection->function)
137     {
138
139       *fd = connection->fd;
140
141       if (connection->status)
142         {
143
144           *how_done = CL_COMPLETED;
145
146           ClCloseConnection (connection);
147
148           return HtLocalText;
149
150         }
151       else
152         {
153
154           *how_done = CL_FAILED;
155
156           ClCloseConnection (connection);
157
158           return 0;
159
160         }
161     }
162
163   /*
164    * Try max 3 pollings at one call. This makes loading faster but does not
165    * get too much cpu
166    */
167   for (continues = 3; continues > 0; continues--)
168     {
169
170       tmpf = *connection->function;
171
172       if (*connection->function)
173         (void) (*connection->function) ();
174
175       /*
176        * If mode is going to change to poll, set it now
177        */
178       if (*connection->function == WWWErwiseSetPoll)
179         (void) WWWErwiseSetPoll ();
180
181       /*
182        * Can we try next polling?
183        */
184       if ((*connection->function == tmpf) || (*how_done != CL_CONTINUES) ||
185           (connection->select_fd))
186         {
187
188           continues = 0;
189         }
190     }
191
192   *how_done = WWWErwiseStatus;
193
194   *fd = connection->select_fd;
195
196   if (*how_done == CL_FAILED)
197     {
198
199       ClCloseConnection (connection);
200
201       return NULL;
202     }
203
204   if (*how_done == CL_COMPLETED)
205     {
206
207       ClCloseConnection (connection);
208
209       return HtLocalText;       /* global variable because @#$#$ <censored> */
210     }
211
212   return NULL;
213 }
214
215
216 /*
217  * User wants to terminate a connection
218  */
219
220 void
221 ClCloseConnection (connection)
222      ClConnection_t *connection;
223 {
224   if (connection->load_to_file)
225     {
226
227       close (connection->load_to_file_fd);
228     }
229
230   if (connection->fd)
231     {
232
233       shutdown (connection->fd, 2);
234
235       close (connection->fd);
236     }
237
238   if (connection->secondary_fd)
239     {
240
241       shutdown (connection->secondary_fd, 2);
242
243       close (connection->secondary_fd);
244     }
245
246   cl_free_connection (connection);
247 }
248
249
250
251 /*
252  * read data from local buffer. If no data on buffer, make normal read
253  */
254 int
255 cl_read_data (fd, data, length)
256      int fd;
257      char *data;
258      int length;
259 {
260   ClConnection_t *p = WWWErwiseConnection;
261
262   cl_data_t *b = p->buffer_first;
263
264   int howmuch = 0;
265
266   if (p->buffer_last)
267     {
268       if (!b)
269         return 0;
270
271       if (length < b->size)
272         {
273
274           memcpy (data, b->data, length);
275
276           howmuch = length;
277
278           b->size -= length;
279
280           b->data += length;
281         }
282       else
283         {
284
285           memcpy (data, b->data, b->size);
286
287           howmuch = b->size;
288
289           free (b->freeptr);
290
291           if (b->next)
292             {
293               b->next->prev = 0;
294               p->buffer_first = b->next;
295             }
296           else
297             {
298               p->buffer_first = 0;
299             }
300           free (b);
301         }
302     }
303   else
304     {
305       return NETREAD (fd, data, length);
306     }
307   return howmuch;
308 }
309
310
311
312 /*
313  * Free everything connection structure has malloced (and not yet freed)
314  */
315
316 void
317 cl_free_connection (connection)
318      ClConnection_t *connection;
319 {
320   if (connection->address)
321     free (connection->address);
322
323   if (connection->addr)
324     free (connection->addr);
325
326   if (connection->command)
327     free (connection->command);
328
329   if (connection->buffer_first)
330     {
331       cl_data_t *p = connection->buffer_first;
332
333       while (p)
334         {
335
336           cl_data_t *p2 = p;
337
338           free (p->freeptr);
339
340           free (p);
341
342           p = p2->next;
343         }
344     }
345
346   /*
347    * NOTE!
348    * anAnchor or diag should not be freed (at least they are not on
349    * original common code.
350    */
351 }
352
353
354 /*
355  * Return true if loading to file is supported with this address
356  */
357 int
358 ClCanLoadToFile (address)
359      char *address;
360 {
361   char *access;
362
363   if (!address)
364     {
365       return 0;
366     }
367
368   access = HTParse (address, "", PARSE_ACCESS);
369
370   if (!strcmp (access, "html"))
371     {
372
373       free (access);
374
375       return 1;
376     }
377
378   if (!strcmp (access, "file"))
379     {
380
381       free (access);
382
383       return 1;
384     }
385
386   free (access);
387
388   return 0;
389 }
390
391
392 /*
393  * Are we loading this connection to file ?
394  */
395 int
396 ClConnectionOnLoadToFileMode (connection)
397      ClConnection_t *connection;
398 {
399   if (!connection)
400     return 0;
401
402   return connection->load_to_file;
403 }
404
405
406 void
407 ClSetFileNameForLoadingToFile (char *filename)
408 {
409   if (filename)
410     WWWErwiseFileLoadName = (char *) strdup (filename);
411   else
412     WWWErwiseFileLoadName = NULL;
413 }