Blame src/LYMap.c

Packit f574b8
/*
Packit f574b8
 * $LynxId: LYMap.c,v 1.50 2018/03/05 22:32:14 tom Exp $
Packit f574b8
 *			Lynx Client-side Image MAP Support	       LYMap.c
Packit f574b8
 *			==================================
Packit f574b8
 *
Packit f574b8
 *	Author: FM	Foteos Macrides (macrides@sci.wfbr.edu)
Packit f574b8
 *
Packit f574b8
 */
Packit f574b8
Packit f574b8
#include <HTUtils.h>
Packit f574b8
#include <HTTP.h>
Packit f574b8
#include <HTAnchor.h>
Packit f574b8
#include <HTAccess.h>
Packit f574b8
#include <HTFormat.h>
Packit f574b8
#include <HTParse.h>
Packit f574b8
#include <HTAlert.h>
Packit f574b8
#include <LYUtils.h>
Packit f574b8
#include <LYMap.h>
Packit f574b8
#include <GridText.h>
Packit f574b8
#include <LYGlobalDefs.h>
Packit f574b8
#include <LYKeymap.h>
Packit f574b8
#include <LYCharUtils.h>
Packit f574b8
#include <LYCharSets.h>
Packit f574b8
#include <LYStrings.h>
Packit f574b8
Packit f574b8
#ifdef DIRED_SUPPORT
Packit f574b8
#include <LYUpload.h>
Packit f574b8
#include <LYLocal.h>
Packit f574b8
#endif
Packit f574b8
Packit f574b8
#include <LYexit.h>
Packit f574b8
#include <LYLeaks.h>
Packit f574b8
Packit f574b8
#define NO_MAP_TITLE "[USEMAP]"
Packit f574b8
Packit f574b8
typedef struct _LYMapElement {
Packit f574b8
    char *address;
Packit f574b8
    char *title;
Packit f574b8
    BOOLEAN intern_flag;
Packit f574b8
} LYMapElement;
Packit f574b8
Packit f574b8
typedef struct _LYImageMap {
Packit f574b8
    char *address;
Packit f574b8
    char *title;
Packit f574b8
    HTList *elements;
Packit f574b8
} LYImageMap;
Packit f574b8
Packit f574b8
static HTList *LynxMaps = NULL;
Packit f574b8
Packit f574b8
BOOL LYMapsOnly = FALSE;
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Utility for freeing a list of MAPs.
Packit f574b8
 */
Packit f574b8
void ImageMapList_free(HTList *theList)
Packit f574b8
{
Packit f574b8
    LYImageMap *map;
Packit f574b8
    LYMapElement *element;
Packit f574b8
    HTList *cur = theList;
Packit f574b8
    HTList *current;
Packit f574b8
Packit f574b8
    if (!cur)
Packit f574b8
	return;
Packit f574b8
Packit f574b8
    while (NULL != (map = (LYImageMap *) HTList_nextObject(cur))) {
Packit f574b8
	FREE(map->address);
Packit f574b8
	FREE(map->title);
Packit f574b8
	if (map->elements) {
Packit f574b8
	    current = map->elements;
Packit f574b8
	    while (NULL !=
Packit f574b8
		   (element = (LYMapElement *) HTList_nextObject(current))) {
Packit f574b8
		FREE(element->address);
Packit f574b8
		FREE(element->title);
Packit f574b8
		FREE(element);
Packit f574b8
	    }
Packit f574b8
	    HTList_delete(map->elements);
Packit f574b8
	    map->elements = NULL;
Packit f574b8
	}
Packit f574b8
	FREE(map);
Packit f574b8
    }
Packit f574b8
    HTList_delete(theList);
Packit f574b8
    return;
Packit f574b8
}
Packit f574b8
Packit f574b8
#ifdef LY_FIND_LEAKS
Packit f574b8
/*
Packit f574b8
 * Utility for freeing the global list of MAPs.  - kw
Packit f574b8
 */
Packit f574b8
static void LYLynxMaps_free(void)
Packit f574b8
{
Packit f574b8
    ImageMapList_free(LynxMaps);
Packit f574b8
    LynxMaps = NULL;
Packit f574b8
    return;
Packit f574b8
}
Packit f574b8
#endif /* LY_FIND_LEAKS */
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * We keep two kinds of lists:
Packit f574b8
 * - A global list (LynxMaps) shared by MAPs from all documents that
Packit f574b8
 *   do not have POST data.
Packit f574b8
 * - For each response to a POST which contains MAPs, a list specific
Packit f574b8
 *   to this combination of URL and post_data.  It is kept in the
Packit f574b8
 *   HTParentAnchor structure and is freed when the document is removed
Packit f574b8
 *   from memory, in the course of normal removal of anchors.
Packit f574b8
 *   MAPs from POST responses can only be accessed via internal links,
Packit f574b8
 *   i.e., from within the same document (with the same post_data).
Packit f574b8
 *   The notion of "same document" is extended, so that LYNXIMGMAP:
Packit f574b8
 *   and List Page screens are logically part of the document on which
Packit f574b8
 *   they are based. - kw
Packit f574b8
 *
Packit f574b8
 * If track_internal_links is false, only the global list will be used
Packit f574b8
 * for all MAPs.
Packit f574b8
 *
Packit f574b8
 */
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Utility for creating an LYImageMap list, if it doesn't exist already, adding
Packit f574b8
 * LYImageMap entry structures if needed, and removing any LYMapElements in a
Packit f574b8
 * pre-existing LYImageMap entry so that it will have only those from AREA tags
Packit f574b8
 * for the current analysis of MAP element content.  - FM
Packit f574b8
 */
Packit f574b8
BOOL LYAddImageMap(char *address,
Packit f574b8
		   char *title,
Packit f574b8
		   HTParentAnchor *node_anchor)
Packit f574b8
{
Packit f574b8
    LYImageMap *tmp = NULL;
Packit f574b8
    LYImageMap *old = NULL;
Packit f574b8
    HTList *cur = NULL;
Packit f574b8
    HTList *theList = NULL;
Packit f574b8
    HTList *curele = NULL;
Packit f574b8
    LYMapElement *ele = NULL;
Packit f574b8
Packit f574b8
    if (isEmpty(address))
Packit f574b8
	return FALSE;
Packit f574b8
    if (!(node_anchor && node_anchor->address))
Packit f574b8
	return FALSE;
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Set theList to either the global LynxMaps list or, if we are associated
Packit f574b8
     * with post data, the specific list.  The list is created if it doesn't
Packit f574b8
     * already exist.  - kw
Packit f574b8
     */
Packit f574b8
    if (track_internal_links && node_anchor->post_data) {
Packit f574b8
	/*
Packit f574b8
	 * We are handling a MAP element found while parsing node_anchor's
Packit f574b8
	 * stream of data, and node_anchor has post_data associated and should
Packit f574b8
	 * therefore represent a POST response, so use the specific list.  - kw
Packit f574b8
	 */
Packit f574b8
	theList = node_anchor->imaps;
Packit f574b8
	if (!theList) {
Packit f574b8
	    theList = node_anchor->imaps = HTList_new();
Packit f574b8
	}
Packit f574b8
    } else {
Packit f574b8
	if (!LynxMaps) {
Packit f574b8
	    LynxMaps = HTList_new();
Packit f574b8
#ifdef LY_FIND_LEAKS
Packit f574b8
	    atexit(LYLynxMaps_free);
Packit f574b8
#endif
Packit f574b8
	}
Packit f574b8
	theList = LynxMaps;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (theList) {
Packit f574b8
	cur = theList;
Packit f574b8
	while (NULL != (old = (LYImageMap *) HTList_nextObject(cur))) {
Packit f574b8
	    if (old->address == 0)	/* shouldn't happen */
Packit f574b8
		continue;
Packit f574b8
	    if (!strcmp(old->address, address)) {
Packit f574b8
		FREE(old->address);
Packit f574b8
		FREE(old->title);
Packit f574b8
		if (old->elements) {
Packit f574b8
		    curele = old->elements;
Packit f574b8
		    while (NULL !=
Packit f574b8
			   (ele = (LYMapElement *) HTList_nextObject(curele))) {
Packit f574b8
			FREE(ele->address);
Packit f574b8
			FREE(ele->title);
Packit f574b8
			FREE(ele);
Packit f574b8
		    }
Packit f574b8
		    HTList_delete(old->elements);
Packit f574b8
		    old->elements = NULL;
Packit f574b8
		}
Packit f574b8
		break;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    tmp = (old != NULL) ?
Packit f574b8
	old : typecalloc(LYImageMap);
Packit f574b8
    if (tmp == NULL) {
Packit f574b8
	outofmem(__FILE__, "LYAddImageMap");
Packit f574b8
	return FALSE;
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(tmp->address, address);
Packit f574b8
    if (non_empty(title))
Packit f574b8
	StrAllocCopy(tmp->title, title);
Packit f574b8
    if (tmp != old)
Packit f574b8
	HTList_addObject(theList, tmp);
Packit f574b8
    return TRUE;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Utility for adding LYMapElement's to LYImageMap's
Packit f574b8
 * in the appropriate list. - FM
Packit f574b8
 */
Packit f574b8
BOOL LYAddMapElement(char *map,
Packit f574b8
		     char *address,
Packit f574b8
		     char *title,
Packit f574b8
		     HTParentAnchor *node_anchor,
Packit f574b8
		     int intern_flag GCC_UNUSED)
Packit f574b8
{
Packit f574b8
    LYMapElement *tmp = NULL;
Packit f574b8
    LYImageMap *theMap = NULL;
Packit f574b8
    HTList *theList = NULL;
Packit f574b8
    HTList *cur = NULL;
Packit f574b8
Packit f574b8
    if (isEmpty(map) || isEmpty(address))
Packit f574b8
	return FALSE;
Packit f574b8
    if (!(node_anchor && node_anchor->address))
Packit f574b8
	return FALSE;
Packit f574b8
Packit f574b8
    /*
Packit f574b8
     * Set theList to either the global LynxMaps list or, if we are associated
Packit f574b8
     * with post data, the specific list.  The list should already exist, since
Packit f574b8
     * this function is only called if the AREA tag we are handling was within
Packit f574b8
     * a MAP element in node_anchor's stream of data, so that LYAddImageMap has
Packit f574b8
     * been called.  - kw
Packit f574b8
     */
Packit f574b8
    if (track_internal_links && node_anchor->post_data) {
Packit f574b8
	/*
Packit f574b8
	 * We are handling an AREA tag found while parsing node_anchor's stream
Packit f574b8
	 * of data, and node_anchor has post_data associated and should
Packit f574b8
	 * therefore represent a POST response, so use the specific list.  - kw
Packit f574b8
	 */
Packit f574b8
	theList = node_anchor->imaps;
Packit f574b8
	if (!theList) {
Packit f574b8
	    return FALSE;
Packit f574b8
	}
Packit f574b8
    } else {
Packit f574b8
	if (!LynxMaps)
Packit f574b8
	    LYAddImageMap(map, NULL, node_anchor);
Packit f574b8
	theList = LynxMaps;
Packit f574b8
    }
Packit f574b8
Packit f574b8
    cur = theList;
Packit f574b8
    while (NULL != (theMap = (LYImageMap *) HTList_nextObject(cur))) {
Packit f574b8
	if (!strcmp(theMap->address, map)) {
Packit f574b8
	    break;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    if (!theMap)
Packit f574b8
	return FALSE;
Packit f574b8
    if (!theMap->elements)
Packit f574b8
	theMap->elements = HTList_new();
Packit f574b8
    cur = theMap->elements;
Packit f574b8
    while (NULL != (tmp = (LYMapElement *) HTList_nextObject(cur))) {
Packit f574b8
	if (!strcmp(tmp->address, address)) {
Packit f574b8
	    FREE(tmp->address);
Packit f574b8
	    FREE(tmp->title);
Packit f574b8
	    HTList_removeObject(theMap->elements, tmp);
Packit f574b8
	    FREE(tmp);
Packit f574b8
	    break;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    tmp = typecalloc(LYMapElement);
Packit f574b8
    if (tmp == NULL) {
Packit f574b8
	perror("Out of memory in LYAddMapElement");
Packit f574b8
	return FALSE;
Packit f574b8
    }
Packit f574b8
    StrAllocCopy(tmp->address, address);
Packit f574b8
    if (non_empty(title))
Packit f574b8
	StrAllocCopy(tmp->title, title);
Packit f574b8
    else
Packit f574b8
	StrAllocCopy(tmp->title, address);
Packit f574b8
    if (track_internal_links)
Packit f574b8
	tmp->intern_flag = (BOOLEAN) intern_flag;
Packit f574b8
    HTList_appendObject(theMap->elements, tmp);
Packit f574b8
Packit f574b8
    CTRACE((tfp,
Packit f574b8
	    "LYAddMapElement\n\tmap     %s\n\taddress %s\n\ttitle   %s)\n",
Packit f574b8
	    NonNull(map), NonNull(address), NonNull(title)));
Packit f574b8
Packit f574b8
    return TRUE;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Utility for checking whether an LYImageMap entry with a given address
Packit f574b8
 * already exists in the LynxMaps structure.  - FM
Packit f574b8
 */
Packit f574b8
BOOL LYHaveImageMap(char *address)
Packit f574b8
{
Packit f574b8
    LYImageMap *Map;
Packit f574b8
    HTList *cur = LynxMaps;
Packit f574b8
Packit f574b8
    if (!(cur && non_empty(address)))
Packit f574b8
	return FALSE;
Packit f574b8
Packit f574b8
    while (NULL != (Map = (LYImageMap *) HTList_nextObject(cur))) {
Packit f574b8
	if (!strcmp(Map->address, address)) {
Packit f574b8
	    return TRUE;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
Packit f574b8
    return FALSE;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Fills in a DocAddress structure for getting the HTParentAnchor of the
Packit f574b8
 * underlying resource.  ALso returns a pointer to that anchor in
Packit f574b8
 * *punderlying if we are dealing with POST data.  - kw
Packit f574b8
 *
Packit f574b8
 * address  is the address of the underlying resource, i.e., the one
Packit f574b8
 *	    containing the MAP element, the MAP's name appended as
Packit f574b8
 *	    fragment is ignored.
Packit f574b8
 * anAnchor is the LYNXIMGMAP: anchor; if it is associated with POST
Packit f574b8
 *	    data, we want the specific list, otherwise the global list.
Packit f574b8
 */
Packit f574b8
static void fill_DocAddress(DocAddress *wwwdoc,
Packit f574b8
			    const char *address,
Packit f574b8
			    HTParentAnchor *anAnchor,
Packit f574b8
			    HTParentAnchor **punderlying)
Packit f574b8
{
Packit f574b8
    char *doc_address = NULL;
Packit f574b8
    HTParentAnchor *underlying;
Packit f574b8
Packit f574b8
    StrAllocCopy(doc_address, address);
Packit f574b8
    if (anAnchor && anAnchor->post_data) {
Packit f574b8
	wwwdoc->address = doc_address;
Packit f574b8
	wwwdoc->post_data = anAnchor->post_data;
Packit f574b8
	wwwdoc->post_content_type = anAnchor->post_content_type;
Packit f574b8
	wwwdoc->bookmark = NULL;
Packit f574b8
	wwwdoc->isHEAD = FALSE;
Packit f574b8
	wwwdoc->safe = FALSE;
Packit f574b8
	underlying = HTAnchor_findAddress(wwwdoc);
Packit f574b8
	if (underlying->safe)
Packit f574b8
	    wwwdoc->safe = TRUE;
Packit f574b8
	if (punderlying)
Packit f574b8
	    *punderlying = underlying;
Packit f574b8
    } else {
Packit f574b8
	wwwdoc->address = doc_address;
Packit f574b8
	wwwdoc->post_data = NULL;
Packit f574b8
	wwwdoc->post_content_type = NULL;
Packit f574b8
	wwwdoc->bookmark = NULL;
Packit f574b8
	wwwdoc->isHEAD = FALSE;
Packit f574b8
	wwwdoc->safe = FALSE;
Packit f574b8
	if (punderlying)
Packit f574b8
	    *punderlying = NULL;
Packit f574b8
    }
Packit f574b8
}
Packit f574b8
Packit f574b8
/*
Packit f574b8
 * Get the appropriate list for creating a LYNXIMGMAP:  pseudo- document: 
Packit f574b8
 * either the global list (LynxMaps), or the specific list if a List Page for a
Packit f574b8
 * POST response is requested.  Also fill in the DocAddress structure etc.  by
Packit f574b8
 * calling fill_DocAddress().
Packit f574b8
 *
Packit f574b8
 * address is the address of the underlying resource, i.e., the one
Packit f574b8
 *	   containing the MAP element, the MAP's name appended as
Packit f574b8
 *	   fragment is ignored.
Packit f574b8
 * anchor  is the LYNXIMGMAP: anchor for which LYLoadIMGmap() is
Packit f574b8
 *	   requested; if it is associated with POST data, we want the
Packit f574b8
 *	   specific list for this combination of address+post_data.
Packit f574b8
 *
Packit f574b8
 * if track_internal_links is false, the Anchor passed to
Packit f574b8
 * LYLoadIMGmap() will never have post_data, so that the global list
Packit f574b8
 * will be used. - kw
Packit f574b8
 */
Packit f574b8
static HTList *get_the_list(DocAddress *wwwdoc,
Packit f574b8
			    const char *address,
Packit f574b8
			    HTParentAnchor *anchor,
Packit f574b8
			    HTParentAnchor **punderlying)
Packit f574b8
{
Packit f574b8
    HTList *result;
Packit f574b8
Packit f574b8
    if (anchor->post_data) {
Packit f574b8
	fill_DocAddress(wwwdoc, address, anchor, punderlying);
Packit f574b8
	if (non_empty(punderlying)) {
Packit f574b8
	    result = (*punderlying)->imaps;
Packit f574b8
	} else {
Packit f574b8
	    result = anchor->imaps;
Packit f574b8
	}
Packit f574b8
    } else {
Packit f574b8
	fill_DocAddress(wwwdoc, address, NULL, punderlying);
Packit f574b8
	result = LynxMaps;
Packit f574b8
    }
Packit f574b8
    return result;
Packit f574b8
}
Packit f574b8
Packit f574b8
/*	LYLoadIMGmap - F.Macrides (macrides@sci.wfeb.edu)
Packit f574b8
 *	------------
Packit f574b8
 *	Create a text/html stream with a list of links
Packit f574b8
 *	for HyperText References in AREAs of a MAP.
Packit f574b8
 */
Packit f574b8
Packit f574b8
static int LYLoadIMGmap(const char *arg,
Packit f574b8
			HTParentAnchor *anAnchor,
Packit f574b8
			HTFormat format_out,
Packit f574b8
			HTStream *sink)
Packit f574b8
{
Packit f574b8
    HTFormat format_in = WWW_HTML;
Packit f574b8
    HTStream *target = NULL;
Packit f574b8
    char *buf = NULL;
Packit f574b8
    LYMapElement *tmp = NULL;
Packit f574b8
    LYImageMap *theMap = NULL;
Packit f574b8
    char *MapTitle = NULL;
Packit f574b8
    char *MapAddress = NULL;
Packit f574b8
    HTList *theList;
Packit f574b8
    HTList *cur = NULL;
Packit f574b8
    const char *address = NULL;
Packit f574b8
    char *cp = NULL;
Packit f574b8
    DocAddress WWWDoc;
Packit f574b8
    HTParentAnchor *underlying;
Packit f574b8
    BOOL old_cache_setting = LYforce_no_cache;
Packit f574b8
    BOOL old_reloading = reloading;
Packit f574b8
    HTFormat old_format_out = HTOutputFormat;
Packit f574b8
Packit f574b8
    if (isLYNXIMGMAP(arg)) {
Packit f574b8
	address = (arg + LEN_LYNXIMGMAP);
Packit f574b8
    }
Packit f574b8
    if (!(address && StrChr(address, ':'))) {
Packit f574b8
	HTAlert(MISDIRECTED_MAP_REQUEST);
Packit f574b8
	return (HT_NOT_LOADED);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    theList = get_the_list(&WWWDoc, address, anAnchor, &underlying);
Packit f574b8
    if (WWWDoc.safe)
Packit f574b8
	anAnchor->safe = TRUE;
Packit f574b8
Packit f574b8
    if (!theList) {
Packit f574b8
	if (anAnchor->post_data && !WWWDoc.safe &&
Packit f574b8
	    ((underlying && underlying->document && !LYforce_no_cache) ||
Packit f574b8
	     HTConfirm(CONFIRM_POST_RESUBMISSION) != TRUE)) {
Packit f574b8
	    HTAlert(FAILED_MAP_POST_REQUEST);
Packit f574b8
	    return (HT_NOT_LOADED);
Packit f574b8
	}
Packit f574b8
	LYforce_no_cache = TRUE;
Packit f574b8
	reloading = TRUE;
Packit f574b8
	HTOutputFormat = WWW_PRESENT;
Packit f574b8
	LYMapsOnly = TRUE;
Packit f574b8
	if (!HTLoadAbsolute(&WWWDoc)) {
Packit f574b8
	    LYforce_no_cache = old_cache_setting;
Packit f574b8
	    reloading = old_reloading;
Packit f574b8
	    HTOutputFormat = old_format_out;
Packit f574b8
	    LYMapsOnly = FALSE;
Packit f574b8
	    HTAlert(MAP_NOT_ACCESSIBLE);
Packit f574b8
	    return (HT_NOT_LOADED);
Packit f574b8
	}
Packit f574b8
	LYforce_no_cache = old_cache_setting;
Packit f574b8
	reloading = old_reloading;
Packit f574b8
	HTOutputFormat = old_format_out;
Packit f574b8
	LYMapsOnly = FALSE;
Packit f574b8
	theList = get_the_list(&WWWDoc, address, anAnchor, &underlying);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (!theList) {
Packit f574b8
	HTAlert(MAPS_NOT_AVAILABLE);
Packit f574b8
	return (HT_NOT_LOADED);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    cur = theList;
Packit f574b8
    while (NULL != (theMap = (LYImageMap *) HTList_nextObject(cur))) {
Packit f574b8
	if (!strcmp(theMap->address, address)) {
Packit f574b8
	    break;
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    if (theMap && HTList_count(theMap->elements) == 0) {
Packit f574b8
	/*
Packit f574b8
	 * We found a MAP without any usable AREA.  Fake a redirection to the
Packit f574b8
	 * address with fragment.  We do this even for post data (internal link
Packit f574b8
	 * within a document with post data) if it will not result in an
Packit f574b8
	 * unwanted network request.  - kw
Packit f574b8
	 */
Packit f574b8
	if (!anAnchor->post_data) {
Packit f574b8
	    StrAllocCopy(redirecting_url, address);
Packit f574b8
	    return (HT_REDIRECTING);
Packit f574b8
	} else if (WWWDoc.safe ||
Packit f574b8
		   (underlying->document && !anAnchor->document &&
Packit f574b8
		    (LYinternal_flag || LYoverride_no_cache))) {
Packit f574b8
	    StrAllocCopy(redirecting_url, address);
Packit f574b8
	    redirect_post_content = TRUE;
Packit f574b8
	    return (HT_REDIRECTING);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    if (!(theMap && theMap->elements)) {
Packit f574b8
	if (anAnchor->post_data && !WWWDoc.safe &&
Packit f574b8
	    ((underlying && underlying->document && !LYforce_no_cache) ||
Packit f574b8
	     HTConfirm(CONFIRM_POST_RESUBMISSION) != TRUE)) {
Packit f574b8
	    HTAlert(FAILED_MAP_POST_REQUEST);
Packit f574b8
	    return (HT_NOT_LOADED);
Packit f574b8
	}
Packit f574b8
	LYforce_no_cache = TRUE;
Packit f574b8
	reloading = TRUE;
Packit f574b8
	HTOutputFormat = WWW_PRESENT;
Packit f574b8
	LYMapsOnly = TRUE;
Packit f574b8
	if (!HTLoadAbsolute(&WWWDoc)) {
Packit f574b8
	    LYforce_no_cache = old_cache_setting;
Packit f574b8
	    reloading = old_reloading;
Packit f574b8
	    HTOutputFormat = old_format_out;
Packit f574b8
	    LYMapsOnly = FALSE;
Packit f574b8
	    HTAlert(MAP_NOT_ACCESSIBLE);
Packit f574b8
	    return (HT_NOT_LOADED);
Packit f574b8
	}
Packit f574b8
	LYforce_no_cache = old_cache_setting;
Packit f574b8
	reloading = old_reloading;
Packit f574b8
	HTOutputFormat = old_format_out;
Packit f574b8
	LYMapsOnly = FALSE;
Packit f574b8
	cur = get_the_list(&WWWDoc, address, anAnchor, &underlying);
Packit f574b8
	while (NULL != (theMap = (LYImageMap *) HTList_nextObject(cur))) {
Packit f574b8
	    if (!strcmp(theMap->address, address)) {
Packit f574b8
		break;
Packit f574b8
	    }
Packit f574b8
	}
Packit f574b8
	if (!(theMap && theMap->elements)) {
Packit f574b8
	    HTAlert(MAP_NOT_AVAILABLE);
Packit f574b8
	    return (HT_NOT_LOADED);
Packit f574b8
	}
Packit f574b8
    }
Packit f574b8
    if (track_internal_links)
Packit f574b8
	anAnchor->no_cache = TRUE;
Packit f574b8
Packit f574b8
    target = HTStreamStack(format_in,
Packit f574b8
			   format_out,
Packit f574b8
			   sink, anAnchor);
Packit f574b8
Packit f574b8
    if (target == NULL) {
Packit f574b8
	HTSprintf0(&buf, CANNOT_CONVERT_I_TO_O,
Packit f574b8
		   HTAtom_name(format_in), HTAtom_name(format_out));
Packit f574b8
	HTAlert(buf);
Packit f574b8
	FREE(buf);
Packit f574b8
	return (HT_NOT_LOADED);
Packit f574b8
    }
Packit f574b8
Packit f574b8
    if (non_empty(theMap->title)) {
Packit f574b8
	StrAllocCopy(MapTitle, theMap->title);
Packit f574b8
    } else if (non_empty(anAnchor->title)) {
Packit f574b8
	StrAllocCopy(MapTitle, anAnchor->title);
Packit f574b8
    } else if (non_empty(LYRequestTitle) &&
Packit f574b8
	       strcasecomp(LYRequestTitle, NO_MAP_TITLE)) {
Packit f574b8
	StrAllocCopy(MapTitle, LYRequestTitle);
Packit f574b8
    } else if ((cp = StrChr(address, '#')) != NULL) {
Packit f574b8
	StrAllocCopy(MapTitle, (cp + 1));
Packit f574b8
    }
Packit f574b8
    if (isEmpty(MapTitle)) {
Packit f574b8
	StrAllocCopy(MapTitle, NO_MAP_TITLE);
Packit f574b8
    } else {
Packit f574b8
	LYEntify(&MapTitle, TRUE);
Packit f574b8
    }
Packit f574b8
Packit f574b8
#define PUTS(buf)    (*target->isa->put_block)(target, buf, (int) strlen(buf))
Packit f574b8
Packit f574b8
    HTSprintf0(&buf, "<html>\n<head>\n");
Packit f574b8
    PUTS(buf);
Packit f574b8
    HTSprintf0(&buf, "<META %s content=\"" STR_HTML ";charset=%s\">\n",
Packit f574b8
	       "http-equiv=\"content-type\"",
Packit f574b8
	       LYCharSet_UC[current_char_set].MIMEname);
Packit f574b8
    PUTS(buf);
Packit f574b8
    /*
Packit f574b8
     * This page is a list of titles and anchors for them.  Since titles
Packit f574b8
     * already passed SGML/HTML stage they are converted to current_char_set. 
Packit f574b8
     * That is why we insist on META charset for this page.
Packit f574b8
     */
Packit f574b8
    HTSprintf0(&buf, "<title>%s</title>\n", MapTitle);
Packit f574b8
    PUTS(buf);
Packit f574b8
    HTSprintf0(&buf, "</head>\n<body>\n");
Packit f574b8
    PUTS(buf);
Packit f574b8
Packit f574b8
    HTSprintf0(&buf, "

%s

\n", MapTitle);
Packit f574b8
    PUTS(buf);
Packit f574b8
Packit f574b8
    StrAllocCopy(MapAddress, address);
Packit f574b8
    LYEntify(&MapAddress, FALSE);
Packit f574b8
    HTSprintf0(&buf, "

MAP: %s

\n", MapAddress);
Packit f574b8
    PUTS(buf);
Packit f574b8
Packit f574b8
    HTSprintf0(&buf, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ?
Packit f574b8
					"ol" : "ul"));
Packit f574b8
    PUTS(buf);
Packit f574b8
    cur = theMap->elements;
Packit f574b8
    while (NULL != (tmp = (LYMapElement *) HTList_nextObject(cur))) {
Packit f574b8
	StrAllocCopy(MapAddress, tmp->address);
Packit f574b8
	LYEntify(&MapAddress, FALSE);
Packit f574b8
	PUTS("
  • Packit f574b8
    	PUTS(MapAddress);
    Packit f574b8
    	PUTS("\"");
    Packit f574b8
    	if (track_internal_links && tmp->intern_flag) {
    Packit f574b8
    	    PUTS(" TYPE=\"internal link\"");
    Packit f574b8
    	}
    Packit f574b8
    	PUTS("\n>");
    Packit f574b8
    	LYformTitle(&MapTitle, tmp->title);
    Packit f574b8
    	LYEntify(&MapTitle, TRUE);
    Packit f574b8
    	PUTS(MapTitle);
    Packit f574b8
    	PUTS("\n");
    Packit f574b8
        }
    Packit f574b8
        HTSprintf0(&buf, "</%s>\n</body>\n</html>\n",
    Packit f574b8
    	       ((keypad_mode == NUMBERS_AS_ARROWS)
    Packit f574b8
    		? "ol"
    Packit f574b8
    		: "ul"));
    Packit f574b8
        PUTS(buf);
    Packit f574b8
    Packit f574b8
        (*target->isa->_free) (target);
    Packit f574b8
        FREE(MapAddress);
    Packit f574b8
        FREE(MapTitle);
    Packit f574b8
        FREE(buf);
    Packit f574b8
        return (HT_LOADED);
    Packit f574b8
    }
    Packit f574b8
    Packit f574b8
    void LYPrintImgMaps(FILE *fp)
    Packit f574b8
    {
    Packit f574b8
        const char *only = HTLoadedDocumentURL();
    Packit f574b8
        size_t only_len = strlen(only);
    Packit f574b8
        HTList *outer = LynxMaps;
    Packit f574b8
        HTList *inner;
    Packit f574b8
        LYImageMap *map;
    Packit f574b8
        LYMapElement *elt;
    Packit f574b8
        int count;
    Packit f574b8
    Packit f574b8
        if (HTList_count(outer) > 0) {
    Packit f574b8
    	while (NULL != (map = (LYImageMap *) HTList_nextObject(outer))) {
    Packit f574b8
    	    if (only_len != 0) {
    Packit f574b8
    		if (StrNCmp(only, map->address, only_len)
    Packit f574b8
    		    || (map->address[only_len] != '\0'
    Packit f574b8
    			&& map->address[only_len] != '#')) {
    Packit f574b8
    		    continue;
    Packit f574b8
    		}
    Packit f574b8
    	    }
    Packit f574b8
    	    fprintf(fp, "\n%s\n", isEmpty(map->title) ? NO_MAP_TITLE : map->title);
    Packit f574b8
    	    fprintf(fp, "%s\n", map->address);
    Packit f574b8
    	    inner = map->elements;
    Packit f574b8
    	    count = 0;
    Packit f574b8
    	    while (NULL != (elt = (LYMapElement *) HTList_nextObject(inner))) {
    Packit f574b8
    		fprintf(fp, "%4d. %s", ++count, elt->address);
    Packit f574b8
    		if (track_internal_links && elt->intern_flag)
    Packit f574b8
    		    fprintf(fp, " TYPE=\"internal link\"");
    Packit f574b8
    		fprintf(fp, "\n");
    Packit f574b8
    	    }
    Packit f574b8
    	}
    Packit f574b8
        }
    Packit f574b8
    }
    Packit f574b8
    Packit f574b8
    #ifdef GLOBALDEF_IS_MACRO
    Packit f574b8
    #define _LYIMGMAP_C_GLOBALDEF_1_INIT { "LYNXIMGMAP", LYLoadIMGmap, 0}
    Packit f574b8
    GLOBALDEF(HTProtocol, LYLynxIMGmap, _LYIMGMAP_C_GLOBALDEF_1_INIT);
    Packit f574b8
    #else
    Packit f574b8
    GLOBALDEF HTProtocol LYLynxIMGmap =
    Packit f574b8
    {"LYNXIMGMAP", LYLoadIMGmap, 0};
    Packit f574b8
    #endif /* GLOBALDEF_IS_MACRO */