/* Lynx Client-side Image MAP Support LYMap.c ** ================================== ** ** Author: FM Foteos Macrides (macrides@sci.wfbr.edu) ** */ #include "HTUtils.h" #include "tcp.h" #include "HTTP.h" #include "HTAnchor.h" #include "HTAccess.h" #include "HTFormat.h" #include "HTParse.h" #include "HTAlert.h" #include "LYUtils.h" #include "LYMap.h" #include "GridText.h" #include "LYSignal.h" #include "LYGlobalDefs.h" #include "LYKeymap.h" #include "LYCharUtils.h" #ifdef DIRED_SUPPORT #include "LYUpload.h" #include "LYLocal.h" #endif #include "LYexit.h" #include "LYLeaks.h" #define FREE(x) if (x) {free(x); x=NULL;} typedef struct _LYMapElement { char * address; char * title; BOOL intern_flag; } LYMapElement; typedef struct _LYImageMap { char * address; char * title; HTList * elements; } LYImageMap; struct _HTStream { HTStreamClass * isa; }; PRIVATE HTList * LynxMaps = NULL; PUBLIC BOOL LYMapsOnly = FALSE; /* * Utility for freeing the list of MAPs. - FM */ PRIVATE void LYLynxMaps_free NOARGS { LYImageMap *map; LYMapElement *element; HTList *cur = LynxMaps; HTList *current; if (!cur) return; while (NULL != (map = (LYImageMap *)HTList_nextObject(cur))) { FREE(map->address); FREE(map->title); if (map->elements) { current = map->elements; while (NULL != (element = (LYMapElement *)HTList_nextObject(current))) { FREE(element->address); FREE(element->title); FREE(element); } HTList_delete(map->elements); map->elements = NULL; } FREE(map); } HTList_delete(LynxMaps); LynxMaps = NULL; return; } /* * Utility for creating an LYImageMap list (LynxMaps), if it doesn't * exist already, adding LYImageMap entry structures if needed, and * removing any LYMapElements in a pre-existing LYImageMap entry so that * it will have only those from AREA tags for the current analysis of * MAP element content. - FM */ PUBLIC BOOL LYAddImageMap ARGS2( char *, address, char *, title) { LYImageMap *new = NULL; LYImageMap *old = NULL; HTList *cur = NULL; HTList *curele = NULL; LYMapElement *ele = NULL; if (!(address && *address)) return FALSE; if (!LynxMaps) { LynxMaps = HTList_new(); atexit(LYLynxMaps_free); } else { cur = LynxMaps; while (NULL != (old = (LYImageMap *)HTList_nextObject(cur))) { if (!strcmp(old->address, address)) { FREE(old->address); FREE(old->title); if (old->elements) { curele = old->elements; while (NULL != (ele = (LYMapElement *)HTList_nextObject(curele))) { FREE(ele->address); FREE(ele->title); FREE(ele); } HTList_delete(old->elements); old->elements = NULL; } break; } } } new = (old != NULL) ? old : (LYImageMap *)calloc(1, sizeof(LYImageMap)); if (new == NULL) { perror("Out of memory in LYAddImageMap"); return FALSE; } StrAllocCopy(new->address, address); if (title && *title) StrAllocCopy(new->title, title); if (new != old) HTList_addObject(LynxMaps, new); return TRUE; } /* * Utility for adding LYMapElements to LYImageMaps * in the LynxMaps list. - FM */ PUBLIC BOOL LYAddMapElement ARGS4( char *, map, char *, address, char *, title, BOOL, intern_flag) { LYMapElement *new = NULL; LYImageMap *theMap = NULL; HTList *cur = NULL; if (!(map && *map && address && *address)) return FALSE; if (!LynxMaps) LYAddImageMap(map, NULL); cur = LynxMaps; while (NULL != (theMap = (LYImageMap *)HTList_nextObject(cur))) { if (!strcmp(theMap->address, map)) { break; } } if (!theMap) return FALSE; if (!theMap->elements) theMap->elements = HTList_new(); cur = theMap->elements; while (NULL != (new = (LYMapElement *)HTList_nextObject(cur))) { if (!strcmp(new->address, address)) { FREE(new->address); FREE(new->title); HTList_removeObject(theMap->elements, new); FREE(new); break; } } new = (LYMapElement *)calloc(1, sizeof(LYMapElement)); if (new == NULL) { perror("Out of memory in LYAddMapElement"); return FALSE; } StrAllocCopy(new->address, address); if (title && *title) StrAllocCopy(new->title, title); else StrAllocCopy(new->title, address); new->intern_flag = intern_flag; HTList_appendObject(theMap->elements, new); return TRUE; } /* * Utility for checking whether an LYImageMap entry * with a given address already exists in the LynxMaps * structure. - FM */ PUBLIC BOOL LYHaveImageMap ARGS1( char *, address) { LYImageMap *Map; HTList *cur = LynxMaps; if (!(cur && address && *address != '\0')) return FALSE; while (NULL != (Map = (LYImageMap *)HTList_nextObject(cur))) { if (!strcmp(Map->address, address)) { return TRUE; } } return FALSE; } /* LYLoadIMGmap - F.Macrides (macrides@sci.wfeb.edu) ** ------------ ** Create a text/html stream with a list of links ** for HyperText References in AREAs of a MAP. */ PRIVATE int LYLoadIMGmap ARGS4 ( CONST char *, arg, HTParentAnchor *, anAnchor, HTFormat, format_out, HTStream*, sink) { HTFormat format_in = WWW_HTML; HTStream *target = NULL; char buf[1024]; LYMapElement *new = NULL; LYImageMap *theMap = NULL; char *MapTitle = NULL; char *MapAddress = NULL; HTList *cur = NULL; char *address = NULL; char *cp = NULL; DocAddress WWWDoc; BOOL old_cache_setting = LYforce_no_cache; BOOL old_reloading = reloading; HTFormat old_format_out = HTOutputFormat; if (!strncasecomp(arg, "LYNXIMGMAP:", 11)) { address = (char * )(arg + 11); } if (!(address && strchr(address, ':'))) { HTAlert(MISDIRECTED_MAP_REQUEST); return(HT_NOT_LOADED); } if (!LynxMaps) { WWWDoc.address = address; WWWDoc.post_data = NULL; WWWDoc.post_content_type = NULL; WWWDoc.bookmark = NULL; WWWDoc.isHEAD = FALSE; WWWDoc.safe = FALSE; LYforce_no_cache = TRUE; reloading = TRUE; HTOutputFormat = WWW_PRESENT; LYMapsOnly = TRUE; if (!HTLoadAbsolute(&WWWDoc)) { LYforce_no_cache = old_cache_setting; reloading = old_reloading; HTOutputFormat = old_format_out; LYMapsOnly = FALSE; HTAlert(MAP_NOT_ACCESSIBLE); return(HT_NOT_LOADED); } LYforce_no_cache = old_cache_setting; reloading = old_reloading; HTOutputFormat = old_format_out; LYMapsOnly = FALSE; } if (!LynxMaps) { HTAlert(MAPS_NOT_AVAILABLE); return(HT_NOT_LOADED); } cur = LynxMaps; while (NULL != (theMap = (LYImageMap *)HTList_nextObject(cur))) { if (!strcmp(theMap->address, address)) { break; } } if (!(theMap && theMap->elements)) { WWWDoc.address = address; WWWDoc.post_data = NULL; WWWDoc.post_content_type = NULL; WWWDoc.bookmark = NULL; WWWDoc.isHEAD = FALSE; WWWDoc.safe = FALSE; LYforce_no_cache = TRUE; reloading = TRUE; HTOutputFormat = WWW_PRESENT; LYMapsOnly = TRUE; if (!HTLoadAbsolute(&WWWDoc)) { LYforce_no_cache = old_cache_setting; reloading = old_reloading; HTOutputFormat = old_format_out; LYMapsOnly = FALSE; HTAlert(MAP_NOT_ACCESSIBLE); return(HT_NOT_LOADED); } LYforce_no_cache = old_cache_setting; reloading = old_reloading; HTOutputFormat = old_format_out; LYMapsOnly = FALSE; cur = LynxMaps; while (NULL != (theMap = (LYImageMap *)HTList_nextObject(cur))) { if (!strcmp(theMap->address, address)) { break; } } if (!(theMap && theMap->elements)) { HTAlert(MAP_NOT_AVAILABLE); return(HT_NOT_LOADED); } } anAnchor->no_cache = TRUE; target = HTStreamStack(format_in, format_out, sink, anAnchor); if (!target || target == NULL) { sprintf(buf, CANNOT_CONVERT_I_TO_O, HTAtom_name(format_in), HTAtom_name(format_out)); HTAlert(buf); return(HT_NOT_LOADED); } if (theMap->title && *theMap->title) { StrAllocCopy(MapTitle, theMap->title); } else if (anAnchor->title && *anAnchor->title) { StrAllocCopy(MapTitle, anAnchor->title); } else if (LYRequestTitle && *LYRequestTitle && strcasecomp(LYRequestTitle, "[USEMAP]")) { StrAllocCopy(MapTitle, LYRequestTitle); } else if ((cp=strrchr(address, '#')) != NULL) { StrAllocCopy(MapTitle, (cp+1)); } if (!(MapTitle && *MapTitle)) { StrAllocCopy(MapTitle, "[USEMAP]"); } else { LYEntify(&MapTitle, TRUE); } sprintf(buf,"\n%s\n\n\n", MapTitle); (*target->isa->put_block)(target, buf, strlen(buf)); sprintf(buf,"

%s

\n", MapTitle); (*target->isa->put_block)(target, buf, strlen(buf)); StrAllocCopy(MapAddress, address); LYEntify(&MapAddress, FALSE); sprintf(buf,"

MAP: %s

\n", MapAddress); (*target->isa->put_block)(target, buf, strlen(buf)); sprintf(buf, "<%s compact>\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); (*target->isa->put_block)(target, buf, strlen(buf)); cur = theMap->elements; while (NULL != (new=(LYMapElement *)HTList_nextObject(cur))) { StrAllocCopy(MapAddress, new->address); LYEntify(&MapAddress, FALSE); (*target->isa->put_block)(target, "
  • isa->put_block)(target, MapAddress, strlen(MapAddress)); if (new->intern_flag) (*target->isa->put_block)(target, "\" TYPE=\"internal link\"\n>",24); else (*target->isa->put_block)(target, "\"\n>", 3); StrAllocCopy(MapTitle, new->title); LYEntify(&MapTitle, TRUE); (*target->isa->put_block)(target, MapTitle, strlen(MapTitle)); (*target->isa->put_block)(target, "\n", 5); } sprintf(buf,"\n\n", ((keypad_mode == NUMBERS_AS_ARROWS) ? "ol" : "ul")); (*target->isa->put_block)(target, buf, strlen(buf)); (*target->isa->_free)(target); FREE(MapAddress); FREE(MapTitle); return(HT_LOADED); } #ifdef GLOBALDEF_IS_MACRO #define _LYIMGMAP_C_GLOBALDEF_1_INIT { "LYNXIMGMAP", LYLoadIMGmap, 0} GLOBALDEF (HTProtocol,LYLynxIMGmap,_LYIMGMAP_C_GLOBALDEF_1_INIT); #else GLOBALDEF PUBLIC HTProtocol LYLynxIMGmap = {"LYNXIMGMAP", LYLoadIMGmap, 0}; #endif /* GLOBALDEF_IS_MACRO */