diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/DefaultStyle.c | 100 | ||||
-rw-r--r-- | src/GridText.c | 299 | ||||
-rw-r--r-- | src/GridText.h | 4 | ||||
-rw-r--r-- | src/HTAlert.c | 90 | ||||
-rw-r--r-- | src/HTAlert.h | 4 | ||||
-rw-r--r-- | src/HTFWriter.c | 147 | ||||
-rw-r--r-- | src/HTFont.h | 2 | ||||
-rw-r--r-- | src/HTInit.c | 9 | ||||
-rw-r--r-- | src/HTML.c | 75 | ||||
-rw-r--r-- | src/HTML.h | 4 | ||||
-rw-r--r-- | src/LYCharUtils.c | 103 | ||||
-rw-r--r-- | src/LYCookie.c | 430 | ||||
-rw-r--r-- | src/LYCurses.c | 6 | ||||
-rw-r--r-- | src/LYForms.c | 3 | ||||
-rw-r--r-- | src/LYGetFile.c | 52 | ||||
-rw-r--r-- | src/LYLocal.c | 4 | ||||
-rw-r--r-- | src/LYMain.c | 4 | ||||
-rw-r--r-- | src/LYMainLoop.c | 63 | ||||
-rw-r--r-- | src/LYOptions.c | 3 | ||||
-rw-r--r-- | src/LYShowInfo.c | 3 | ||||
-rw-r--r-- | src/LYUtils.c | 122 | ||||
-rw-r--r-- | src/Makefile | 1 | ||||
-rw-r--r-- | src/UCAux.c | 5 | ||||
-rw-r--r-- | src/UCdomap.c | 3 | ||||
-rw-r--r-- | src/chrtrans/MAKEW32.BAT | 4 | ||||
-rw-r--r-- | src/chrtrans/Makefile | 1 | ||||
-rw-r--r-- | src/chrtrans/build-chrtrans.com | 2 | ||||
-rw-r--r-- | src/chrtrans/cp1251_uni.tbl | 1 | ||||
-rw-r--r-- | src/chrtrans/cp866_uni.tbl | 189 | ||||
-rw-r--r-- | src/chrtrans/koi8r_uni.tbl | 14 | ||||
-rw-r--r-- | src/chrtrans/makefile.in | 1 | ||||
-rw-r--r-- | src/makefile.in | 1 |
32 files changed, 1197 insertions, 552 deletions
diff --git a/src/DefaultStyle.c b/src/DefaultStyle.c index 974a27db..140f0a77 100644 --- a/src/DefaultStyle.c +++ b/src/DefaultStyle.c @@ -38,324 +38,324 @@ PRIVATE HTTabStop tabs_16[] = { PRIVATE HTStyle HTStyleNormal = { 0, "Normal", "P", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 3, 6, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleDivCenter = { &HTStyleNormal, "DivCenter", "DCENTER", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 3, 6, HT_CENTER, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleDivLeft = { &HTStyleDivCenter, "DivLeft", "DLEFT", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 3, 6, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleDivRight = { &HTStyleDivLeft, "DivRight", "DRIGHT", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 3, 6, HT_RIGHT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleBanner = { &HTStyleDivRight, "Banner", "BANNER", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 3, 6, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleBlockquote = { &HTStyleBanner, "Blockquote", "BLOCKQUOTE", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 5, 5, 7, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleBq = { /* HTML 3.0 BLOCKQUOTE - FM */ &HTStyleBlockquote, "Bq", "BQ", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 5, 5, 7, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleFootnote = { /* HTML 3.0 FN - FM */ &HTStyleBq, "Footnote", "FN", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 5, 5, 7, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleList = { &HTStyleFootnote, "List", "UL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 7, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleList1 = { &HTStyleList, "List1", "UL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 8, 12, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleList2 = { &HTStyleList1, "List2", "UL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 13, 17, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleList3 = { &HTStyleList2, "List3", "UL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 18, 22, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleList4 = { &HTStyleList3, "List4", "UL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 23, 27, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleList5 = { &HTStyleList4, "List5", "UL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 28, 32, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleList6 = { &HTStyleList5, "List6", "UL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 33, 37, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleMenu = { &HTStyleList6, "Menu", "MENU", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 7, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleMenu1 = { &HTStyleMenu, "Menu1", "MENU", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 8, 12, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleMenu2= { &HTStyleMenu1, "Menu2", "MENU", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 13, 17, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleMenu3= { &HTStyleMenu2, "Menu3", "MENU", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 18, 22, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleMenu4= { &HTStyleMenu3, "Menu4", "MENU", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 23, 27, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleMenu5= { &HTStyleMenu4, "Menu5", "MENU", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 28, 33, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleMenu6= { &HTStyleMenu5, "Menu6", "MENU", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 33, 38, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleGlossary = { &HTStyleMenu6, "Glossary", "DL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 10, 6, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleGlossary1 = { &HTStyleGlossary, "Glossary1", "DL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 8, 16, 6, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleGlossary2 = { &HTStyleGlossary1, "Glossary2", "DL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 14, 22, 6, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleGlossary3 = { &HTStyleGlossary2, "Glossary3", "DL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 20, 28, 6, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleGlossary4 = { &HTStyleGlossary3, "Glossary4", "DL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 26, 34, 6, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleGlossary5 = { &HTStyleGlossary4, "Glossary5", "DL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 32, 40, 6, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleGlossary6 = { &HTStyleGlossary5, "Glossary6", "DL", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 38, 46, 6, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleGlossaryCompact = { &HTStyleGlossary6, "GlossaryCompact", "DLC", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 3, 10, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleGlossaryCompact1 = { &HTStyleGlossaryCompact, "GlossaryCompact1", "DLC", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 8, 15, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleGlossaryCompact2 = { &HTStyleGlossaryCompact1, "GlossaryCompact2", "DLC", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 13, 20, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleGlossaryCompact3 = { &HTStyleGlossaryCompact2, "GlossaryCompact3", "DLC", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 18, 25, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleGlossaryCompact4 = { &HTStyleGlossaryCompact3, "GlossaryCompact4", "DLC", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 23, 30, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleGlossaryCompact5 = { &HTStyleGlossaryCompact4, "GlossaryCompact5", "DLC", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 28, 35, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleGlossaryCompact6 = { &HTStyleGlossaryCompact5, "GlossaryCompact6", "DLC", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 33, 40, 6, HT_LEFT, 1, 0, 0, YES, YES, 0, 0, 0 }; PRIVATE HTStyle HTStyleExample = { &HTStyleGlossaryCompact6, "Example", "XMP", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 0, 0, 0, HT_LEFT, 1, 0, tabs_8, NO, NO, 0, 0, 0 }; PRIVATE HTStyle HTStylePreformatted = { &HTStyleExample, "Preformatted", "PRE", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 0, 0, 0, HT_LEFT, 1, 0, tabs_8, NO, NO, 0, 0, 0 }; PRIVATE HTStyle HTStyleListing = { &HTStylePreformatted, "Listing", "LISTING", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 0, 0, 0, HT_LEFT, 1, 0, tabs_8, NO, NO, 0, 0, 0 }; PRIVATE HTStyle HTStyleAddress = { &HTStyleListing, "Address", "ADDRESS", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 4, 4, 7, HT_LEFT, 1, 0, tabs_8, YES, YES, 2, 0, 0 }; PRIVATE HTStyle HTStyleNote = { /* HTML 3.0 NOTE - FM */ &HTStyleAddress, "Note", "NOTE", - HT_FONT, 1.0, HT_BLACK, 0, 0, + HT_FONT, 1, HT_BLACK, 0, 0, 5, 5, 7, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleHeading1 = { &HTStyleNote, "Heading1", "H1", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 0, 0, 0, HT_CENTER, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleHeading2 = { &HTStyleHeading1, "Heading2", "H2", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 0, 0, 0, HT_LEFT, 1, 0, 0, YES, YES, 1, 1, 0 }; PRIVATE HTStyle HTStyleHeading3 = { &HTStyleHeading2, "Heading3", "H3", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 2, 2, 0, HT_LEFT, 1, 0, 0, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleHeading4 = { &HTStyleHeading3, "Heading4", "H4", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 4, 4, 0, HT_LEFT, 1, 0, 0, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleHeading5 = { &HTStyleHeading4, "Heading5", "H5", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 6, 6, 0, HT_LEFT, 1, 0, 0, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleHeading6 = { &HTStyleHeading5, "Heading6", "H6", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 8, 8, 0, HT_LEFT, 1, 0, 0, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleHeadingCenter = { &HTStyleHeading6, "HeadingCenter", "HCENTER", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 0, 0, 3, HT_CENTER, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleHeadingLeft = { &HTStyleHeadingCenter, "HeadingLeft", "HLEFT", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 0, 0, 3, HT_LEFT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; PRIVATE HTStyle HTStyleHeadingRight = { &HTStyleHeadingLeft, "HeadingRight", "HRIGHT", - HT_FONT+HT_BOLD, 1.0, HT_BLACK, 0, 0, + HT_FONT+HT_BOLD, 1, HT_BLACK, 0, 0, 0, 0, 3, HT_RIGHT, 1, 0, tabs_8, YES, YES, 1, 0, 0 }; diff --git a/src/GridText.c b/src/GridText.c index 0f764f49..e1c414d6 100644 --- a/src/GridText.c +++ b/src/GridText.c @@ -230,7 +230,7 @@ PRIVATE int ctrl_chars_on_this_line = 0; /* num of ctrl chars in current line */ PRIVATE HTStyle default_style = { 0, "(Unstyled)", "", - (HTFont)0, 1.0, HT_BLACK, 0, 0, + (HTFont)0, 1, HT_BLACK, 0, 0, 0, 0, 0, HT_LEFT, 1, 0, 0, NO, NO, 0, 0, 0 }; @@ -1834,10 +1834,18 @@ PRIVATE void split_line ARGS2( */ if (split > 0) { for (a = text->first_anchor; a; a = a->next) { - if (a->line_num == CurLine && a->line_pos >= split) { - a->start += (1 + SpecialAttrChars - HeadTrim - TailTrim); - a->line_pos -= (split - SpecialAttrChars + HeadTrim); - a->line_num = text->Lines; + if (a->line_num == CurLine) { + if (a->line_pos >= split) { + a->start += (1 + SpecialAttrChars - HeadTrim - TailTrim); + a->line_pos -= (split - SpecialAttrChars + HeadTrim); + a->line_num = text->Lines; + } else if ((a->link_type & HYPERTEXT_ANCHOR) && + (a->line_pos + a->extent) >= split) { + a->extent -= (TailTrim + HeadTrim); + if (a->extent < 0) { + a->extent = 0; + } + } } } } @@ -2431,8 +2439,8 @@ PUBLIC int HText_beginAnchor ARGS3( if (a == NULL) outofmem(__FILE__, "HText_beginAnchor"); - a->hightext = 0; - a->hightext2 = 0; + a->hightext = NULL; + a->hightext2 = NULL; a->start = text->chars + text->last_line->size; a->inUnderline = underline; @@ -2946,7 +2954,7 @@ PRIVATE void remove_special_attr_chars ARGS1( PUBLIC void HText_endAppend ARGS1( HText *, text) { - int cur_line, cur_char, cur_shift; + int cur_line, cur_char, cur_shift, len; TextAnchor *anchor_ptr; HTLine *line_ptr; unsigned char ch; @@ -3084,16 +3092,41 @@ re_parse: * Double check that we have a line pointer, * and if so, copy into hightext2. */ - if (line_ptr) { + if (line_ptr2) { StrnAllocCopy(anchor_ptr->hightext2, line_ptr2->data, (anchor_ptr->extent - strlen(anchor_ptr->hightext))); anchor_ptr->hightext2offset = line_ptr2->offset; remove_special_attr_chars(anchor_ptr->hightext2); + if (anchor_ptr->link_type & HYPERTEXT_ANCHOR) { + if ((len = strlen(anchor_ptr->hightext2)) > 0) { + len--; + while (len >= 0 && + isspace((unsigned char) + anchor_ptr->hightext2[len])) { + anchor_ptr->hightext2[len] = '\0'; + len--; + } + } + if (len <= 0 && anchor_ptr->hightext2[0] == '\0') { + FREE(anchor_ptr->hightext2); + anchor_ptr->hightext2offset = 0; + } + } } - } + } remove_special_attr_chars(anchor_ptr->hightext); + if (anchor_ptr->link_type & HYPERTEXT_ANCHOR) { + if ((len = strlen(anchor_ptr->hightext)) > 0) { + len--; + while (len >= 0 && + isspace((unsigned char)anchor_ptr->hightext[len])) { + anchor_ptr->hightext[len] = '\0'; + len--; + } + } + } /* * Subtract any formatting characters from the x position @@ -3511,7 +3544,7 @@ PUBLIC BOOL HText_getFirstTargetInLine ARGS7( */ PUBLIC int HText_getNumOfLines NOARGS { - return(HTMainText ? HTMainText->Lines : 0); + return(HTMainText ? HTMainText->Lines : 0); } /* @@ -3520,7 +3553,7 @@ PUBLIC int HText_getNumOfLines NOARGS */ PUBLIC char * HText_getTitle NOARGS { - return(HTMainText ? + return(HTMainText ? (char *) HTAnchor_title(HTMainText->node_anchor) : NULL); } @@ -3535,21 +3568,212 @@ PUBLIC char *HText_getStyle NOARGS /* * HText_getSugFname returns the suggested filename of the current * document (normally derived from a Content-Disposition header with - * file; filename=name.suffix). - FM + * attachment; filename=name.suffix). - FM */ PUBLIC char * HText_getSugFname NOARGS { - return(HTMainText ? + return(HTMainText ? (char *) HTAnchor_SugFname(HTMainText->node_anchor) : NULL); } /* + * HTCheckFnameForCompression receives the address of an allocated + * string containing a filename, and an anchor pointer, and expands + * or truncates the string's suffix if appropriate, based on whether + * the anchor indicates that the file is compressed. We assume + * that the file was not uncompressed (as when downloading), and + * believe the headers about whether it's compressed or not. - FM + * + * Added third arg - if strip_ok is FALSE, we don't trust the anchor + * info enough to remove a compression suffix if the anchor object + * does not indicate compression. - kw + */ +PUBLIC void HTCheckFnameForCompression ARGS3( + char **, fname, + HTParentAnchor *, anchor, + BOOL, strip_ok) +{ + char *fn = *fname; + char *dot = NULL, *cp = NULL; + CONST char *ct = NULL; + CONST char *ce = NULL; + BOOLEAN method = 0; + + /* + * Make sure we have a string and anchor. - FM + */ + if (!(fn && *fn && anchor)) + return; + + /* + * Make sure we have a file, not directory, name. -FM + */ + if ((cp = strrchr(fn, '/')) != NULL) { + fn = (cp +1); + if (*fn == '\0') { + return; + } + } + + /* + * Check the anchor's content_type and content_encoding + * elements for a gzip or Unix compressed file. - FM + */ + ct = HTAnchor_content_type(anchor); + ce = HTAnchor_content_encoding(anchor); + if (ce == NULL) { + /* + * No Content-Encoding, so check + * the Content-Type. - FM + */ + if (!strncasecomp((ct ? ct : ""), "application/gzip", 16) || + !strncasecomp((ct ? ct : ""), "application/x-gzip", 18)) { + method = 1; + } else if (!strncasecomp((ct ? ct : ""), + "application/compress", 20) || + !strncasecomp((ct ? ct : ""), + "application/x-compress", 22)) { + method = 2; + } + } else if (!strcasecomp(ce, "gzip") || + !strcasecomp(ce, "x-gzip")) { + /* + * It's gzipped. - FM + */ + method = 1; + } else if (!strcasecomp(ce, "compress") || + !strcasecomp(ce, "x-compress")) { + /* + * It's Unix compressed. - FM + */ + method = 2; + } + + /* + * If no Content-Encoding has been detected via the anchor + * pointer, but strip_ok is not set, there is nothing left + * to do. - kw + */ + if (method == 0 && !strip_ok) + return; + + /* + * Seek the last dot, and check whether + * we have a gzip or compress suffix. - FM + */ + if ((dot = strrchr(fn, '.')) != NULL) { + if (!strcasecomp(dot, ".tgz") || + !strcasecomp(dot, ".gz") || + !strcasecomp(dot, ".Z")) { + if (!method) { + /* + * It has a suffix which signifies a gzipped + * or compressed file for us, but the anchor + * claims otherwise, so tweak the suffix. - FM + */ + cp = (dot + 1); + *dot = '\0'; + if (!strcasecomp(cp, "tgz")) { + StrAllocCat(*fname, ".tar"); + } + } + return; + } + if (strlen(dot) > 4) { + cp = ((dot + strlen(dot)) - 3); + if (!strcasecomp(cp, "-gz") || + !strcasecomp(cp, "_gz")) { + if (!method) { + /* + * It has a tail which signifies a gzipped + * file for us, but the anchor claims otherwise, + * so tweak the suffix. - FM + */ + *dot = '\0'; + } else { + /* + * The anchor claims it's gzipped, and we + * believe it, so force this tail to the + * conventional suffix. - FM + */ +#ifdef VMS + *cp = '-'; +#else + *cp = '.'; +#endif /* VMS */ + cp++; + *cp = TOLOWER(*cp); + cp++; + *cp = TOLOWER(*cp); + } + return; + } + } + if (strlen(dot) > 3) { + cp = ((dot + strlen(dot)) - 2); + if (!strcasecomp(cp, "-Z") || + !strcasecomp(cp, "_Z")) { + if (!method) { + /* + * It has a tail which signifies a compressed + * file for us, but the anchor claims otherwise, + * so tweak the suffix. - FM + */ + *dot = '\0'; + } else { + /* + * The anchor claims it's compressed, and + * we believe it, so force this tail to the + * conventional suffix. - FM + */ +#ifdef VMS + *cp = '-'; +#else + *cp = '.'; +#endif /* VMS */ + cp++; + *cp = TOUPPER(*cp); + } + return; + } + } + } + if (!method) { + /* + * Don't know what compression method + * was used, if any, so we won't do + * anything. - FM + */ + return; + } + + /* + * Add the appropriate suffix. - FM + */ + if (!dot) { + StrAllocCat(*fname, ((method == 1) ? ".gz" : ".Z")); + return; + } + dot++; + if (*dot == '\0') { + StrAllocCat(*fname, ((method == 1) ? "gz" : "Z")); + return; + } +#ifdef VMS + StrAllocCat(*fname, ((method == 1) ? "-gz" : "-Z")); +#else + StrAllocCat(*fname, ((method == 1) ? ".gz" : ".Z")); +#endif /* !VMS */ + return; +} + +/* * HText_getLastModified returns the Last-Modified header * if available, for the current document. - FM */ PUBLIC char * HText_getLastModified NOARGS { - return(HTMainText ? + return(HTMainText ? (char *) HTAnchor_last_modified(HTMainText->node_anchor) : NULL); } @@ -3559,7 +3783,7 @@ PUBLIC char * HText_getLastModified NOARGS */ PUBLIC char * HText_getDate NOARGS { - return(HTMainText ? + return(HTMainText ? (char *) HTAnchor_date(HTMainText->node_anchor) : NULL); } @@ -3569,7 +3793,7 @@ PUBLIC char * HText_getDate NOARGS */ PUBLIC char * HText_getServer NOARGS { - return(HTMainText ? + return(HTMainText ? (char *)HTAnchor_server(HTMainText->node_anchor) : NULL); } @@ -4258,10 +4482,22 @@ PUBLIC void print_wwwfile_to_fd ARGS2( fputc(' ',fp); /* add data */ - for (i = 0; line->data[i] != '\0'; i++) - if (!IsSpecialAttrChar(line->data[i])) + for (i = 0; line->data[i] != '\0'; i++) { + if (!IsSpecialAttrChar(line->data[i])) { fputc(line->data[i],fp); - else if (dump_output_immediately && use_underscore) { + } else if (line->data[i] == LY_SOFT_HYPHEN && + line->data[i + 1] == '\0') { /* last char on line */ + if (dump_output_immediately && + LYRawMode && + LYlowest_eightbit[current_char_set] <= 173 && + (current_char_set == 0 || + LYCharSet_UC[current_char_set].enc == UCT_ENC_8859 || + LYCharSet_UC[current_char_set].like8859 & UCT_R_8859SPECL)) { + fputc(0xad, fp); /* the iso8859 byte for SHY */ + } else { + fputc('-', fp); + } + } else if (dump_output_immediately && use_underscore) { switch (line->data[i]) { case LY_UNDERLINE_START_CHAR: case LY_UNDERLINE_END_CHAR: @@ -4271,7 +4507,9 @@ PUBLIC void print_wwwfile_to_fd ARGS2( case LY_BOLD_END_CHAR: break; } - } + } + } + /* add the return */ fputc('\n',fp); @@ -4320,10 +4558,23 @@ PUBLIC void print_crawl_to_fd ARGS3( /* * Add data. */ - for (i = 0; line->data[i] != '\0'; i++) - if (!IsSpecialAttrChar(line->data[i])) + for (i = 0; line->data[i] != '\0'; i++) { + if (!IsSpecialAttrChar(line->data[i])) { fputc(line->data[i],fp); - + } else if (line->data[i] == LY_SOFT_HYPHEN && + line->data[i + 1] == '\0') { /* last char on line */ + if (dump_output_immediately && + LYRawMode && + LYlowest_eightbit[current_char_set] <= 173 && + (current_char_set == 0 || + LYCharSet_UC[current_char_set].enc == UCT_ENC_8859 || + LYCharSet_UC[current_char_set].like8859 & UCT_R_8859SPECL)) { + fputc(0xad, fp); /* the iso8859 byte for SHY */ + } else { + fputc('-', fp); + } + } + } /* * Add the return. */ diff --git a/src/GridText.h b/src/GridText.h index 92c2d40f..fbd8455d 100644 --- a/src/GridText.h +++ b/src/GridText.h @@ -71,6 +71,10 @@ extern void HText_setStale PARAMS((HText * text)); extern void HText_refresh PARAMS((HText * text)); extern char * HText_getTitle NOPARAMS; extern char * HText_getSugFname NOPARAMS; +extern void HTCheckFnameForCompression PARAMS(( + char ** fname, + HTParentAnchor * anchor, + BOOLEAN strip_ok)); extern char * HText_getLastModified NOPARAMS; extern char * HText_getDate NOPARAMS; extern char * HText_getServer NOPARAMS; diff --git a/src/HTAlert.c b/src/HTAlert.c index 926a2b71..93fb0fed 100644 --- a/src/HTAlert.c +++ b/src/HTAlert.c @@ -421,39 +421,75 @@ PUBLIC BOOL HTConfirmCookie ARGS6( ** ** On entry, ** Redirecting_url is the Location. +** server_status is the server status code. ** ** On exit, ** Returns 0 on cancel, ** 1 for redirect of POST with content, ** 303 for redirect as GET without content */ -PUBLIC int HTConfirmPostRedirect ARGS1( - CONST char *, Redirecting_url) +PUBLIC int HTConfirmPostRedirect ARGS2( + CONST char *, Redirecting_url, + int, server_status) { char *show_POST_url = NULL; + char StatusInfo[256]; char url[256]; int on_screen = 0; /* 0 - show menu * 1 - show url * 2 - menu is already on screen */ - if (dump_output_immediately) + if (server_status == 303 || + server_status == 302) { /* - ** Treat as 303 (GET without content) if not interactive. - */ - return 303; + * HTTP.c should not have called us for either of + * these because we're treating 302 as historical, + * so just return 303. - FM + */ + return 303; + } + + if (dump_output_immediately) + if (server_status == 301) { + /* + ** Treat 301 as historical, i.e., like 303 (GET + ** without content), when not interactive. - FM + */ + return 303; + } else { + /* + ** Treat anything else (e.g., 305, 306 or 307) as too + ** dangerous to redirect without confirmation, and thus + ** cancel when not interactive. - FM + */ + return 0; + } + StatusInfo[254] = StatusInfo[255] = '\0'; + url[254] = url[(LYcols < 250 ? LYcols-1 : 255)] = '\0'; if (user_mode == NOVICE_MODE) { on_screen = 2; move(LYlines-2, 0); - addstr(SERVER_ASKED_FOR_REDIRECTION); + sprintf(StatusInfo, SERVER_ASKED_FOR_REDIRECTION, server_status); + addstr(StatusInfo); clrtoeol(); move(LYlines-1, 0); sprintf(url, "URL: %.*s", (LYcols < 250 ? LYcols-6 : 250), Redirecting_url); addstr(url); clrtoeol(); - _statusline(PROCEED_GET_CANCEL); + if (server_status == 301) { + _statusline(PROCEED_GET_CANCEL); + } else { + _statusline(PROCEED_OR_CANCEL); + } } else { + sprintf(StatusInfo, "%d %.*s", + server_status, + 251, + ((server_status == 301) ? + ADVANCED_POST_GET_REDIRECT : + ADVANCED_POST_REDIRECT)); StrAllocCopy(show_POST_url, LOCATION_HEADER); StrAllocCat(show_POST_url, Redirecting_url); } @@ -462,7 +498,7 @@ PUBLIC int HTConfirmPostRedirect ARGS1( switch (on_screen) { case 0: - _statusline(ADVANCED_POST_REDIRECT); + _statusline(StatusInfo); break; case 1: _statusline(show_POST_url); @@ -471,8 +507,8 @@ PUBLIC int HTConfirmPostRedirect ARGS1( switch (TOUPPER(c)) { case 'P': /* - ** Proceed with 301 or 302 redirect of POST - ** (we check only for 0 and 303 in HTTP.c). + ** Proceed with 301 or 307 redirect of POST + ** with same method and POST content. - FM */ FREE(show_POST_url); return 1; @@ -480,37 +516,43 @@ PUBLIC int HTConfirmPostRedirect ARGS1( case 7: case 'C': /* - ** Cancel request. + ** Cancel request. */ FREE(show_POST_url); return 0; - case 'G': - /* - ** Treat as 303 (GET without content). - */ - FREE(show_POST_url); - return 303; - case 'U': /* ** Show URL for intermediate or advanced mode. */ - if (user_mode != NOVICE_MODE) - if (on_screen == 1) + if (user_mode != NOVICE_MODE) { + if (on_screen == 1) { on_screen = 0; - else + } else { on_screen = 1; + } + } break; + case 'G': + if (server_status == 301) { + /* + ** Treat as 303 (GET without content). + */ + FREE(show_POST_url); + return 303; + } + /* fall through to default */ + default: /* ** Get another character. */ - if (on_screen == 1) + if (on_screen == 1) { on_screen = 0; - else + } else { on_screen = 2; + } } } } diff --git a/src/HTAlert.h b/src/HTAlert.h index 744a2a35..bb07b2a1 100644 --- a/src/HTAlert.h +++ b/src/HTAlert.h @@ -112,6 +112,7 @@ extern BOOL HTConfirmCookie PARAMS(( ** ---------------------------- ** On entry, ** Redirecting_url is the Location. +** server_status is the server status code. ** ** On exit, ** Returns 0 on cancel, @@ -119,7 +120,8 @@ extern BOOL HTConfirmCookie PARAMS(( ** 303 for redirect as GET without content */ extern int HTConfirmPostRedirect PARAMS(( - CONST char * Redirecting_url)); + CONST char * Redirecting_url, + int server_status)); /* diff --git a/src/HTFWriter.c b/src/HTFWriter.c index 93e75a68..5f41becb 100644 --- a/src/HTFWriter.c +++ b/src/HTFWriter.c @@ -72,6 +72,7 @@ struct _HTStream { FILE * fp; /* The file we've opened */ char * end_command; /* What to do on _free. */ char * remove_command; /* What to do on _abort. */ + char * viewer_command; /* saved external viewer */ HTFormat input_format; /* Original pres->rep */ HTFormat output_format; /* Original pres->rep_out */ HTParentAnchor * anchor; /* Original stream's anchor. */ @@ -124,7 +125,7 @@ PRIVATE void HTFWriter_write ARGS3(HTStream *, me, CONST char*, s, int, l) */ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) { - FILE *fp; + FILE *fp = NULL; int len; char *path = NULL; char *addr = NULL; @@ -132,6 +133,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) extern int HTLoadFile PARAMS(( CONST char *addr, HTParentAnchor *anchor, HTFormat format_out, HTStream *sink)); + BOOL use_gzread = NO; fflush(me->fp); if (me->end_command) { /* Temp file */ @@ -162,6 +164,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) * a temporary file for uncompression. - FM */ if (me->anchor->FileCache != NULL) { + BOOL skip_loadfile = (me->viewer_command != NULL); /* * Save the path with the "gz" or "Z" suffix trimmed, * and remove any previous uncompressed copy. - FM @@ -169,27 +172,38 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) StrAllocCopy(path, me->anchor->FileCache); if ((len = strlen(path)) > 2) { if (!strcasecomp((char *)&path[len-2], "gz")) { - path[len-3] = '\0'; - remove(path); +#ifdef USE_ZLIB + if (!skip_loadfile) { + use_gzread = YES; + } else +#endif /* USE_ZLIB */ + { + path[len-3] = '\0'; + remove(path); + } } else if (!strcasecomp((char *)&path[len-1], "Z")) { path[len-2] = '\0'; remove(path); } } - if (!dump_output_immediately) { + if (!use_gzread) { + if (!dump_output_immediately) { + /* + * Tell user what's happening. - FM + */ + _HTProgress(me->end_command); + } /* - * Tell user what's happening. - FM + * Uncompress it. - FM */ - _HTProgress(me->end_command); + if (me->end_command && me->end_command[0]) + system(me->end_command); + fp = fopen(me->anchor->FileCache, "r"); } - /* - * Uncompress it. - FM - */ - system(me->end_command); - if ((fp = fopen(me->anchor->FileCache, "r")) != NULL) { + if (fp != NULL) { /* - * It's still there with the "gz" of "Z" suffix, - * so the uncompression failed. - FM + * It's still there with the "gz" of "Z" suffix when + * it shouldn't, so the uncompression failed. - FM */ fclose(fp); fp = NULL; @@ -217,19 +231,23 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) StrAllocCat(addr, path); #endif /* VMS */ #endif /* DOSPATH */ - StrAllocCopy(me->anchor->FileCache, path); + if (!use_gzread) { + StrAllocCopy(me->anchor->FileCache, path); + FREE(me->anchor->content_encoding); + } FREE(path); - FREE(me->anchor->content_encoding); #ifdef EXP_CHARTRANS /* * Lock the chartrans info we may possibly have, * so HTCharsetFormat() will not apply the default * for local files. - KW */ - HTAnchor_copyUCInfoStage(me->anchor, - UCT_STAGE_PARSER, - UCT_STAGE_MIME, - UCT_SETBY_PARSER); + if (!skip_loadfile) { + HTAnchor_copyUCInfoStage(me->anchor, + UCT_STAGE_PARSER, + UCT_STAGE_MIME, + UCT_SETBY_PARSER); + } #endif /* * Now have HTLoadFile() handle the uncompressed @@ -241,6 +259,49 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) */ _user_message(WWW_USING_MESSAGE, addr); } + + if (skip_loadfile) { + /* + * It's a temporary file we're passing to a + * viewer or helper application. + * Loading the temp file through HTLoadFile() + * would result in yet another HTStream (created + * with HTSaveAndExecute()) which would just + * copy the temp file to another temp file + * (or even the same!). We can skip this + * needless duplication by using the + * viewer_command which has already been + * determind when the HTCompressed stream was + * created. - kw + */ + FREE(me->end_command); + me->end_command = (char *)calloc ( + (strlen (me->viewer_command) + 10 + + strlen(me->anchor->FileCache)) + * sizeof (char),1); + if (me->end_command == NULL) + outofmem(__FILE__, "HTFWriter_free (HTCompressed)"); + + sprintf(me->end_command, + me->viewer_command, me->anchor->FileCache, + "", "", "", "", "", ""); + if (!dump_output_immediately) { + /* + * Tell user what's happening. - FM + */ + HTProgress(me->end_command); + stop_curses(); + } + system(me->end_command); + + if (me->remove_command) { + /* NEVER REMOVE THE FILE unless during an abort!!!*/ + /* system(me->remove_command); */ + FREE(me->remove_command); + } + if (!dump_output_immediately) + start_curses(); + } else status = HTLoadFile(addr, me->anchor, me->output_format, @@ -252,6 +313,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) FREE(me->anchor->FileCache); FREE(me->remove_command); FREE(me->end_command); + FREE(me->viewer_command); FREE(me); return; } @@ -298,6 +360,7 @@ PRIVATE void HTFWriter_free ARGS1(HTStream *, me) } FREE(me->end_command); } + FREE(me->viewer_command); if (dump_output_immediately) { if (me->anchor->FileCache) @@ -330,6 +393,7 @@ PRIVATE void HTFWriter_abort ARGS2(HTStream *, me, HTError, e) fprintf(stderr,"HTFWriter_abort called\n"); fclose(me->fp); + FREE(me->viewer_command); if (me->end_command) { /* Temp file */ if (TRACE) fprintf(stderr, "HTFWriter: Aborting: file not executed.\n"); @@ -523,6 +587,7 @@ SaveAndExecute_tempname: } chmod(fnam, 0600); + StrAllocCopy(me->viewer_command, pres->command); /* * Make command to process file. */ @@ -773,7 +838,8 @@ SaveToFile_tempname: StrAllocCopy(anchor->FileCache, fnam); Prepend_BASE: - if (!strncasecomp(pres->rep->name, "text/html", 9)) { + if (!strncasecomp(pres->rep->name, "text/html", 9) && + !anchor->content_encoding) { /* * Add the document's base as a BASE tag at the top of the file, * so that any partial or relative URLs within it will be resolved @@ -986,13 +1052,44 @@ Compressed_tempname: chmod(fnam, 0600); /* + * me->viewer_command will be NULL if the converter Pres found above + * is not for an external viewer but an internal HTStream converter. + * We also don't set it under conditions where HTSaveAndExecute would + * disallow execution of the command. - kw + */ + if (!dump_output_immediately && !traversal +#if defined(EXEC_LINKS) || defined(EXEC_SCRIPTS) + && (Pres->quality != 999.0 || + (!no_exec && /* allowed exec link or script ? */ + (local_exec || + (local_exec_on_local_files && + (LYJumpFileURL || + !strncmp(anchor->address,"file://localhost",16)))))) +#endif /* EXEC_LINKS || EXEC_SCRIPTS */ + ) { + StrAllocCopy(me->viewer_command, Pres->command); + } + + /* * Make command to process file. - FM */ - me->end_command = (char *)calloc(1, (strlen(uncompress_mask) + 10 + - strlen(fnam)) * sizeof(char)); - if (me->end_command == NULL) - outofmem(__FILE__, "HTCompressed"); - sprintf(me->end_command, uncompress_mask, fnam, "", "", "", "", "", ""); +#if USE_ZLIB + if (compress_suffix[0] == 'g' && /* must be gzip */ + !me->viewer_command) { + /* + * We won't call gzip externally, so we don't need to supply + * a command for it. - kw + */ + StrAllocCopy(me->end_command, ""); + } else +#endif /* USE_ZLIB */ + { + me->end_command = (char *)calloc(1, (strlen(uncompress_mask) + 10 + + strlen(fnam)) * sizeof(char)); + if (me->end_command == NULL) + outofmem(__FILE__, "HTCompressed"); + sprintf(me->end_command, uncompress_mask, fnam, "", "", "", "", "", ""); + } FREE(uncompress_mask); /* diff --git a/src/HTFont.h b/src/HTFont.h index 7b34bbb9..9ab44fd5 100644 --- a/src/HTFont.h +++ b/src/HTFont.h @@ -6,7 +6,7 @@ #ifndef HTFONT_H #define HTFONT_H -typedef long int HTLMFont; /* For now */ +typedef long int HTMLFont; /* For now */ #define HT_NON_BREAK_SPACE ((char)1) /* For now */ #define HT_EM_SPACE ((char)2) /* For now */ diff --git a/src/HTInit.c b/src/HTInit.c index e8c74065..5c27d8bf 100644 --- a/src/HTInit.c +++ b/src/HTInit.c @@ -60,9 +60,11 @@ PUBLIC void HTFormatInit NOARGS HTSetPresentation("image/gif", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-xbm", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-xbitmap", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/x-png", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + HTSetPresentation("image/x-png", XLoadImageCommand, 2.0, 3.0, 0.0, 0); + HTSetPresentation("image/png", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/x-rgb", XLoadImageCommand, 1.0, 3.0, 0.0, 0); - HTSetPresentation("image/x-tiff", XLoadImageCommand, 1.0, 3.0, 0.0, 0); + HTSetPresentation("image/x-tiff", XLoadImageCommand, 2.0, 3.0, 0.0, 0); + HTSetPresentation("image/tiff", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("image/jpeg", XLoadImageCommand, 1.0, 3.0, 0.0, 0); HTSetPresentation("video/mpeg", "mpeg_play %s &", 1.0, 3.0, 0.0, 0); @@ -810,7 +812,7 @@ PUBLIC void HTFileInit NOARGS HTSetSuffix(".pbm", "image/x-portable-bitmap", "binary", 1.0); HTSetSuffix(".pgm", "image/x-portable-graymap", "binary", 1.0); HTSetSuffix(".ppm", "image/x-portable-pixmap", "binary", 1.0); - HTSetSuffix(".png", "image/x-png", "binary", 1.0); + HTSetSuffix(".png", "image/png", "binary", 1.0); HTSetSuffix(".rgb", "image/x-rgb", "binary", 1.0); HTSetSuffix(".xbm", "image/x-xbitmap", "binary", 1.0); HTSetSuffix(".xpm", "image/x-xpixmap", "binary", 1.0); @@ -842,6 +844,7 @@ PUBLIC void HTFileInit NOARGS HTSetSuffix(".htm", "text/html", "8bit", 1.0); HTSetSuffix(".html3", "text/html", "8bit", 1.0); HTSetSuffix(".ht3", "text/html", "8bit", 1.0); + HTSetSuffix(".phtml", "text/html", "8bit", 1.0); HTSetSuffix(".shtml", "text/html", "8bit", 1.0); HTSetSuffix(".htmlx", "text/html", "8bit", 1.0); HTSetSuffix(".html", "text/html", "8bit", 1.0); diff --git a/src/HTML.c b/src/HTML.c index 4de030c8..4a60ac9a 100644 --- a/src/HTML.c +++ b/src/HTML.c @@ -546,11 +546,11 @@ PRIVATE void HTML_start_element ARGS5( strcat (Style_className, class_string); strcat (myHash, "."); strcat (myHash, class_string); -#if !defined(PREVAIL) - } -#else /* PREVAIL */ +#ifdef PREVAIL strcpy (prevailing_class, class_string); +#endif } +#ifdef PREVAIL else if (prevailing_class[0]) { strcat (Style_className, "."); @@ -558,7 +558,7 @@ PRIVATE void HTML_start_element ARGS5( strcat (myHash, "."); strcat (myHash, prevailing_class); } -#endif /* !PREVAIL */ +#endif /* PREVAIL */ class_string[0]='\0'; strtolower(myHash); hcode=hash_code(myHash); @@ -2031,8 +2031,8 @@ PRIVATE void HTML_start_element ARGS5( /* * Set the default TYPE. */ - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = '1'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = '1'; /* * Check whether we have a starting sequence number, @@ -2065,23 +2065,23 @@ PRIVATE void HTML_start_element ARGS5( */ if (present[HTML_OL_TYPE] && value[HTML_OL_TYPE]) { if (*value[HTML_OL_TYPE] == 'A') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'A'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'A'; if (seqnum < 1) seqnum = 1; } else if (*value[HTML_OL_TYPE] == 'a') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'a'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'a'; if (seqnum < 1) seqnum = 1; } else if (*value[HTML_OL_TYPE] == 'I') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'I'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'I'; if (seqnum < 1) seqnum = 1; } else if (*value[HTML_OL_TYPE] == 'i') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'i'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'i'; if (seqnum < 1) seqnum = 1; } else { @@ -2092,29 +2092,29 @@ PRIVATE void HTML_start_element ARGS5( seqnum = OL_VOID + 1; } - me->OL_Counter[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = seqnum; + me->OL_Counter[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = seqnum; } else if (present && present[HTML_OL_CONTINUE]) { - me->OL_Counter[me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6] = OL_CONTINUE; + me->OL_Counter[me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11] = OL_CONTINUE; } else { - me->OL_Counter[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 1; + me->OL_Counter[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 1; if (present && present[HTML_OL_TYPE] && value[HTML_OL_TYPE]) { if (*value[HTML_OL_TYPE] == 'A') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'A'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'A'; } else if (*value[HTML_OL_TYPE] == 'a') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'a'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'a'; } else if (*value[HTML_OL_TYPE] == 'I') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'I'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'I'; } else if (*value[HTML_OL_TYPE] == 'i') { - me->OL_Type[(me->List_Nesting_Level < 5 ? - me->List_Nesting_Level+1 : 6)] = 'i'; + me->OL_Type[(me->List_Nesting_Level < 11 ? + me->List_Nesting_Level+1 : 11)] = 'i'; } } } @@ -2214,7 +2214,8 @@ PRIVATE void HTML_start_element ARGS5( int counter, seqnum; char seqtype; - counter = me->List_Nesting_Level < 6 ? me->List_Nesting_Level : 6; + counter = me->List_Nesting_Level < 11 ? + me->List_Nesting_Level : 11; if (present && present[HTML_LI_TYPE] && value[HTML_LI_TYPE]) { if (*value[HTML_LI_TYPE] == '1') { me->OL_Type[counter] = '1'; @@ -5855,20 +5856,22 @@ PRIVATE void HTML_end_element ARGS3( break; case HTML_OL: - me->OL_Counter[me->List_Nesting_Level < 6 ? - me->List_Nesting_Level : 6] = OL_VOID; + me->OL_Counter[me->List_Nesting_Level < 11 ? + me->List_Nesting_Level : 11] = OL_VOID; case HTML_DL: case HTML_UL: case HTML_MENU: case HTML_DIR: me->List_Nesting_Level--; - if (TRACE) - fprintf(stderr, "Reducing List Nesting Level to %d\n", - me->List_Nesting_Level); + if (TRACE) { + fprintf(stderr, + "HTML_end_element: Reducing List Nesting Level to %d\n", + me->List_Nesting_Level); + } change_paragraph_style(me, me->sp->style); /* Often won't really change */ UPDATE_STYLE; if (me->List_Nesting_Level >= 0) - HText_NegateLineOne(me->text); + LYEnsureSingleSpace(me); break; case HTML_SPAN: @@ -7151,7 +7154,7 @@ PUBLIC HTStructured* HTML_new ARGS3( * Used for nested lists. - FM */ me->List_Nesting_Level = -1; /* counter for list nesting level */ - LYZero_OL_Counter(me); /* Initializes OL_Counter[7] and OL_Type[7] */ + LYZero_OL_Counter(me); /* Initializes OL_Counter[] and OL_Type[] */ me->Last_OL_Count = 0; /* last count in ordered lists */ me->Last_OL_Type = '1'; /* last type in ordered lists */ diff --git a/src/HTML.h b/src/HTML.h index 8d313e81..0061f7d4 100644 --- a/src/HTML.h +++ b/src/HTML.h @@ -88,8 +88,8 @@ struct _HTStructured { * Used for nested lists. - FM */ int List_Nesting_Level; /* counter for list nesting level */ - int OL_Counter[7]; /* counter for ordered lists */ - char OL_Type[7]; /* types for ordered lists */ + int OL_Counter[12]; /* counter for ordered lists */ + char OL_Type[12]; /* types for ordered lists */ int Last_OL_Count; /* last count in ordered lists */ char Last_OL_Type; /* last type in ordered lists */ diff --git a/src/LYCharUtils.c b/src/LYCharUtils.c index b7d82c97..8ee363e8 100644 --- a/src/LYCharUtils.c +++ b/src/LYCharUtils.c @@ -9,6 +9,7 @@ #include "HTChunk.h" #include "HText.h" #include "HTStyle.h" +#include "HTMIME.h" #include "HTML.h" #include "HTCJK.h" @@ -1673,7 +1674,7 @@ PUBLIC void LYZero_OL_Counter ARGS1( if (!me) return; - for (i = 0; i < 7; i++) { + for (i = 0; i < 12; i++) { me->OL_Counter[i] = OL_VOID; me->OL_Type[i] = '1'; } @@ -2227,25 +2228,37 @@ PUBLIC void LYHandleMETA ARGS4( /* * Check for a suggested filename via a Content-Disposition with - * file; filename=name.suffix in it, if we don't already have it + * a filename=name.suffix in it, if we don't already have it * via a server header. - FM */ } else if (!(me->node_anchor->SugFname && *me->node_anchor->SugFname) && !strcasecomp((http_equiv ? http_equiv : ""), "Content-Disposition")) { cp = content; - while (*cp != '\0' && strncasecomp(cp, "file;", 5)) + while (*cp != '\0' && strncasecomp(cp, "filename", 8)) cp++; if (*cp != '\0') { - cp += 5; + cp += 8; + while ((*cp != '\0') && (WHITE(*cp) || *cp == '=')) + cp++; while (*cp != '\0' && WHITE(*cp)) cp++; if (*cp != '\0') { - while (*cp != '\0' && strncasecomp(cp, "filename=", 9)) - cp++; - if (*cp != '\0') { - StrAllocCopy(me->node_anchor->SugFname, (cp + 9)); - cp = me->node_anchor->SugFname; + StrAllocCopy(me->node_anchor->SugFname, cp); + if (*me->node_anchor->SugFname == '\"') { + if ((cp = strchr((me->node_anchor->SugFname + 1), + '\"')) != NULL) { + *(cp + 1) = '\0'; + HTMIME_TrimDoubleQuotes(me->node_anchor->SugFname); + } else { + FREE(me->node_anchor->SugFname); + } + if (me->node_anchor->SugFname != NULL && + *me->node_anchor->SugFname == '\0') { + FREE(me->node_anchor->SugFname); + } + } + if ((cp = me->node_anchor->SugFname) != NULL) { while (*cp != '\0' && !WHITE(*cp)) cp++; *cp = '\0'; @@ -2685,54 +2698,64 @@ PUBLIC int LYLegitimizeHREF ARGS4( "http", 4)) { /* * We will be resolving a partial reference versus an http - * or https URL, and it has lead dots, which are retained - * when resolving, in compliance with the URL specs, but - * the request would fail if the first element of the - * resultant path is two dots, because no http or https - * server accepts such paths, so if that's the case, and - * strip_dots is TRUE, we'll strip that element now, but - * issue a message about this as "immediate feedback", - * such that the bad partial reference might get corrected - * by the document provider. Note that if the second and - * further symbolic elements also contain(s) only dots, - * those will still be retained, and the resolved URL may - * still fail, but it should, IMHO, if the partial reference - * is that much out of compliance with the URL specs. - FM + * or https URL, and it has lead dots, which may be retained + * when resolving via HTParse(), but the request would fail + * if the first element of the resultant path is two dots, + * because no http or https server accepts such paths, and + * the current URL draft, likely to become an RFC, says that + * it's optional for the UA to strip them as a form of error + * recovery. So we will, recursively, for http/https URLs, + * like the "major market browsers" which made this problem + * so common on the Web, but we'll also issue a message about + * it, such that the bad partial reference might get corrected + * by the document provider. - FM */ int i = 0, j = 0; - char *temp = NULL, *str = ""; + char *temp = NULL, *path = NULL, *str = "", *cp; - if (((temp = HTParse((me->inBASE ? + if (((temp = HTParse(*href, + (me->inBASE ? me->base_href : me->node_anchor->address), - "", PARSE_PATH+PARSE_PUNCTUATION)) == NULL) || - temp[0] == '\0' || - !strchr((char *)&temp[1], '/')) { - FREE(temp); - temp = *href; - if ((me->inBASE ? - me->base_href[4] : me->node_anchor->address[4]) == 's') - str = "s"; - while (temp[j] == '.') - j++; - if ((j == 2) && (temp[j] == '/' || temp[j] == '\0')) { + PARSE_ALL)) != NULL && temp[0] != '\0') && + (path = HTParse(temp, "", + PARSE_PATH+PARSE_PUNCTUATION)) != NULL && + !strncmp(path, "/..", 3)) { + cp = (path + 3); + if (*cp == '/' || *cp == '\0') { + if ((me->inBASE ? + me->base_href[4] : me->node_anchor->address[4]) == 's') { + str = "s"; + } if (TRACE) { fprintf(stderr, "LYLegitimizeHREF: Bad value '%s' for http%s URL.\n", *href, str); fprintf(stderr, - " Stripping lead dots.\n"); + " Stripping lead dots.\n"); } else if (!me->inBadHREF) { _statusline(BAD_PARTIAL_REFERENCE); me->inBadHREF = TRUE; sleep(AlertSecs); } - while (temp[j] != '\0') - temp[i++] = temp[j++]; - temp[i] = '\0'; } - temp = NULL; + if (*cp == '\0') { + StrAllocCopy(*href, "/"); + } else if (*cp == '/') { + while (!strncmp(cp, "/..", 3)) { + if (*(cp + 3) == '/') { + cp += 3; + continue; + } else if (*(cp + 3) == '\0') { + *(cp + 1) = '\0'; + *(cp + 2) = '\0'; + } + break; + } + StrAllocCopy(*href, cp); + } } FREE(temp); + FREE(path); } return(url_type); } diff --git a/src/LYCookie.c b/src/LYCookie.c index 07d51595..aacd99ac 100644 --- a/src/LYCookie.c +++ b/src/LYCookie.c @@ -12,6 +12,10 @@ ** http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-state-man-mec-02.txt ** - FM 1997-07-09 ** +** Updated for: +** ftp://ds.internic.net/internet-drafts/draft-ietf-http-state-man-mec-03.txt +** - FM 1997-08-02 +** ** TO DO: (roughly in order of decreasing priority) * A means to specify "always allow" and "never allow" domains via a configuration file is needed. @@ -34,8 +38,8 @@ collections to bring us back down under the limits, rather than actively removing cookies and/or domains based on age or frequency of use. - * If the a cookie has the secure flag set, we presently treat only - SSL connections as secure. This may need to be expanded for other + * If a cookie has the secure flag set, we presently treat only SSL + connections as secure. This may need to be expanded for other secure communication protocols that become standarized. * Cookies could be optionally stored in a file from session to session. */ @@ -309,7 +313,9 @@ PRIVATE void store_cookie ARGS3( /* * Section 4.3.2, condition 2: The value for the Domain attribute * contains no embedded dots or does not start with a dot. - * (A dot is embedded if it's neither the first nor last character.) + * (A dot is embedded if it's neither the first nor last character.) + * Note that we added a lead dot ourselves if a domain attribute + * value otherwise qualified. - FM */ if (co->domain[0] != '.' || co->domain[1] == '\0') { if (TRACE) @@ -682,31 +688,24 @@ PRIVATE void LYProcessSetCookies ARGS6( /* * If we have both Set-Cookie and Set-Cookie2 headers. - * process the Set-Cookie2 header, then the Set-Cookie - * header. The most current draft has abandoned the - * the earlier requirement to combine them, but we'll - * keep doing that for now, until we're sure that holds - * up, since we never replace anything that was in the - * Set-Cookie2 headers with it's equivalent in the - * Set-Cookie header. If we have only a Set-Cookie2 - * or only a Set-Cookie header, that's what we use. So - * set up a list for the cookies we process out of the - * header(s). Note that if more than one instance of a - * valued attribute for the same cookie is encountered, - * even within the same header, the value for the first - * instance is retained, with consequent preference to - * that in a Set-Cookie2 header, since that was processed - * first. We only accept up to 50 cookies from either - * header, and only if a cookie's values do not exceed - * the 4096 byte limit on overall size. - FM + * process the Set-Cookie2 header. Otherwise, process + * whichever of the two headers we do have. Note that + * if more than one instance of a valued attribute for + * the same cookie is encountered, the value for the + * first instance is retained. We only accept up to 50 + * cookies from the header, and only if a cookie's values + * do not exceed the 4096 byte limit on overall size. - FM */ CombinedCookies = HTList_new(); /* - * First process the Set-Cookie2 header, if present, adding - * each cookie to the CombinedCookies list. - FM + * Process the Set-Cookie2 header, if present and not zero-length, + * adding each cookie to the CombinedCookies list. - FM */ p = (SetCookie2 ? SetCookie2 : ""); + if (TRACE && SetCookie && *p) { + fprintf(stderr, "LYProcessSetCookies: Using Set-Cookie2 header.\n"); + } while (NumCookies <= 50 && *p) { attr_start = attr_end = value_start = value_end = NULL; while (*p != '\0' && isspace((unsigned char)*p)) { @@ -955,23 +954,17 @@ PRIVATE void LYProcessSetCookies ARGS6( address, PARSE_ALL); /* - * Accept only URLs for servers. - FM + * Accept only URLs for http or https servers. - FM */ if ((url_type = is_url(cur_cookie->commentURL)) && (url_type == HTTP_URL_TYPE || - url_type == HTTPS_URL_TYPE || - url_type == FTP_URL_TYPE || - url_type == GOPHER_URL_TYPE || - url_type == HTML_GOPHER_URL_TYPE || - url_type == INDEX_GOPHER_URL_TYPE || - url_type == NEWS_URL_TYPE || - url_type == NNTP_URL_TYPE || - url_type == SNEWS_URL_TYPE || - url_type == WAIS_URL_TYPE || - url_type == CSO_URL_TYPE || - url_type == FINGER_URL_TYPE)) { + url_type == HTTPS_URL_TYPE)) { length += strlen(cur_cookie->commentURL); } else { + if (TRACE) + fprintf(stderr, + "LYProcessSetCookies: Rejecting commentURL value '%s'\n", + cur_cookie->commentURL); FREE(cur_cookie->commentURL); } } @@ -983,7 +976,38 @@ PRIVATE void LYProcessSetCookies ARGS6( */ !(cur_cookie->flags & COOKIE_FLAG_DOMAIN_SET)) { length -= strlen(cur_cookie->domain); - StrAllocCopy(cur_cookie->domain, value); + /* + * If the value does not have a lead dot, + * but does have an embedded dot, and is + * not an exact match to the hostname, nor + * is a numeric IP address, add a lead dot. + * Otherwise, use the value as is. - FM + */ + if (value[0] != '.' && value[0] != '\0' && + value[1] != '\0' && strcmp(value, hostname)) { + char *ptr = strchr(value, '.'); + if (ptr != NULL && ptr[1] != '\0') { + ptr = value; + while (*ptr == '.' || + isdigit((unsigned char)*ptr)) + ptr++; + if (*ptr != '\0') { + if (TRACE) { + fprintf(stderr, + "LYProcessSetCookies: Adding lead dot for domain value '%s'\n", + value); + } + StrAllocCopy(cur_cookie->domain, "."); + StrAllocCat(cur_cookie->domain, value); + } else { + StrAllocCopy(cur_cookie->domain, value); + } + } else { + StrAllocCopy(cur_cookie->domain, value); + } + } else { + StrAllocCopy(cur_cookie->domain, value); + } length += strlen(cur_cookie->domain); cur_cookie->flags |= COOKIE_FLAG_DOMAIN_SET; } @@ -1091,7 +1115,7 @@ PRIVATE void LYProcessSetCookies ARGS6( } /* - * If none of the above comparisions succeeded, and we have + * If none of the above comparisons succeeded, and we have * a value, then we have an unknown pair of the form 'foo=bar', * which means it's time to create a new cookie. If we don't * have a non-zero-length value, assume it's an error or a @@ -1111,6 +1135,19 @@ PRIVATE void LYProcessSetCookies ARGS6( cur_cookie->version = 1; } HTList_appendObject(CombinedCookies, cur_cookie); + } else if (cur_cookie != NULL) { + if (TRACE) { + fprintf(stderr, + "LYProcessSetCookies: Rejecting Set-Cookie2: %s=%s\n", + (cur_cookie->name ? + cur_cookie->name : "[no name]"), + (cur_cookie->value ? + cur_cookie->value : "[no value]")); + fprintf(stderr, + " due to excessive length!\n"); + } + freeCookie(cur_cookie); + cur_cookie = NULL; } /* * Start a new cookie. - FM @@ -1160,14 +1197,16 @@ PRIVATE void LYProcessSetCookies ARGS6( } /* - * Now process the Set-Cookie header, if present, checking the - * CombinedCookies list for a corresponding cookie and supplementing - * that if one is present, otherwise, adding the new cookie. - FM + * Process the Set-Cookie header, if no non-zero-length Set-Cookie2 + * header was present. - FM */ length = 0; NumCookies = 0; cur_cookie = NULL; - p = (SetCookie ? SetCookie : ""); + p = ((SetCookie && !(SetCookie2 && *SetCookie2)) ? SetCookie : ""); + if (TRACE && SetCookie2 && *p) { + fprintf(stderr, "LYProcessSetCookies: Using Set-Cookie header.\n"); + } while (NumCookies <= 50 && *p) { attr_start = attr_end = value_start = value_end = NULL; while (*p != '\0' && isspace((unsigned char)*p)) { @@ -1413,25 +1452,17 @@ PRIVATE void LYProcessSetCookies ARGS6( address, PARSE_ALL); /* - * Accept only URLs for servers. The most - * recent draft says just http, so the others - * are commented out here. - FM + * Accept only URLs for http or https servers. - FM */ if ((url_type = is_url(cur_cookie->commentURL)) && (url_type == HTTP_URL_TYPE || - url_type == HTTPS_URL_TYPE/* || - url_type == FTP_URL_TYPE || - url_type == GOPHER_URL_TYPE || - url_type == HTML_GOPHER_URL_TYPE || - url_type == INDEX_GOPHER_URL_TYPE || - url_type == NEWS_URL_TYPE || - url_type == NNTP_URL_TYPE || - url_type == SNEWS_URL_TYPE || - url_type == WAIS_URL_TYPE || - url_type == CSO_URL_TYPE || - url_type == FINGER_URL_TYPE */)) { + url_type == HTTPS_URL_TYPE)) { length += strlen(cur_cookie->commentURL); } else { + if (TRACE) + fprintf(stderr, + "LYProcessSetCookies: Rejecting commentURL value '%s'\n", + cur_cookie->commentURL); FREE(cur_cookie->commentURL); } } @@ -1443,7 +1474,38 @@ PRIVATE void LYProcessSetCookies ARGS6( */ !(cur_cookie->flags & COOKIE_FLAG_DOMAIN_SET)) { length -= strlen(cur_cookie->domain); - StrAllocCopy(cur_cookie->domain, value); + /* + * If the value does not have a lead dot, + * but does have an embedded dot, and is + * not an exact match to the hostname, nor + * is a numeric IP address, add a lead dot. + * Otherwise, use the value as is. - FM + */ + if (value[0] != '.' && value[0] != '\0' && + value[1] != '\0' && strcmp(value, hostname)) { + char *ptr = strchr(value, '.'); + if (ptr != NULL && ptr[1] != '\0') { + ptr = value; + while (*ptr == '.' || + isdigit((unsigned char)*ptr)) + ptr++; + if (*ptr != '\0') { + if (TRACE) { + fprintf(stderr, + "LYProcessSetCookies: Adding lead dot for domain value '%s'\n", + value); + } + StrAllocCopy(cur_cookie->domain, "."); + StrAllocCat(cur_cookie->domain, value); + } else { + StrAllocCopy(cur_cookie->domain, value); + } + } else { + StrAllocCopy(cur_cookie->domain, value); + } + } else { + StrAllocCopy(cur_cookie->domain, value); + } length += strlen(cur_cookie->domain); cur_cookie->flags |= COOKIE_FLAG_DOMAIN_SET; } @@ -1534,7 +1596,7 @@ PRIVATE void LYProcessSetCookies ARGS6( } /* - * If none of the above comparisions succeeded, and we have + * If none of the above comparisons succeeded, and we have * a value, then we have an unknown pair of the form 'foo=bar', * which means it's time to create a new cookie. If we don't * have a non-zero-length value, assume it's an error or a @@ -1542,132 +1604,40 @@ PRIVATE void LYProcessSetCookies ARGS6( * ignore it. - FM */ if (!known_attr && value_end > value_start) { - if (cur_cookie) { + /* + * If we've started a cookie, and it's not too big, + * save it in the CombinedCookies list. - FM + */ + if (length <= 4096 && cur_cookie != NULL) { + /* + * If we had a Set-Cookie2 header, make sure + * the version is at least 1, and mark it for + * quoting. - FM + */ if (SetCookie2 != NULL) { - /* - * If we had a Set-Cookie2 header, make sure - * the version is at least 1, and mark it for - * quoting. - FM - */ if (cur_cookie->version < 1) { cur_cookie->version = 1; } cur_cookie->quoted = TRUE; } - cl = CombinedCookies; - while (NULL != (co = (cookie *)HTList_nextObject(cl))) { - /* - * Check whether the cookie from the Set-Cookie2 - * header has the same name and value as this one - * from the Set-Cookie header. If they both had a - * domain attribute, make sure those match, and - * similarly if they both had a path attribute. - FM - */ - if ((!strcmp(co->name, cur_cookie->name) && - !strcmp(co->value, cur_cookie->value)) && - !(((co->flags & COOKIE_FLAG_DOMAIN_SET) && - (cur_cookie->flags & - COOKIE_FLAG_DOMAIN_SET)) && - strcmp(co->domain, cur_cookie->domain)) && - !(((co->flags & COOKIE_FLAG_PATH_SET) && - (cur_cookie->flags & - COOKIE_FLAG_PATH_SET)) && - strcmp(co->path, cur_cookie->path))) { - /* - * If the Set-Cookie2 header didn't include - * a domain attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_DOMAIN_SET) && - (cur_cookie->flags & COOKIE_FLAG_DOMAIN_SET)) { - StrAllocCopy(co->domain, cur_cookie->domain); - co->flags |= COOKIE_FLAG_DOMAIN_SET; - } - /* - * If the Set-Cookie2 header didn't include - * a path attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_PATH_SET) && - (cur_cookie->flags & COOKIE_FLAG_PATH_SET)) { - StrAllocCopy(co->path, cur_cookie->path); - co->pathlen = cur_cookie->pathlen; - co->flags |= COOKIE_FLAG_PATH_SET; - } - /* - * If the Set-Cookie2 header didn't include - * a comment attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!co->comment && cur_cookie->comment) { - StrAllocCopy(co->comment, - cur_cookie->comment); - } - /* - * If the Set-Cookie2 header didn't include - * a commentURL attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!co->commentURL && cur_cookie->commentURL) { - StrAllocCopy(co->commentURL, - cur_cookie->commentURL); - } - /* - * If the Set-Cookie2 header didn't include - * a port attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!co->PortList && cur_cookie->PortList) { - StrAllocCopy(co->PortList, - cur_cookie->PortList); - } - /* - * If the Set-Cookie2 header didn't include - * a secure attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_SECURE) && - (cur_cookie->flags & COOKIE_FLAG_SECURE)) { - co->flags |= COOKIE_FLAG_SECURE; - } - /* - * If the Set-Cookie2 header didn't set an - * expiration and the Set-Cookie header did, - * add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_EXPIRES_SET) && - (cur_cookie->flags & - COOKIE_FLAG_EXPIRES_SET)) { - co->expires = cur_cookie->expires; - co->flags |= COOKIE_FLAG_EXPIRES_SET; - } - /* - * If the Set-Cookie2 header didn't set - * discard and the Set-Cookie header did, - * add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_DISCARD) && - (cur_cookie->flags & COOKIE_FLAG_DISCARD)) { - co->flags |= COOKIE_FLAG_DISCARD; - } - /* - * If the cookie from the Set-Cookie2 header - * has a lower version than this cookie, use - * this cookie's version (though it should - * not have a version number). - FM - */ - if (co->version < cur_cookie->version) { - co->version = cur_cookie->version; - } - freeCookie(cur_cookie); - cur_cookie = NULL; - break; - } - } - if (co == NULL) { - HTList_appendObject(CombinedCookies, cur_cookie); + HTList_appendObject(CombinedCookies, cur_cookie); + } else if (cur_cookie != NULL) { + if (TRACE) { + fprintf(stderr, + "LYProcessSetCookies: Rejecting Set-Cookie: %s=%s\n", + (cur_cookie->name ? + cur_cookie->name : "[no name]"), + (cur_cookie->value ? + cur_cookie->value : "[no value]")); + fprintf(stderr, + " due to excessive length!\n"); } + freeCookie(cur_cookie); + cur_cookie = NULL; } + /* + * Start a new cookie. - FM + */ cur_cookie = newCookie(); length = 0; MemAllocCopy(&(cur_cookie->name), attr_start, attr_end); @@ -1697,113 +1667,7 @@ PRIVATE void LYProcessSetCookies ARGS6( } cur_cookie->quoted = TRUE; } - cl = CombinedCookies; - while (NULL != (co = (cookie *)HTList_nextObject(cl))) { - /* - * Check whether the cookie from the Set-Cookie2 - * header has the same name and value as this one - * from the Set-Cookie header. If they both had a - * domain attribute, make sure those match, and - * similarly if they both had a path attribute. - FM - */ - if ((!strcmp(co->name, cur_cookie->name) && - !strcmp(co->value, cur_cookie->value)) && - !(((co->flags & COOKIE_FLAG_DOMAIN_SET) && - (cur_cookie->flags & COOKIE_FLAG_DOMAIN_SET)) && - strcmp(co->domain, cur_cookie->domain)) && - !(((co->flags & COOKIE_FLAG_PATH_SET) && - (cur_cookie->flags & COOKIE_FLAG_PATH_SET)) && - strcmp(co->path, cur_cookie->path))) { - /* - * If the Set-Cookie2 header didn't include - * a domain attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_DOMAIN_SET) && - (cur_cookie->flags & COOKIE_FLAG_DOMAIN_SET)) { - StrAllocCopy(co->domain, cur_cookie->domain); - co->flags |= COOKIE_FLAG_DOMAIN_SET; - } - /* - * If the Set-Cookie2 header didn't include - * a path attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_PATH_SET) && - (cur_cookie->flags & COOKIE_FLAG_PATH_SET)) { - StrAllocCopy(co->path, cur_cookie->path); - co->pathlen = cur_cookie->pathlen; - co->flags |= COOKIE_FLAG_PATH_SET; - } - /* - * If the Set-Cookie2 header didn't include - * a comment attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!co->comment && cur_cookie->comment) { - StrAllocCopy(co->comment, cur_cookie->comment); - } - /* - * If the Set-Cookie2 header didn't include - * a commentURL attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!co->commentURL && cur_cookie->commentURL) { - StrAllocCopy(co->commentURL, cur_cookie->commentURL); - } - /* - * If the Set-Cookie2 header didn't include - * a port attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!co->PortList && cur_cookie->PortList) { - StrAllocCopy(co->PortList, cur_cookie->PortList); - } - /* - * If the Set-Cookie2 header didn't include - * a secure attribute and the Set-Cookie - * header did, add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_SECURE) && - (cur_cookie->flags & COOKIE_FLAG_SECURE)) { - co->flags |= COOKIE_FLAG_SECURE; - } - /* - * If the Set-Cookie2 header didn't set an - * expiration and the Set-Cookie header did, - * add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_EXPIRES_SET) && - (cur_cookie->flags & COOKIE_FLAG_EXPIRES_SET)) { - co->expires = cur_cookie->expires; - co->flags |= COOKIE_FLAG_EXPIRES_SET; - } - /* - * If the Set-Cookie2 header didn't set - * discard and the Set-Cookie header did, - * add it. - FM - */ - if (!(co->flags & COOKIE_FLAG_DISCARD) && - (cur_cookie->flags & COOKIE_FLAG_DISCARD)) { - co->flags |= COOKIE_FLAG_DISCARD; - } - /* - * If the cookie from the Set-Cookie2 header - * has a lower version than this cookie, use - * this cookie's version (though it should - * not have a version number). - FM - */ - if (co->version < cur_cookie->version) { - co->version = cur_cookie->version; - } - freeCookie(cur_cookie); - cur_cookie = NULL; - break; - } - } - if (co == NULL) { - HTList_appendObject(CombinedCookies, cur_cookie); - } + HTList_appendObject(CombinedCookies, cur_cookie); } else if (cur_cookie != NULL) { if (TRACE) { fprintf(stderr, @@ -1869,8 +1733,8 @@ PUBLIC void LYSetCookie ARGS3( /* * Get the hostname, port and path of the address, and report - * the Set-Cookie request if trace mode is on, but set the cookie - * only if LYSetCookies is TRUE. - FM + * the Set-Cookie and/or Set-Cookie2 header(s) if trace mode is + * on, but set the cookie(s) only if LYSetCookies is TRUE. - FM */ if (((hostname = HTParse(address, "", PARSE_HOST)) != NULL) && (ptr = strchr(hostname, ':')) != NULL) { diff --git a/src/LYCurses.c b/src/LYCurses.c index ffffcb1c..41a29cc4 100644 --- a/src/LYCurses.c +++ b/src/LYCurses.c @@ -575,6 +575,12 @@ PUBLIC void start_curses NOARGS if (slinit == 0) { SLtt_get_terminfo(); +#ifdef UNIX +#if SLANG_VERSION >= 9935 + SLang_TT_Read_FD = fileno(stdin); +#endif /* SLANG_VERSION >= 9935 */ +#endif /* UNIX */ + /* * Check whether a saved show_color:off override is in effect. - kw */ diff --git a/src/LYForms.c b/src/LYForms.c index 1c053bca..e48a6ca8 100644 --- a/src/LYForms.c +++ b/src/LYForms.c @@ -673,6 +673,9 @@ PRIVATE int popup_options ARGS7( return(orig_selection); } scrollok(form_window, TRUE); +#ifdef PDCURSES + keypad(form_window, TRUE); +#endif /* PDCURSES */ #ifdef NCURSES #ifdef wgetbkgd #define getbkgd(w) wgetbkgd(w) /* workaround pre-1.9.9g bug */ diff --git a/src/LYGetFile.c b/src/LYGetFile.c index f58fcd84..917bb037 100644 --- a/src/LYGetFile.c +++ b/src/LYGetFile.c @@ -48,6 +48,7 @@ PRIVATE int fix_http_urls PARAMS((document *doc)); extern char * WWW_Download_File; extern char LYCancelDownload; +extern BOOL redirect_post_content; #ifdef VMS extern BOOLEAN LYDidRename; #endif /* VMS */ @@ -127,13 +128,15 @@ Try_Redirected_URL: redirect_post_content = FALSE; if (TRACE) { - fprintf(stderr,"LYGetFile: getting %s\n\n",doc->address); + fprintf(stderr,"getfile: getting %s\n\n",doc->address); } /* * Protect against denial of service attacks * via the port 19 CHARGEN service, and block - * connections to the port 25 ESMTP service. - FM + * connections to the port 25 ESMTP service. + * Also reject any likely spoof attempts via + * wrap arounds at 65536. - FM */ if ((temp = HTParse(doc->address, "", PARSE_HOST)) != NULL && strlen(temp) > 3) { @@ -146,21 +149,27 @@ Try_Redirected_URL: cp++; if (sscanf(cp, "%ld", &value) == 1) { - if (value > 65535 || value < 0) { - HTAlert(PORT_INVALID); - FREE(temp); - return(NULLFILE); - } - if (value == 19) { + if (value == 19 || value == 65555) { HTAlert(PORT_NINETEEN_INVALID); FREE(temp); return(NULLFILE); } - if (value == 25) { + if (value == 25 || value == 65561) { HTAlert(PORT_TWENTYFIVE_INVALID); FREE(temp); return(NULLFILE); } + if (value > 65535 || value < 0) { + char msg[265]; + sprintf(msg, PORT_INVALID, (unsigned long)value); + HTAlert(msg); + FREE(temp); + return(NULLFILE); + } + } else if (isdigit((unsigned char)*cp)) { + HTAlert(URL_PORT_BAD); + FREE(temp); + return(NULLFILE); } } } @@ -591,7 +600,7 @@ Try_Redirected_URL: StrAllocCopy(tmp, "http://"); if (TRACE) fprintf(stderr, - "LYGetFile: URL %s\n", + "getfile: URL '%s'\n", doc->address); *cp = '\0'; StrAllocCat(tmp, doc->address+9); @@ -606,7 +615,7 @@ Try_Redirected_URL: StrAllocCat(tmp, cp+8); StrAllocCopy(doc->address, tmp); if (TRACE) - fprintf(stderr, " changed to %s\n", + fprintf(stderr, " changed to '%s'\n", doc->address); FREE(tmp); url_type = HTTP_URL_TYPE; @@ -639,7 +648,7 @@ Try_Redirected_URL: char *cp2; if (TRACE) - fprintf(stderr, "LYGetFile: URL %s\n", + fprintf(stderr, "getfile: URL '%s'\n", doc->address); *cp1 = '\0'; cp1 += 2; @@ -661,7 +670,7 @@ Try_Redirected_URL: StrAllocCopy(doc->address, temp); FREE(temp); if (TRACE) - fprintf(stderr, " changed to %s\n", + fprintf(stderr, " changed to '%s'\n", doc->address); WWWDoc.address = doc->address; } @@ -863,6 +872,15 @@ Try_Redirected_URL: } else { StrAllocCopy(fname, doc->address); } + /* + * Check whether this is a compressed file, + * which we don't uncompress for downloads, + * and adjust any suffix appropriately. - FM + */ + if (tmpanchor != NULL) { + HTCheckFnameForCompression(&fname, tmpanchor, + FALSE); + } if (LYdownload_options(&fname, WWW_Download_File) < 0) { FREE(fname); @@ -1295,10 +1313,10 @@ PRIVATE int fix_http_urls ARGS1( * If we get to here, trim the trailing slash. - FM */ if (TRACE) - fprintf(stderr,"LYGetFile: URL %s\n", doc->address); + fprintf(stderr, "fix_http_urls: URL '%s'\n", doc->address); doc->address[strlen(doc->address)-1] = '\0'; if (TRACE) { - fprintf(stderr," changed to %s\n", doc->address); + fprintf(stderr, " changed to '%s'\n", doc->address); sleep(MessageSecs); } } @@ -1312,10 +1330,10 @@ PRIVATE int fix_http_urls ARGS1( } } if (TRACE) - fprintf(stderr,"LYGetFile: URL %s\n", doc->address); + fprintf(stderr, "fix_http_urls: URL '%s'\n", doc->address); StrAllocCat(doc->address, "/"); if (TRACE) { - fprintf(stderr," changed to %s\n",doc->address); + fprintf(stderr, " changed to '%s'\n",doc->address); sleep(MessageSecs); } diff --git a/src/LYLocal.c b/src/LYLocal.c index 1524d84f..df518553 100644 --- a/src/LYLocal.c +++ b/src/LYLocal.c @@ -44,9 +44,11 @@ #include "LYSystem.h" #ifndef VMS +#ifndef _WINDOWS #include <sys/wait.h> #include <errno.h> #include <grp.h> +#endif /*_WINDOWS */ #endif /* VMS */ #include "LYLeaks.h" @@ -2192,7 +2194,7 @@ PUBLIC int LYExecv ARGS3( char **, argv, char *, msg) { -#ifdef VMS +#if defined(VMS) || defined(_WINDOWS) if (TRACE) { fprintf(stderr, "LYExecv: Called inappropriately!\n"); } diff --git a/src/LYMain.c b/src/LYMain.c index 89db134d..8b1c838a 100644 --- a/src/LYMain.c +++ b/src/LYMain.c @@ -1192,6 +1192,10 @@ PUBLIC int main ARGS2( /* * Process the configuration file. */ + if (TRACE) { + fprintf(stderr, + "Loading cfg file '%s'.\n", lynx_cfg_file); + } read_cfg(lynx_cfg_file); FREE(lynx_cfg_file); diff --git a/src/LYMainLoop.c b/src/LYMainLoop.c index 154930e6..40b113e3 100644 --- a/src/LYMainLoop.c +++ b/src/LYMainLoop.c @@ -156,6 +156,7 @@ int mainloop NOARGS BOOLEAN LYRawMode_flag = LYRawMode; BOOLEAN LYSelectPopups_flag = LYSelectPopups; BOOLEAN trace_mode_flag = FALSE; + BOOLEAN forced_HTML_mode = LYforce_HTML_mode; char cfile[128]; FILE *cfp; char *cp, *toolbar; @@ -963,6 +964,11 @@ try_again: */ first_file = FALSE; + /* + * Set the startrealm, and deal as best we can + * with preserving forced HTML mode for a local + * startfile. - FM + */ temp = HTParse(curdoc.address, "", PARSE_ACCESS+PARSE_HOST+PARSE_PUNCTUATION); if (!temp || *temp == '\0') { @@ -976,6 +982,30 @@ try_again: StrAllocCat(startrealm, "/"); } } else { + if (forced_HTML_mode && + !dump_output_immediately && + !curdoc.bookmark && + !strncasecomp(curdoc.address, "file:", 5) && + strlen(temp) > 1) { + /* + * We forced HTML for a local startfile which + * is not a bookmark file and has a path of at + * least two letters. It it doesn't have a + * suffix mapped to text/html, we'll set the + * entire path (including the lead slash) as a + * "suffix" mapped to text/html to ensure it is + * always treated as an HTML source file. We + * are counting on a tail match to this full path + * for some other URL fetched during the session + * having too low a probability to worry about, + * but it could happen. - FM + */ + HTAtom *encoding; + + if (HTFileFormat(temp, &encoding) != WWW_HTML) { + HTSetSuffix(temp, "text/html", "8bit", 1.0); + } + } if ((cp = strrchr(temp, '/')) != NULL) { *(cp+1) = '\0'; StrAllocCat(startrealm, temp); @@ -2520,6 +2550,8 @@ new_cmd: /* !strncmp(curdoc.address, "file:", 5)) { LYNoRefererForThis = TRUE; } + StrAllocCopy(newdoc.title, + links[curdoc.link].hightext); } c = change_form_link(&links[curdoc.link], FORM_UP, &newdoc, &refresh_screen, @@ -4641,6 +4673,10 @@ check_add_bookmark_to_self: (links[curdoc.link].type != WWW_FORM_LINK_TYPE || links[curdoc.link].form->type == F_SUBMIT_TYPE || links[curdoc.link].form->type == F_IMAGE_SUBMIT_TYPE)) { + /* + * We have links, and the current link is a + * normal link or a form's submit button. - FM + */ _statusline(HEAD_D_L_OR_CANCEL); c = LYgetch(); if (TOUPPER(c) == 'D') { @@ -4662,6 +4698,7 @@ check_add_bookmark_to_self: } HEAD_request = TRUE; LYforce_no_cache = TRUE; + StrAllocCopy(newdoc.title, curdoc.title); if (HTLoadedDocumentIsHEAD()) { HTuncache_current_document(); FREE(curdoc.address); @@ -4688,14 +4725,16 @@ check_add_bookmark_to_self: _statusline(FORM_ACTION_NOT_HTTP_URL); sleep(MessageSecs); } else if (links[curdoc.link].type == WWW_FORM_LINK_TYPE && - links[curdoc.link].form->submit_method == URL_POST_METHOD && + links[curdoc.link].form->submit_method == + URL_POST_METHOD && HTConfirm(CONFIRM_POST_LINK_HEAD) == FALSE) { _statusline(CANCELLED); sleep(InfoSecs); } else { HEAD_request = TRUE; LYforce_no_cache = TRUE; - StrAllocCat(newdoc.title, " - HEAD"); + StrAllocCopy(newdoc.title, links[curdoc.link].hightext); + StrAllocCat(newdoc.title, " - (HEAD)"); cmd = LYK_ACTIVATE; goto new_cmd; } @@ -4704,6 +4743,7 @@ check_add_bookmark_to_self: break; } else { /* + * We can offer only this document for a HEAD request. * Check if this is a reply from a POST, and if so, * seek confirmation if the safe element is not set. - FM */ @@ -4714,18 +4754,35 @@ check_add_bookmark_to_self: sleep(InfoSecs); break; } else if (nlinks > 0) { + /* + * The current link is a non-submittable form + * link, so prompt the user to make it clear + * that the HEAD request would be for the + * current document, not the form link. - FM + */ _statusline(HEAD_D_OR_CANCEL); c = LYgetch(); } else { + /* + * No links, so we can just assume that + * the user wants a HEAD request for the + * current document. - FM + */ c = 'D'; } if (TOUPPER(c) == 'D') { + /* + * The user didn't cancel, so check if + * a HEAD request is appropriate for the + * current document. - FM + */ if (strncmp(curdoc.address, "http", 4)) { _statusline(DOC_NOT_HTTP_URL); sleep(MessageSecs); } else { HEAD_request = TRUE; LYforce_no_cache = TRUE; + StrAllocCopy(newdoc.title, curdoc.title); if (HTLoadedDocumentIsHEAD()) { HTuncache_current_document(); FREE(curdoc.address); @@ -4738,7 +4795,7 @@ check_add_bookmark_to_self: break; case LYK_TOGGLE_HELP: - if (user_mode==NOVICE_MODE) { + if (user_mode == NOVICE_MODE) { toggle_novice_line(); noviceline(more); } diff --git a/src/LYOptions.c b/src/LYOptions.c index 59ba4822..c4ef236c 100644 --- a/src/LYOptions.c +++ b/src/LYOptions.c @@ -2133,6 +2133,9 @@ PRIVATE int popup_choice ARGS6( return(orig_choice); } scrollok(form_window, TRUE); +#ifdef PDCURSES + keypad(form_window, TRUE); +#endif /* PDCURSES */ #ifdef NCURSES #ifdef wgetbkgd #define getbkgd(w) wgetbkgd(w) /* workaround pre-1.9.9g bug */ diff --git a/src/LYShowInfo.c b/src/LYShowInfo.c index 156e4baf..2cd1b05b 100644 --- a/src/LYShowInfo.c +++ b/src/LYShowInfo.c @@ -240,7 +240,8 @@ PUBLIC int showinfo ARGS4( StrAllocCopy(Title, doc->title); LYEntify(&Title, TRUE); - fprintf(fp0,"<dt><em>Linkname:</em> %s\n", Title); + fprintf(fp0, "<dt><em>Linkname:</em> %s%s\n", + Title, (doc->isHEAD ? " (HEAD)" : "")); StrAllocCopy(Address, doc->address); LYEntify(&Address, TRUE); diff --git a/src/LYUtils.c b/src/LYUtils.c index 8073ac04..ba4d706d 100644 --- a/src/LYUtils.c +++ b/src/LYUtils.c @@ -191,7 +191,12 @@ PUBLIC void highlight ARGS3( if (links[cur].hightext2 && links[cur].ly < display_lines) { lynx_stop_link_color (flag == ON, links[cur].inUnderline); - addch('\n'); +#ifndef USE_SLANG + if ((char)(inch() & A_CHARTEXT) == '-') + move(links[cur].ly + 1, 0); + else +#endif + addch('\n'); for (i = 0; i < links[cur].hightext2_offset; i++) addch(' '); @@ -660,8 +665,8 @@ highlight_hit_within_hightext: /* * Start emphasis immediately if we are making * the link non-current, or we are making it - * current but this is not the first character - * of the hightext. - FM + * current but this is not the first or last + * character of the hightext. - FM */ if (flag != ON || (offset > hoffset && data[itmp+1] != '\0')) { @@ -1329,10 +1334,11 @@ highlight_hit_within_hightext2: /* * Start emphasis immediately if we are making * the link non-current, or we are making it - * current but this is not the first character - * of the hightext2. - FM + * current but this is not the first or last + * character of the hightext2. - FM */ - if (flag != ON || offset > hoffset) { + if (flag != ON || + (offset > hoffset && data[itmp+1] != '\0')) { LYstartTargetEmphasis(); TargetEmphasisON = TRUE; addstr(tmp); @@ -1350,10 +1356,11 @@ highlight_hit_within_hightext2: /* * Start emphasis immediately if we are making * the link non-current, or we are making it - * current but this is not the first character - * of the hightext2. - FM + * current but this is not the first or last + * character of the hightext2. - FM */ - if (flag != ON || offset > hoffset) { + if (flag != ON || + (offset > hoffset && data[itmp+1] != '\0')) { LYstartTargetEmphasis(); TargetEmphasisON = TRUE; addstr(tmp); @@ -1366,10 +1373,11 @@ highlight_hit_within_hightext2: /* * Start emphasis immediately if we are making * the link non-current, or we are making it - * current but this is not the first character - * of the hightext2. - FM + * current but this is not the first or last + * character of the hightext2. - FM */ - if (flag != ON || offset > hoffset) { + if (flag != ON || + (offset > hoffset && data[itmp+1] != '\0')) { LYstartTargetEmphasis(); TargetEmphasisON = TRUE; addstr(tmp); @@ -4182,29 +4190,61 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3( fprintf(stdout, "Looking up '%s' first.\n", host); } #ifndef DJGPP - if ((phost = gethostbyname(host)) != NULL) { + if ((phost = gethostbyname(host)) != NULL) #else - if (resolve(host) != 0) { + if (resolve(host) != 0) #endif /* DJGPP */ + { + /* + * Clear any residual interrupt. - FM + */ + if (LYCursesON && HTCheckForInterrupt()) { + if (TRACE) { + fprintf(stderr, + "LYExpandHostForURL: Ignoring interrupt because '%s' resolved.\n", + host); + } + } + + /* + * Return success. - FM + */ GotHost = TRUE; FREE(host); FREE(Str); FREE(MsgStr); return GotHost; + } else if (LYCursesON && HTCheckForInterrupt()) { + /* + * Give the user chance to interrupt lookup cycles. - KW & FM + */ + if (TRACE) { + fprintf(stderr, + "LYExpandHostForURL: Interrupted while '%s' failed to resolve.\n", + host); + } + + /* + * Return failure. - FM + */ + FREE(host); + FREE(Str); + FREE(MsgStr); + return FALSE; } /* - ** Set the first prefix, making it a zero-length string - ** if the list is NULL or if the potential host field - ** ends with a dot. - FM - */ + * Set the first prefix, making it a zero-length string + * if the list is NULL or if the potential host field + * ends with a dot. - FM + */ StartP = ((prefix_list && Str[strlen(Str)-1] != '.') ? prefix_list : ""); /* - ** If we have a prefix, but the allocated string is - ** one of the common host prefixes, make our prefix - ** a zero-length string. - FM - */ + * If we have a prefix, but the allocated string is + * one of the common host prefixes, make our prefix + * a zero-length string. - FM + */ if (*StartP && *StartP != '.') { if (!strncasecomp(*AllocatedString, "www.", 4) || !strncasecomp(*AllocatedString, "ftp.", 4) || @@ -4229,14 +4269,14 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3( LYstrncpy(DomainPrefix, StartP, (EndP - StartP)); /* - ** Test each prefix with each suffix. - FM - */ + * Test each prefix with each suffix. - FM + */ do { /* - ** Set the first suffix, making it a zero-length string - ** if the list is NULL or if the potential host field - ** begins with a dot. - FM - */ + * Set the first suffix, making it a zero-length string + * if the list is NULL or if the potential host field + * begins with a dot. - FM + */ StartS = ((suffix_list && *Str != '.') ? suffix_list : ""); while ((*StartS) && (WHITE(*StartS) || *StartS == ',')) { @@ -4249,8 +4289,8 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3( LYstrncpy(DomainSuffix, StartS, (EndS - StartS)); /* - ** Create domain names and do DNS tests. - FM - */ + * Create domain names and do DNS tests. - FM + */ do { StrAllocCopy(Host, DomainPrefix); StrAllocCat(Host, ((*Str == '.') ? (Str + 1) : Str)); @@ -4287,7 +4327,7 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3( if (LYCursesON && HTCheckForInterrupt()) { if (TRACE) { fprintf(stderr, - "*** LYExpandHostForURL interrupted while %s failed to resolve\n", + "LYExpandHostForURL: Interrupted while '%s' failed to resolve.\n", host); } FREE(Str); @@ -4298,8 +4338,8 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3( } /* - ** Advance to the next suffix, or end of suffix list. - FM - */ + * Advance to the next suffix, or end of suffix list. - FM + */ StartS = ((*EndS == '\0') ? EndS : (EndS + 1)); while ((*StartS) && (WHITE(*StartS) || *StartS == ',')) { StartS++; /* Skip whitespace and separators */ @@ -4314,8 +4354,8 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3( if (GotHost == FALSE) { /* - ** Advance to the next prefix, or end of prefix list. - FM - */ + * Advance to the next prefix, or end of prefix list. - FM + */ StartP = ((*EndP == '\0') ? EndP : (EndP + 1)); while ((*StartP) && (WHITE(*StartP) || *StartP == ',')) { StartP++; /* Skip whitespace and separators */ @@ -4351,6 +4391,18 @@ PUBLIC BOOLEAN LYExpandHostForURL ARGS3( } /* + * Clear any residual interrupt. - FM + */ + if (LYCursesON && HTCheckForInterrupt()) { + if (TRACE) { + fprintf(stderr, + "LYExpandHostForURL: Ignoring interrupt because '%s' %s.\n", + host, + (GotHost ? "resolved" : "timed out")); + } + } + + /* * Clean up and return the last test result. - FM */ FREE(Str); diff --git a/src/Makefile b/src/Makefile index 5c8048cc..30ad4f31 100644 --- a/src/Makefile +++ b/src/Makefile @@ -69,6 +69,7 @@ TABLES= $(CHRTR)iso02_uni.h \ $(CHRTR)cp437_uni.h \ $(CHRTR)cp850_uni.h \ $(CHRTR)cp852_uni.h \ + $(CHRTR)cp866_uni.h \ $(CHRTR)cp1250_uni.h \ $(CHRTR)cp1251_uni.h \ $(CHRTR)cp1252_uni.h \ diff --git a/src/UCAux.c b/src/UCAux.c index e6d9247f..3eb5fcfe 100644 --- a/src/UCAux.c +++ b/src/UCAux.c @@ -69,12 +69,13 @@ PUBLIC BOOL UCCanTranslateFromTo ARGS2( if (!strcmp(fromname, "koi8-r") || /* from cyrillic */ !strcmp(fromname, "iso-8859-5") || + !strcmp(fromname, "cp866") || !strcmp(fromname, "windows-1251") || !strcmp(fromname, "koi-8")) { if (strcmp(toname, "iso-8859-5") && strcmp(toname, "koi8-r") && - strcmp(toname, "windows-1251") && - strcmp(toname, "iso-8859-2")) + strcmp(toname, "cp866") && + strcmp(toname, "windows-1251")) return NO; } } diff --git a/src/UCdomap.c b/src/UCdomap.c index c32044f2..288b52aa 100644 --- a/src/UCdomap.c +++ b/src/UCdomap.c @@ -46,6 +46,7 @@ #include "[.chrtrans]cp437_uni.h" #include "[.chrtrans]cp850_uni.h" #include "[.chrtrans]cp852_uni.h" +#include "[.chrtrans]cp866_uni.h" #include "[.chrtrans]cp1250_uni.h" #include "[.chrtrans]cp1251_uni.h" #include "[.chrtrans]cp1252_uni.h" @@ -69,6 +70,7 @@ #include "chrtrans/cp437_uni.h" #include "chrtrans/cp850_uni.h" #include "chrtrans/cp852_uni.h" +#include "chrtrans/cp866_uni.h" #include "chrtrans/cp1250_uni.h" #include "chrtrans/cp1251_uni.h" #include "chrtrans/cp1252_uni.h" @@ -1670,6 +1672,7 @@ PUBLIC void UCInit NOARGS UC_CHARSET_SETUP_cp437; UC_CHARSET_SETUP_cp850; UC_CHARSET_SETUP_cp852; + UC_CHARSET_SETUP_cp866; UC_CHARSET_SETUP_windows_1250; UC_CHARSET_SETUP_windows_1251; UC_CHARSET_SETUP_iso_8859_1_windows_; diff --git a/src/chrtrans/MAKEW32.BAT b/src/chrtrans/MAKEW32.BAT index 3655ba0f..0c17aa1d 100644 --- a/src/chrtrans/MAKEW32.BAT +++ b/src/chrtrans/MAKEW32.BAT @@ -7,13 +7,17 @@ makeuctb iso02_uni.tbl > iso02_uni.h makeuctb iso03_uni.tbl > iso03_uni.h makeuctb iso04_uni.tbl > iso04_uni.h makeuctb iso05_uni.tbl > iso05_uni.h +makeuctb iso06_uni.tbl > iso06_uni.h makeuctb iso07_uni.tbl > iso07_uni.h +makeuctb iso08_uni.tbl > iso08_uni.h makeuctb iso09_uni.tbl > iso09_uni.h makeuctb iso10_uni.tbl > iso10_uni.h makeuctb cp437_uni.tbl > cp437_uni.h +makeuctb cp866_uni.tbl > cp866_uni.h makeuctb cp850_uni.tbl > cp850_uni.h makeuctb cp852_uni.tbl > cp852_uni.h makeuctb cp1250_uni.tbl > cp1250_uni.h +makeuctb cp1251_uni.tbl > cp1251_uni.h makeuctb cp1252_uni.tbl > cp1252_uni.h makeuctb utf8_uni.tbl > utf8_uni.h makeuctb mnemonic_suni.tbl > mnemonic_suni.h diff --git a/src/chrtrans/Makefile b/src/chrtrans/Makefile index af982a90..f5a44374 100644 --- a/src/chrtrans/Makefile +++ b/src/chrtrans/Makefile @@ -35,6 +35,7 @@ TABLES= $(CHRTR)iso02_uni.h \ $(CHRTR)cp437_uni.h \ $(CHRTR)cp850_uni.h \ $(CHRTR)cp852_uni.h \ + $(CHRTR)cp866_uni.h \ $(CHRTR)cp1250_uni.h \ $(CHRTR)cp1251_uni.h \ $(CHRTR)cp1252_uni.h \ diff --git a/src/chrtrans/build-chrtrans.com b/src/chrtrans/build-chrtrans.com index c2604a9f..f6f0609e 100644 --- a/src/chrtrans/build-chrtrans.com +++ b/src/chrtrans/build-chrtrans.com @@ -102,6 +102,8 @@ $ define/user sys$output 'CHRwhere'cp850_uni.h $ makeuctb cp850_uni.tbl $ define/user sys$output 'CHRwhere'cp852_uni.h $ makeuctb cp852_uni.tbl +$ define/user sys$output 'CHRwhere'cp866_uni.h +$ makeuctb cp866_uni.tbl $ define/user sys$output 'CHRwhere'cp1250_uni.h $ makeuctb cp1250_uni.tbl $ define/user sys$output 'CHRwhere'cp1251_uni.h diff --git a/src/chrtrans/cp1251_uni.tbl b/src/chrtrans/cp1251_uni.tbl index ada70396..21a44414 100644 --- a/src/chrtrans/cp1251_uni.tbl +++ b/src/chrtrans/cp1251_uni.tbl @@ -21,6 +21,7 @@ OWinCyrillic (cp1251) # # The entries are in cp1251_WinCyrillic order # +0x20-0x7f idem 0x80 U+0402 #CYRILLIC CAPITAL LETTER DJE 0x81 U+0403 #CYRILLIC CAPITAL LETTER GJE 0x82 U+201A #SINGLE LOW-9 QUOTATION MARK diff --git a/src/chrtrans/cp866_uni.tbl b/src/chrtrans/cp866_uni.tbl new file mode 100644 index 00000000..2b109897 --- /dev/null +++ b/src/chrtrans/cp866_uni.tbl @@ -0,0 +1,189 @@ +# +#The MIME name of this charset. +Mcp866 + +#Name as a Display Charset (used on Options screen) +ODosCyrillic (cp866) +# +# Name: cp866_DOSCyrillicRussian to Unicode table +# Unicode version: 2.0 +# Table version: 2.00 +# Table format: Format A +# Date: 04/24/96 +# Authors: Lori Brownell <loribr@microsoft.com> +# K.D. Chang <a-kchang@microsoft.com> +# General notes: none +# +# Format: Three tab-separated columns +# Column #1 is the cp866_DOSCyrillicRussian code (in hex) +# Column #2 is the Unicode (in hex as 0xXXXX) +# Column #3 is the Unicode name (follows a comment sign, '#') +# +# The entries are in cp866_DOSCyrillicRussian order +# +0x20-0x40 idem + +# some mapppings of greek capital letters to latin letters added - kw +0x41 U+0041 U+0391 #LATIN CAPITAL LETTER A +0x42 U+0042 U+0392 #LATIN CAPITAL LETTER B +0x43 U+0043 #LATIN CAPITAL LETTER C +0x44 U+0044 #LATIN CAPITAL LETTER D +0x45 U+0045 U+0395 #LATIN CAPITAL LETTER E +0x46 U+0046 #LATIN CAPITAL LETTER F +0x47 U+0047 #LATIN CAPITAL LETTER G +0x48 U+0048 U+0397 #LATIN CAPITAL LETTER H +0x49 U+0049 U+0399 #LATIN CAPITAL LETTER I +0x4a U+004a #LATIN CAPITAL LETTER J +0x4b U+004b U+039a #LATIN CAPITAL LETTER K +0x4c U+004c #LATIN CAPITAL LETTER L +0x4d U+004d U+039c #LATIN CAPITAL LETTER M +0x4e U+004e U+039d #LATIN CAPITAL LETTER N +0x4f U+004f U+039f #LATIN CAPITAL LETTER O +0x50 U+0050 U+03a1 #LATIN CAPITAL LETTER P +0x51 U+0051 #LATIN CAPITAL LETTER Q +0x52 U+0052 #LATIN CAPITAL LETTER R +0x53 U+0053 #LATIN CAPITAL LETTER S +0x54 U+0054 U+03a4 #LATIN CAPITAL LETTER T +0x55 U+0055 #LATIN CAPITAL LETTER U +0x56 U+0056 #LATIN CAPITAL LETTER V +0x57 U+0057 #LATIN CAPITAL LETTER W +0x58 U+0058 U+03a7 #LATIN CAPITAL LETTER X +0x59 U+0059 U+03a5 #LATIN CAPITAL LETTER Y +0x5a U+005a U+0396 #LATIN CAPITAL LETTER Z +0x5b-0x7f idem + +0x80 U+0410 #CYRILLIC CAPITAL LETTER A +0x81 U+0411 #CYRILLIC CAPITAL LETTER BE +0x82 U+0412 #CYRILLIC CAPITAL LETTER VE +0x83 U+0413 #CYRILLIC CAPITAL LETTER GHE +0x84 U+0414 #CYRILLIC CAPITAL LETTER DE +0x85 U+0415 #CYRILLIC CAPITAL LETTER IE +0x86 U+0416 #CYRILLIC CAPITAL LETTER ZHE +0x87 U+0417 #CYRILLIC CAPITAL LETTER ZE +0x88 U+0418 #CYRILLIC CAPITAL LETTER I +0x89 U+0419 #CYRILLIC CAPITAL LETTER SHORT I +0x8a U+041a #CYRILLIC CAPITAL LETTER KA +0x8b U+041b #CYRILLIC CAPITAL LETTER EL +0x8c U+041c #CYRILLIC CAPITAL LETTER EM +0x8d U+041d #CYRILLIC CAPITAL LETTER EN +0x8e U+041e #CYRILLIC CAPITAL LETTER O +0x8f U+041f #CYRILLIC CAPITAL LETTER PE +0x90 U+0420 #CYRILLIC CAPITAL LETTER ER +0x91 U+0421 #CYRILLIC CAPITAL LETTER ES +0x92 U+0422 #CYRILLIC CAPITAL LETTER TE +0x93 U+0423 #CYRILLIC CAPITAL LETTER U +0x94 U+0424 #CYRILLIC CAPITAL LETTER EF +0x95 U+0425 #CYRILLIC CAPITAL LETTER HA +0x96 U+0426 #CYRILLIC CAPITAL LETTER TSE +0x97 U+0427 #CYRILLIC CAPITAL LETTER CHE +0x98 U+0428 #CYRILLIC CAPITAL LETTER SHA +0x99 U+0429 #CYRILLIC CAPITAL LETTER SHCHA +0x9a U+042a #CYRILLIC CAPITAL LETTER HARD SIGN +0x9b U+042b #CYRILLIC CAPITAL LETTER YERU +0x9c U+042c #CYRILLIC CAPITAL LETTER SOFT SIGN +0x9d U+042d #CYRILLIC CAPITAL LETTER E +0x9e U+042e #CYRILLIC CAPITAL LETTER YU +0x9f U+042f #CYRILLIC CAPITAL LETTER YA +0xa0 U+0430 #CYRILLIC SMALL LETTER A +0xa1 U+0431 #CYRILLIC SMALL LETTER BE +0xa2 U+0432 #CYRILLIC SMALL LETTER VE +0xa3 U+0433 #CYRILLIC SMALL LETTER GHE +0xa4 U+0434 #CYRILLIC SMALL LETTER DE +0xa5 U+0435 #CYRILLIC SMALL LETTER IE +0xa6 U+0436 #CYRILLIC SMALL LETTER ZHE +0xa7 U+0437 #CYRILLIC SMALL LETTER ZE +0xa8 U+0438 #CYRILLIC SMALL LETTER I +0xa9 U+0439 #CYRILLIC SMALL LETTER SHORT I +0xaa U+043a #CYRILLIC SMALL LETTER KA +0xab U+043b #CYRILLIC SMALL LETTER EL +0xac U+043c #CYRILLIC SMALL LETTER EM +0xad U+043d #CYRILLIC SMALL LETTER EN +0xae U+043e #CYRILLIC SMALL LETTER O +0xaf U+043f #CYRILLIC SMALL LETTER PE +0xb0 U+2591 #LIGHT SHADE +0xb1 U+2592 #MEDIUM SHADE +0xb2 U+2593 #DARK SHADE +0xb3 U+2502 #BOX DRAWINGS LIGHT VERTICAL +0xb4 U+2524 #BOX DRAWINGS LIGHT VERTICAL AND LEFT +0xb5 U+2561 #BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE +0xb6 U+2562 #BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE +0xb7 U+2556 #BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE +0xb8 U+2555 #BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE +0xb9 U+2563 #BOX DRAWINGS DOUBLE VERTICAL AND LEFT +0xba U+2551 #BOX DRAWINGS DOUBLE VERTICAL +0xbb U+2557 #BOX DRAWINGS DOUBLE DOWN AND LEFT +0xbc U+255d #BOX DRAWINGS DOUBLE UP AND LEFT +0xbd U+255c #BOX DRAWINGS UP DOUBLE AND LEFT SINGLE +0xbe U+255b #BOX DRAWINGS UP SINGLE AND LEFT DOUBLE +0xbf U+2510 #BOX DRAWINGS LIGHT DOWN AND LEFT +0xc0 U+2514 #BOX DRAWINGS LIGHT UP AND RIGHT +0xc1 U+2534 #BOX DRAWINGS LIGHT UP AND HORIZONTAL +0xc2 U+252c #BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +0xc3 U+251c #BOX DRAWINGS LIGHT VERTICAL AND RIGHT +0xc4 U+2500 #BOX DRAWINGS LIGHT HORIZONTAL +0xc5 U+253c #BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +0xc6 U+255e #BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE +0xc7 U+255f #BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE +0xc8 U+255a #BOX DRAWINGS DOUBLE UP AND RIGHT +0xc9 U+2554 #BOX DRAWINGS DOUBLE DOWN AND RIGHT +0xca U+2569 #BOX DRAWINGS DOUBLE UP AND HORIZONTAL +0xcb U+2566 #BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL +0xcc U+2560 #BOX DRAWINGS DOUBLE VERTICAL AND RIGHT +0xcd U+2550 #BOX DRAWINGS DOUBLE HORIZONTAL +0xce U+256c #BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL +0xcf U+2567 #BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE +0xd0 U+2568 #BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE +0xd1 U+2564 #BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE +0xd2 U+2565 #BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE +0xd3 U+2559 #BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE +0xd4 U+2558 #BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE +0xd5 U+2552 #BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE +0xd6 U+2553 #BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE +0xd7 U+256b #BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE +0xd8 U+256a #BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE +0xd9 U+2518 #BOX DRAWINGS LIGHT UP AND LEFT +0xda U+250c #BOX DRAWINGS LIGHT DOWN AND RIGHT +0xdb U+2588 #FULL BLOCK +0xdc U+2584 #LOWER HALF BLOCK +0xdd U+258c #LEFT HALF BLOCK +0xde U+2590 #RIGHT HALF BLOCK +0xdf U+2580 #UPPER HALF BLOCK +0xe0 U+0440 #CYRILLIC SMALL LETTER ER +0xe1 U+0441 #CYRILLIC SMALL LETTER ES +0xe2 U+0442 #CYRILLIC SMALL LETTER TE +0xe3 U+0443 #CYRILLIC SMALL LETTER U +0xe4 U+0444 #CYRILLIC SMALL LETTER EF +0xe5 U+0445 #CYRILLIC SMALL LETTER HA +0xe6 U+0446 #CYRILLIC SMALL LETTER TSE +0xe7 U+0447 #CYRILLIC SMALL LETTER CHE +0xe8 U+0448 #CYRILLIC SMALL LETTER SHA +0xe9 U+0449 #CYRILLIC SMALL LETTER SHCHA +0xea U+044a #CYRILLIC SMALL LETTER HARD SIGN +0xeb U+044b #CYRILLIC SMALL LETTER YERU +0xec U+044c #CYRILLIC SMALL LETTER SOFT SIGN +0xed U+044d #CYRILLIC SMALL LETTER E +0xee U+044e #CYRILLIC SMALL LETTER YU +0xef U+044f #CYRILLIC SMALL LETTER YA +0xf0 U+0401 #CYRILLIC CAPITAL LETTER IO +0xf1 U+0451 #CYRILLIC SMALL LETTER IO +0xf2 U+0404 #CYRILLIC CAPITAL LETTER UKRAINIAN IE +0xf3 U+0454 #CYRILLIC SMALL LETTER UKRAINIAN IE +0xf4 U+0407 #CYRILLIC CAPITAL LETTER YI +0xf5 U+0457 #CYRILLIC SMALL LETTER YI +0xf6 U+040e #CYRILLIC CAPITAL LETTER SHORT U +0xf7 U+045e #CYRILLIC SMALL LETTER SHORT U +0xf8 U+00b0 #DEGREE SIGN +0xf9 U+2219 #BULLET OPERATOR +0xfa U+00b7 #MIDDLE DOT +0xfb U+221a #SQUARE ROOT +0xfc U+2116 #NUMERO SIGN +0xfd U+00a4 #CURRENCY SIGN +0xfe U+25a0 #BLACK SQUARE +0xff U+00a0 #NO-BREAK SPACE + +# TRADE MARK SIGN: +U+2122:(TM) + +0x60 U+2018 # left single quotation mark <`> +0x27 U+2019-U+201b # various single quotation marks <'> +0x22 U+201c-U+201f # various double quotation marks <"> diff --git a/src/chrtrans/koi8r_uni.tbl b/src/chrtrans/koi8r_uni.tbl index 99b5e28d..c4946a50 100644 --- a/src/chrtrans/koi8r_uni.tbl +++ b/src/chrtrans/koi8r_uni.tbl @@ -1,11 +1,10 @@ - - # Options screen name for this character set -O KOI8-R character set +OKOI8-R character set # MIME name for this charset -M koi8-r +Mkoi8-r +0x20-0x7f idem # Based on a table received from "Glenn E. Thobe" <thobe@lafn.org> #hex unicode # description #--- U+---- # --------------- @@ -137,3 +136,10 @@ M koi8-r 0xFD U+0429 # CAP SHCHA 0xFE U+0427 # CAP CHE 0xFF U+042A # CAP HARD SIGN + +# TRADE MARK SIGN: +U+2122:(TM) + +0x60 U+2018 # left single quotation mark <`> +0x27 U+2019-U+201b # various single quotation marks <'> +0x22 U+201c-U+201f # various double quotation marks <"> diff --git a/src/chrtrans/makefile.in b/src/chrtrans/makefile.in index e293d1ad..b1e00c7d 100644 --- a/src/chrtrans/makefile.in +++ b/src/chrtrans/makefile.in @@ -47,6 +47,7 @@ TABLES= $(CHRTR)iso02_uni.h \ $(CHRTR)cp437_uni.h \ $(CHRTR)cp850_uni.h \ $(CHRTR)cp852_uni.h \ + $(CHRTR)cp866_uni.h \ $(CHRTR)cp1250_uni.h \ $(CHRTR)cp1251_uni.h \ $(CHRTR)cp1252_uni.h \ diff --git a/src/makefile.in b/src/makefile.in index 773fb6bf..e024ff12 100644 --- a/src/makefile.in +++ b/src/makefile.in @@ -101,6 +101,7 @@ TABLES= $(CHRTR)iso02_uni.h \ $(CHRTR)cp437_uni.h \ $(CHRTR)cp850_uni.h \ $(CHRTR)cp852_uni.h \ + $(CHRTR)cp866_uni.h \ $(CHRTR)cp1250_uni.h \ $(CHRTR)cp1251_uni.h \ $(CHRTR)cp1252_uni.h \ |