Merge branch 'master' of https://git.maemo.org/projects/erwise
[erwise] / WWWLibrary / HTAccess.c
1 /*              Access Manager                                  HTAccess.c
2 **              ==============
3 */
4
5
6 #include "HTParse.h"
7 #include "HTUtils.h"
8 #include "WWW.h"
9 #include "HTAnchor.h"
10 #include "HTFTP.h"
11 #include "HTTP.h"
12 #include "HTFile.h"
13 #include <errno.h>
14 #include <stdio.h>
15
16 #include "tcp.h"
17 #include "HText.h"
18 #include "HTNews.h"
19 #include "HTGopher.h"
20 #include "HTBrowse.h"           /* Need global HTClientHost */
21
22 #include "HTAccess.h"
23
24 #ifdef ERWISE
25 #include "Cl.h"
26 #endif
27
28 #define HT_NO_DATA -9999
29
30 PUBLIC int HTDiag = 0;          /* Diagnostics: load source as text */
31
32 /*      Telnet or "rlogin" access
33 **      -------------------------
34 */
35 PRIVATE int remote_session ARGS2(char *, access, char *, host)
36 {
37         char * user = host;
38         char * hostname = strchr(host, '@');
39         char * port = strchr(host, ':');
40         char   command[256];
41         BOOL rlogin = strcmp(access, "rlogin");
42         
43         if (hostname) {
44             *hostname++ = 0;    /* Split */
45         } else {
46             hostname = host;
47             user = 0;           /* No user specified */
48         }
49         if (port) *port++ = 0;  /* Split */
50
51 #ifdef unix
52         sprintf(command, "%s%s%s %s %s", access,
53                 user ? " -l " : "",
54                 user ? user : "",
55                 hostname,
56                 port ? port : "");
57         if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
58         system(command);
59         return HT_NO_DATA;              /* Ok - it was done but no data */
60 #define TELNET_DONE
61 #endif
62
63 #ifdef MULTINET                         /* VMS varieties */
64         if (!rlogin) {                  /* telnet */
65             if (user) printf("When you are connected, log in as %s\n", user);
66             sprintf(command, "TELNET %s%s %s",
67                 port ? "/PORT=" : "",
68                 port ? port : "",
69                 hostname);
70         } else {
71             sprintf(command, "RLOGIN%s%s%s%s %s", access,
72                 user ? "/USERNAME=" : "",
73                 user ? user : "",
74                 port ? "/PORT=" : "",
75                 port ? port : "",
76                 hostname);
77         }
78         if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
79         system(command);
80         return HT_NO_DATA;              /* Ok - it was done but no data */
81 #define TELNET_DONE
82 #endif
83
84 #ifdef UCX
85 #define SIMPLE_TELNET
86 #endif
87 #ifdef VM
88 #define SIMPLE_TELNET
89 #endif
90 #ifdef SIMPLE_TELNET
91         if (!rlogin) {                  /* telnet only */
92             if (user) printf("When you are connected, log in as %s\n", user);
93             sprintf(command, "TELNET  %s",      /* @@ Bug: port ignored */
94                 hostname);
95             if (TRACE) fprintf(stderr, "HTaccess: Command is: %s\n", command);
96             system(command);
97             return HT_NO_DATA;          /* Ok - it was done but no data */
98         }
99 #endif
100
101 #ifndef TELNET_DONE
102         fprintf(stderr,
103         "Sorry, this browser was compiled without the %s access option.\n",
104                 access);
105         fprintf(stderr,
106         "\nTo access the information you must %s to %s", access, hostname);
107         if (port) fprintf(stderr," (port %s)", port);
108         if (user) fprintf(stderr," logging in with username %s", user);
109         fprintf(stderr, ".\n");
110         return -1;
111 #endif
112 }
113
114 /*      Open a file descriptor for a document
115 **      -------------------------------------
116 **
117 ** On entry,
118 **      addr            must point to the fully qualified hypertext reference.
119 **
120 ** On exit,
121 **      returns         <0      Error has occured.
122 **                      >=0     Value of file descriptor or socket to be used
123 **                               to read data.
124 **      *pFormat        Set to the format of the file, if known.
125 **                      (See WWW.h)
126 **
127 */
128 PRIVATE int HTOpen ARGS3(
129         CONST char *,addr1,
130         HTFormat *,pFormat,
131         HTParentAnchor *,anchor)
132 {
133     char * access=0;    /* Name of access method */
134     int status;
135     char * gateway;
136     char * gateway_parameter;
137     char * addr = (char *)malloc(strlen(addr1)+1);
138     
139     if (addr == NULL) outofmem(__FILE__, "HTOpen");
140     strcpy(addr, addr1);                        /* Copy to play with */
141     
142     access =  HTParse(addr, "file:", PARSE_ACCESS);
143     
144     gateway_parameter = (char *)malloc(strlen(access)+20);
145     if (gateway_parameter == NULL) outofmem(__FILE__, "HTOpen");
146     strcpy(gateway_parameter, "WWW_");
147     strcat(gateway_parameter, access);
148     strcat(gateway_parameter, "_GATEWAY");
149     gateway = getenv(gateway_parameter);
150     free(gateway_parameter);
151
152     if (gateway) {
153         status = HTLoadHTTP(addr, gateway, anchor, HTDiag);
154 #ifndef CURSES
155         if (status<0) fprintf(stderr,   /* For simple users */
156             "Cannot connect to information gateway %s\n", gateway);
157 #endif 
158     } else if (0==strcmp(access, "http")) {
159         status = HTLoadHTTP(addr, 0, anchor, HTDiag);
160 #ifndef CURSES
161         if (status<0) fprintf(stderr,   /* For simple users */
162                 "Cannot connect to information server.\n");
163 #endif
164     } else if (0==strcmp(access, "file")) {
165         status = HTOpenFile(addr, pFormat, anchor);
166
167     } else if (0==strcmp(access, "news")) {
168         status = HTLoadNews(addr, anchor, HTDiag);
169         if (status>0) status = HT_LOADED;
170
171     } else if (0==strcmp(access, "gopher")) {
172         status = HTLoadGopher(addr, anchor, HTDiag);
173         if (status>0) status = HT_LOADED;
174
175     } else if (!strcmp(access, "telnet") ||             /* TELNET */
176         !strcmp(access, "rlogin")) {                    /* RLOGIN */
177         char * host = HTParse(addr, "", PARSE_HOST);
178         remote_session(access, host);
179         free(host);
180         
181     } else if (0==strcmp(access, "wais")) {
182         user_message(
183 "HTAccess: For WAIS access set WWW_wais_GATEWAY to gateway address.\n");
184     } else {
185
186         user_message(
187         "HTAccess: name scheme `%s' unknown by this browser version.\n",
188                  access);
189         status = -1;
190     }
191     free(access);
192     free(addr);
193     return status;
194 }
195
196
197 /*      Close socket opened for reading a file
198 **      --------------------------------------
199 **
200 */
201 #ifdef ERWISE
202 PUBLIC int HTClose ARGS1(int,soc)
203 #else
204 PRIVATE int HTClose ARGS1(int,soc)
205 #endif
206 {
207     return HTFTP_close_file(soc);
208 }
209
210
211 /*              Load a document
212 **              ---------------
213 **
214 **    On Entry,
215 **        anchor            is the node_anchor for the document
216 **        full_address      The address of the file to be accessed.
217 **
218 **    On Exit,
219 **        returns    YES     Success in opening file
220 **                   NO      Failure 
221 **
222 */
223
224 PUBLIC BOOL HTLoadDocument ARGS3(HTParentAnchor *,anchor,
225         CONST char *,full_address,
226         BOOL,   filter)
227
228 {
229     int         new_file_number;
230     HTFormat    format;
231     HText *     text;
232
233     if (text=(HText *)HTAnchor_document(anchor)) {      /* Already loaded */
234 #ifdef ERWISE
235         /*
236          * do NOT do this
237          */
238         fprintf(stderr, "HTBrowse: Document already in memory.\n");
239
240         WWWErwiseStatus = CL_ALREADY_LOADED;
241
242         return YES;
243 #else
244         if (TRACE) fprintf(stderr, "HTBrowse: Document already in memory.\n");
245         HText_select(text);
246         return YES;
247 #endif
248     }
249     
250 #ifdef CURSES
251       prompt_set("Retrieving document...");
252 #endif
253     if (filter) {
254         new_file_number = 0;
255         format = WWW_HTML;
256     } else {
257         new_file_number = HTOpen(full_address, &format, anchor);
258     }
259 /*      Log the access if necessary
260 */
261     if (logfile) {
262         time_t theTime;
263         time(&theTime);
264         fprintf(logfile, "%24.24s %s %s %s\n",
265             ctime(&theTime),
266             HTClientHost ? HTClientHost : "local",
267             new_file_number<0 ? "FAIL" : "GET",
268             full_address);
269         fflush(logfile);        /* Actually update it on disk */
270         if (TRACE) fprintf(stderr, "Log: %24.24s %s %s %s\n",
271             ctime(&theTime),
272             HTClientHost ? HTClientHost : "local",
273             new_file_number<0 ? "FAIL" : "GET",
274             full_address);
275     }
276     
277
278     if (new_file_number == HT_LOADED) {
279         if (TRACE) {
280             printf("HTAccess: `%s' has been accessed.\n",
281             full_address);
282         }
283 #ifdef ERWISE
284         WWWErwiseStatus = CL_COMPLETED;
285         WWWErwiseConnection->fd = -1;
286 #endif
287         return YES;
288     }
289     
290     if (new_file_number == HT_NO_DATA) {
291         if (TRACE) {
292             printf("HTAccess: `%s' has been accessed, No data left.\n",
293             full_address);
294         }
295 #ifdef ERWISE
296         WWWErwiseStatus = CL_FAILED;
297 #endif
298         return NO;
299     }
300     
301     if (new_file_number<0) {                  /* Failure in accessing a file */
302
303 #ifdef CURSES
304         user_message("Can't access `%s'", full_address);
305 #else
306         printf("\nWWW: Can't access `%s'\n", full_address);
307 #endif
308 #ifdef ERWISE
309         WWWErwiseStatus = CL_FAILED;
310         return NO;
311 #endif
312         if (!HTMainText){
313             exit(2);                            /* Can't get first page */
314         } else {
315             return NO;
316         }
317     }
318     
319     if (TRACE) {
320         printf("WWW: Opened `%s' as fd %d\n",
321         full_address, new_file_number);
322     }
323
324 #ifdef ERWISE
325     /*
326      * Do the rest elsewhere (if this connection can be loaded
327      * using non blocking transfer)
328      */
329
330     if(WWWErwiseConnection->function) {
331         WWWErwiseConnection->fd = new_file_number;
332
333         return YES;
334     }
335 #endif
336
337     HTParseFormat(HTDiag ? WWW_PLAINTEXT : format, anchor, new_file_number);
338     
339     HTClose(new_file_number);
340     
341     return YES;
342     
343 } /* HTLoadDocument */
344
345
346 /*              Load a document from absolute name
347 **              ---------------
348 **
349 **    On Entry,
350 **        relative_name     The relative address of the file to be accessed.
351 **
352 **    On Exit,
353 **        returns    YES     Success in opening file
354 **                   NO      Failure 
355 **
356 **
357 */
358
359 PUBLIC BOOL HTLoadAbsolute ARGS2(CONST char *,addr, BOOL, filter)
360 {
361    return HTLoadDocument(
362                 HTAnchor_parent(HTAnchor_findAddress(addr)),
363                 addr, filter);
364 }
365
366
367 /*              Load a document from relative name
368 **              ---------------
369 **
370 **    On Entry,
371 **        relative_name     The relative address of the file to be accessed.
372 **
373 **    On Exit,
374 **        returns    YES     Success in opening file
375 **                   NO      Failure 
376 **
377 **
378 */
379
380 PUBLIC BOOL HTLoadRelative ARGS1(CONST char *,relative_name)
381 {
382     char *              full_address = 0;
383     BOOL                result;
384     char *              mycopy = 0;
385     char *              stripped = 0;
386     char *              current_address =
387                                 HTAnchor_address((HTAnchor*)HTMainAnchor);
388
389     StrAllocCopy(mycopy, relative_name);
390
391     stripped = HTStrip(mycopy);
392     full_address = HTParse(stripped,
393                    current_address,
394                    PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
395     result = HTLoadAbsolute(full_address, NO);
396     free(full_address);
397     free(current_address);
398     return result;
399 }
400
401
402 /*              Load if necessary, and select an anchor
403 **              --------------------------------------
404 **
405 **    On Entry,
406 **        destination               The child or parenet anchor to be loaded.
407 **
408 **    On Exit,
409 **        returns    YES     Success
410 **                   NO      Failure 
411 **
412 */
413
414 PUBLIC BOOL HTLoadAnchor ARGS1(HTAnchor *,destination)
415 {
416     HTParentAnchor * parent;
417
418     if (!destination) return NO;        /* No link */
419     
420     parent  = HTAnchor_parent(destination);
421     
422     if ( /* HTAnchor_document (parent) == NULL) { */ parent != HTMainAnchor)    {       /* If not already loaded */
423         BOOL result;
424         char * address = HTAnchor_address((HTAnchor*) parent);
425         result = HTLoadDocument(parent, address, NO);
426         free(address);
427         if (!result) return NO;
428     }
429     
430     if (destination != (HTAnchor *)parent)      /* If child anchor */
431         HText_selectAnchor(HTMainText, 
432                 (HTChildAnchor*)destination); /* Double display? @@ */
433                 
434     return YES;
435         
436 } /* HTLoadAnchor */
437
438
439 #ifndef ERWISE
440 /*              Search
441 **              ------
442 **  Performs a keyword search on word given by the user. Adds the keyword to 
443 **  the end of the current address and attempts to open the new address.
444 **
445 **  On Entry,
446 **       *keywords      space-separated keyword list or similar search list
447 **      HTMainAnchor    global must be valid.
448 */
449
450 PUBLIC BOOL HTSearch ARGS1(char *,keywords)
451
452 {
453     char * p;             /* pointer to first non-blank */
454     char * q, *s;
455     char * address = HTAnchor_address((HTAnchor*)HTMainAnchor);
456     BOOL result;
457     
458     p = HTStrip(keywords);
459     for (q=p; *q; q++)
460         if (WHITE(*q)) {
461             *q = '+';
462         }
463
464     s=strchr(address, '?');             /* Find old search string */
465     if (s) *s = 0;                              /* Chop old search off */
466
467     StrAllocCat(address, "?");
468     StrAllocCat(address, p);
469
470     result = HTLoadRelative(address);
471     free(address);
472     return result;
473     
474 }
475 #else /* ERWISE */
476
477 /*
478  * Why everything is so hardcoded ???? 
479  */
480
481 PUBLIC char *HTSearchAddress ARGS1(char *,keywords)
482 {
483     char * p;             /* pointer to first non-blank */
484     char * q, *s;
485     char * address = HTAnchor_address((HTAnchor*)HTMainAnchor);
486     char * current_address;
487     char * mycopy;
488     char * stripped;
489     char * full_address;
490
491     
492     p = HTStrip(keywords);
493     for (q=p; *q; q++)
494         if (WHITE(*q)) {
495             *q = '+';
496         }
497
498     s=strchr(address, '?');             /* Find old search string */
499     if (s) *s = 0;                              /* Chop old search off */
500
501     StrAllocCat(address, "?");
502     StrAllocCat(address, p);
503
504     StrAllocCopy(mycopy, address);
505     
506     current_address = HTAnchor_address((HTAnchor*)HTMainAnchor);
507
508     stripped = HTStrip(mycopy);
509
510     full_address = HTParse(stripped,
511                    current_address,
512                    PARSE_ACCESS|PARSE_HOST|PARSE_PATH|PARSE_PUNCTUATION);
513
514     free(address);
515     
516     return full_address;
517 }
518
519 #endif /* ERWISE */
520