Annotation of libwww/LineMode/src/HTBrowse.c, revision 1.48.2.4

1.44      frystyk     1: /*                                                                  HTBrowse.c
                      2: **     HYPERTEXT BROWSER FOR DUMB TERMINALS
                      3: **
                      4: **     (c) COPYRIGHT CERN 1994.
                      5: **     Please first read the full copyright statement in the file COPYRIGH.
1.1       timbl       6: **
                      7: **  Authors:
                      8: **     NP:  Nicola Pellow  Tech.Student CERN 1990-91
                      9: **     TBL: Tim Berners-Lee CERN (timbl@info.cern.ch)
                     10: **     JFG: Jean-Francois Groff, Cooperant CERN 1991-92 (jfg@info.cern.ch)
                     11: **     DR:  Dudu Rashty +972-2-584848 <RASHTY@hujivms.bitnet>
1.8       duns       12: **     MD:  Mark Donszelmann, DELPHI CERN, (duns@vxdeop.cern.ch)
1.34      frystyk    13: **     HFN: Henrik Frystyk Nielsen, CERN, (frystyk@dxcern.cern.ch)
1.1       timbl      14: **
                     15: **  History:
                     16: **
                     17: **   4 Dec 90:  Written from scratch (NP)
                     18: **  11 Feb 91:  Code written by TBL so that the browser could be linked with
                     19: **              code produced by Bernd Pollermann, enabling access to the
                     20: **              data on CERNVM. This involved changing the code to handle file
                     21: **              numbers rather than file pointers.
                     22: **  18 Mar 91:  The feature of history mechanism was included, enabling a  
                     23: **              record of previous nodes visited to be kept.
                     24: **   6 Apr 91:  When a node is accessed, it is immediately read into a 
1.40      frystyk    25: **              buffer, in an unformatted state, as soon as the connection is  
1.1       timbl      26: **              made, so that the server is freed as quickly as possible. 
                     27: **              The program now also uses the additional modules HTBufferFile.c
                     28: **              and HTBufferFile.h.
                     29: **  17 Apr 91:  Can be used on machines running ANSI C and ordinary C.
                     30: **  10 May 91:  Formatted text is stored in a linked list buffer which allows
                     31: **              scrolling and better page breaks in the middle of text.
                     32: **              Code incorporated by Tim BL, to enable anonymous FTP.          
                     33: **  21 May 91:  Accepts various parameters on the command line.
                     34: **  19 Aug 91:  Currently available in Unix, VAX/VMS and MVS environments.
                     35: **  21 Nov 91:  Character grid uses new architecture. (TBL)
                     36: **              added -w option, new commands, print,
                     37: **                  ...        See Features.html for further details
                     38: **  16 Jan 92:  Put in VIOLA-compatible options - see \017 characters.
                     39: **                  \017 and \016 bracket user-selectable input.
                     40: **  27 Feb 92: New handling of user input, enhanced command syntax. (JFG)
                     41: **  18 May 92: PS command see ifdef SLAVE_PRINTER (DR/TBL)
                     42: **   6 Oct 92:  Painful recovery from someone(?)'s attept to pretty print.(TBL)
                     43: **             Please see coding style guide before changing indentation etc!
                     44: **     Mar 93: Force on HTFile's HTDirAccess and HTDirReadme flags.
1.8       duns       45: **   3 Nov 93: (MD) Changed vms into VMS
                     46: **             (MD) Assigne output in main, not at initialize (VMS only)
1.1       timbl      47: **
                     48: ** Compilation-time macro options
                     49: **
                     50: **     REF_MARK        Printf string to be used for printing anchor numbers
                     51: **     END_MARK        String to be used to denote the end of a document
                     52: **     VL              Version number, quoted eg "1.2a"
                     53: */
                     54: 
1.48.2.4! frystyk    55: #include "WWWLib.h"
1.11      frystyk    56: #include "HTBrowse.h"  /* Things exported, short names */
                     57: #include "GridText.h"  /* Hypertext definition */
1.1       timbl      58: 
1.48.2.4! frystyk    59: #if 0
        !            60: #include <ctype.h>
1.1       timbl      61: #include "HTFormat.h"
                     62: #include "HTTCP.h"     /* TCP/IP utilities */
                     63: #include "HTAnchor.h"   /* Anchor class */
                     64: #include "HTParse.h"    /* WWW address manipulation */
                     65: #include "HTAccess.h"   /* WWW document access network code */
1.48.2.4! frystyk    66: #include "HTHist.h"    /* Navigational aids */
1.1       timbl      67: #include "HTML.h"      /* For parser */
1.48.2.4! frystyk    68: #include "HTFWrite.h"  /* For non-interactive output */
1.33      timbl      69: #include "HTMLGen.h"   /* For reformatting HTML */
1.1       timbl      70: #include "HTFile.h"    /* For Dir access flags */
1.3       timbl      71: #include "HTRules.h"    /* For loading rule file */
1.30      frystyk    72: #include "HTError.h"
1.38      frystyk    73: #include "HTAlert.h"
1.41      frystyk    74: #include "HTTP.h"
1.40      frystyk    75: #include "HTEvent.h"
1.48.2.4! frystyk    76: #endif
1.40      frystyk    77: 
                     78: /* HWL 18/7/94: applied patch from agl@glas2.glas.apc.org (Anton Tropashko) */
                     79: #ifdef CYRILLIC                
                     80: #include "a_stdio.h"
                     81: #endif
1.1       timbl      82: 
1.40      frystyk    83: #ifdef THINK_C                      /* Macintosh Think C development system */
1.1       timbl      84: #include <console.h>
                     85: #include <time.h>
1.40      frystyk    86: extern int socketdebug;                   /* Must be declared in the socket library */
                     87: #endif
                     88: 
                     89: /* Macros and other defines */
                     90: #ifndef VL
                     91: #define VL "unspecified"
                     92: #endif
                     93: 
                     94: /*     If the guy gives the "MANUAL" command, jump to this: */
                     95: #ifndef MANUAL
                     96: #define MANUAL "http://info.cern.ch/hypertext/WWW/LineMode/Defaults/QuickGuide.html"
                     97: #endif
                     98: 
                     99: #ifndef COM_HELP_FILE
                    100: #define COM_HELP_FILE "http://info.cern.ch/hypertext/WWW/LineMode/Defaults/CommandLine.html"
1.1       timbl     101: #endif
                    102: 
1.40      frystyk   103: #ifndef DEFAULT_LOCAL_LOGFILE
                    104: #define DEFAULT_LOCAL_LOGFILE          "WWW-log"       /* Log file name for local execution */
                    105: #endif
1.1       timbl     106: 
1.40      frystyk   107: #ifndef DEFAULT_OUTPUT_FILE
                    108: #define DEFAULT_OUTPUT_FILE            "WWW-out"       /* Output file name for non-interactive run */
1.37      howcome   109: #endif
                    110: 
1.40      frystyk   111: #ifndef DEFAULT_REF_HEAD
                    112: #define DEFAULT_REF_HEAD               "*** References from this document ***"
                    113: #endif
1.1       timbl     114: 
                    115: #ifndef REF_MARK               /* May be redefined on command line */
                    116: #ifdef VIOLA
                    117: #define REF_MARK "[\017%d\016]"        /* Shift-in, shift-out around number */
                    118: #define PROMPT_MARK "\017%s\016"
                    119: #else
                    120: #define PROMPT_MARK "%s"
                    121: #ifdef VM
                    122: #define REF_MARK " <%d>"       /* IBM terminals can't handle [] well */
                    123: #else
                    124: #define REF_MARK "[%d]"
                    125: #endif
                    126: #endif
                    127: #endif
                    128: 
                    129: #ifndef END_MARK
                    130: #ifdef VM
                    131: #define END_MARK "     <End>"
                    132: #else
                    133: #define END_MARK "     [End]"
                    134: #endif
                    135: #endif
                    136: 
                    137: #ifdef NEWLIB
1.13      frystyk   138: #define SCREEN_WIDTH           78
1.1       timbl     139: #endif
                    140: 
                    141: #ifndef SCREEN_WIDTH      
1.13      frystyk   142: #define SCREEN_WIDTH           79  /* Default width of the screen */ 
1.1       timbl     143: #endif
1.13      frystyk   144: 
                    145: #ifndef MIN_SCREEN_WIDTH
                    146: #define MIN_SCREEN_WIDTH       10 
                    147: #endif
                    148: 
                    149: #ifndef MAX_SCREEN_WIDTH
                    150: #define MAX_SCREEN_WIDTH       150      
                    151: #endif
                    152: 
1.1       timbl     153: #ifndef SCREEN_HEIGHT
1.13      frystyk   154: #define SCREEN_HEIGHT          24 /* Default number of lines to the screen */
                    155: #endif
                    156: 
                    157: #ifndef MIN_SCREEN_HEIGHT
                    158: #define MIN_SCREEN_HEIGHT      5 
                    159: #endif
                    160: 
                    161: #ifndef MAX_SCREEN_HEIGHT
1.14      frystyk   162: #define MAX_SCREEN_HEIGHT      200      
1.1       timbl     163: #endif
                    164: 
1.16      frystyk   165: #define INFINITY               1024                                 /*!! BUG*/
                    166: #define ADDRESS_LENGTH         INFINITY   /* Maximum address length of node */
                    167: #define RESPONSE_LENGTH                INFINITY /* Maximum length of users response */
                    168: 
1.40      frystyk   169: /* #define LONG_PROMPT 1 */                    /* Long or short user prompt */
                    170: 
                    171: #if defined(ultrix) || defined(__osf__)
                    172: #define GET_SCREEN_SIZE
                    173: #endif
                    174: 
1.48.2.1  frystyk   175: #if defined(__svr4__)
                    176: #define CATCH_SIG
                    177: #endif
                    178: 
1.40      frystyk   179: #define Check_User_Input(command) \
                    180:     (!strncasecomp (command, this_word, strlen(this_word)))
1.1       timbl     181: 
1.40      frystyk   182: /* Public Variables etc. */
                    183: /* HWL 18/7/94: applied patch from agl@glas2.glas.apc.org (Anton Tropashko) */
                    184: #ifdef CYRILLIC
                    185: struct ARc arc;
                    186: #endif
1.2       timbl     187: 
1.40      frystyk   188: PUBLIC char *          HTAppName = "CERN-LineMode";     /* Application name */
                    189: PUBLIC char *          HTAppVersion = VL;            /* Application version */
                    190: PUBLIC int             HTScreenWidth   = SCREEN_WIDTH;        /* By default */
                    191: PUBLIC int             HTScreenHeight  = -1;              /* -1 = Undefined */
                    192: PUBLIC BOOL            display_anchors = YES;      /* Show anchors in text? */
                    193: PUBLIC char *          start_reference = NULL;   /* Format for start anchor */
                    194: PUBLIC char *          end_reference = REF_MARK;          /* for end anchor */
                    195: PUBLIC char *          reference_mark = "[%d] ";     /* for reference lists */
                    196: PUBLIC char *          end_mark = END_MARK;      /* Format string for [End] */
1.1       timbl     197:  
1.40      frystyk   198: /* Type definitions and global variables local to this module */
                    199: PRIVATE HTRequest *    request = NULL;
                    200: PRIVATE        HTList *        reqlist = NULL;           /* List of active requests */
                    201: PRIVATE HTParentAnchor*        home_anchor = NULL;         /* First document anchor */
                    202: PRIVATE char           keywords[ADDRESS_LENGTH];       /* From command line */
                    203: PRIVATE char *         output_file_name = NULL;                  /* -o xxxx */
                    204: PRIVATE char           choice[RESPONSE_LENGTH];          /* Users response  */
                    205: PRIVATE char *         refhead = DEFAULT_REF_HEAD;      /* Ref list heading */
                    206: PRIVATE char *         logfile_root = NULL;                /* Log file name */
                    207: PRIVATE BOOL           filter = NO;                     /* Load from stdin? */
                    208: PRIVATE BOOL           reformat_html = NO;                /* Reformat html? */
                    209: PRIVATE BOOL           listrefs_option = NO;     /* -listrefs option used?  */
                    210: PRIVATE BOOL           OutSource = NO;             /* Output source, YES/NO */
                    211: PRIVATE char *         HTLogFileName = NULL;       /* Root of log file name */
                    212: PRIVATE int            OldTraceFlag = SHOW_ALL_TRACE;
1.47      frystyk   213: PRIVATE HTList *       conversions = NULL;            /* Format conversions */
1.48.2.1  frystyk   214: PRIVATE BOOL           UseMulti = YES;                 /* Use multithreaded */
1.8       duns      215: 
                    216: #ifdef VMS
                    217: PRIVATE FILE *       output;           /* assignment done in main */
1.17      duns      218: #ifdef __DECC
                    219: /* dummy declarations to make sure that LINKER will not complain */
                    220: PUBLIC char *HTBinDir;
                    221: PUBLIC int HTDiag;
                    222: PUBLIC char *HTPostScript;
                    223: PUBLIC char *HTPutScript;
                    224: PUBLIC char *HTSearchScript;
                    225: #endif /* DECC */
1.8       duns      226: #else /* not VMS */
1.4       timbl     227: PRIVATE FILE *      output = stdout;
1.8       duns      228: #endif /* not VMS */ 
1.4       timbl     229: 
1.40      frystyk   230: /* ------------------------------------------------------------------------- */
                    231: /*                             HELP FUNCTIONS                               */
                    232: /* ------------------------------------------------------------------------- */
1.7       secret    233: 
                    234: #ifdef GET_SCREEN_SIZE
                    235: #include <sys/ioctl.h>
                    236: /*
1.40      frystyk   237: ** Get size of the output screen. Stolen from less.
                    238: */
                    239: PRIVATE void scrsize ARGS2(int *, p_height, int *, p_width)
1.7       secret    240: {
                    241:       register char *s;
                    242:       int ioctl();
                    243:       struct winsize w;
                    244: 
                    245:       if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_row > 0)
                    246:               *p_height = w.ws_row;
                    247:       else
                    248:       if ((s = getenv("LINES")) != NULL)
                    249:               *p_height = atoi(s);
                    250:       else
                    251:               *p_height = SCREEN_HEIGHT;
                    252: 
                    253:       if (ioctl(2, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
                    254:               *p_width = w.ws_col;
                    255:       else
                    256:       if ((s = getenv("COLUMNS")) != NULL)
                    257:               *p_width = atoi(s);
                    258:       else
                    259:               *p_width = 80;
                    260: }
                    261: #endif /* GET_SCREEN_SIZE, BSN */
                    262: 
1.48.2.1  frystyk   263: #ifdef CATCH_SIG
                    264: #include <signal.h>
                    265: /*                                                                 SetSignal
                    266: **  This function sets up signal handlers. This might not be necessary to
                    267: **  call if the application has its own handlers.
                    268: */
                    269: PRIVATE void SetSignal NOARGS
                    270: {
                    271:     /* On some systems (SYSV) it is necessary to catch the SIGPIPE signal
                    272:     ** when attemting to connect to a remote host where you normally should
                    273:     ** get `connection refused' back
                    274:     */
                    275:     if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
                    276:        if (PROT_TRACE) fprintf(stderr, "HTSignal.... Can't catch SIGPIPE\n");
                    277:     } else {
                    278:        if (PROT_TRACE) fprintf(stderr, "HTSignal.... Ignoring SIGPIPE\n");
                    279:     }
                    280: }
                    281: #endif /* CATCH_SIG */
                    282: 
1.7       secret    283: 
1.40      frystyk   284: /*             Display Help screen                      Help_screen
                    285: **             -------------------
                    286: ** Produce a help screen, displaying the current document address and
                    287: ** a list of * available commands *in this context*.  * ?? Perhaps this
                    288: ** should be a hypertext page, not included in the history list.
1.1       timbl     289: */
1.40      frystyk   290: PRIVATE void help_screen NOARGS {
                    291: 
                    292:     char * current_address = HTAnchor_address((HTAnchor*)HTMainAnchor);
                    293:     CONST char * title = HTAnchor_title(HTMainAnchor);
                    294:     
                    295:     printf("\n\nWWW LineMode Browser version %s (WWWLib %s)   COMMANDS AVAILABLE\n\n",
                    296:                            VL, HTLibraryVersion);
                    297:     if (title) printf("You are reading\n \"%s\"\nwhose address is\n  %s\n\n",
                    298:                                                    title, current_address);
                    299:     else printf("You are reading a document whose address is\n    '%s' \n\n",
                    300:                                    current_address);
                    301:     
                    302:     if (HText_canScrollDown(HTMainText)) {
                    303:        printf(
                    304:                "  <RETURN>        Move down one page within the document.\n");
                    305:        printf(
                    306:                "  BOttom          Go to the last page of the document.\n");
                    307:        };
                    308:            
                    309:     if (HText_canScrollUp(HTMainText)) {
                    310:        printf(
                    311:                "  Top             Return to the first page of the document.\n");
                    312:        printf(
                    313:                "  Up              Move up one page within the document\n");
                    314:        };
                    315:            
                    316:     if (HText_sourceAnchors(HTMainText) != 0) {
                    317:        printf("  List            List the references from this document.\n *");
                    318:        printf("  <number>        Select a referenced document by number (from 1 to %d).\n",
                    319:                HText_sourceAnchors(HTMainText));
                    320:     }
                    321:            
1.48.2.1  frystyk   322:     if (UseMulti) {
                    323:        printf("  z               Interrupt a request\n");
                    324:     }
                    325: 
1.40      frystyk   326:     if (HTAnchor_isIndex(HTMainAnchor)) {
                    327:        printf(
                    328:                "  Find <words>    Search this index for given words (separated by spaces).\n"); 
                    329:     }
                    330:            
                    331:     if (HTHistory_canBacktrack()) {
                    332:        printf("  Recall          List visited documents.\n");
                    333:        printf("  Recall <number> Return to a previously visited document\n");
                    334:        printf("                  as numbered in the recall list.\n");
                    335:        printf("  HOme            Return to the starting document.\n");
                    336:        printf("  Back            Move back to the last document.\n");
                    337:     }
                    338:            
                    339:     if (HTHistory_canMoveBy(1))
                    340:            printf("  Next            Take next link from last document.\n");
                    341:                    
                    342:     if (HTHistory_canMoveBy(-1))
                    343:            printf("  Previous        Take previous link from last document.\n");
1.1       timbl     344: 
1.40      frystyk   345:     printf("  REFresh         Refresh screen with current document\n");
                    346:     printf("  Go <address>    Go to document of given [relative] address\n");
                    347:            
                    348: #ifdef GOT_SYSTEM
                    349:     if (!HTClientHost) {       /* NOT for telnet guest! */
                    350:            printf("  PRInt           Print text of this document. *\n");
                    351:            printf("  ! <command>     Execute shell <command> without leaving.\n");
                    352:            printf("  > <file>        Save the text of this document in <file>. *\n");
                    353:            printf("                  If <file> exists use '>!' to overwrite it.\n");
                    354:            printf("  >> <file>       Append the text of this document to <file>. *\n");
                    355:            printf("  | <command>     Pipe this document to the shell <command>. *\n");
                    356: #ifdef unix
                    357:            printf("  CD <directory>  Change local working directory.\n");
                    358: #endif
                    359:            printf("* Prefix these commands with \"Source \" to use raw source.\n\n");
                    360:     }
                    361: #endif
                    362:            
                    363: #ifdef SLAVE_PRINTER
                    364:     printf(
                    365:     "  Ps              Print text of this document to Terminal's Slave printer.\n");
1.1       timbl     366: #endif
1.40      frystyk   367:            
                    368:     printf("  Verbose         Switch to %sverbose mode.\n", WWW_TraceFlag ? "non-" : "");
                    369:            
                    370:     printf("  Help            Display this page.\n");
                    371:     printf("  Manual          Jump to the online manual for this program\n");
                    372:     printf("  Quit            Leave the www program.\n");          
                    373:     printf("\n");
                    374:     free(current_address);    
                    375: } /* End of help_screen */
1.1       timbl     376: 
                    377: 
1.40      frystyk   378: /*     Reference_List
                    379: **     --------------
                    380: **     Print out a list of HyperText References accumulated within the text.
                    381: **
                    382: ** On entry
                    383: **     titles          Set:    if we want titles where available
                    384: **                     Clear:  we only get addresses.
                    385: */
1.7       secret    386: 
1.40      frystyk   387: PRIVATE void Reference_List ARGS1(BOOL, titles)
                    388: {
1.48.2.1  frystyk   389:     int cnt;
                    390:     int refs = HText_sourceAnchors(HTMainText);
                    391:     if (refs <= 0) {
1.40      frystyk   392:        fprintf(output, "\n\nThere are no references from this document.\n\n");
                    393:     } else {
                    394:        fprintf(output, "\n%s\n", refhead);
1.48.2.1  frystyk   395:        for (cnt=1; cnt<=refs; cnt++) {
                    396:            HTAnchor *dest =
                    397:                HTAnchor_followMainLink((HTAnchor *)
                    398:                                        HText_childNumber(HTMainText, cnt));
                    399:            HTParentAnchor * parent = HTAnchor_parent(dest);
                    400:            char * address =  HTAnchor_address(dest);
                    401:            CONST char * title = titles ? HTAnchor_title(parent) : NULL;
                    402:            fprintf(output, reference_mark, cnt);
1.40      frystyk   403:            fprintf(output, "%s%s\n",
1.48.2.1  frystyk   404:                    ((HTAnchor*)parent!=dest) && title ? "in " : "",
1.40      frystyk   405:                    (char *)(title ? title : address));
                    406:            free(address);
                    407:        }
                    408:        fflush(stdout);
                    409:     }
                    410: }      
1.1       timbl     411: 
                    412: 
1.40      frystyk   413: /*             History_List
                    414: **             ------------
                    415: */
                    416: /*     Display a history list of nodes visited during the session.
                    417: **     ?? This should really be a hypertext page (not itself in history!).
                    418: **     ?? Should have option to display address even when anchor has a title.
1.1       timbl     419: */
                    420: 
1.40      frystyk   421: PRIVATE void History_List NOARGS {
1.38      frystyk   422: 
1.40      frystyk   423:     int  history_number = 1; 
                    424:     printf("\n  Documents you have visited:-\n\n");
1.1       timbl     425:     
1.40      frystyk   426:     do {
1.1       timbl     427:     
1.40      frystyk   428:        char * address;
                    429:        CONST char * title;
                    430:        HTAnchor * anchor = HTHistory_read(history_number);
                    431:        HTParentAnchor * parent;
1.1       timbl     432:        
1.40      frystyk   433:        if (!anchor) break;
                    434:        parent = HTAnchor_parent(anchor);
                    435:        title = HTAnchor_title(parent);
                    436:        address = HTAnchor_address(anchor);
                    437: #ifdef VIOLA
                    438:        printf("\017R %2d\016)   %s%s\n",       /* SI user field SO */
1.1       timbl     439: #else
1.40      frystyk   440:        printf("R %2d)   %s%s\n",
1.1       timbl     441: #endif
1.40      frystyk   442:                history_number,
                    443:                ((HTAnchor*)parent!=anchor) && title ? "in " : "",
                    444:                title ? title : address);
                    445:        free(address);
                    446:        
                    447:        history_number++;
                    448:        
                    449:     } while (YES);
1.1       timbl     450: 
1.40      frystyk   451:     printf("\n");
1.1       timbl     452: }
                    453: 
                    454: 
1.40      frystyk   455: /*                                                             MakeCommandLine
1.1       timbl     456: **
1.40      frystyk   457: **     Generate the Prompt line and flush it to the user
1.1       timbl     458: */
1.40      frystyk   459: PRIVATE void MakeCommandLine ARGS1(BOOL, is_index)
                    460: {
                    461:     int length_of_prompt = 0;
1.1       timbl     462: 
1.40      frystyk   463: #ifndef VM     /* Normal prompt */
                    464:     if (is_index){     
                    465:        printf("FIND <keywords>, ");
                    466:        length_of_prompt = length_of_prompt + 14;
                    467:     }
                    468:     if (HTAnchor_hasChildren(HTMainAnchor)!=0){
                    469:        int refs = HText_sourceAnchors(HTMainText);
                    470:        if (refs>1) {
                    471:            printf("1-%d, ", refs);
                    472:            length_of_prompt = length_of_prompt + 6;              /* Roughly */
                    473:        }
                    474:        else {
                    475:            printf("1, ");      
                    476:            length_of_prompt = length_of_prompt + 3;
                    477:        }
                    478:     }
                    479:     if (HTHistory_canBacktrack()){
                    480:        printf(PROMPT_MARK, "Back"); printf(", ");
                    481: #ifdef LONG_PROMPT
                    482:        printf(PROMPT_MARK, "Recall"); printf(", ");
                    483: #endif
                    484:        length_of_prompt = length_of_prompt + 6;
                    485:     }
                    486:     if (HText_canScrollUp(HTMainText)){ 
                    487:        printf(PROMPT_MARK,"Up"); printf(", ");
                    488:        length_of_prompt = length_of_prompt + 4;
                    489:     }
                    490:     if (HText_canScrollDown(HTMainText)) {
                    491:        printf("<RETURN> for more, ");
                    492:        length_of_prompt = length_of_prompt + 19;
                    493:     }
                    494:     if (length_of_prompt <= 47) {
                    495:        printf(PROMPT_MARK, "Quit"); printf(", ");
                    496:     }
1.1       timbl     497:     
1.40      frystyk   498:     printf("or Help: ");       
                    499:        
                    500: #else  /* Special prompt for VM assuming PF keys set*/
                    501:     if (is_index) {    
                    502:        printf("FIND <words>, ");                                      /* 14 */
                    503:        length_of_prompt = length_of_prompt + 14;
                    504:     }
                    505:     if (HTAnchor_hasChildren(HTMainAnchor)!=0){
                    506:        int refs = HText_sourceAnchors(HTMainText);
                    507:        if (refs>1) {
                    508:            printf("1-%d, ", refs);
                    509:            length_of_prompt = length_of_prompt + 6;             /* approx 6 */
                    510:        }
                    511:        else {
                    512:            printf("1, ");
                    513:            length_of_prompt = length_of_prompt + 3;
                    514:        }
                    515:     }
                    516:     if (HTHistory_canMoveBy(1)) {
                    517:        printf("PF2=Next ");
                    518:        length_of_prompt = length_of_prompt + 9;                        /* 9 */
                    519:     }
                    520:     printf("PF3=Quit PF4=Return, ");
                    521:     length_of_prompt = length_of_prompt + 21;                          /* 21 */
1.1       timbl     522:     
1.40      frystyk   523:     if (HTHistory_canBacktrack()){
                    524:        printf("Recall, ");
                    525:        length_of_prompt = length_of_prompt + 8;                        /* 8 */
1.1       timbl     526:     }
1.40      frystyk   527:     if (HText_canScrollUp(HTMainText)){
                    528:        printf(PROMPT_MARK,"PF7=Up "); printf(", ");
                    529:        length_of_prompt = length_of_prompt + 7;                        /* 7 */
1.1       timbl     530:     }
1.40      frystyk   531:     if (HText_canScrollDown(HTMainText)){
                    532:        printf("PF8=Down ");
                    533:        length_of_prompt = length_of_prompt + 9;                        /* 9 */
1.1       timbl     534:     }
1.40      frystyk   535:     if (length_of_prompt<70) printf("PF11=Help");                      /* 9 */
                    536:                                                                  /* EQUAL 82 */
1.1       timbl     537: #endif
                    538: 
1.44      frystyk   539:     fflush(stdout);                      /* For use to flush out the prompt */
1.40      frystyk   540:     return;
                    541: }
1.1       timbl     542: 
1.40      frystyk   543: /*                                                                      ErrMsg
                    544: **
                    545: **   General Error Message for Line Mode Browser. If verbose mode is on, then
                    546: **   the message is passed to stderr.
                    547: **
                    548: */
                    549: PRIVATE void ErrMsg ARGS2(char *, Msg, char *, Str)
                    550: {
1.44      frystyk   551:     if (TRACE || HTInteractive)
                    552:        fprintf(stderr, "Warning: %s (%s)\n", Msg, Str ? Str : "");
1.40      frystyk   553: }
1.1       timbl     554: 
1.40      frystyk   555: /* ------------------------------------------------------------------------- */
                    556: /*                             EVENT FUNCTIONS                              */
                    557: /* ------------------------------------------------------------------------- */
1.1       timbl     558: 
1.40      frystyk   559: /*
                    560: **  This function creates a new request structure and adds it to the global
                    561: **  list of active threads
1.1       timbl     562: */
1.40      frystyk   563: PRIVATE HTRequest *Thread_new ARGS1(BOOL, Interactive)
                    564: {
                    565:     HTRequest *newreq = HTRequest_new();            /* Set up a new request */
                    566:     if (!reqlist)
                    567:        reqlist = HTList_new();
1.47      frystyk   568:     if (Interactive) {
                    569:        HTList_delete(newreq->conversions);
                    570:        newreq->conversions = conversions;          /* Take from global list */
                    571:     } else
                    572:        HTFormatInitNIM(newreq->conversions);
1.48.2.1  frystyk   573:     if (!UseMulti)
                    574:        request->BlockingIO = YES;                       /* Use blocking I/O */
1.40      frystyk   575:     HTList_addObject(reqlist, (void *) newreq);
                    576:     return newreq;
                    577: }
1.1       timbl     578: 
                    579: 
1.40      frystyk   580: /*
                    581: **  This function deletes a request structure and takes it out of the list
                    582: **  of active threads.
                    583: */
                    584: PRIVATE void Thread_delete ARGS1(HTRequest *, oldreq)
                    585: {
                    586:     if (oldreq) {
                    587:        if (reqlist)
                    588:            HTList_removeObject(reqlist, (void *) oldreq);
1.48      frystyk   589:        if (oldreq->conversions == conversions)
                    590:            oldreq->conversions = NULL;     /* We keep them in a global list */
1.40      frystyk   591:        HTRequest_delete(oldreq);
                    592:     }
                    593: }
1.1       timbl     594: 
1.47      frystyk   595: 
1.40      frystyk   596: /*
                    597: **  This function deletes the whole list of active threads.
                    598: */
                    599: PRIVATE void Thread_deleteAll NOARGS
                    600: {
1.47      frystyk   601:     BOOL first=YES;          /* We only have one global list of conversions */
1.40      frystyk   602:     if (reqlist) {
                    603:        HTList *cur = reqlist;
                    604:        HTRequest* pres;
1.47      frystyk   605:        while ((pres = (HTRequest *) HTList_nextObject(cur)) != NULL) {
                    606:            if (first) {
                    607:                HTRequest_delete(pres);
                    608:                first = NO;
                    609:            } else {
                    610:                pres->conversions = NULL;
                    611:                HTRequest_delete(pres);
                    612:            }
                    613:        }
1.40      frystyk   614:        HTList_delete(reqlist);
                    615:        reqlist = NULL;
                    616:     }
                    617: }
1.1       timbl     618: 
                    619: 
                    620: /*
1.40      frystyk   621: **  This function puts up a stream to a file in order to save a document. This
                    622: **  is activated by '>', '>>' or '>!' from the prompt line.
1.47      frystyk   623: **  Returns:
                    624: **     YES if load terminated (either success or failure)
                    625: **      NO if error or operation blocked
1.1       timbl     626: **
1.40      frystyk   627: **  Henrik Frystyk 02/03-94
1.1       timbl     628: */
1.40      frystyk   629: PRIVATE BOOL SaveOutputStream ARGS2(char *, This, char *, Next)
                    630: {
                    631:     FILE *fp;
                    632:     char *fname;
                    633:     char *fmode;
                    634:     
                    635:     /* Checks if file exists. Can be overruled by using '>!' */
                    636:     if (*(This+1) == '>') {                               /* Append to file */
                    637:        fmode = "a";
                    638:        fname = *(This+2) ? (This+2) : Next;
                    639:     } else if (*(This+1) == '!') {
                    640:        fmode = "w";                                       /* Overwrite file */
                    641:        fname = *(This+2) ? (This+2) : Next;
                    642:     } else {                                           /* File name follows */
                    643:        fmode = "w";
                    644:        fname = *(This+1) ? (This+1) : Next;
                    645:        if (fname) {                                   /* See if file exists */
                    646:            if ((fp = fopen(fname, "r")) != NULL) {
                    647:                printf("%s: File exists\n", fname);
                    648:                fclose(fp);
                    649:                return NO;
                    650:            }
                    651:        }
                    652:     }
                    653:     if (!fname)                                               /* No file name given */
                    654:        return NO;
                    655:     if ((fp = fopen(fname, fmode)) == NULL) {
                    656:        ErrMsg("Can't access file", fname);
                    657:        return NO;
                    658:     }
1.1       timbl     659: 
1.40      frystyk   660:     /* Now, file is open and OK: reload the text and put up a stream for it! */
1.47      frystyk   661:     if (TRACE)
                    662:        fprintf(stderr, "Saving to file %s\n", fname);
1.40      frystyk   663:     {
1.47      frystyk   664:        int status;
1.40      frystyk   665:        HTRequest *req = Thread_new(NO);             /* Set up a new request */
1.47      frystyk   666:        if (OutSource)
1.40      frystyk   667:            req->output_format = WWW_SOURCE;
                    668:        req->output_stream = HTFWriter_new(fp, NO);
                    669:        HTForceReload = YES;
1.47      frystyk   670:        status = HTLoadAnchor((HTAnchor*) HTMainAnchor, req);
1.40      frystyk   671:        HTForceReload = NO;
1.47      frystyk   672:        return (status != HT_WOULD_BLOCK);
1.40      frystyk   673:     }
                    674: }
1.1       timbl     675: 
                    676: 
1.40      frystyk   677: /*                                                                EventHandler
                    678: **
                    679: **     Read in the user's input, and deal with it as necessary.
                    680: **
                    681: **     Any Command which works returns from the routine. If nothing
                    682: **     works then a search or error message down at the bottom.
1.1       timbl     683: */
1.47      frystyk   684: PUBLIC HTEventState EventHandler ARGS1(HTRequest **, actreq)
1.1       timbl     685: { 
1.40      frystyk   686:     int  ref_num;
1.46      frystyk   687:     HTEventState status = EVENT_OK;
1.40      frystyk   688:     char * the_choice = 0;                        /* preserved user command */
                    689:     char * this_word = 0;                          /* First word of command */
                    690:     char * this_command;                         /* this_word and following */
                    691:     char * next_word;                                        /* Second word */
                    692:     char * other_words;                                /* Second word and following */
1.14      frystyk   693:     BOOL is_index = HTAnchor_isIndex(HTMainAnchor);
1.48      frystyk   694:     BOOL found = YES;
1.47      frystyk   695:     int loadstat = HT_INTERNAL;
1.40      frystyk   696: 
                    697:     if (!fgets(choice, RESPONSE_LENGTH, stdin))                  /* Read User Input */
                    698:        return EVENT_QUIT;                                    /* Exit if EOF */
                    699:     
                    700:     StrAllocCopy (the_choice, choice);                /* Remember it as is, */
                    701:     if (the_choice[strlen(the_choice)-1] == '\n')            /* The final \n */
                    702:        the_choice[strlen(the_choice)-1] = '\0';
1.14      frystyk   703:     
1.40      frystyk   704: #ifdef VM  /* Clear the screen (on screen-mode systems) */
                    705:     clear_screen();
                    706: #endif 
                    707:     this_word = strtok (choice, " \t\n\r");          /* Tokenize user input */
                    708:     this_command = the_choice;
                    709:     if (this_word) {
                    710:        next_word = strtok (NULL, " \t\n\r");
                    711:        other_words = the_choice + (next_word - choice);
1.14      frystyk   712:     }
1.40      frystyk   713:     else
                    714:        goto down;                              /* Empty input : scroll down */
                    715:     
                    716:     /* Process Command */
                    717:   loop:
                    718:     switch (TOUPPER(*this_word)) {
                    719:       case '0':
                    720:       case '1':
                    721:       case '2':
                    722:       case '3':
                    723:       case '4':
                    724:       case '5':
                    725:       case '6':
                    726:       case '7':
                    727:       case '8':
                    728:       case '9':
                    729:        sscanf(this_word,"%d",&ref_num);
                    730:        if (ref_num>0 && ref_num<=HText_sourceAnchors(HTMainText)) {
                    731:            HTAnchor *destination;
                    732:            HTChildAnchor *source = HText_childNumber(HTMainText, ref_num);
1.45      frystyk   733:            if (source) {
1.47      frystyk   734:                *actreq = Thread_new(YES);
1.44      frystyk   735:                destination = HTAnchor_followMainLink((HTAnchor*) source);
1.47      frystyk   736:                (*actreq)->parentAnchor = HTAnchor_parent((HTAnchor *) source);
                    737:                loadstat = HTLoadAnchor(destination, *actreq);
1.45      frystyk   738:            } else {
                    739:                status = EVENT_QUIT;                            /* No anchor */
1.44      frystyk   740:            }
                    741:        } else {
                    742:            if (TRACE || HTInteractive)
                    743:                fprintf(stderr, "Warning: Invalid Reference Number: (%d)\n",
                    744:                        ref_num);
1.40      frystyk   745:        }
                    746:        break;
                    747:        
                    748:       case 'B':                
                    749:        if (Check_User_Input("BACK")) {           /* Return to previous node */
                    750:            if (HTHistory_canBacktrack()) {
1.47      frystyk   751:                *actreq = Thread_new(YES);
                    752:                loadstat = HTLoadAnchor(HTHistory_backtrack(), *actreq);
1.40      frystyk   753:            } else {
                    754:                printf("\n  The BACK command cannot be used,");
                    755:                printf(" as there are no previous documents\n"); 
                    756:            }
1.47      frystyk   757:        } else if (Check_User_Input("BOTTOM")) {        /* Scroll to bottom  */
1.40      frystyk   758:            HText_scrollBottom(HTMainText);
1.48      frystyk   759:        } else
                    760:            found = NO;
1.40      frystyk   761:        break;
                    762:        
                    763: #ifdef unix
                    764:       case 'C':
1.48      frystyk   765:        if (Check_User_Input("CD")) {          /* Change working directory ? */
1.40      frystyk   766:            goto lcd;
1.48      frystyk   767:        } else
                    768:            found = NO;
1.40      frystyk   769:        break;
                    770: #endif
                    771:        
                    772:       case 'D':
                    773:        if (Check_User_Input("DOWN")) {             /* Scroll down one page  */
                    774:          down:
                    775:            if (HText_canScrollDown(HTMainText))
                    776:                HText_scrollDown(HTMainText);
1.48      frystyk   777:        } else
                    778:            found = NO;
1.40      frystyk   779:        break;
                    780:        
                    781:       case 'E':                               /* Quit program ? Alternative command */
1.48      frystyk   782:        if (Check_User_Input("EXIT")) {
1.47      frystyk   783:            status = EVENT_QUIT;
1.48      frystyk   784:        } else
                    785:            found = NO;
1.40      frystyk   786:        break;
                    787:        
                    788:       case 'F':                                                 /* Keyword search ? */
                    789:        if (is_index && Check_User_Input("FIND")) {
                    790:          find:
1.47      frystyk   791:            {
                    792:                if (next_word) {
                    793:                    *actreq = Thread_new(YES);
                    794:                    loadstat = HTSearch(other_words, HTMainAnchor, *actreq);
                    795:                }
                    796:            }
1.48      frystyk   797:        } else
                    798:            found = NO;
1.40      frystyk   799:        break;
                    800:        
                    801:       case 'G':
                    802:        if (Check_User_Input("GOTO")) {                              /* GOTO */
                    803:            if (next_word) {
1.47      frystyk   804:                *actreq = Thread_new(YES);
                    805:                loadstat = HTLoadRelative(next_word, HTMainAnchor, *actreq);
1.40      frystyk   806:            }
1.48      frystyk   807:        } else
                    808:            found = NO;
1.40      frystyk   809:        break;
                    810:        
                    811:       case '?':
                    812:        help_screen();
1.47      frystyk   813:        break;
1.40      frystyk   814:        
                    815:       case 'H':
1.47      frystyk   816:        if (Check_User_Input("HELP")) {                      /* help menu, ..*/
1.40      frystyk   817:            help_screen();                        /*!! or a keyword search ? */
1.47      frystyk   818:        } else if (Check_User_Input("HOME")) {                  /* back HOME */
                    819:            if (!HTHistory_canBacktrack()) {
1.40      frystyk   820:                HText_scrollTop(HTMainText);
                    821:            } else {
1.47      frystyk   822:                *actreq = Thread_new(YES);
                    823:                loadstat = HTLoadAnchor(HTHistory_recall(1), *actreq);
1.40      frystyk   824:            }
1.48      frystyk   825:        } else
                    826:            found = NO;
1.40      frystyk   827:        break;
                    828:        
                    829:       case 'K':                                                 /* Keyword search ? */
                    830:        if (is_index && Check_User_Input("KEYWORDS")) {
                    831:            goto find;
1.48      frystyk   832:        } else
                    833:            found = NO;
1.40      frystyk   834:        break;
                    835:        
                    836:       case 'L':
1.47      frystyk   837:        if (Check_User_Input("LIST")) {              /* List of references ? */
1.40      frystyk   838:            Reference_List(!OutSource);
                    839:        }
                    840: #ifdef unix
                    841:        else if (Check_User_Input ("LCD")) {           /* Local change dir ? */
                    842:          lcd:
                    843:            if (!next_word) {                            /* Missing argument */
                    844:                printf ("\nName of the new local directory missing.\n");
1.47      frystyk   845:            } else if (chdir (next_word)) {              /* failed : say why */
1.40      frystyk   846:                fprintf (stderr, "\n  ");
                    847:                perror (next_word);
1.47      frystyk   848:            } else {                /* Success : display new local directory */
1.40      frystyk   849:                /* AS Sep 93 */
                    850: #ifdef NO_GETWD     /* No getwd() on this machine */
                    851: #ifdef HAS_GETCWD   /* System V variant SIGN CHANGED TBL 921006 !! */
                    852:                printf ("\nLocal directory is now:\n %s\n",
                    853:                        getcwd (choice, sizeof(choice)));
                    854: #else   /* has NO getcwd */
                    855:                ErrMsg("This platform does not support getwd() or getcwd()",
                    856:                       NULL);
                    857: #endif /* has no getcwd */
                    858: #else   /* has getwd */
                    859:                printf("\nLocal directory is now:\n %s\n",
                    860:                       (char *) getwd (choice));
                    861: #endif  /* has getwd */
                    862:                /* End AS Sep 93 */
                    863:            }
                    864:        }
                    865: #endif
1.48      frystyk   866:        else
                    867:            found = NO;
1.40      frystyk   868:        break;
                    869:        
                    870:       case 'M':
                    871:        if (Check_User_Input("MANUAL")) {                /* Read User manual */
1.47      frystyk   872:            *actreq = Thread_new(YES);
                    873:            loadstat = HTLoadRelative(MANUAL, HTMainAnchor,*actreq);
1.48      frystyk   874:        } else
                    875:            found = NO;
1.40      frystyk   876:        break;
                    877:        
                    878:       case 'N':                    
                    879:        if (Check_User_Input("NEXT")) {
                    880:            if (!HTHistory_canMoveBy(1)) {       /* No nodes to jump back to */
                    881:                printf("\n  Can't take the NEXT link from the last");
                    882:                if (!HTHistory_canBacktrack())
                    883:                    printf(" document as there is no last");
                    884:                printf(" document.\n");
1.47      frystyk   885:            } else {
                    886:                *actreq = Thread_new(YES);
                    887:                loadstat = HTLoadAnchor(HTHistory_moveBy(1),*actreq);
1.40      frystyk   888:            }
1.48      frystyk   889:        } else
                    890:            found = NO;
1.40      frystyk   891:        break;
                    892:        
                    893:       case 'P':                    
                    894:        if (Check_User_Input("PREVIOUS")) {
                    895:            if (!HTHistory_canMoveBy(-1)){ 
                    896:                printf("\n  Can't take the PREVIOUS link from the last");
                    897:                if (!HTHistory_canBacktrack())
                    898:                    printf(" document as there is no last");
                    899:                printf(" document.\n");
1.47      frystyk   900:            } else {
                    901:                *actreq = Thread_new(YES);
                    902:                loadstat = HTLoadAnchor(HTHistory_moveBy(-1), *actreq);
1.40      frystyk   903:            }
                    904:        }
                    905: #ifdef GOT_SYSTEM          
                    906:        else if (!HTClientHost && Check_User_Input("PRINT")) {
                    907:            char * address = HTAnchor_address((HTAnchor *) HTMainAnchor);
                    908:            char * command;
1.46      frystyk   909:            char * tmplate = (char*)getenv("WWW_PRINT_COMMAND");
1.40      frystyk   910:            int result;
                    911:            
1.46      frystyk   912:            if (!tmplate) tmplate = "www -n -na -p66 '%s' | lpr";
                    913:            command = (char *) malloc(strlen(address)+strlen(tmplate)+20);
                    914:            sprintf(command, tmplate, address);
1.40      frystyk   915:            result = system(command);
                    916:            free(address);
                    917:            free(command);
                    918:            if (result) printf("  %s\n  returns %d\n", command, result);
                    919:        }
                    920: #endif
                    921:        /* this command prints the entire current text to the
                    922:           terminal's printer; at the end it displays the top of the text */
                    923: #ifdef SLAVE_PRINTER
                    924: #define SLAVE_PRINTER_ON  "\033\133\065\151"
                    925: #define SLAVE_PRINTER_OFF "\033\133\064\151"
                    926:        
1.47      frystyk   927:        else if (Check_User_Input("PS")) {
1.40      frystyk   928:            printf ("%s",SLAVE_PRINTER_ON);
                    929:            printf("\f");                          /* Form feed for new page */
                    930:            HText_scrollTop(HTMainText);
                    931:            while(HText_canScrollDown(HTMainText)) {
                    932:                HText_scrollDown(HTMainText);
                    933:            }
                    934:            printf("\f");  /* Form feed for new page */
                    935:            printf ("%s",SLAVE_PRINTER_OFF);
                    936:            HText_scrollTop(HTMainText);
                    937:        }       
                    938: #endif
1.48      frystyk   939:        else
                    940:            found = NO;
1.40      frystyk   941:        break;
                    942:        
                    943:       case 'Q':                                                   /* Quit program ? */
                    944:        if (Check_User_Input("QUIT")) {
1.47      frystyk   945: 
1.40      frystyk   946:            /*  JFG 9/7/92, following a complaint of 'q' mis-typed for '1'.
                    947:                JFG Then made optional because I hate it !!!
                    948:                TBL made it only affect remote logged on users. 921122 */
                    949:            
                    950:            if (HTClientHost && (strcasecomp(this_word, "quit") != 0) ) {
                    951:                printf ("\n Please type \"quit\" in full to leave www.\n");
1.47      frystyk   952:            } else
                    953:                status = EVENT_QUIT;
1.48      frystyk   954:        } else
                    955:            found = NO;
1.40      frystyk   956:        break;
                    957:        
                    958:       case 'R':        
                    959: #ifdef VM
                    960:        if (Check_User_Input("RETURN"))                /* Means quit program */
1.47      frystyk   961:            status = EVENT_QUIT;
                    962:        else
1.40      frystyk   963: #endif     
                    964:        if (Check_User_Input("RECALL")) {
                    965:            int  recall_node_num;
                    966:            
                    967:            if (!HTHistory_canBacktrack()) {           /* No nodes to recall */
                    968:                printf("\n  No other documents to recall.\n");
1.47      frystyk   969:            } else {
                    970:                /* Previous node number exists, or does the user just */
                    971:                /* require a list of nodes visited? */
                    972:                if (next_word) {
                    973:                    if ((recall_node_num = atoi(next_word)) > 0) {
                    974:                        *actreq = Thread_new(YES);
                    975:                        loadstat =
                    976:                            HTLoadAnchor(HTHistory_recall(recall_node_num),
                    977:                                         *actreq);
                    978:                    } else {
                    979:                        ErrMsg("Bad command, for list of commands type help.",
                    980:                               this_command);
                    981:                    }
                    982:                } else {
                    983:                    History_List();
                    984:                }
1.40      frystyk   985:            }
                    986:        } else if (Check_User_Input("REFRESH")) {
1.48.2.1  frystyk   987:            HText_setStale(HTMainText);                     /* Force refresh */
                    988:            HText_refresh(HTMainText);                     /* Refresh screen */
1.48      frystyk   989:        } else
                    990:            found = NO;
1.40      frystyk   991:        break;
                    992:        
                    993:       case 'S':                                                       /* TBL 921009 */
                    994:        if (Check_User_Input("SOURCE")) {                 /* Apply to source */
1.47      frystyk   995:            if (next_word) {
                    996:                OutSource = YES;                 /* Load and print as source */
                    997:                this_word = next_word;                   /* Move up one word */
                    998:                next_word = strtok (NULL, " \t\n\r");
                    999:                this_command = the_choice + (this_word - choice);
                   1000:                other_words = the_choice + (next_word - choice);
                   1001:                goto loop;                             /* Go treat as before */
                   1002:            }
1.40      frystyk  1003:        } else if (Check_User_Input("SET")) {                      /* config */
                   1004:            HTSetConfiguration(other_words);
1.48      frystyk  1005:        } else
                   1006:            found = NO;
1.40      frystyk  1007:        break;
                   1008:        
                   1009:       case 'T':
                   1010:        if (Check_User_Input("TOP")) {                     /* Return to top  */
                   1011:            HText_scrollTop(HTMainText);
1.48      frystyk  1012:        } else
                   1013:            found = NO;
1.40      frystyk  1014:        break;
                   1015:        
                   1016:       case 'U':
                   1017:        if (Check_User_Input("UP")) {                 /* Scroll up one page  */
                   1018:            HText_scrollUp(HTMainText);
1.48      frystyk  1019:        } else
                   1020:            found = NO;
1.40      frystyk  1021:        break;
                   1022:        
                   1023:       case 'V':
                   1024:        if (Check_User_Input("VERBOSE")) {           /* Switch verbose mode  */
                   1025:            WWW_TraceFlag = WWW_TraceFlag ? 0 : OldTraceFlag;
                   1026:            printf ("\n  Verbose mode %s.\n", WWW_TraceFlag ? "ON":"OFF");
1.48      frystyk  1027:        } else
                   1028:            found = NO;
1.40      frystyk  1029:        break;
                   1030:        
                   1031:       case 'Z':
1.48.2.1  frystyk  1032:        HText_setStale(HTMainText);                         /* Force refresh */
                   1033:        HText_refresh(HTMainText);                         /* Refresh screen */
1.44      frystyk  1034:        status = EVENT_INTR_ALL;
                   1035:        break;
1.40      frystyk  1036: 
                   1037:       case '>':
                   1038:        if (!HTClientHost) {
1.47      frystyk  1039:            if (SaveOutputStream(this_word, next_word))
                   1040:                loadstat = HT_WOULD_BLOCK;
1.40      frystyk  1041:        }
                   1042:        break;
1.1       timbl    1043:        
1.40      frystyk  1044: #ifdef GOT_PIPE
                   1045:       case '|':
                   1046:        if (!HTClientHost) {                               /* Local only!!!! */
                   1047:            char * address = HTAnchor_address((HTAnchor *) HTMainAnchor);
                   1048:            char * command;
                   1049:            int result;
                   1050:            command = (char*) malloc(strlen(address) +strlen(this_command)+30);
                   1051:            
                   1052: #ifdef VM      
                   1053:            sprintf(command, "PIPE CMS WWW %s \"%s\" | %s",
                   1054:                    OutSource ? "-source" : "-n -na -p", address,this_command);
                   1055: 
                   1056: #else  
                   1057:            sprintf(command, "www %s \"%s\" %s", 
                   1058:                    OutSource ? "-source" : "-n -na -p", address,this_command);
                   1059: #endif
                   1060:            printf("Command: %s\n", command);
                   1061:            result = system(command);
                   1062:            if (result)
                   1063:                printf("  %s  returns %d\n", command, result);
                   1064:            free(command);
                   1065:            free(address);
1.14      frystyk  1066:        }
1.47      frystyk  1067:        break;
1.40      frystyk  1068: #endif
                   1069:            
                   1070: #ifdef GOT_SYSTEM
                   1071:       case '!':
                   1072:        if (!HTClientHost) {                                  /* Local only! */
                   1073:            int result;
                   1074:            ErrMsg("Executing", this_command);
                   1075:            result = system(strchr(this_command, '!') + 1);
                   1076:            if (result) printf("  %s  returns %d\n",
                   1077:                               strchr(this_command, '!') + 1, result);
1.1       timbl    1078:        }
1.47      frystyk  1079:        break;
1.1       timbl    1080: #endif
1.40      frystyk  1081:       default:
1.48      frystyk  1082:        found = NO;
                   1083:        break;
                   1084:     } /* Switch on 1st character */
                   1085: 
                   1086:     if (!found) {
                   1087:        if (is_index && *this_word) {  /* No commands, search keywords */
1.47      frystyk  1088:            next_word = other_words = this_command;
1.48      frystyk  1089:            found = YES;
1.47      frystyk  1090:            goto find;
                   1091:        } else {             
                   1092:            ErrMsg("Bad command, for list of commands type help.",
                   1093:                   this_command);
                   1094:        }
1.48      frystyk  1095:     }
1.47      frystyk  1096:     if (loadstat != HT_INTERNAL && loadstat != HT_WOULD_BLOCK)
                   1097:        status = EVENT_TERM;
1.48.2.4! frystyk  1098:     if (loadstat != HT_LOADED && loadstat != HT_ERROR)
1.47      frystyk  1099:        MakeCommandLine(is_index);
1.40      frystyk  1100:     free (the_choice);
1.44      frystyk  1101:     return status;
1.40      frystyk  1102: }
                   1103: 
                   1104: 
                   1105: /*                                                     HTEventRequestTerminate
1.1       timbl    1106: **
1.40      frystyk  1107: **     React to the status of the terminated request
1.1       timbl    1108: */
1.40      frystyk  1109: PUBLIC HTEventState HTEventRequestTerminate ARGS2(HTRequest *, actreq,
                   1110:                                                  int,          status) 
                   1111: {
                   1112:     BOOL is_index = HTAnchor_isIndex(HTMainAnchor);
                   1113:     if (status == HT_LOADED) {
                   1114:        if (actreq->parentAnchor) {
                   1115:            HTParentAnchor *parent = actreq->parentAnchor;
                   1116:            HTParentAnchor *destination = actreq->anchor;
                   1117:            HTHistory_leavingFrom((HTAnchor *) parent);
                   1118:            HTHistory_record((HTAnchor *) destination);
                   1119:            actreq->parentAnchor = NULL;
1.14      frystyk  1120:        }
1.40      frystyk  1121:        /* Now generate the new prompt line as a function of the result */
                   1122:        if (!HText_canScrollDown(HTMainText) &&
                   1123:            !HTAnchor_hasChildren(HTMainAnchor) && !is_index &&
                   1124:            (!HTHistory_canBacktrack())) {
                   1125:            ErrMsg("No way out of here, so I exit!", NULL);         
                   1126:            return EVENT_QUIT;                   /* Exit if no other options */
                   1127:        }
                   1128:        HText_setStale(HTMainText);                /* We corrupt the display */
                   1129:        MakeCommandLine(is_index);
                   1130:     } else if (!HTMainText)                          /* If first try failed */
                   1131:        return EVENT_QUIT;
1.48.2.2  frystyk  1132:     else
                   1133:        MakeCommandLine(is_index);
1.47      frystyk  1134:     Thread_delete(actreq);
1.40      frystyk  1135:     return EVENT_OK;
                   1136: }
1.1       timbl    1137: 
1.40      frystyk  1138: /* ------------------------------------------------------------------------- */
                   1139: /*                               MAIN PROGRAM                               */
                   1140: /* ------------------------------------------------------------------------- */
1.1       timbl    1141: 
1.40      frystyk  1142: int main ARGS2(int, argc, char **, argv)
                   1143: {
                   1144:     int                return_status = 0;      
                   1145:     int                arg;                           /* Argument number as we scan */
                   1146:     BOOL       argument_found = NO;
                   1147:     BOOL       logfile_flag = NO;
                   1148:     BOOL       first_keyword = YES;
                   1149:     char *     default_default = HTFindRelatedName();
                   1150:     HTFormat   input_format = WWW_HTML;                 /* Used with filter */
                   1151:     HTEventCallBack user;              /* To register STDIN for user events */
1.1       timbl    1152: 
1.40      frystyk  1153: #ifdef THINK_C /* command line from Think_C */
                   1154:     int i;
                   1155:     argc=ccommand(&argv);
                   1156: #endif
                   1157:     
                   1158:     /* HWL 18/7/94: applied patch from
                   1159:        agl@glas2.glas.apc.org (Anton Tropashko) */
                   1160: #ifdef CYRILLIC
                   1161:     arc.locale=0; arc.encoding=0; arc.i_encoding=0; doinull();
1.1       timbl    1162: #endif
                   1163: 
1.40      frystyk  1164: #ifdef VMS
                   1165:     output = stdout;
                   1166: #endif /* VMS */
1.1       timbl    1167:        
1.40      frystyk  1168:     request =  HTRequest_new();
                   1169: 
                   1170:     /* Check for command line options */
                   1171:     *keywords = '\0';
                   1172:     for (arg=1; arg<argc ; arg++) {
                   1173:        if (*argv[arg] == '-') {
                   1174: 
                   1175:            /* - alone => filter */
                   1176:            if (argv[arg][1] == 0) {
                   1177:                filter = YES;      
                   1178:                HTInteractive = NO;     /* From stdin, Force non-interactive */
                   1179:            
                   1180:            /* -? or -help: show the command line help page */
                   1181:            } else if (!strcmp(argv[arg], "-?") ||
                   1182:                       !strcmp(argv[arg], "-help")) {
                   1183:                home_anchor = (HTParentAnchor *)
                   1184:                    HTAnchor_findAddress(COM_HELP_FILE);
                   1185:                argument_found = YES;       /* Don't try to find other pages */
                   1186: 
                   1187:            /* from -- Initial represntation (only with filter) */
                   1188: 
                   1189:            } else if (!strcmp(argv[arg], "-from")) {
                   1190:                input_format = (arg+1 >= argc || *argv[arg+1] == '-') ?
                   1191:                    WWW_HTML : HTAtom_for(argv[++arg]);
                   1192: 
                   1193: #ifdef CYRILLIC
                   1194:            /* HWL 18/7/94: applied patch from agl@glas2.glas.apc.org
                   1195:               (Anton Tropashko) */
                   1196:            } else if (!strcmp(argv[arg], "-koi2alt")) {
                   1197:                doia2k(); printf("Ahak2a!");
                   1198: #endif
                   1199: 
                   1200:            /* Page size */
                   1201:            } else if (!strncmp(argv[arg], "-p", 2)) {
                   1202:                if (*(argv[arg]+2)) {
                   1203:                    if (sscanf(argv[arg]+2, "%d", &HTScreenHeight) < 1)
                   1204:                        HTScreenHeight = -1;            
                   1205:                    else {
                   1206:                        if(HTScreenHeight < MIN_SCREEN_HEIGHT)
                   1207:                            HTScreenHeight = MIN_SCREEN_HEIGHT;
                   1208:                        if(HTScreenHeight > MAX_SCREEN_HEIGHT)
                   1209:                            HTScreenHeight = MAX_SCREEN_HEIGHT;
                   1210:                    }
                   1211:                } else if (arg+1 < argc && *argv[arg+1] != '-') {
                   1212:                    if (sscanf(argv[++arg], "%d", &HTScreenHeight) < 1)
                   1213:                        HTScreenHeight = -1;
                   1214:                    else {
                   1215:                        if(HTScreenHeight < MIN_SCREEN_HEIGHT)
                   1216:                            HTScreenHeight = MIN_SCREEN_HEIGHT;
                   1217:                        if(HTScreenHeight > MAX_SCREEN_HEIGHT)
                   1218:                            HTScreenHeight = MAX_SCREEN_HEIGHT;
                   1219:                    }
                   1220:                }
1.1       timbl    1221: 
1.40      frystyk  1222:            /* Page width */
                   1223:            } else if (!strncmp(argv[arg], "-w", 2)) {
                   1224:                if (*(argv[arg]+2)) {
                   1225:                    if (sscanf(argv[arg]+2, "%d", &HTScreenWidth) < 1)
                   1226:                        HTScreenWidth = SCREEN_WIDTH;
                   1227:                } else if (arg+1 < argc && *argv[arg+1] != '-') {
                   1228:                    if (sscanf(argv[++arg], "%d", &HTScreenWidth) < 1)
                   1229:                        HTScreenWidth = SCREEN_WIDTH;
1.14      frystyk  1230:                }
1.40      frystyk  1231:                if(HTScreenWidth < MIN_SCREEN_WIDTH)
                   1232:                    HTScreenWidth = MIN_SCREEN_WIDTH;
                   1233:                if(HTScreenWidth > MAX_SCREEN_WIDTH)
                   1234:                    HTScreenWidth = MAX_SCREEN_WIDTH;
                   1235:                    
                   1236:            /* reformat html */
                   1237:            } else if (!strcmp(argv[arg], "-reformat")) {
                   1238:                request->output_format = WWW_HTML;
                   1239:                    HTInteractive = NO;
                   1240:                    reformat_html = YES;
1.1       timbl    1241: 
1.48.2.1  frystyk  1242:            /* Specify a cache root (caching is otherwise disabled) */
                   1243:            } else if (!strcmp(argv[arg], "-cacheroot")) {
                   1244:                StrAllocCopy(HTCacheDir,
                   1245:                             (arg+1>=argc || *argv[arg+1]=='-') ?
                   1246:                             CACHE_HOME_DIR : argv[++arg]);
                   1247: 
                   1248:            /* to -- Final representation */
1.40      frystyk  1249:            } else if (!strcmp(argv[arg], "-to")) {
                   1250:                request->output_format =
                   1251:                    (arg+1 >= argc || *argv[arg+1] == '-') ?
                   1252:                        WWW_PRESENT : 
                   1253:                        HTAtom_for(argv[++arg]);
                   1254:                    HTInteractive = NO;                 /* JFG */
1.1       timbl    1255: 
1.40      frystyk  1256:            /* Telnet from */
                   1257:            } else if (!strcmp(argv[arg], "-h")) {
                   1258:                if (arg+1 < argc && *argv[arg+1] != '-') {
                   1259:                    HTClientHost = argv[++arg];             /* Use host name */
1.14      frystyk  1260:                }
1.40      frystyk  1261: 
                   1262:            /* Log file */
                   1263:            } else if (!strcmp(argv[arg], "-l")) {
                   1264:                if (arg+1 < argc && *argv[arg+1] != '-')
                   1265:                    logfile_root = argv[++arg];
                   1266:                logfile_flag = YES;
                   1267:                    
                   1268:            /* List References */
                   1269:            } else if (!strcmp(argv[arg], "-listrefs")) {
                   1270:                listrefs_option = YES;
                   1271:                HTInteractive = NO;                     /* non-interactive */
                   1272: 
                   1273:            /* Method Used (Currently on GET and HEAD are supported) */
                   1274:            } else if (!strcmp(argv[arg], "-m")) {
                   1275:                HTInteractive = NO;
                   1276:                if (++arg < argc) {
                   1277:                    if (!strcasecomp(argv[arg], "head")) {
                   1278:                        request->method = METHOD_HEAD;
                   1279:                        request->output_format = WWW_MIME;
                   1280:                    } else if (!strcasecomp(argv[arg], "get"))
                   1281:                        request->method = METHOD_GET;
                   1282:                    else
                   1283:                        request->method = METHOD_INVALID;
1.1       timbl    1284:                }
1.40      frystyk  1285: 
                   1286:            /* Non-interactive */
                   1287:            } else if (!strcmp(argv[arg], "-n")) {
                   1288:                HTInteractive = NO;
                   1289: 
1.48.2.1  frystyk  1290:            /* Multithreaded ot not? */
                   1291:            } else if (!strcmp(argv[arg], "-single")) {
                   1292:                UseMulti = NO;
                   1293: 
1.40      frystyk  1294:            /* Output filename */
                   1295:            } else if (!strcmp(argv[arg], "-o")) { 
                   1296:                output_file_name = (arg+1 < argc && *argv[arg+1] != '-') ?
                   1297:                    argv[++arg] : DEFAULT_OUTPUT_FILE;
                   1298:                    HTInteractive = NO;
                   1299:                    
                   1300:            /* Anchor format */
                   1301:            } else if (!strcmp(argv[arg], "-a")) { 
                   1302:                if (arg+1 < argc && *argv[arg+1] != '-')
                   1303:                    end_reference = argv[++arg];      /* New representation */
                   1304: 
                   1305:            /* Anchor format */
                   1306:            } else if (!strcmp(argv[arg], "-ar")) { 
                   1307:                if (arg+1 < argc && *argv[arg+1] != '-')
                   1308:                    reference_mark = argv[++arg];  /* Change representation */
                   1309: 
                   1310:            /* Anchor format */
                   1311:            } else if (!strcmp(argv[arg], "-as")) { 
                   1312:                if (arg+1 < argc && *argv[arg+1] != '-')
                   1313:                    start_reference = argv[++arg]; /* Change representation */
                   1314: 
                   1315:            /* No anchors */
                   1316:            } else if (!strcmp(argv[arg], "-na")) { 
                   1317:                    display_anchors = NO;
                   1318: 
                   1319: #ifndef NO_RULES
                   1320:            } else if (!strcmp(argv[arg], "-r")) {
                   1321:                if (arg+1 < argc && *argv[arg+1] != '-') { 
                   1322:                    if (HTLoadRules(argv[++arg]) < 0) {
                   1323:                        ErrMsg("Can't open rule file", argv[arg]);
                   1324:                        return_status = -1;
                   1325:                        goto endproc;
                   1326:                    }
1.14      frystyk  1327:                }
1.1       timbl    1328: #endif
1.40      frystyk  1329: #ifndef NO_DIR_OPTIONS
                   1330:            } else if (!strncmp(argv[arg], "-d", 2)) {
                   1331:                char *p = argv[arg]+2;
                   1332:                for(;*p;p++) {
                   1333:                    switch (argv[arg][2]) {
                   1334:                    case 'b':   HTDirReadme = HT_DIR_README_BOTTOM; break;
                   1335:                    case 'n':   HTDirAccess = HT_DIR_FORBID; break;
                   1336:                    case 'r':   HTDirReadme = HT_DIR_README_NONE; break;
                   1337:                    case 's':   HTDirAccess = HT_DIR_SELECTIVE; break;
                   1338:                    case 't':   HTDirReadme = HT_DIR_README_TOP; break;
                   1339:                    case 'y':   HTDirAccess = HT_DIR_OK; break;
                   1340:                    default:
                   1341:                        ErrMsg("Bad parameter for directory listing -d option",
                   1342:                               argv[arg]);
                   1343:                        return_status = -4;
                   1344:                        goto endproc;
                   1345:                    }
                   1346:                } /* loop over characters */
                   1347: #endif
                   1348:            /* Reference list heading */
                   1349:            } else if (!strcmp(argv[arg], "-refhead")) { 
                   1350:                if (arg+1 < argc && *argv[arg+1] != '-')
                   1351:                    refhead = argv[++arg];
1.1       timbl    1352: 
1.40      frystyk  1353:            /* Print version and exit */
                   1354:            } else if (!strcmp(argv[arg], "-version")) { 
                   1355:                printf("WWW LineMode Browser version %s (WWW Library %s)\n",
                   1356:                            VL, HTLibraryVersion);
                   1357:                goto endproc;                           
1.1       timbl    1358: 
1.40      frystyk  1359: #ifdef TRACE
                   1360:           /* Verify: Turns on trace */
                   1361:            } else if (!strncmp(argv[arg], "-v", 2)) {
                   1362:                char *p = argv[arg]+2;
                   1363:                WWW_TraceFlag = 0;
                   1364:                for(; *p; p++) {
                   1365:                    switch (*p) {
                   1366:                      case 'a': WWW_TraceFlag += SHOW_ANCHOR_TRACE; break;
                   1367:                      case 'p': WWW_TraceFlag += SHOW_PROTOCOL_TRACE; break;
                   1368:                      case 's': WWW_TraceFlag += SHOW_SGML_TRACE; break;
                   1369:                      case 't': WWW_TraceFlag += SHOW_THREAD_TRACE; break;
                   1370:                      case 'u': WWW_TraceFlag += SHOW_URI_TRACE; break;
                   1371:                      default:
                   1372:                        ErrMsg("Bad parameter for verbose mode", argv[arg]);
                   1373:                    }
                   1374:                }/* loop over characters */
                   1375:                if (!WWW_TraceFlag)
                   1376:                    WWW_TraceFlag = SHOW_ALL_TRACE;
                   1377:                OldTraceFlag = WWW_TraceFlag;            /* Remember setting */
1.1       timbl    1378: #endif
1.14      frystyk  1379:            
1.40      frystyk  1380:            /* Source please */
                   1381:            } else if (!strcmp(argv[arg], "-source")) {
                   1382:                    request->output_format = WWW_SOURCE;
                   1383:                    HTInteractive = NO;                 /* JFG */
                   1384: 
                   1385: #ifdef THINK_C
                   1386:            /* Echo to file */
                   1387:            } else if (!strcmp(argv[arg], "-e")){
                   1388:                struct tm *tm_now; time_t time_now;
                   1389:                cecho2file("ThinkCconsole",FALSE,stdout);
                   1390:                time_now=time(NULL);tm_now=localtime(&time_now);
                   1391:                printf("\n--------------------------------------------"
                   1392:                        "\n Time: %d.%.2d.%.2d %d:%d:%d\n"
                   1393:                        "--------------------------------------------\n",
                   1394:                        (*tm_now).tm_year,
                   1395:                        (*tm_now).tm_mon+1,
                   1396:                        (*tm_now).tm_mday,
                   1397:                        (*tm_now).tm_hour,
                   1398:                        (*tm_now).tm_min,
                   1399:                        (*tm_now).tm_sec);
                   1400:     
                   1401:            /* debug socket library */
                   1402:            } else if (!strcmp(argv[arg], "-s")) {
                   1403:                socketdebug=1;
1.1       timbl    1404: #endif
1.40      frystyk  1405:              /* endif long list of argument options */
1.1       timbl    1406: 
1.40      frystyk  1407:            } else {
                   1408:                ErrMsg("Bad Command Line Argument", argv[arg]);
                   1409:            }
                   1410:        } else {           /* If no leading `-' then check for main argument */
                   1411:            if (!argument_found) {
                   1412:                char * ref = HTParse(argv[arg], default_default, PARSE_ALL);
                   1413:                home_anchor = (HTParentAnchor*) HTAnchor_findAddress(ref);
                   1414:                free(ref);
                   1415:                argument_found = YES;
                   1416:            } else {               /* Check for successive keyword arguments */
                   1417:                if (first_keyword) {                    /* Collect keywords */
                   1418:                    first_keyword = NO;
1.14      frystyk  1419:                } else {
1.40      frystyk  1420:                    strcat(keywords, " ");
1.14      frystyk  1421:                }
1.40      frystyk  1422:                strcat(keywords,HTStrip(argv[arg]));
                   1423:            } /* argument already found */
                   1424:        } /* Not an option '-'*/
                   1425:     } /* End of argument loop */
                   1426: 
                   1427:     /* Initialization */
1.44      frystyk  1428:     HTLibInit();
1.40      frystyk  1429:     if (HTClientHost) HTSecure = YES;             /* Access to local files? */
                   1430:     HTEnableFrom = YES;                             /* Send `From:' in the request? */
1.48.2.1  frystyk  1431: #ifdef CATCH_SIG
                   1432:     SetSignal();
                   1433: #endif
1.40      frystyk  1434:     if (HTScreenHeight == -1) {                                /* Default page size */
                   1435:        if (HTInteractive) {
                   1436: #ifdef GET_SCREEN_SIZE
                   1437:            int scr_height, scr_width;
                   1438:            scrsize(&scr_height, &scr_width);
                   1439:            HTScreenHeight = scr_height;
                   1440: #else
1.42      frystyk  1441:            HTScreenHeight = SCREEN_HEIGHT;
1.1       timbl    1442: #endif
1.40      frystyk  1443:        } else
1.42      frystyk  1444:            HTScreenHeight = 999999;
1.40      frystyk  1445:     }
1.23      frystyk  1446: 
1.48.2.3  frystyk  1447:     /* Siable free directory browsing when using telnet host */
                   1448:     if (HTClientHost && HTDirAccess==HT_DIR_OK)
                   1449:        HTDirAccess = HT_DIR_SELECTIVE;
1.1       timbl    1450: 
1.40      frystyk  1451: #ifndef NO_RULES
                   1452:     {
                   1453:        char * rules = getenv("WWW_CONFIG");
                   1454:        if (rules && HTLoadRules(rules) < 0) {
                   1455:            ErrMsg("Cant't open rule file", rules);
                   1456:        }
                   1457:     }
                   1458: #endif
1.1       timbl    1459: 
1.40      frystyk  1460:     /* Force predefined presentations etc to be set up */
1.47      frystyk  1461:     if (HTInteractive) {
                   1462:        conversions = HTList_new();
                   1463:        HTFormatInit(conversions);
                   1464:        HTList_delete(request->conversions);
                   1465:        request->conversions = conversions;
                   1466:     } else
1.40      frystyk  1467:        HTFormatInitNIM(request->conversions);
1.4       timbl    1468: 
1.40      frystyk  1469:     /* Open output file */
                   1470:     if (!HTInteractive)        {
                   1471:        if (output_file_name) {
                   1472:            FILE * fp = fopen(output_file_name, "w");
                   1473:            if (!fp) {
                   1474:                ErrMsg("Can't open file for writing", output_file_name);
                   1475:                return_status = -3;
                   1476:                goto endproc;
1.14      frystyk  1477:            }
1.40      frystyk  1478:            output = fp;
                   1479:        }
                   1480:        request->output_stream = HTFWriter_new(output, 
                   1481:                                               output == stdout ? YES : NO);  
                   1482:        /* Just pump to stdout but YES: leave it open */
                   1483:        
                   1484:        /*      To reformat HTML, just put it through a parser running
                   1485:        **      into a regenerator   tbl 940613 */
                   1486:        
                   1487:        if (reformat_html) {
                   1488:            request->output_stream = SGML_new(&HTMLP_dtd,
                   1489:                                  HTMLGenerator(request->output_stream));
1.1       timbl    1490: 
1.40      frystyk  1491:        }
                   1492:     }
                   1493:     
                   1494:     /* Open Log File. Logfile via Telnet is now optional (HENRIK 11/02-94) */
                   1495:     if (logfile_flag) {
                   1496:         if(!logfile_root)
                   1497:             logfile_root = HTClientHost ?
                   1498:                DEFAULT_LOGFILE : DEFAULT_LOCAL_LOGFILE;
                   1499:        HTLogFileName = (char*) malloc(strlen(logfile_root)+20);
1.14      frystyk  1500: 
1.40      frystyk  1501: #ifdef NO_GETPID
                   1502:        sprintf(HTLogFileName, "%s", logfile_root);  /* No getpid() */
                   1503: #else
                   1504:        sprintf(HTLogFileName, "%s-%d", logfile_root, (int) getpid());
1.14      frystyk  1505: #endif
1.40      frystyk  1506:        HTlogfile = fopen(HTLogFileName, "a");
                   1507:        if (!HTlogfile)
                   1508:            ErrMsg("Can't open log file", HTLogFileName);
                   1509:     };
1.14      frystyk  1510: 
1.40      frystyk  1511:     /* Make home page address */
                   1512:     if (!home_anchor)
                   1513:        home_anchor = HTHomeAnchor();
1.1       timbl    1514: 
1.40      frystyk  1515:     /* Now we are ready to start the program! If in interactive mode then start
                   1516:        the event loop which will run until the program terminates */
                   1517:     if (filter) {                                   /* Just convert formats */
                   1518:        HTBindAnchor((HTAnchor*)home_anchor, request);
                   1519:        HTParseSocket(input_format, 0, request);      /* From std UNIX input */
                   1520:            goto endproc;
                   1521:     }
                   1522:     if (HTInteractive) {
                   1523:        reqlist = HTList_new();
                   1524:        user.sockfd = STDIN_FILENO;
                   1525:        user.callback = EventHandler;
                   1526:        HTList_addObject(reqlist, (void *) request);
1.45      frystyk  1527:        HTEventRegister(&user);                            /* Register STDIN */
                   1528:        HTHistory_record((HTAnchor *) home_anchor);         /* Setup history */
1.40      frystyk  1529:        return_status = HTEventLoop(request, home_anchor,
                   1530:                                    (keywords && *keywords) ? keywords : NULL);
                   1531:     } else {
1.48      frystyk  1532:        request->BlockingIO = YES;              /* Turn off non-blocking I/O */
1.40      frystyk  1533:        if (((keywords && *keywords) ?
                   1534:             HTSearch(keywords, home_anchor, request) :
                   1535:             HTLoadAnchor((HTAnchor*) home_anchor, request)) != HT_LOADED) {
                   1536:            char *addr = HTAnchor_address((HTAnchor *) home_anchor);
                   1537:            ErrMsg("Can't access document", addr);
                   1538:            free(addr);
                   1539:            if (!HTMainText) {
                   1540:                return_status = -2;                  /* Can't get first page */
1.14      frystyk  1541:            }
1.48.2.1  frystyk  1542:        } else if (listrefs_option) {
                   1543:            Reference_List(NO);                       /* List without titles */
1.1       timbl    1544:        }
1.34      frystyk  1545:     }
1.18      frystyk  1546: 
1.40      frystyk  1547: endproc:
                   1548:     Thread_deleteAll();
1.48.2.1  frystyk  1549:     if (default_default)
1.40      frystyk  1550:        free(default_default);
1.48.2.4! frystyk  1551:     HTLibTerminate();
1.48.2.1  frystyk  1552:     printf("\n");
                   1553:     if (!return_status) {                      /* Everything is working :-) */
1.40      frystyk  1554: #ifdef VMS 
                   1555:        return 1;
                   1556: #else
                   1557:        return 0;       /* Good */
                   1558: #endif
1.18      frystyk  1559:     }
1.40      frystyk  1560:     return return_status;                     /* An error occured somewhere */
1.14      frystyk  1561: }
1.1       timbl    1562: 
1.18      frystyk  1563: /* End HTBrowse.c */
1.14      frystyk  1564: 

Webmaster