home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / infoserv / www / cern / proxy-support / Mosaic-2.4 / gui-documents.c.Z / gui-documents.c
Encoding:
C/C++ Source or Header  |  1994-05-11  |  32.9 KB  |  1,019 lines

  1. /****************************************************************************
  2.  * NCSA Mosaic for the X Window System                                      *
  3.  * Software Development Group                                               *
  4.  * National Center for Supercomputing Applications                          *
  5.  * University of Illinois at Urbana-Champaign                               *
  6.  * 605 E. Springfield, Champaign IL 61820                                   *
  7.  * mosaic@ncsa.uiuc.edu                                                     *
  8.  *                                                                          *
  9.  * Copyright (C) 1993, Board of Trustees of the University of Illinois      *
  10.  *                                                                          *
  11.  * NCSA Mosaic software, both binary and source (hereafter, Software) is    *
  12.  * copyrighted by The Board of Trustees of the University of Illinois       *
  13.  * (UI), and ownership remains with the UI.                                 *
  14.  *                                                                          *
  15.  * The UI grants you (hereafter, Licensee) a license to use the Software    *
  16.  * for academic, research and internal business purposes only, without a    *
  17.  * fee.  Licensee may distribute the binary and source code (if released)   *
  18.  * to third parties provided that the copyright notice and this statement   *
  19.  * appears on all copies and that no charge is associated with such         *
  20.  * copies.                                                                  *
  21.  *                                                                          *
  22.  * Licensee may make derivative works.  However, if Licensee distributes    *
  23.  * any derivative work based on or derived from the Software, then          *
  24.  * Licensee will (1) notify NCSA regarding its distribution of the          *
  25.  * derivative work, and (2) clearly notify users that such derivative       *
  26.  * work is a modified version and not the original NCSA Mosaic              *
  27.  * distributed by the UI.                                                   *
  28.  *                                                                          *
  29.  * Any Licensee wishing to make commercial use of the Software should       *
  30.  * contact the UI, c/o NCSA, to negotiate an appropriate license for such   *
  31.  * commercial use.  Commercial use includes (1) integration of all or       *
  32.  * part of the source code into a product for sale or license by or on      *
  33.  * behalf of Licensee to third parties, or (2) distribution of the binary   *
  34.  * code or source code to third parties that need it to utilize a           *
  35.  * commercial product sold or licensed by or on behalf of Licensee.         *
  36.  *                                                                          *
  37.  * UI MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THIS SOFTWARE FOR   *
  38.  * ANY PURPOSE.  IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED          *
  39.  * WARRANTY.  THE UI SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY THE    *
  40.  * USERS OF THIS SOFTWARE.                                                  *
  41.  *                                                                          *
  42.  * By using or copying this Software, Licensee agrees to abide by the       *
  43.  * copyright law and all other applicable laws of the U.S. including, but   *
  44.  * not limited to, export control laws, and the terms of this license.      *
  45.  * UI shall have the right to terminate this license immediately by         *
  46.  * written notice upon Licensee's breach of, or non-compliance with, any    *
  47.  * of its terms.  Licensee may be held legally responsible for any          *
  48.  * copyright infringement that is caused or encouraged by Licensee's        *
  49.  * failure to abide by the terms of this license.                           *
  50.  *                                                                          *
  51.  * Comments and questions are welcome and can be sent to                    *
  52.  * mosaic-x@ncsa.uiuc.edu.                                                  *
  53.  ****************************************************************************/
  54.  
  55. #include "mosaic.h"
  56. #include "libhtmlw/HTML.h"
  57.  
  58. extern char *cached_url;
  59. extern int binary_transfer;
  60. #ifdef PEM_AUTH
  61. extern int post_gave_encrypt;
  62. #endif /* PEM_AUTH */
  63. extern char *startup_document, *home_document;
  64. extern Display *dsp;
  65.  
  66. int loading_inlined_images = 0;
  67. char *url_base_override = NULL;
  68. int interrupted = 0;
  69.  
  70. extern char *mo_post_pull_er_over (char *url, char *content_type, 
  71.                                    char *post_data, 
  72.                                    char **texthead);
  73.  
  74. /****************************************************************************
  75.  * name:    mo_snarf_scrollbar_values
  76.  * purpose: Store current viewing state in the current node, in case
  77.  *          we want to return to the same location later.
  78.  * inputs:  
  79.  *   - mo_window *win: Current window.
  80.  * returns: 
  81.  *   mo_succeed
  82.  *   (mo_fail if no current node exists)
  83.  * remarks: 
  84.  *   Snarfs current docid position in the HTML widget.
  85.  ****************************************************************************/
  86. static mo_status mo_snarf_scrollbar_values (mo_window *win)
  87. {
  88.   /* Make sure we have a node. */
  89.   if (!win->current_node)
  90.     return mo_fail;
  91.  
  92.   win->current_node->docid = HTMLPositionToId(win->scrolled_win, 0, 3);
  93.  
  94.   /* Do the cached stuff thing. */
  95.   win->current_node->cached_stuff = HTMLGetWidgetInfo (win->scrolled_win);
  96.  
  97.   return mo_succeed;
  98. }
  99.  
  100.  
  101. /* ---------------------- mo_reset_document_headers ----------------------- */
  102.  
  103. static mo_status mo_reset_document_headers (mo_window *win)
  104. {
  105.   if (win->current_node)
  106.     {
  107.       XmxTextSetString (win->title_text, win->current_node->title);
  108.       XmxTextSetString (win->url_text, win->current_node->url);
  109.     }
  110.  
  111.   return mo_succeed;
  112. }
  113.  
  114. /* --------------------------- mo_back_possible --------------------------- */
  115.  
  116. /* This could be cached, but since it shouldn't take too long... */
  117. static void mo_back_possible (mo_window *win)
  118. {
  119.   XmxSetSensitive (win->back_button, XmxSensitive);
  120.   XmxRSetSensitive (win->menubar, mo_back, XmxSensitive);
  121.   return;
  122. }
  123.  
  124.  
  125. /****************************************************************************
  126.  * name:    mo_back_impossible
  127.  * purpose: Can't go back (nothing in the history list).
  128.  ****************************************************************************/
  129. mo_status mo_back_impossible (mo_window *win)
  130. {
  131.   XmxSetSensitive (win->back_button, XmxNotSensitive);
  132.   XmxRSetSensitive (win->menubar, mo_back, XmxNotSensitive);
  133.   return mo_succeed;
  134. }
  135.  
  136. static void mo_forward_possible (mo_window *win)
  137. {
  138.   XmxSetSensitive (win->forward_button, XmxSensitive);
  139.   XmxRSetSensitive (win->menubar, mo_forward, XmxSensitive);
  140.   return;
  141. }
  142.  
  143.  
  144. /****************************************************************************
  145.  * name:    mo_forward_impossible
  146.  * purpose: Can't go forward (nothing in the history list).
  147.  ****************************************************************************/
  148. mo_status mo_forward_impossible (mo_window *win)
  149. {
  150.   XmxSetSensitive (win->forward_button, XmxNotSensitive);
  151.   XmxRSetSensitive (win->menubar, mo_forward, XmxNotSensitive);
  152.   return mo_succeed;
  153. }
  154.  
  155. /* ---------------------- mo_annotate_edit_possible ----------------------- */
  156.  
  157. static void mo_annotate_edit_possible (mo_window *win)
  158. {
  159.   XmxRSetSensitive (win->menubar, mo_annotate_edit, XmxSensitive);
  160.   XmxRSetSensitive (win->menubar, mo_annotate_delete, XmxSensitive);
  161.   return;
  162. }
  163.  
  164. static void mo_annotate_edit_impossible (mo_window *win)
  165. {
  166.   XmxRSetSensitive (win->menubar, mo_annotate_edit, XmxNotSensitive);
  167.   XmxRSetSensitive (win->menubar, mo_annotate_delete, XmxNotSensitive);
  168.   return;
  169. }
  170.  
  171.  
  172. /* ------------------------------------------------------------------------ */
  173.  
  174. static void mo_set_text (Widget w, char *txt, char *ans, int id, 
  175.                          char *target_anchor, void *cached_stuff)
  176. {
  177.   /* Any data transfer that takes place in here must be inlined
  178.      image loading. */
  179.   loading_inlined_images = 1;
  180.   interrupted = 0;
  181.   mo_set_image_cache_nuke_threshold ();
  182.   if (Rdata.annotations_on_top)
  183.     HTMLSetText (w, txt, ans ? ans : "\0", "\0", id, target_anchor, 
  184.                  cached_stuff);
  185.   else
  186.     HTMLSetText (w, txt, "\0", ans ? ans : "\0", id, target_anchor, 
  187.                  cached_stuff);
  188.   loading_inlined_images = 0;
  189.   interrupted = 0;
  190.   mo_gui_done_with_icon ();
  191. }
  192.  
  193.  
  194. /****************************************************************************
  195.  * name:    mo_do_window_text (PRIVATE)
  196.  * purpose: Set a window's text and do lots of other housekeeping
  197.  *          and GUI-maintenance things.
  198.  * inputs:  
  199.  *   - mo_window *win: The current window.
  200.  *   - char      *url: The URL for the text; assumed to be canonicalized
  201.  *                     and otherwise ready for inclusion in history lists,
  202.  *                     the window's overhead URL display, etc.
  203.  *   - char      *txt: The new text for the window.
  204.  *   - char  *txthead: The start of the malloc'd block of text corresponding
  205.  *                     to txt.
  206.  *   - int register_visit: If TRUE, then this text should be registerd
  207.  *                         as a new node in the history list.  If FALSE,
  208.  *                         then we're just moving around in the history list.
  209.  *   - char      *ref: Reference (possible title) for this text.
  210.  * returns: 
  211.  *   mo_succeed
  212.  * remarks: 
  213.  *   This is the mother of all functions in Mosaic.  Probably should be
  214.  *   rethought and broken down.
  215.  ****************************************************************************/
  216. static mo_status mo_do_window_text (mo_window *win, char *url, char *txt,
  217.                                     char *txthead,
  218.                                     int register_visit, char *ref)
  219. {
  220.   char *line, *ans;
  221.  
  222.   mo_set_current_cached_win (win);
  223.  
  224.   if (Rdata.track_pointer_motion)
  225.     {
  226.       XmString xmstr = XmStringCreateLtoR (" ", XmSTRING_DEFAULT_CHARSET);
  227.       XtVaSetValues
  228.         (win->tracker_label,
  229.          XmNlabelString, (XtArgVal)xmstr,
  230.          NULL);
  231.       XmStringFree (xmstr);
  232.     }
  233.       
  234.   /* If !register_visit, we're just screwing around with current_node
  235.      already, so don't bother snarfing scrollbar values. */
  236.   if (register_visit)
  237.     mo_snarf_scrollbar_values (win);
  238.  
  239.   /* cached_url HAS to be set here, since Resolve counts on it. */
  240.   cached_url = mo_url_canonicalize (url, "");
  241.   win->cached_url = cached_url;
  242.  
  243.   mo_here_we_are_son (url);
  244.   
  245.   {
  246.     /* Since mo_fetch_annotation_links uses the communications code,
  247.        we need to play games with binary_transfer. */
  248.     int tmp = binary_transfer;
  249.     binary_transfer = 0;
  250.     ans = mo_fetch_annotation_links (url,
  251.                                      Rdata.annotations_on_top);
  252.     binary_transfer = tmp;
  253.   }
  254.  
  255.   /* If there is a BASE tag in the document that contains a "real"
  256.      URL, this will be non-NULL by the time we exit and base_callback
  257.      will have been called. */
  258.   url_base_override = NULL;
  259.  
  260.   {
  261.     int id = 0, freeta = 0;
  262.     void *cached_stuff = NULL;
  263.     char *target_anchor = win->target_anchor;
  264.  
  265.     if ((!register_visit) && win->current_node)
  266.       {
  267.         id = win->current_node->docid;
  268.         cached_stuff = win->current_node->cached_stuff;
  269.       }
  270.  
  271.     /* If the window doesn't have a target anchor already,
  272.        see if there's one in this node's URL. */
  273.     if ((!target_anchor || !(*target_anchor)) && win->current_node)
  274.       {
  275.         target_anchor = mo_url_extract_anchor (win->current_node->url);
  276.         freeta = 1;
  277.       }
  278.  
  279.     if (!txt || !txthead)
  280.       {
  281. #if 0
  282.         txt = strdup ("<h1>Uh oh, I'm stumped</h1> Mosaic has encountered a situation in which it doesn't know what to do.  Please back up and try again, or send a bug report including full details about what you're trying to do to <b>mosaic-x@ncsa.uiuc.edu</b>.  We thank you for your support.");
  283. #endif
  284.         /* Just make it look OK...  band-aid city. */
  285.         txt = strdup ("\0");
  286.         txthead = txt;
  287.       }
  288.  
  289.     mo_set_text (win->scrolled_win, txt, ans, id, target_anchor,
  290.                  cached_stuff);
  291.  
  292.     if (win->target_anchor)
  293.       free (win->target_anchor);
  294.  
  295.     win->target_anchor = NULL;
  296.  
  297.     if (freeta)
  298.       free (target_anchor);
  299.   }
  300.  
  301.   if (url_base_override)
  302.     {
  303.       /* Get the override URL -- this should be all we need to do here. */
  304.       url = url_base_override;
  305.       mo_here_we_are_son (url);
  306.     }
  307.  
  308.   /* Every time we view the document, we reset the search_start
  309.      struct so searches will start at the beginning of the document. */
  310.   ((ElementRef *)win->search_start)->id = 0;
  311.  
  312.   /* CURRENT_NODE ISN'T SET UNTIL HERE (assuming register_visit is 1). */
  313.   /* Now that WbNtext has been set, we can pull out WbNtitle. */
  314.   /* First, check and see if we have a URL.  If not, we probably
  315.      are only jumping around inside a document. */
  316.   if (url && *url)
  317.     {
  318.       if (register_visit)
  319.         mo_record_visit (win, url, txt, txthead, ref);
  320.       else
  321.         {
  322.           /* At the very least we want to pull out the new title,
  323.              if one exists. */
  324.           if (win->current_node)
  325.             {
  326.               if (win->current_node->title)
  327.                 free (win->current_node->title);
  328.               win->current_node->title = mo_grok_title (win, url, ref);
  329.             }
  330.         }
  331.     }
  332.   
  333.   mo_reset_document_headers (win);
  334.  
  335.   if (win->history_list && win->current_node)
  336.     {
  337.       XmListSelectPos (win->history_list, win->current_node->position, False);
  338.       XmListSetBottomPos (win->history_list, win->current_node->position);
  339.     }
  340.  
  341.   /* Update source text if necessary. */
  342.   if (win->source_text && XtIsManaged(win->source_text) &&
  343.       win->current_node)
  344.     {
  345.       XmxTextSetString (win->source_text, win->current_node->text);
  346.       XmxTextSetString (win->source_url_text, win->current_node->url);
  347.     }
  348.  
  349.   if (win->current_node && win->current_node->previous != NULL)
  350.     mo_back_possible (win);
  351.   else
  352.     mo_back_impossible (win);
  353.   
  354.   if (win->current_node && win->current_node->next != NULL)
  355.     mo_forward_possible (win);
  356.   else
  357.     mo_forward_impossible (win);
  358.  
  359.   if (win->current_node && 
  360.       mo_is_editable_annotation (win, win->current_node->text))
  361.     mo_annotate_edit_possible (win);
  362.   else
  363.     mo_annotate_edit_impossible (win);
  364.  
  365.   mo_not_busy ();
  366.  
  367.   return mo_succeed;
  368. }
  369.  
  370.  
  371. /****************************************************************************
  372.  * name:    mo_set_win_current_node
  373.  * purpose: Given a window and a node, set the window's current node.
  374.  *          This assumes node is already all put together, in the history
  375.  *          list for the window, etc.
  376.  * inputs:  
  377.  *   - mo_window *win: The current window.
  378.  *   - mo_node  *node: The node to use.
  379.  * returns: 
  380.  *   Result of calling mo_do_window_text.
  381.  * remarks: 
  382.  *   This routine is meant to be used to move forward, backward,
  383.  *   and to arbitrarily locations in the history list.
  384.  ****************************************************************************/
  385. mo_status mo_set_win_current_node (mo_window *win, mo_node *node)
  386. {
  387.   void *to_free = NULL;
  388.   mo_status r;
  389.   
  390.   mo_snarf_scrollbar_values (win);
  391.  
  392.   if (win->current_node && win->reloading)
  393.     {
  394.       to_free = win->current_node->cached_stuff;
  395.  
  396.       win->current_node->cached_stuff = NULL;
  397.     }
  398.  
  399.   win->current_node = node;
  400.  
  401.   mo_busy ();
  402.   mo_set_current_cached_win (win);
  403.   r = mo_do_window_text (win, win->current_node->url, 
  404.                          win->current_node->text, 
  405.                          win->current_node->texthead,
  406.                          FALSE, win->current_node->ref);
  407.  
  408.   if (win->reloading)
  409.     {
  410.       if (to_free)
  411.         HTMLFreeWidgetInfo (to_free);
  412.       
  413.       win->reloading = 0;
  414.     }
  415.  
  416.   return r;
  417. }
  418.  
  419.  
  420. /****************************************************************************
  421.  * name:    mo_reload_window_text
  422.  * purpose: Reload the current window's text by pulling it over the
  423.  *          network again.
  424.  * inputs:  
  425.  *   - mo_window *win: The current window.
  426.  * returns: 
  427.  *   mo_succeed
  428.  * remarks: 
  429.  *   This frees the current window's texthead.  This calls mo_pull_er_over
  430.  *   directly, and needs to be smarter about handling HDF, etc.
  431.  ****************************************************************************/
  432. mo_status mo_reload_window_text (mo_window *win, int reload_images_also)
  433. {
  434.   mo_busy ();
  435.  
  436.   mo_set_current_cached_win (win);
  437.  
  438.   /* Uh oh, this is trouble... */
  439.   if (!win->current_node)
  440.     return mo_load_window_text 
  441.       (win, startup_document ? startup_document : home_document, NULL);
  442.  
  443.   /* Free all images in the current document. */
  444.   if (Rdata.reload_reloads_images || reload_images_also)
  445.     mo_zap_cached_images_here (win);
  446.  
  447.   /* Free the current document's text. */
  448.   /* REALLY we shouldn't do this until we've verified we have new text that's
  449.      actually good here -- for instance, if we have a document on display,
  450.      then go to binary transfer mode, then do reload, we should pick up the
  451.      access override here and keep the old copy up on screen. */
  452.   if (win->current_node->texthead != NULL)
  453.     {
  454.       free (win->current_node->texthead);
  455.       win->current_node->texthead = NULL;
  456.     }
  457.  
  458.   /* Set binary_transfer as per current window. */
  459.   binary_transfer = win->binary_transfer;
  460.   mo_set_current_cached_win (win);
  461.   interrupted = 0;
  462.  
  463. #ifdef PEM_AUTH
  464.     /*
  465.      * For http requests only, we may have a mandatory encrypt
  466.      * state.  Try and enforce that here.
  467.      */
  468.     if ((!post_gave_encrypt)&&
  469.         (strncmp(win->current_node->url, "http:", 5) == 0))
  470.     {
  471.         int encrypt_ok;
  472.  
  473.         switch(win->encrypt_state)
  474.         {
  475.         case mo_no_encrypt:
  476.             break;
  477.         case mo_pem_encrypt:
  478.             encrypt_ok = mo_url_set_encryption("PEM", NULL,
  479.                 win->current_node->url);
  480.             break;
  481.         case mo_pgp_encrypt:
  482.             encrypt_ok = mo_url_set_encryption("PGP", NULL,
  483.                 win->current_node->url);
  484.             break;
  485.         }
  486.     }
  487.     post_gave_encrypt = 0;
  488. #endif /* PEM_AUTH */
  489.  
  490.   {
  491.       /*
  492.        * Reload should force a cache refresh on a proxy
  493.        *    -- Ari L. <luotonen@dxcern.cern.ch>
  494.        */
  495.       extern char reloading;    /* is really a BOOL */
  496.       reloading = 1;
  497.       win->current_node->text = mo_pull_er_over (win->current_node->url, 
  498.                          &win->current_node->texthead);
  499.       reloading = 0;
  500.   }
  501.   {
  502.     /* Check use_this_url_instead from HTAccess.c. */
  503.     /* IS THIS GOOD ENOUGH FOR THIS CASE??? */
  504.     extern char *use_this_url_instead;
  505.     if (use_this_url_instead)
  506.       {
  507.         win->current_node->url = use_this_url_instead;
  508.       }
  509.   }
  510. #ifdef HAVE_HDF
  511.   if (win->current_node->text && 
  512.       strncmp (win->current_node->text, "<mosaic-internal-reference", 26) == 0)
  513.     {
  514.       char *text = mo_decode_internal_reference 
  515.         (win->current_node->url, win->current_node->text,
  516.          mo_url_extract_anchor (win->current_node->url));
  517.       win->current_node->text = text;
  518.       win->current_node->texthead = text;
  519.     }
  520. #endif 
  521.   
  522.   /* Clear out the cached stuff, if any exists. */
  523.   win->reloading = 1;
  524.  
  525.   mo_set_win_current_node (win, win->current_node);
  526.  
  527.   win->reloading = 0;
  528.  
  529.   return mo_succeed;
  530. }
  531.  
  532.  
  533.  
  534. /****************************************************************************
  535.  * name:    mo_refresh_window_text
  536.  * purpose: Reload the current window's text without pulling it over the net.
  537.  * inputs:  
  538.  *   - mo_window *win: The current window.
  539.  * returns: 
  540.  *   mo_succeed
  541.  * remarks: 
  542.  ****************************************************************************/
  543. mo_status mo_refresh_window_text (mo_window *win)
  544. {
  545.   mo_busy ();
  546.  
  547.   mo_set_current_cached_win (win);
  548.  
  549.   if (!win->current_node)
  550.     {
  551.       mo_not_busy ();
  552.       return mo_fail;
  553.     }
  554.  
  555.   /* Clear out the cached stuff, if any exists. */
  556.   win->reloading = 1;
  557.  
  558.   mo_set_win_current_node (win, win->current_node);
  559.  
  560.   mo_not_busy ();
  561.  
  562.   return mo_succeed;
  563. }
  564.  
  565.  
  566.  
  567. /****************************************************************************
  568.  * name:    mo_load_window_text
  569.  * purpose: Given a window and a raw URL, load the window.  The window
  570.  *          is assumed to already exist with a document inside, etc.
  571.  * inputs:  
  572.  *   - mo_window *win: The current window.
  573.  *   - char      *url: The URL to load.
  574.  *   - char      *ref: The reference ("parent") URL.
  575.  * returns: 
  576.  *   mo_succeed
  577.  * remarks: 
  578.  *   This is getting ugly.
  579.  ****************************************************************************/
  580. mo_status mo_load_window_text (mo_window *win, char *url, char *ref)
  581. {
  582.   char *newtext = NULL, *newtexthead = NULL;
  583.   mo_busy ();
  584.  
  585.   win->target_anchor = mo_url_extract_anchor (url);
  586.  
  587.   /* If we're just referencing an anchor inside a document,
  588.      do the right thing. */
  589.   if (url && *url == '#')
  590.     {
  591.       /* Now we make a copy of the current text and make sure we ask
  592.          for a new mo_node and entry in the history list. */
  593.       /* IF we're not dealing with an internal reference. */
  594.       if (strncmp (url, "#hdfref;", 8) &&
  595.           strncmp (url, "#hdfdtm;", 8))
  596.         {
  597.           if (win->current_node)
  598.             {
  599.               newtext = strdup (win->current_node->text);
  600.               newtexthead = newtext;
  601.             }
  602.           else
  603.             {
  604.               newtext = strdup ("lose");
  605.               newtexthead = newtext;
  606.             }
  607.         }
  608.       url = mo_url_canonicalize_keep_anchor 
  609.         (url, win->current_node ? win->current_node->url : "");
  610.     }
  611.   else
  612.     {
  613.       /* Get a full address for this URL. */
  614.       /* Under some circumstances we may not have a current node yet
  615.          and may wish to just run with it... so check for that. */
  616.       if (win->current_node && win->current_node->url)
  617.         {
  618.           url = mo_url_canonicalize_keep_anchor (url, win->current_node->url);
  619.         }
  620.  
  621.       /* Set binary_transfer as per current window. */
  622.       binary_transfer = win->binary_transfer;
  623.       mo_set_current_cached_win (win);
  624.  
  625.       {
  626.         char *canon = mo_url_canonicalize (url, "");
  627.         interrupted = 0;
  628.  
  629. #ifdef PEM_AUTH
  630.     /*
  631.      * For http requests only, we may have a mandatory encrypt
  632.      * state.  Try and enforce that here.
  633.      */
  634.     if ((!post_gave_encrypt)&&(strncmp(canon, "http:", 5) == 0))
  635.     {
  636.         int encrypt_ok;
  637.  
  638.         switch(win->encrypt_state)
  639.         {
  640.         case mo_no_encrypt:
  641.             break;
  642.         case mo_pem_encrypt:
  643.             encrypt_ok = mo_url_set_encryption("PEM", NULL, canon);
  644.             break;
  645.         case mo_pgp_encrypt:
  646.             encrypt_ok = mo_url_set_encryption("PGP", NULL, canon);
  647.             break;
  648.         }
  649.     }
  650.     post_gave_encrypt = 0;
  651. #endif /* PEM_AUTH */
  652.  
  653.         newtext = mo_pull_er_over (canon, &newtexthead);
  654.         free (canon);
  655.       }
  656.  
  657.       {
  658.         /* Check use_this_url_instead from HTAccess.c. */
  659.         extern char *use_this_url_instead;
  660.         if (use_this_url_instead)
  661.           {
  662.             mo_here_we_are_son (url);
  663.             url = use_this_url_instead;
  664.             
  665.             /* Go get another target_anchor. */
  666.             if (win->target_anchor)
  667.               free (win->target_anchor);
  668.             win->target_anchor = mo_url_extract_anchor (url);
  669.           }
  670.       }
  671.     }
  672.  
  673. #ifdef HAVE_HDF
  674.   /* If a target anchor exists, and if it's an HDF reference, then
  675.      go decode the HDF reference and call mo_do_window_text on the
  676.      resulting text. */
  677.   if (win->target_anchor &&
  678.       strncmp (win->target_anchor, "hdfref;", 7) == 0 &&
  679.       strlen (win->target_anchor) > 8)
  680.     {
  681.       char *text;
  682.       text = (char *)mo_decode_hdfref (url, win->target_anchor);
  683.       {
  684.         /* Check use_this_url_instead from HTAccess.c. */
  685.         extern char *use_this_url_instead;
  686.         if (use_this_url_instead)
  687.           {
  688.             mo_here_we_are_son (url);
  689.             url = use_this_url_instead;
  690.             mo_load_window_text(win, url, ref);
  691.             return;
  692.           }
  693.       }
  694.       mo_do_window_text (win, url, text, text, 1, ref);
  695.     }
  696.   /* An hdfdtm reference means that we should blast the referenced
  697.      HDF data object over the output DTM port to Collage.  Currently
  698.      this can only be an image; in the future we'll do SDS's, etc. */
  699.   else if (win->target_anchor &&
  700.            strncmp (win->target_anchor, "hdfdtm;", 7) == 0 &&
  701.            strlen (win->target_anchor) > 8)
  702.     {
  703. #ifdef HAVE_DTM
  704.       /* We specifically want to make sure that the anchor is allowed
  705.          to stay in the URL, so we don't canonicalize to strip it out. */
  706.       mo_do_hdf_dtm_thang (url, &(win->target_anchor[7]));
  707. #endif
  708.  
  709.       if (win->target_anchor)
  710.         free (win->target_anchor);
  711.       win->target_anchor = NULL;
  712.  
  713.       mo_gui_done_with_icon ();
  714.       mo_not_busy ();
  715.     }
  716.   /* Assuming we have HDF, the only thing mosaic-internal-reference
  717.      currently can be is pointer to an HDF file. */
  718.   else if (newtext && strncmp (newtext, "<mosaic-internal-reference", 26) == 0)
  719.     {
  720.       char *text;
  721.       text = mo_decode_internal_reference (url, newtext, win->target_anchor);
  722.       mo_do_window_text (win, url, text, text, 1, ref);
  723.     }
  724.   else
  725. #endif
  726.   /* Now, if it's a telnet session, there should be no need
  727.      to do anything else.  Also check for override in text itself. */
  728.   if (strncmp (url, "telnet:", 7) == 0 || strncmp (url, "tn3270:", 7) == 0 ||
  729.       strncmp (url, "rlogin:", 7) == 0 ||
  730.       (newtext && strncmp (newtext, "<mosaic-access-override>", 24) == 0))
  731.     {
  732.       /* We don't need this anymore. */
  733.       free (newtext);
  734.  
  735.       /* We still want a global history entry but NOT a 
  736.          window history entry. */
  737.       mo_here_we_are_son (url);
  738.       /* ... and we want to redisplay the current window to
  739.          get the effect of the history entry today, not tomorrow. */
  740.       mo_redisplay_window (win);
  741.       /* We're not busy anymore... */
  742.       mo_gui_done_with_icon ();
  743.       mo_not_busy ();
  744.     }
  745.   else if (newtext)
  746.     {
  747.       /* Not a telnet session and not an override, but text present
  748.          (the "usual" case): */
  749.  
  750.       /* Set the window text. */
  751.       mo_do_window_text (win, url, newtext, newtexthead, 1, ref);
  752.     }
  753.   else
  754.     {
  755.       /* No text at all. */
  756.       mo_gui_done_with_icon ();
  757.       mo_not_busy ();
  758.     }
  759.  
  760.  outtahere:
  761.   return mo_succeed;
  762. }
  763.  
  764.  
  765. mo_status mo_post_load_window_text (mo_window *win, char *url, 
  766.                                     char *content_type, char *post_data, 
  767.                                     char *ref)
  768. {
  769.   char *newtext = NULL, *newtexthead = NULL;
  770.   mo_busy ();
  771.  
  772.   win->target_anchor = mo_url_extract_anchor (url);
  773.  
  774.   /* If we're just referencing an anchor inside a document,
  775.      do the right thing. */
  776.   if (url && *url == '#')
  777.     {
  778.       /* Now we make a copy of the current text and make sure we ask
  779.          for a new mo_node and entry in the history list. */
  780.       /* IF we're not dealing with an internal reference. */
  781.       if (strncmp (url, "#hdfref;", 8) &&
  782.           strncmp (url, "#hdfdtm;", 8))
  783.         {
  784.           if (win->current_node)
  785.             {
  786.               newtext = strdup (win->current_node->text);
  787.               newtexthead = newtext;
  788.             }
  789.           else
  790.             {
  791.               newtext = strdup ("lose");
  792.               newtexthead = newtext;
  793.             }
  794.         }
  795.       url = mo_url_canonicalize_keep_anchor 
  796.         (url, win->current_node ? win->current_node->url : "");
  797.     }
  798.   else
  799.     {
  800.       /* Get a full address for this URL. */
  801.       /* Under some circumstances we may not have a current node yet
  802.          and may wish to just run with it... so check for that. */
  803.       if (win->current_node && win->current_node->url)
  804.         {
  805.           url = mo_url_canonicalize_keep_anchor (url, win->current_node->url);
  806.         }
  807.  
  808.       /* Set binary_transfer as per current window. */
  809.       binary_transfer = win->binary_transfer;
  810.       mo_set_current_cached_win (win);
  811.  
  812.       {
  813.         char *canon = mo_url_canonicalize (url, "");
  814.         interrupted = 0;
  815.  
  816. #ifdef PEM_AUTH
  817.     /*
  818.      * For http requests only, we may have a mandatory encrypt
  819.      * state.  Try and enforce that here.
  820.      */
  821.     if ((!post_gave_encrypt)&&(strncmp(canon, "http:", 5) == 0))
  822.     {
  823.         int encrypt_ok;
  824.  
  825.         switch(win->encrypt_state)
  826.         {
  827.         case mo_no_encrypt:
  828.             break;
  829.         case mo_pem_encrypt:
  830.             encrypt_ok = mo_url_set_encryption("PEM", NULL, canon);
  831.             break;
  832.         case mo_pgp_encrypt:
  833.             encrypt_ok = mo_url_set_encryption("PGP", NULL, canon);
  834.             break;
  835.         }
  836.     }
  837.     post_gave_encrypt = 0;
  838. #endif /* PEM_AUTH */
  839.  
  840.         newtext = mo_post_pull_er_over (canon, content_type, post_data, 
  841.                                         &newtexthead);
  842.         free (canon);
  843.       }
  844.  
  845.       {
  846.         /* Check use_this_url_instead from HTAccess.c. */
  847.         extern char *use_this_url_instead;
  848.         if (use_this_url_instead)
  849.           {
  850.             mo_here_we_are_son (url);
  851.             url = use_this_url_instead;
  852.           }
  853.       }
  854.     }
  855.  
  856. #ifdef HAVE_HDF
  857.   /* If a target anchor exists, and if it's an HDF reference, then
  858.      go decode the HDF reference and call mo_do_window_text on the
  859.      resulting text. */
  860.   if (win->target_anchor &&
  861.       strncmp (win->target_anchor, "hdfref;", 7) == 0 &&
  862.       strlen (win->target_anchor) > 8)
  863.     {
  864.       char *text;
  865.       text = (char *)mo_decode_hdfref (url, win->target_anchor);
  866.       {
  867.         /* Check use_this_url_instead from HTAccess.c. */
  868.         extern char *use_this_url_instead;
  869.         if (use_this_url_instead)
  870.           {
  871.             mo_here_we_are_son (url);
  872.             url = use_this_url_instead;
  873.             mo_load_window_text(win, url, ref);
  874.             return;
  875.           }
  876.       }
  877.       mo_do_window_text (win, url, text, text, 1, ref);
  878.     }
  879.   /* An hdfdtm reference means that we should blast the referenced
  880.      HDF data object over the output DTM port to Collage.  Currently
  881.      this can only be an image; in the future we'll do SDS's, etc. */
  882.   else if (win->target_anchor &&
  883.            strncmp (win->target_anchor, "hdfdtm;", 7) == 0 &&
  884.            strlen (win->target_anchor) > 8)
  885.     {
  886. #ifdef HAVE_DTM
  887.       /* We specifically want to make sure that the anchor is allowed
  888.          to stay in the URL, so we don't canonicalize to strip it out. */
  889.       mo_do_hdf_dtm_thang (url, &(win->target_anchor[7]));
  890. #endif
  891.  
  892.       if (win->target_anchor)
  893.         free (win->target_anchor);
  894.       win->target_anchor = NULL;
  895.  
  896.       mo_gui_done_with_icon ();
  897.       mo_not_busy ();
  898.     }
  899.   /* Assuming we have HDF, the only thing mosaic-internal-reference
  900.      currently can be is pointer to an HDF file. */
  901.   else if (newtext && strncmp (newtext, "<mosaic-internal-reference", 26) == 0)
  902.     {
  903.       char *text;
  904.       text = mo_decode_internal_reference (url, newtext, win->target_anchor);
  905.       mo_do_window_text (win, url, text, text, 1, ref);
  906.     }
  907.   else
  908. #endif
  909.   /* Now, if it's a telnet session, there should be no need
  910.      to do anything else.  Also check for override in text itself. */
  911.   if (strncmp (url, "telnet:", 7) == 0 || strncmp (url, "tn3270:", 7) == 0 ||
  912.       strncmp (url, "rlogin:", 7) == 0 ||
  913.       (newtext && strncmp (newtext, "<mosaic-access-override>", 24) == 0))
  914.     {
  915.       /* We don't need this anymore. */
  916.       free (newtext);
  917.  
  918.       /* We still want a global history entry but NOT a 
  919.          window history entry. */
  920.       mo_here_we_are_son (url);
  921.       /* ... and we want to redisplay the current window to
  922.          get the effect of the history entry today, not tomorrow. */
  923.       mo_redisplay_window (win);
  924.       /* We're not busy anymore... */
  925.       mo_gui_done_with_icon ();
  926.       mo_not_busy ();
  927.     }
  928.   else if (newtext)
  929.     {
  930.       /* Not a telnet session and not an override, but text present
  931.          (the "usual" case): */
  932.  
  933.       /* Set the window text. */
  934.       mo_do_window_text (win, url, newtext, newtexthead, 1, ref);
  935.     }
  936.   else
  937.     {
  938.       /* No text at all. */
  939.       mo_gui_done_with_icon ();
  940.       mo_not_busy ();
  941.     }
  942.  
  943.  outtahere:
  944.   return mo_succeed;
  945. }
  946.  
  947.  
  948.  
  949.  
  950.  
  951. /****************************************************************************
  952.  * name:    mo_duplicate_window_text
  953.  * purpose: Given an old window and a new window, make a copy of the text
  954.  *          in the old window and install it in the new window.
  955.  * inputs:  
  956.  *   - mo_window *oldw: The old window.
  957.  *   - mo_window *neww: The new window.
  958.  * returns: 
  959.  *   mo_succeed
  960.  * remarks: 
  961.  *   This is how windows are cloned: a new window is created and this
  962.  *   call sets up its contents.
  963.  ****************************************************************************/
  964. mo_status mo_duplicate_window_text (mo_window *oldw, mo_window *neww)
  965. {
  966.   /* We can get away with just cloning text here and forgetting
  967.      about texthead, obviously, since we're making a new copy. */
  968.   char *newtext;
  969.  
  970.   if (!oldw->current_node)
  971.     return mo_fail;
  972.  
  973.   newtext = strdup (oldw->current_node->text);
  974.  
  975.   mo_do_window_text 
  976.     (neww, strdup (oldw->current_node->url), 
  977.      newtext, newtext, TRUE, 
  978.      oldw->current_node->ref ? strdup (oldw->current_node->ref) : NULL);
  979.  
  980.   return mo_succeed;
  981. }
  982.  
  983.  
  984. /****************************************************************************
  985.  * name:    mo_access_document
  986.  * purpose: Given a URL, access the document by loading the current 
  987.  *          window's text.
  988.  * inputs:  
  989.  *   - mo_window *win: The current window.
  990.  *   - char      *url: URL to access.
  991.  * returns: 
  992.  *   mo_succeed
  993.  * remarks: 
  994.  *   This should be the standard call for accessing a document.
  995.  ****************************************************************************/
  996. mo_status mo_access_document (mo_window *win, char *url)
  997. {
  998.   mo_busy ();
  999.  
  1000.   mo_set_current_cached_win (win);
  1001.  
  1002.   mo_load_window_text (win, url, NULL);
  1003.  
  1004.   return mo_succeed;
  1005. }
  1006.  
  1007.  
  1008. mo_status mo_post_access_document (mo_window *win, char *url,
  1009.                                    char *content_type, char *post_data)
  1010. {
  1011.   mo_busy ();
  1012.  
  1013.   mo_set_current_cached_win (win);
  1014.  
  1015.   mo_post_load_window_text (win, url, content_type, post_data, NULL);
  1016.  
  1017.   return mo_succeed;
  1018. }
  1019.