diff options
| author | 2000-03-25 18:16:41 +0000 | |
|---|---|---|
| committer | 2000-03-25 18:16:41 +0000 | |
| commit | 05e9de5ac11bf4eb5b700d64593e66bf62b6167f (patch) | |
| tree | 4b0f8191aef831df789ac65b9bfac3d70d0ffbdd /gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c | |
| parent | if_gm attaches on pci, not macobio. (diff) | |
| download | wireguard-openbsd-05e9de5ac11bf4eb5b700d64593e66bf62b6167f.tar.xz wireguard-openbsd-05e9de5ac11bf4eb5b700d64593e66bf62b6167f.zip | |
Upgrade to Lynx 2.8.2. -moj
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c')
| -rw-r--r-- | gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c | 1426 |
1 files changed, 775 insertions, 651 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c index 89a93d14f81..f0b294e7952 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFile.c @@ -17,35 +17,31 @@ ** 15 Nov 93 (MD) Moved HTVMSname to HTVMSUTILS.C ** 27 Dec 93 (FM) FTP now works with VMS hosts. ** FTP path must be Unix-style and cannot include -** the device or top directory. +** the device or top directory. */ +#include <HTUtils.h> + #ifndef VMS -/* #define LONG_LIST */ /* Define this for long style unix listings (ls -l) */ +#ifdef DOSPATH +#define LONG_LIST /* Define this for long style unix listings (ls -l), + the actual style is configurable from lynx.cfg */ +#define lstat stat +#endif /* #define NO_PARENT_DIR_REFERENCE */ /* Define this for no parent links */ #endif /* !VMS */ #ifdef DOSPATH #define HAVE_READDIR 1 -#include <dirent.h> #define USE_DIRENT -#include "HTDOS.h" +#include <HTDOS.h> #endif /* DOSPATH */ -#include "HTUtils.h" -#include "tcp.h" -#include "HTFile.h" /* Implemented here */ +#include <HTFile.h> /* Implemented here */ #ifdef VMS #include <stat.h> #endif /* VMS */ -#ifndef VMS -#ifdef LONG_LIST -#include <pwd.h> -#include <grp.h> -#endif /* LONG_LIST */ -#endif /* !VMS */ - #ifdef USE_ZLIB #include <GridText.h> #endif @@ -53,36 +49,29 @@ #define INFINITY 512 /* file name length @@ FIXME */ #define MULTI_SUFFIX ".multi" /* Extension for scanning formats */ -#define HT_EM_SPACE ((char)2) - -#define FREE(x) if (x) {free(x); x = NULL;} - -#ifdef VMS -#include "HTVMSUtils.h" -#endif /* VMS */ - -#include "HTParse.h" -#include "HTTCP.h" +#include <HTParse.h> +#include <HTTCP.h> #ifndef DECNET -#include "HTFTP.h" +#include <HTFTP.h> #endif /* !DECNET */ -#include "HTAnchor.h" -#include "HTAtom.h" -#include "HTWriter.h" -#include "HTFWriter.h" -#include "HTInit.h" -#include "HTBTree.h" -#include "HTAlert.h" -#include "HTCJK.h" -#include "UCDefs.h" -#include "UCMap.h" -#include "UCAux.h" - -#include "LYexit.h" -#include "LYCharSets.h" -#include "LYGlobalDefs.h" -#include "LYUtils.h" -#include "LYLeaks.h" +#include <HTAnchor.h> +#include <HTAtom.h> +#include <HTAAProt.h> +#include <HTFWriter.h> +#include <HTInit.h> +#include <HTBTree.h> +#include <HTAlert.h> +#include <HTCJK.h> +#include <UCDefs.h> +#include <UCMap.h> +#include <UCAux.h> + +#include <LYexit.h> +#include <LYCharSets.h> +#include <LYGlobalDefs.h> +#include <LYStrings.h> +#include <LYUtils.h> +#include <LYLeaks.h> typedef struct _HTSuffix { char * suffix; @@ -100,7 +89,11 @@ typedef struct _HTSuffix { #endif /* NGROUPS_MAX */ #endif /* NGROUPS */ -#include "HTML.h" /* For directory object building */ +#ifndef GETGROUPS_T +#define GETGROUPS_T int +#endif + +#include <HTML.h> /* For directory object building */ #define PUTC(c) (*target->isa->put_character)(target, c) #define PUTS(s) (*target->isa->put_string)(target, s) @@ -109,6 +102,8 @@ typedef struct _HTSuffix { #define MAYBE_END(e) if (HTML_dtd.tags[e].contents != SGML_EMPTY) \ (*target->isa->end_element)(target, e, 0) #define FREE_TARGET (*target->isa->_free)(target) +#define ABORT_TARGET (*targetClass._abort)(target, NULL); + struct _HTStructured { CONST HTStructuredClass * isa; /* ... */ @@ -121,15 +116,10 @@ PUBLIC int HTDirAccess = HT_DIR_OK; #ifdef DIRED_SUPPORT PUBLIC int HTDirReadme = HT_DIR_README_NONE; -#define FILES_FIRST 1 -#define MIXED_STYLE 2 -extern BOOLEAN lynx_edit_mode; -extern BOOLEAN dir_list_style; #else PUBLIC int HTDirReadme = HT_DIR_README_TOP; #endif /* DIRED_SUPPORT */ -extern BOOLEAN LYRawMode; extern BOOL HTPassEightBitRaw; extern HTCJKlang HTCJK; @@ -161,15 +151,48 @@ int exists(char *filename) /* To free up the suffixes at program exit. ** ---------------------------------------- */ +#ifdef LY_FIND_LEAKS PRIVATE void free_suffixes NOPARAMS; +#endif #ifdef LONG_LIST +PRIVATE char *FormatStr ARGS3( + char **, bufp, + char *, start, + CONST char *, entry) +{ + char fmt[512]; + if (*start) { + sprintf(fmt, "%%%.*ss", (int) sizeof(fmt) - 3, start); + HTSprintf0(bufp, fmt, entry); + } else { + HTSprintf0(bufp, "%s", entry); + } + return *bufp; +} + +PRIVATE char *FormatNum ARGS3( + char **, bufp, + char *, start, + int, entry) +{ + char fmt[512]; + if (*start) { + sprintf(fmt, "%%%.*sd", (int) sizeof(fmt) - 3, start); + HTSprintf0(bufp, fmt, entry); + } else { + sprintf(fmt, "%d", entry); + StrAllocCat(*bufp, fmt); + } + return *bufp; +} + PRIVATE void LYListFmtParse ARGS5( - char *, fmtstr, - char *, file, + char *, fmtstr, + char *, file, HTStructured *, target, - char *, entry, - char *, tail) + char *, entry, + char *, tail) { char c; char *s; @@ -177,11 +200,10 @@ PRIVATE void LYListFmtParse ARGS5( char *start; char *str = NULL; struct stat st; - char buf[512]; - char fmt[512]; + char *buf = NULL; + char tmp[LY_MAXPATH]; char type; - struct passwd *p; - struct group *g; + char *name; time_t now; char *datestr; int len; @@ -192,9 +214,16 @@ PRIVATE void LYListFmtParse ARGS5( "r-S", "r-s", "rwS", "rws", 0 }; #define PBIT(a, n, s) (s) ? psbits[((a) >> (n)) & 0x7] : \ pbits[((a) >> (n)) & 0x7] +#ifdef S_ISVTX + static char *ptbits[] = { "--T", "--t", "-wT", "-wt", + "r-T", "r-t", "rwT", "rwt", 0 }; +#define PTBIT(a, s) (s) ? ptbits[(a) & 0x7] : pbits[(a) & 0x7] +#else +#define PTBIT(a, s) PBIT(a, 0, 0) +#endif if (lstat(file, &st) < 0) - fmtstr = "%a"; /* can't stat so just do anchor */ + fmtstr = " %a"; /* can't stat so just do anchor */ StrAllocCopy(str, fmtstr); s = str; @@ -219,33 +248,65 @@ PRIVATE void LYListFmtParse ARGS5( if (s == end) break; start = ++s; - while (isdigit(*s) || *s == '.' || *s == '-') + while (isdigit(*s) || *s == '.' || *s == '-' || *s == ' ' || + *s == '#' || *s == '+' || *s == '\'') s++; - c = *s; /* the format char. or \0 */ + c = *s; /* the format char. or \0 */ *s = '\0'; switch (c) { case '\0': - break; + PUTS(start); + continue; case 'A': case 'a': /* anchor */ HTDirEntry(target, tail, entry); - sprintf(fmt, "%%%ss", start); - sprintf(buf, fmt, entry); + FormatStr(&buf, start, entry); PUTS(buf); END(HTML_A); + *buf = '\0'; #ifdef S_IFLNK - if (c != 'A' && (st.st_mode & S_IFMT) == S_IFLNK && - (len = readlink(file, buf, sizeof(buf))) >= 0) { + if (c != 'A' && S_ISLNK(st.st_mode) && + (len = readlink(file, tmp, sizeof(tmp))) >= 0) { PUTS(" -> "); - buf[len] = '\0'; - PUTS(buf); + tmp[len] = '\0'; + PUTS(tmp); } #endif - *buf = '\0'; break; + case 'T': /* MIME type */ + case 't': /* MIME type description */ + if (S_ISDIR(st.st_mode)) { + if (c != 'T') { + FormatStr(&buf, start, ENTRY_IS_DIRECTORY); + } else { + FormatStr(&buf, start, ""); + } + } else { + CONST char *cp2; + HTFormat format; + format = HTFileFormat(file, NULL, &cp2); + + if (c != 'T') { + if (cp2 == NULL) { + if (!strncmp(HTAtom_name(format), + "application",11)) { + cp2 = HTAtom_name(format) + 12; + if (!strncmp(cp2,"x-",2)) + cp2 += 2; + } else { + cp2 = HTAtom_name(format); + } + } + FormatStr(&buf, start, cp2); + } else { + FormatStr(&buf, start, HTAtom_name(format)); + } + } + break; + case 'd': /* date */ now = time(0); datestr = ctime(&st.st_mtime); @@ -253,32 +314,29 @@ PRIVATE void LYListFmtParse ARGS5( /* ** MMM DD HH:MM */ - sprintf(buf, "%.12s", datestr + 4); + sprintf(tmp, "%.12s", datestr + 4); else /* ** MMM DD YYYY */ - sprintf(buf, "%.7s %.4s ", datestr + 4, - datestr + 20); - sprintf(fmt, "%%%ss", start); - sprintf(buf, fmt, buf); + sprintf(tmp, "%.7s %.4s ", datestr + 4, + datestr + 20); + FormatStr(&buf, start, tmp); break; case 's': /* size in bytes */ - sprintf(fmt, "%%%sd", start); - sprintf(buf, fmt, st.st_size); + FormatNum(&buf, start, (int) st.st_size); break; case 'K': /* size in Kilobytes but not for directories */ - if ((st.st_mode & S_IFMT) == S_IFDIR) { - sprintf(fmt, "%%%ss ", start); - sprintf(buf, fmt, ""); + if (S_ISDIR(st.st_mode)) { + FormatStr(&buf, start, ""); break; } /* FALL THROUGH */ case 'k': /* size in Kilobytes */ - sprintf(fmt, "%%%sdK", start); - sprintf(buf, fmt, (st.st_size+1023)/1024); + FormatNum(&buf, start, (int)((st.st_size+1023)/1024)); + StrAllocCat(buf, "K"); break; case 'p': /* unix-style permission bits */ @@ -294,7 +352,7 @@ PRIVATE void LYListFmtParse ARGS5( case S_IFLNK: type = 'l'; break; #endif #ifdef S_IFSOCK -# ifdef S_IFIFO /* some older machines (e.g., apollo) have a conflict */ +# ifdef S_IFIFO /* some older machines (e.g., apollo) have a conflict */ # if S_IFIFO != S_IFSOCK case S_IFSOCK: type = 's'; break; # endif @@ -304,41 +362,37 @@ PRIVATE void LYListFmtParse ARGS5( #endif /* S_IFSOCK */ default: type = '?'; break; } - sprintf(buf, "%c%s%s%s", type, - PBIT(st.st_mode, 6, st.st_mode & S_ISUID), - PBIT(st.st_mode, 3, st.st_mode & S_ISGID), - PBIT(st.st_mode, 0, 0)); - sprintf(fmt, "%%%ss", start); - sprintf(buf, fmt, buf); + sprintf(tmp, "%c%s%s%s", type, + PBIT(st.st_mode, 6, st.st_mode & S_ISUID), + PBIT(st.st_mode, 3, st.st_mode & S_ISGID), + PTBIT(st.st_mode, st.st_mode & S_ISVTX)); + FormatStr(&buf, start, tmp); break; case 'o': /* owner */ - sprintf(fmt, "%%%ss", start); - p = getpwuid(st.st_uid); - if (p) { - sprintf(fmt, "%%%ss", start); - sprintf(buf, fmt, p->pw_name); + name = HTAA_UidToName (st.st_uid); + if (*name) { + FormatStr(&buf, start, name); } else { - - sprintf(fmt, "%%%sd", start); - sprintf(buf, fmt, st.st_uid); + FormatNum(&buf, start, (int) st.st_uid); } break; case 'g': /* group */ - g = getgrgid(st.st_gid); - if (g) { - sprintf(fmt, "%%%ss", start); - sprintf(buf, fmt, g->gr_name); + name = HTAA_GidToName(st.st_gid); + if (*name) { + FormatStr(&buf, start, name); } else { - sprintf(fmt, "%%%sd", start); - sprintf(buf, fmt, st.st_gid); + FormatNum(&buf, start, (int) st.st_gid); } break; case 'l': /* link count */ - sprintf(fmt, "%%%sd", start); - sprintf(buf, fmt, st.st_nlink); + FormatNum(&buf, start, (int) st.st_nlink); + break; + + case '%': /* literal % with flags/width */ + FormatStr(&buf, start, "%"); break; default: @@ -346,12 +400,14 @@ PRIVATE void LYListFmtParse ARGS5( "Unknown format character `%c' in list format\n", c); break; } - PUTS(buf); + if (buf) + PUTS(buf); s++; } + FREE(buf); END(HTML_PRE); - PUTS("\n"); + PUTC('\n'); FREE(str); } #endif /* LONG_LIST */ @@ -405,7 +461,9 @@ PUBLIC void HTSetSuffix5 ARGS5( */ if (!HTSuffixes) { HTSuffixes = HTList_new(); +#ifdef LY_FIND_LEAKS atexit(free_suffixes); +#endif } HTList_addObject(HTSuffixes, suff); @@ -429,6 +487,7 @@ PUBLIC void HTSetSuffix5 ARGS5( suff->quality = value; } +#ifdef LY_FIND_LEAKS /* ** Purpose: Free all added suffixes. ** Arguments: void @@ -460,60 +519,8 @@ PRIVATE void free_suffixes NOARGS HTList_delete(HTSuffixes); HTSuffixes = NULL; } +#endif /* LY_FIND_LEAKS */ -/* Send README file. -** ----------------- -** -** If a README file exists, then it is inserted into the document here. -*/ -#ifdef HAVE_READDIR -PRIVATE void do_readme ARGS2(HTStructured *, target, CONST char *, localname) -{ - FILE * fp; - char * readme_file_name = - malloc(strlen(localname)+ 1 + strlen(HT_DIR_README_FILE) + 1); - if (readme_file_name == NULL) - outofmem(__FILE__, "do_readme"); - strcpy(readme_file_name, localname); - strcat(readme_file_name, "/"); - strcat(readme_file_name, HT_DIR_README_FILE); - - fp = fopen(readme_file_name, "r"); - - if (fp) { - HTStructuredClass targetClass; - - targetClass = *target->isa; /* (Can't init agregate in K&R) */ - START(HTML_PRE); - for (;;){ - char c = fgetc(fp); - if (c == (char)EOF) break; -#ifdef NOTDEFINED - switch (c) { - case '&': - case '<': - case '>': - PUTC('&'); - PUTC('#'); - PUTC((char)(c / 10)); - PUTC((char) (c % 10)); - PUTC(';'); - break; -/* case '\n': - PUTC('\r'); -Bug removed thanks to joe@athena.mit.edu */ - default: - PUTC(c); - } -#else - PUTC(c); -#endif /* NOTDEFINED */ - } - END(HTML_PRE); - fclose(fp); - } -} -#endif /* HAVE_READDIR */ /* Make the cache file name for a W3 document. ** ------------------------------------------- @@ -531,14 +538,10 @@ PUBLIC char * HTCacheFileName ARGS1( char * acc_method = HTParse(name, "", PARSE_ACCESS); char * host = HTParse(name, "", PARSE_HOST); char * path = HTParse(name, "", PARSE_PATH+PARSE_PUNCTUATION); + char * result = NULL; + + HTSprintf0(&result, "%s/WWW/%s/%s%s", HTCacheRoot, acc_method, host, path); - char * result; - result = (char *)malloc( - strlen(HTCacheRoot)+strlen(acc_method) - +strlen(host)+strlen(path)+6+1); - if (result == NULL) - outofmem(__FILE__, "HTCacheFileName"); - sprintf(result, "%s/WWW/%s/%s%s", HTCacheRoot, acc_method, host, path); FREE(path); FREE(acc_method); FREE(host); @@ -565,71 +568,68 @@ PRIVATE int HTCreatePath ARGS1(CONST char *,path) ** On exit: ** Returns a malloc'ed string which must be freed by the caller. */ -PUBLIC char * HTLocalName ARGS1( - CONST char *, name) +PUBLIC char * HTnameOfFile_WWW ARGS3( + CONST char *, name, + BOOL, WWW_prefix, + BOOL, expand_all) { char * acc_method = HTParse(name, "", PARSE_ACCESS); char * host = HTParse(name, "", PARSE_HOST); char * path = HTParse(name, "", PARSE_PATH+PARSE_PUNCTUATION); + char * home; + char * result = NULL; - HTUnEscape(path); /* Interpret % signs */ + if (expand_all) + HTUnEscape(path); /* Interpret all % signs */ + else + HTUnEscapeSome(path, "/"); /* Interpret % signs for path delims */ - if (0 == strcmp(acc_method, "file")) { /* local file */ - FREE(acc_method); + if (0 == strcmp(acc_method, "file") /* local file */ + || !*acc_method) { /* implicitly local? */ if ((0 == strcasecomp(host, HTHostName())) || (0 == strcasecomp(host, "localhost")) || !*host) { - FREE(host); - if (TRACE) - fprintf(stderr, "Node `%s' means path `%s'\n", name, path); + CTRACE(tfp, "Node `%s' means path `%s'\n", name, path); #ifdef DOSPATH - { - char *ret_path = NULL; - StrAllocCopy(ret_path, HTDOS_name(path)); - if (TRACE) { - fprintf(stderr, "HTDOS_name changed `%s' to `%s'\n", - path, ret_path); - } - FREE(path); - return(ret_path); - } + StrAllocCopy(result, HTDOS_name(path)); +#else +#ifdef __EMX__ + if (path[0] == '/' + && isalpha(path[1]) + && path[2] == ':') /* pesky leading slash */ + StrAllocCopy(result, path+1); + else + StrAllocCopy(result, path); + CTRACE(tfp, "EMX hack changed `%s' to `%s'\n", path, result); #else - return(path); + StrAllocCopy(result, path); +#endif /* __EMX__ */ #endif /* DOSPATH */ + } else if (WWW_prefix) { + HTSprintf0(&result, "%s%s%s", "/Net/", host, path); + CTRACE(tfp, "Node `%s' means file `%s'\n", name, result); } else { - char * result = (char *)malloc( - strlen("/Net/")+strlen(host)+strlen(path)+1); - if (result == NULL) - outofmem(__FILE__, "HTLocalName"); - sprintf(result, "%s%s%s", "/Net/", host, path); - FREE(host); - FREE(path); - if (TRACE) - fprintf(stderr, "Node `%s' means file `%s'\n", name, result); - return result; + StrAllocCopy(result, path); } - } else { /* other access */ - char * result; + } else if (WWW_prefix) { /* other access */ #ifdef VMS - char * home = getenv("HOME"); - if (!home) + if ((home = getenv("HOME")) == 0) home = HTCacheRoot; else home = HTVMS_wwwName(home); #else - CONST char * home = (CONST char*)getenv("HOME"); - if (!home) + if ((home = getenv("HOME")) == 0) home = "/tmp"; #endif /* VMS */ - result = (char *)malloc( - strlen(home)+strlen(acc_method)+strlen(host)+strlen(path)+6+1); - if (result == NULL) - outofmem(__FILE__, "HTLocalName"); - sprintf(result, "%s/WWW/%s/%s%s", home, acc_method, host, path); - FREE(path); - FREE(acc_method); - FREE(host); - return result; + HTSprintf0(&result, "%s/WWW/%s/%s%s", home, acc_method, host, path); + } else { + StrAllocCopy(result, path); } + + FREE(host); + FREE(path); + FREE(acc_method); + + return result; } /* Make a WWW name from a full local path name. @@ -637,34 +637,24 @@ PUBLIC char * HTLocalName ARGS1( ** ** Bugs: ** At present, only the names of two network root nodes are hand-coded -** in and valid for the NeXT only. This should be configurable in +** in and valid for the NeXT only. This should be configurable in ** the general case. */ PUBLIC char * WWW_nameOfFile ARGS1( CONST char *, name) { - char * result; + char * result = NULL; #ifdef NeXT if (0 == strncmp("/private/Net/", name, 13)) { - result = (char *)malloc(7+strlen(name+13)+1); - if (result == NULL) - outofmem(__FILE__, "WWW_nameOfFile"); - sprintf(result, "file://%s", name+13); + HTSprintf0(&result, "file://%s", name+13); } else #endif /* NeXT */ if (0 == strncmp(HTMountRoot, name, 5)) { - result = (char *)malloc(7+strlen(name+5)+1); - if (result == NULL) - outofmem(__FILE__, "WWW_nameOfFile"); - sprintf(result, "file://%s", name+5); + HTSprintf0(&result, "file://%s", name+5); } else { - result = (char *)malloc(7+strlen(HTHostName())+strlen(name)+1); - if (result == NULL) - outofmem(__FILE__, "WWW_nameOfFile"); - sprintf(result, "file://%s%s", HTHostName(), name); + HTSprintf0(&result, "file://%s%s", HTHostName(), name); } - if (TRACE) - fprintf(stderr, "File `%s'\n\tmeans node `%s'\n", name, result); + CTRACE(tfp, "File `%s'\n\tmeans node `%s'\n", name, result); return result; } @@ -859,17 +849,13 @@ PUBLIC HTFormat HTCharsetFormat ARGS3( char *cp = NULL, *cp1, *cp2, *cp3 = NULL, *cp4; BOOL chartrans_ok = FALSE; int chndl = -1; - int i; FREE(anchor->charset); StrAllocCopy(cp, format->name); - for (i = 0; cp[i]; i++) - cp[i] = TOLOWER(cp[i]); + LYLowerCase(cp); if (((cp1 = strchr(cp, ';')) != NULL) && (cp2 = strstr(cp1, "charset")) != NULL) { - if (TRACE) - fprintf(stderr, - "HTCharsetFormat: Extended MIME Content-Type is %s\n", + CTRACE(tfp, "HTCharsetFormat: Extended MIME Content-Type is %s\n", format->name); cp2 += 7; while (*cp2 == ' ' || *cp2 == '=') @@ -896,6 +882,12 @@ PUBLIC HTFormat HTCharsetFormat ARGS3( ** Got something but we don't recognize it. */ chndl = UCLYhndl_for_unrec; + if (chndl < 0) + /* + ** UCLYhndl_for_unrec not defined :-( + ** fallback to UCLYhndl_for_unspec which always valid. + */ + chndl = UCLYhndl_for_unspec; /* always >= 0 */ if (UCCanTranslateFromTo(chndl, current_char_set)) { chartrans_ok = YES; HTAnchor_setUCInfoStage(anchor, chndl, @@ -940,48 +932,48 @@ PUBLIC HTFormat HTCharsetFormat ARGS3( HTPassEightBitRaw = TRUE; } } else if (p_out->enc == UCT_ENC_CJK) { - if (LYRawMode) { - if ((!strcmp(p_in->MIMEname, "euc-jp") || - !strcmp(p_in->MIMEname, "shift_jis")) && - (!strcmp(p_out->MIMEname, "euc-jp") || - !strcmp(p_out->MIMEname, "shift_jis"))) { - HTCJK = JAPANESE; - } else if (!strcmp(p_in->MIMEname, "euc-cn") && - !strcmp(p_out->MIMEname, "euc-cn")) { - HTCJK = CHINESE; - } else if (!strcmp(p_in->MIMEname, "big-5") && - !strcmp(p_out->MIMEname, "big-5")) { - HTCJK = TAIPEI; - } else if (!strcmp(p_in->MIMEname, "euc-kr") && - !strcmp(p_out->MIMEname, "euc-kr")) { - HTCJK = KOREAN; - } else { - HTCJK = NOCJK; - } - } else { - HTCJK = NOCJK; - } + Set_HTCJK(p_in->MIMEname, p_out->MIMEname); } - /* - ** Check for an iso-8859-# we don't know. - FM - */ - } else if (!strncmp(cp4, "iso-8859-", 9) && - isdigit((unsigned char)cp4[9]) && - !strncmp(LYchar_set_names[current_char_set], - "Other ISO Latin", 15)) { + } else { /* - ** Hope it's a match, for now. - FM + ** Cannot translate. + ** If according to some heuristic the given + ** charset and the current display character + ** both are likely to be like ISO-8859 in + ** structure, pretend we have some kind + ** of match. */ - *cp1 = '\0'; - format = HTAtom_for(cp); - cp1 = &cp4[10]; - while (*cp1 && - isdigit((unsigned char)(*cp1))) - cp1++; - *cp1 = '\0'; - StrAllocCopy(anchor->charset, cp4); - HTPassEightBitRaw = TRUE; - HTAlert(anchor->charset); + BOOL given_is_8859 + = (!strncmp(cp4, "iso-8859-", 9) && + isdigit((unsigned char)cp4[9])); + BOOL given_is_8859like + = (given_is_8859 || + !strncmp(cp4, "windows-", 8) || + !strncmp(cp4, "cp12", 4) || + !strncmp(cp4, "cp-12", 5)); + BOOL given_and_display_8859like + = (given_is_8859like && + (strstr(LYchar_set_names[current_char_set], + "ISO-8859") || + strstr(LYchar_set_names[current_char_set], + "windows-"))); + + if (given_and_display_8859like) { + *cp1 = '\0'; + format = HTAtom_for(cp); + } + if (given_is_8859) { + cp1 = &cp4[10]; + while (*cp1 && + isdigit((unsigned char)(*cp1))) + cp1++; + *cp1 = '\0'; + } + if (given_and_display_8859like) { + StrAllocCopy(anchor->charset, cp4); + HTPassEightBitRaw = TRUE; + } + HTAlert(*cp4 ? cp4 : anchor->charset); } FREE(cp3); } else if (cp1 != NULL) { @@ -1033,13 +1025,12 @@ PUBLIC float HTFileValue ARGS1( suff = (HTSuffix *)HTList_objectAt(HTSuffixes, i); ls = strlen(suff->suffix); if ((ls <= lf) && 0==strcmp(suff->suffix, filename + lf - ls)) { - if (TRACE) - fprintf(stderr, "File: Value of %s is %.3f\n", - filename, suff->quality); + CTRACE(tfp, "File: Value of %s is %.3f\n", + filename, suff->quality); return suff->quality; /* OK -- found */ } } - return 0.3; /* Dunno! */ + return 0.3; /* Dunno! */ } /* Determine write access to a file. @@ -1082,15 +1073,11 @@ PUBLIC BOOL HTEditable ARGS1( #ifdef NO_GROUPS return NO; /* Safe answer till we find the correct algorithm */ #else -#ifdef NeXT - int groups[NGROUPS]; -#else - gid_t groups[NGROUPS]; -#endif /* NeXT */ + GETGROUPS_T groups[NGROUPS]; uid_t myUid; - int ngroups; /* The number of groups */ + int ngroups; /* The number of groups */ struct stat fileStatus; - int i; + int i; if (stat(filename, &fileStatus)) /* Get details of filename */ return NO; /* Can't even access file! */ @@ -1100,14 +1087,16 @@ PUBLIC BOOL HTEditable ARGS1( if (TRACE) { int i2; - fprintf(stderr, + fprintf(tfp, "File mode is 0%o, uid=%d, gid=%d. My uid=%d, %d groups (", - (unsigned int) fileStatus.st_mode, fileStatus.st_uid, - fileStatus.st_gid, - myUid, ngroups); + (unsigned int) fileStatus.st_mode, + (int) fileStatus.st_uid, + (int) fileStatus.st_gid, + (int) myUid, + (int) ngroups); for (i2 = 0; i2 < ngroups; i2++) - fprintf(stderr, " %d", groups[i2]); - fprintf(stderr, ")\n"); + fprintf(tfp, " %d", (int) groups[i2]); + fprintf(tfp, ")\n"); } if (fileStatus.st_mode & 0002) /* I can write anyway? */ @@ -1124,8 +1113,7 @@ PUBLIC BOOL HTEditable ARGS1( return YES; } } - if (TRACE) - fprintf(stderr, "\tFile is not editable.\n"); + CTRACE(tfp, "\tFile is not editable.\n"); return NO; /* If no excuse, can't do */ #endif /* NO_GROUPS */ } @@ -1185,10 +1173,8 @@ PUBLIC void HTDirEntry ARGS3( /* ** If empty tail, gives absolute ref below. */ - relative = (char*)malloc(strlen(tail) + strlen(escaped)+2); - if (relative == NULL) - outofmem(__FILE__, "HTDirEntry"); - sprintf(relative, "%s%s%s", + relative = 0; + HTSprintf0(&relative, "%s%s%s", tail, (*escaped != '\0' ? "/" : ""), escaped); @@ -1260,11 +1246,11 @@ PUBLIC BOOL HTDirTitles ARGS3( char * printable = NULL; #ifdef DIRED_SUPPORT - if (0 == strncasecomp(path, "/%2F", 4)) - StrAllocCopy(printable, (path+1)); - else - StrAllocCopy(printable, path); - if (0 == strncasecomp(printable, "/vmsysu%2b", 10) || + printable = HTfullURL_toFile( + (0 == strncasecomp(path, "/%2F", 4)) /* "//" ? */ + ? (path+1) + : path); + if (0 == strncasecomp(printable, "/vmsysu:", 8) || 0 == strncasecomp(printable, "/anonymou.", 10)) { StrAllocCopy(cp, (printable+1)); StrAllocCopy(printable, cp); @@ -1272,30 +1258,30 @@ PUBLIC BOOL HTDirTitles ARGS3( } #else StrAllocCopy(printable, (current ? current + 1 : "")); + HTUnEscape(printable); #endif /* DIRED_SUPPORT */ START(HTML_HEAD); - PUTS("\n"); - HTUnEscape(printable); + PUTC('\n'); START(HTML_TITLE); - PUTS(*printable ? printable : "Welcome"); - PUTS(" directory"); + PUTS(*printable ? printable : WELCOME_MSG); + PUTS(SEGMENT_DIRECTORY); END(HTML_TITLE); - PUTS("\n"); + PUTC('\n'); END(HTML_HEAD); - PUTS("\n"); + PUTC('\n'); #ifdef DIRED_SUPPORT START(HTML_H2); - PUTS(*printable ? "Current directory is " : ""); - PUTS(*printable ? printable : "Welcome"); + PUTS(*printable ? SEGMENT_CURRENT_DIR : ""); + PUTS(*printable ? printable : WELCOME_MSG); END(HTML_H2); - PUTS("\n"); + PUTC('\n'); #else START(HTML_H1); - PUTS(*printable ? printable : "Welcome"); + PUTS(*printable ? printable : WELCOME_MSG); END(HTML_H1); - PUTS("\n"); + PUTC('\n'); #endif /* DIRED_SUPPORT */ if (((0 == strncasecomp(printable, "vmsysu:", 7)) && (cp = strchr(printable, '.')) != NULL && @@ -1330,10 +1316,8 @@ PUBLIC BOOL HTDirTitles ARGS3( return(need_parent_link); } - relative = (char*) malloc(strlen(current) + 4); - if (relative == NULL) - outofmem(__FILE__, "HTDirTitles"); - sprintf(relative, "%s/..", current); + relative = 0; + HTSprintf0(&relative, "%s/..", current); #ifdef DOSPATH if (local_link) @@ -1403,7 +1387,7 @@ PUBLIC BOOL HTDirTitles ARGS3( HTStartAnchor(target, "", relative); FREE(relative); - PUTS("Up to "); + PUTS(SEGMENT_UP_TO); if (parent) { if ((0 == strcmp(current,".")) || (0 == strcmp(current,".."))) { @@ -1420,9 +1404,10 @@ PUBLIC BOOL HTDirTitles ARGS3( FREE(printable); } } else { - PUTS("/"); + PUTC('/'); } END(HTML_A); + PUTC('\n'); } #endif /* !NO_PARENT_DIR_REFERENCE */ @@ -1431,6 +1416,418 @@ PUBLIC BOOL HTDirTitles ARGS3( return(need_parent_link); } +#if defined HAVE_READDIR +/* Send README file. +** ----------------- +** +** If a README file exists, then it is inserted into the document here. +*/ +PRIVATE void do_readme ARGS2(HTStructured *, target, CONST char *, localname) +{ + FILE * fp; + char * readme_file_name = + malloc(strlen(localname)+ 1 + strlen(HT_DIR_README_FILE) + 1); + if (readme_file_name == NULL) + outofmem(__FILE__, "do_readme"); + strcpy(readme_file_name, localname); + strcat(readme_file_name, "/"); + strcat(readme_file_name, HT_DIR_README_FILE); + + fp = fopen(readme_file_name, "r"); + + if (fp) { + HTStructuredClass targetClass; + + targetClass = *target->isa; /* (Can't init agregate in K&R) */ + START(HTML_PRE); + for (;;){ + char c = fgetc(fp); + if (c == (char)EOF) break; +#ifdef NOTDEFINED + switch (c) { + case '&': + case '<': + case '>': + PUTC('&'); + PUTC('#'); + PUTC((char)(c / 10)); + PUTC((char) (c % 10)); + PUTC(';'); + break; +/* case '\n': + PUTC('\r'); +Bug removed thanks to joe@athena.mit.edu */ + default: + PUTC(c); + } +#else + PUTC(c); +#endif /* NOTDEFINED */ + } + END(HTML_PRE); + HTDisplayPartial(); + fclose(fp); + } + FREE(readme_file_name); +} + +PRIVATE int print_local_dir ARGS5( + DIR *, dp, + char *, localname, + HTParentAnchor *, anchor, + HTFormat, format_out, + HTStream *, sink) +{ + HTStructured *target; /* HTML object */ + HTStructuredClass targetClass; + STRUCT_DIRENT * dirbuf; + char *logical = NULL; + char *pathname = NULL; + char *tail = NULL; + BOOL present[HTML_A_ATTRIBUTES]; + char * tmpfilename = NULL; + BOOL need_parent_link = FALSE; + struct stat file_info; + int status; + + CTRACE(tfp, "print_local_dir() started\n"); + + logical = HTAnchor_address((HTAnchor*)anchor); + pathname = HTParse(logical, "", + PARSE_PATH + PARSE_PUNCTUATION); + + if (!strcmp(pathname,"/")) { + /* + ** Root path. + */ + StrAllocCopy (tail, "/foo/.."); + } else { + char *p = strrchr(pathname, '/'); /* find last slash */ + + if (!p) { + /* + ** This probably should not happen, + ** but be prepared if it does. - KW + */ + StrAllocCopy (tail, "/foo/.."); + } else { + /* + ** Take slash off the beginning. + */ + StrAllocCopy(tail, (p + 1)); + } + } + FREE(pathname); + + if (UCLYhndl_HTFile_for_unspec >= 0) { + HTAnchor_setUCInfoStage(anchor, + UCLYhndl_HTFile_for_unspec, + UCT_STAGE_PARSER, + UCT_SETBY_DEFAULT); + } + + target = HTML_new(anchor, format_out, sink); + targetClass = *target->isa; /* Copy routine entry points */ + + { int i; + for (i = 0; i < HTML_A_ATTRIBUTES; i++) + present[i] = (i == HTML_A_HREF); + } + + /* + ** The need_parent_link flag will be set if an + ** "Up to <parent>" link was not created for a + ** readable parent in HTDirTitles() because + ** LONG_LIST is defined and NO_PARENT_DIR_REFERENCE + ** is not defined so that need we to create the + ** link via an LYListFmtParse() call. - FM + */ + need_parent_link = HTDirTitles(target, + (HTAnchor *)anchor, FALSE); + +#ifdef DIRED_SUPPORT + if (strncmp(anchor->address, "lynxcgi:", 8)) { + HTAnchor_setFormat((HTParentAnchor *) anchor, WWW_DIRED); + lynx_edit_mode = TRUE; + } +#endif /* DIRED_SUPPORT */ + if (HTDirReadme == HT_DIR_README_TOP) + do_readme(target, localname); + + + { + HTBTree * bt = HTBTree_new((HTComparer)AS_cmp); + int num_of_entries = 0; /* lines counter */ + + _HTProgress (gettext("Reading directory...")); + status = HT_LOADED; /* assume we don't get interrupted */ + while ((dirbuf = readdir(dp)) != NULL) { + /* + ** While there are directory entries to be read... + */ + char * dirname = NULL; + +#ifndef DOSPATH + if (dirbuf->d_ino == 0) + /* + ** If the entry is not being used, skip it. + */ + continue; +#endif + /* + ** Skip self, parent if handled in HTDirTitles() + ** or if NO_PARENT_DIR_REFERENCE is not defined, + ** and any dot files if no_dotfiles is set or + ** show_dotfiles is not set. - FM + */ + if (!strcmp(dirbuf->d_name, ".") /* self */ || + (!strcmp(dirbuf->d_name, "..") /* parent */ && + need_parent_link == FALSE) || + ((strcmp(dirbuf->d_name, "..")) && + (dirbuf->d_name[0] == '.' && + (no_dotfiles || !show_dotfiles)))) + continue; + + StrAllocCopy(tmpfilename, localname); + if (strcmp(localname, "/")) + /* + ** If filename is not root directory. + */ + StrAllocCat(tmpfilename, "/"); + + StrAllocCat(tmpfilename, dirbuf->d_name); + stat(tmpfilename, &file_info); + if (S_ISDIR(file_info.st_mode)) +#ifndef DIRED_SUPPORT + HTSprintf0(&dirname, "D%s",dirbuf->d_name); + else + HTSprintf0(&dirname, "F%s",dirbuf->d_name); + /* D & F to have first directories, then files */ +#else + { + if (dir_list_style == MIXED_STYLE) + HTSprintf0(&dirname, " %s/", dirbuf->d_name); + else if (!strcmp(dirbuf->d_name, "..")) + HTSprintf0(&dirname, "A%s", dirbuf->d_name); + else + HTSprintf0(&dirname, "D%s", dirbuf->d_name); + } + else if (dir_list_style == MIXED_STYLE) + HTSprintf0(&dirname, " %s", dirbuf->d_name); + else if (dir_list_style == FILES_FIRST) + HTSprintf0(&dirname, "C%s", dirbuf->d_name); + /* C & D to have first files, then directories */ + else + HTSprintf0(&dirname, "F%s", dirbuf->d_name); +#endif /* !DIRED_SUPPORT */ + /* + ** Sort dirname in the tree bt. + */ + HTBTree_add(bt, dirname); + +#ifdef DISP_PARTIAL + /* optimize for expensive operation: */ + if (num_of_entries % (partial_threshold > 0 ? + partial_threshold : display_lines) + == 0) { + if (HTCheckForInterrupt()) { + status = HT_PARTIAL_CONTENT; + break; + } + } + num_of_entries++; +#endif /* DISP_PARTIAL */ + + } /* end while directory entries left to read */ + + if (status != HT_PARTIAL_CONTENT) + _HTProgress (gettext("OK")); + else + CTRACE(tfp, "Reading the directory interrupred by user\n"); + + + /* + ** Run through tree printing out in order. + */ + { + HTBTElement * next_element = HTBTree_next(bt,NULL); + /* pick up the first element of the list */ + int num_of_entries_partial = 0; /* lines counter */ + + char state; + /* I for initial (.. file), + D for directory file, + F for file */ + +#ifdef DIRED_SUPPORT + char test; +#endif /* DIRED_SUPPORT */ + state = 'I'; + + while (next_element != NULL) { + char *entry, *file_extra; + + StrAllocCopy(tmpfilename,localname); + if (strcmp(localname, "/")) + /* + ** If filename is not root directory. + */ + StrAllocCat(tmpfilename, "/"); + + StrAllocCat(tmpfilename, + (char *)HTBTree_object(next_element)+1); + /* + ** Append the current entry's filename + ** to the path. + */ + HTSimplify(tmpfilename); + /* + ** Output the directory entry. + */ + if (strcmp((char *) + (HTBTree_object(next_element)), "D..") && + strcmp((char *) + (HTBTree_object(next_element)), "A..")) + { +#ifdef DIRED_SUPPORT + test = (*(char *)(HTBTree_object(next_element)) + == 'D' ? 'D' : 'F'); + if (state != test) { +#ifndef LONG_LIST + if (dir_list_style == FILES_FIRST) { + if (state == 'F') { + END(HTML_DIR); + PUTC('\n'); + } + } else if (dir_list_style != MIXED_STYLE) + if (state == 'D') { + END(HTML_DIR); + PUTC('\n'); + } +#endif /* !LONG_LIST */ + state = + (*(char *)(HTBTree_object(next_element)) + == 'D' ? 'D' : 'F'); + START(HTML_H2); + if (dir_list_style != MIXED_STYLE) { + START(HTML_EM); + PUTS(state == 'D' + ? LABEL_SUBDIRECTORIES + : LABEL_FILES); + END(HTML_EM); + } + END(HTML_H2); + PUTC('\n'); +#ifndef LONG_LIST + START(HTML_DIR); + PUTC('\n'); +#endif /* !LONG_LIST */ + } +#else + if (state != *(char *)(HTBTree_object( + next_element))) { +#ifndef LONG_LIST + if (state == 'D') { + END(HTML_DIR); + PUTC('\n'); + } +#endif /* !LONG_LIST */ + state = + (*(char *)(HTBTree_object(next_element)) + == 'D' ? 'D' : 'F'); + START(HTML_H2); + START(HTML_EM); + PUTS(state == 'D' + ? LABEL_SUBDIRECTORIES + : LABEL_FILES); + END(HTML_EM); + END(HTML_H2); + PUTC('\n'); +#ifndef LONG_LIST + START(HTML_DIR); + PUTC('\n'); +#endif /* !LONG_LIST */ + } +#endif /* DIRED_SUPPORT */ +#ifndef LONG_LIST + START(HTML_LI); +#endif /* !LONG_LIST */ + } + entry = (char*)HTBTree_object(next_element)+1; + file_extra = NULL; + +#ifdef LONG_LIST + LYListFmtParse(list_format, tmpfilename, target, + entry, tail); +#else + HTDirEntry(target, tail, entry); + PUTS(entry); + END(HTML_A); + if (file_extra) { + PUTS(file_extra); + FREE(file_extra); + } + MAYBE_END(HTML_LI); + PUTC('\n'); +#endif /* LONG_LIST */ + + next_element = HTBTree_next(bt, next_element); + /* pick up the next element of the list; + if none, return NULL*/ + + /* optimize for expensive operation: */ +#ifdef DISP_PARTIAL + if (num_of_entries_partial % + (partial_threshold > 0 ? partial_threshold : display_lines) + == 0) { + /* num_of_entries, num_of_entries_partial... */ + /* HTReadProgress...(bytes, 0); */ + HTDisplayPartial(); + + if (HTCheckForInterrupt()) { + _HTProgress (TRANSFER_INTERRUPTED); + status = HT_PARTIAL_CONTENT; + break; + } + } + num_of_entries_partial++; +#endif /* DISP_PARTIAL */ + + } /* end while next_element */ + + if (status == HT_LOADED) { + if (state == 'I') { + START(HTML_P); + PUTS("Empty Directory"); + } +#ifndef LONG_LIST + else + END(HTML_DIR); +#endif /* !LONG_LIST */ + } + } /* end printing out the tree in order */ + + closedir(dp); + FREE(logical); + FREE(tmpfilename); + FREE(tail); + HTBTreeAndObject_free(bt); + + if (status == HT_LOADED) { + if (HTDirReadme == HT_DIR_README_BOTTOM) + do_readme(target, localname); + FREE_TARGET; + } else { + ABORT_TARGET; + } + } + HTFinishDisplayPartial(); + return status; /* document loaded, maybe partial */ +} +#endif /* HAVE_READDIR */ + + + /* Load a document. ** ---------------- ** @@ -1439,7 +1836,7 @@ PUBLIC BOOL HTDirTitles ARGS3( ** This is the physical address of the file ** ** On exit: -** returns <0 Error has occurred. +** returns <0 Error has occurred. ** HTLOADED OK ** */ @@ -1488,7 +1885,11 @@ PUBLIC int HTLoadFile ARGS4( FREE(filename); FREE(nodename); FREE(acc_method); +#ifndef DISABLE_FTP return HTFTPLoad(addr, anchor, format_out, sink); +#else + return -1; +#endif /* DISABLE_FTP */ } else { FREE(newname); FREE(acc_method); @@ -1509,6 +1910,13 @@ PUBLIC int HTLoadFile ARGS4( format = HTAtom_for(anchor->content_type); myEncoding = HTAtom_for(anchor->content_encoding); } else { + int default_UCLYhndl = UCLYhndl_HTFile_for_unspec; + + if (force_old_UCLYhndl_on_reload) { + force_old_UCLYhndl_on_reload = FALSE; + default_UCLYhndl = forced_UCLYhdnl; + } + format = HTFileFormat(filename, &myEncoding, NULL); /* @@ -1517,7 +1925,7 @@ PUBLIC int HTLoadFile ARGS4( ** by the last parameter (fallback will effectively be ** UCLYhndl_for_unspec, by default ISO-8859-1). - kw */ - format = HTCharsetFormat(format, anchor, UCLYhndl_HTFile_for_unspec); + format = HTCharsetFormat(format, anchor, default_UCLYhndl ); } #ifdef VMS @@ -1528,15 +1936,13 @@ PUBLIC int HTLoadFile ARGS4( ** to the directories or files listed. */ if (HTStat(filename, &stat_info) == -1) { - if (TRACE) - fprintf(stderr, "HTLoadFile: Can't stat %s\n", filename); + CTRACE(tfp, "HTLoadFile: Can't stat %s\n", filename); } else { - if (((stat_info.st_mode) & S_IFMT) == S_IFDIR) { + if (S_ISDIR(stat_info.st_mode)) { if (HTDirAccess == HT_DIR_FORBID) { FREE(filename); FREE(nodename); - return HTLoadError(sink, 403, - "Directory browsing is not allowed."); + return HTLoadError(sink, 403, DISALLOWED_DIR_SCAN); } if (HTDirAccess == HT_DIR_SELECTIVE) { @@ -1551,8 +1957,8 @@ PUBLIC int HTLoadFile ARGS4( if (HTStat(enable_file_name, &stat_info) == -1) { FREE(filename); FREE(nodename); - return HTLoadError(sink, 403, - "Selective access is not enabled for this directory"); + FREE(enable_file_name); + return HTLoadError(sink, 403, DISALLOWED_SELECTIVE_ACCESS); } } @@ -1576,16 +1982,15 @@ PUBLIC int HTLoadFile ARGS4( ** If the file wasn't VMS syntax, then perhaps it is Ultrix. */ if (!fp) { - char ultrixname[INFINITY]; - if (TRACE) - fprintf(stderr, "HTLoadFile: Can't open as %s\n", vmsname); - sprintf(ultrixname, "%s::\"%s\"", nodename, filename); + char * ultrixname = 0; + CTRACE(tfp, "HTLoadFile: Can't open as %s\n", vmsname); + HTSprintf0(&ultrixname, "%s::\"%s\"", nodename, filename); fp = fopen(ultrixname, "r", "shr=put", "shr=upd"); if (!fp) { - if (TRACE) - fprintf(stderr, "HTLoadFile: Can't open as %s\n", - ultrixname); + CTRACE(tfp, "HTLoadFile: Can't open as %s\n", + ultrixname); } + FREE(ultrixname); } if (fp) { int len; @@ -1624,9 +2029,7 @@ PUBLIC int HTLoadFile ARGS4( *semicolon = ';'; gzfp = gzopen(vmsname, "rb"); - if (TRACE) - fprintf(stderr, - "HTLoadFile: gzopen of `%s' gives %p\n", + CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", vmsname, (void*)gzfp); use_gzread = YES; } else @@ -1672,9 +2075,7 @@ PUBLIC int HTLoadFile ARGS4( *semicolon = ';'; gzfp = gzopen(vmsname, "rb"); - if (TRACE) - fprintf(stderr, - "HTLoadFile: gzopen of `%s' gives %p\n", + CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", vmsname, (void*)gzfp); use_gzread = YES; } @@ -1717,7 +2118,7 @@ PUBLIC int HTLoadFile ARGS4( } else { status = HTLoadError(NULL, -(HT_ERROR), - "Could not open file for decompression!"); + FAILED_OPEN_COMPRESSED_FILE); } } else #endif /* USE_ZLIB */ @@ -1757,7 +2158,7 @@ PUBLIC int HTLoadFile ARGS4( if ((strlen(localname) > strlen(MULTI_SUFFIX)) && (0 == strcmp(localname + strlen(localname) - strlen(MULTI_SUFFIX), MULTI_SUFFIX))) { - DIR *dp; + DIR *dp = 0; BOOL forget_multi = NO; STRUCT_DIRENT * dirbuf; @@ -1772,7 +2173,7 @@ PUBLIC int HTLoadFile ARGS4( if (!base || base == localname) { forget_multi = YES; } else { - *base++ = '\0'; /* Just got directory name */ + *base++ = '\0'; /* Just got directory name */ baselen = strlen(base)- strlen(MULTI_SUFFIX); base[baselen] = '\0'; /* Chop off suffix */ @@ -1781,8 +2182,7 @@ PUBLIC int HTLoadFile ARGS4( if (forget_multi || !dp) { FREE(localname); FREE(nodename); - return HTLoadError(sink, 500, - "Multiformat: directory scan failed."); + return HTLoadError(sink, 500, FAILED_DIR_SCAN); } while ((dirbuf = readdir(dp)) != NULL) { @@ -1847,16 +2247,14 @@ PUBLIC int HTLoadFile ARGS4( } } if (value != NO_VALUE_FOUND) { - if (TRACE) - fprintf(stderr, - "HTLoadFile: value of presenting %s is %f\n", + CTRACE(tfp, "HTLoadFile: value of presenting %s is %f\n", HTAtom_name(rep), value); if (value > best) { best_rep = rep; best_enc = enc; best = value; StrAllocCopy(best_name, dirbuf->d_name); - } + } } /* if best so far */ } /* if match */ @@ -1866,15 +2264,14 @@ PUBLIC int HTLoadFile ARGS4( if (best_rep) { format = best_rep; myEncoding = best_enc; - base[-1] = '/'; /* Restore directory name */ + base[-1] = '/'; /* Restore directory name */ base[0] = '\0'; StrAllocCat(localname, best_name); FREE(best_name); } else { /* If not found suitable file */ FREE(localname); FREE(nodename); - return HTLoadError(sink, 403, /* List formats? */ - "Could not find suitable representation for transmission."); + return HTLoadError(sink, 403, FAILED_NO_REPRESENTATION); } /*NOTREACHED*/ } /* if multi suffix */ @@ -1894,9 +2291,8 @@ PUBLIC int HTLoadFile ARGS4( if (stat(localname,&dir_info) == -1) /* get file information */ #endif { - /* if can't read file information */ - if (TRACE) - fprintf(stderr, "HTLoadFile: can't stat %s\n", localname); + /* if can't read file information */ + CTRACE(tfp, "HTLoadFile: can't stat %s\n", localname); } else { /* Stat was OK */ @@ -1904,24 +2300,14 @@ PUBLIC int HTLoadFile ARGS4( if (stat(localname,&dir_info) == -1) dir_info.st_mode = S_IFDIR; #endif - if (((dir_info.st_mode) & S_IFMT) == S_IFDIR) { + if (S_ISDIR(dir_info.st_mode)) { /* ** If localname is a directory. */ - HTStructured *target; /* HTML object */ - HTStructuredClass targetClass; DIR *dp; - STRUCT_DIRENT * dirbuf; - char *logical = NULL; - char *pathname = NULL; - char *tail = NULL; - BOOL present[HTML_A_ATTRIBUTES]; - char * tmpfilename = NULL; - BOOL need_parent_link = FALSE; struct stat file_info; - if (TRACE) - fprintf(stderr, "%s is a directory\n", localname); + CTRACE(tfp, "%s is a directory\n", localname); /* ** Check directory access. @@ -1931,8 +2317,7 @@ PUBLIC int HTLoadFile ARGS4( if (HTDirAccess == HT_DIR_FORBID) { FREE(localname); FREE(nodename); - return HTLoadError(sink, 403, - "Directory browsing is not allowed."); + return HTLoadError(sink, 403, DISALLOWED_DIR_SCAN); } @@ -1948,8 +2333,8 @@ PUBLIC int HTLoadFile ARGS4( if (stat(enable_file_name, &file_info) != 0) { FREE(localname); FREE(nodename); - return HTLoadError(sink, 403, - "Selective access is not enabled for this directory"); + FREE(enable_file_name); + return HTLoadError(sink, 403, DISALLOWED_SELECTIVE_ACCESS); } } @@ -1957,285 +2342,20 @@ PUBLIC int HTLoadFile ARGS4( if (!dp) { FREE(localname); FREE(nodename); - return HTLoadError(sink, 403, - "This directory is not readable."); + return HTLoadError(sink, 403, FAILED_DIR_UNREADABLE); } /* ** Directory access is allowed and possible. */ - logical = HTAnchor_address((HTAnchor*)anchor); - pathname = HTParse(logical, "", - PARSE_PATH + PARSE_PUNCTUATION); - - if (!strcmp(pathname,"/")) { - /* - ** Root path. - */ - StrAllocCopy (tail, "/foo/.."); - } else { - char *p = strrchr(pathname, '/'); /* find last slash */ - - if (!p) { - /* - ** This probably should not happen, - ** but be prepared if it does. - KW - */ - StrAllocCopy (tail, "/foo/.."); - } else { - /* - ** Take slash off the beginning. - */ - StrAllocCopy(tail, (p + 1)); - } - } - FREE(pathname); - - if (UCLYhndl_HTFile_for_unspec >= 0) { - HTAnchor_setUCInfoStage(anchor, - UCLYhndl_HTFile_for_unspec, - UCT_STAGE_PARSER, - UCT_SETBY_DEFAULT); - } - - target = HTML_new(anchor, format_out, sink); - targetClass = *target->isa; /* Copy routine entry points */ - - { int i; - for (i = 0; i < HTML_A_ATTRIBUTES; i++) - present[i] = (i == HTML_A_HREF); - } - - /* - ** The need_parent_link flag will be set if an - ** "Up to <parent>" link was not created for a - ** readable parent in HTDirTitles() because - ** LONG_LIST is defined and NO_PARENT_DIR_REFERENCE - ** is not defined so that need we to create the - ** link via an LYListFmtParse() call. - FM - */ - need_parent_link = HTDirTitles(target, - (HTAnchor *)anchor, FALSE); -#ifdef DIRED_SUPPORT - if (strncmp(anchor->address, "lynxcgi:", 8)) { - HTAnchor_setFormat((HTParentAnchor *) anchor, WWW_DIRED); - lynx_edit_mode = TRUE; - } -#endif /* DIRED_SUPPORT */ - if (HTDirReadme == HT_DIR_README_TOP) - do_readme(target, localname); - { - HTBTree * bt = HTBTree_new((HTComparer)strcmp); - - while ((dirbuf = readdir(dp)) != NULL) { - /* - ** While there are directory entries to be read... - */ - char * dirname = NULL; - -#ifndef DOSPATH - if (dirbuf->d_ino == 0) - /* - ** If the entry is not being used, skip it. - */ - continue; -#endif - /* - ** Skip self, parent if handled in HTDirTitles() - ** or if NO_PARENT_DIR_REFERENCE is not defined, - ** and any dot files if no_dotfiles is set or - ** show_dotfiles is not set. - FM - */ - if (!strcmp(dirbuf->d_name, ".") /* self */ || - (!strcmp(dirbuf->d_name, "..") /* parent */ && - need_parent_link == FALSE) || - ((strcmp(dirbuf->d_name, "..")) && - (dirbuf->d_name[0] == '.' && - (no_dotfiles || !show_dotfiles)))) - continue; - - dirname = (char *)malloc(strlen(dirbuf->d_name) + 4); - if (dirname == NULL) - outofmem(__FILE__, "HTLoadFile"); - StrAllocCopy(tmpfilename, localname); - if (strcmp(localname, "/")) - /* - ** If filename is not root directory. - */ - StrAllocCat(tmpfilename, "/"); - - StrAllocCat(tmpfilename, dirbuf->d_name); - stat(tmpfilename, &file_info); - if (((file_info.st_mode) & S_IFMT) == S_IFDIR) -#ifndef DIRED_SUPPORT - sprintf((char *)dirname, "D%s",dirbuf->d_name); - else - sprintf((char *)dirname, "F%s",dirbuf->d_name); - /* D & F to have first directories, then files */ -#else - if (dir_list_style == MIXED_STYLE) - sprintf((char *)dirname, - " %s/", dirbuf->d_name); - else if (!strcmp(dirbuf->d_name, "..")) - sprintf((char *)dirname, - "A%s", dirbuf->d_name); - else - sprintf((char *)dirname, - "D%s", dirbuf->d_name); - else if (dir_list_style == MIXED_STYLE) - sprintf((char *)dirname, " %s", dirbuf->d_name); - else if (dir_list_style == FILES_FIRST) - sprintf((char *)dirname, "C%s", dirbuf->d_name); - /* C & D to have first files, then directories */ - else - sprintf((char *)dirname, "F%s", dirbuf->d_name); -#endif /* !DIRED_SUPPORT */ - /* - ** Sort dirname in the tree bt. - */ - HTBTree_add(bt, dirname); - } - - /* - ** Run through tree printing out in order. - */ - { - HTBTElement * next_element = HTBTree_next(bt,NULL); - /* pick up the first element of the list */ - char state; - /* I for initial (.. file), - D for directory file, - F for file */ - -#ifdef DIRED_SUPPORT - char test; -#endif /* DIRED_SUPPORT */ - state = 'I'; - - while (next_element != NULL) { - char *entry, *file_extra; - - StrAllocCopy(tmpfilename,localname); - if (strcmp(localname, "/")) - /* - ** If filename is not root directory. - */ - StrAllocCat(tmpfilename, "/"); - - StrAllocCat(tmpfilename, - (char *)HTBTree_object(next_element)+1); - /* - ** Append the current entry's filename - ** to the path. - */ - HTSimplify(tmpfilename); - /* - ** Output the directory entry. - */ - if (strcmp((char *) - (HTBTree_object(next_element)), "D..") && - strcmp((char *) - (HTBTree_object(next_element)), "A..")) - { -#ifdef DIRED_SUPPORT - test = (*(char *)(HTBTree_object(next_element)) - == 'D' ? 'D' : 'F'); - if (state != test) { -#ifndef LONG_LIST - if (dir_list_style == FILES_FIRST) { - if (state == 'F') - END(HTML_DIR); - } else if (dir_list_style != MIXED_STYLE) - if (state == 'D') - END(HTML_DIR); -#endif /* !LONG_LIST */ - state = - (*(char *)(HTBTree_object(next_element)) - == 'D' ? 'D' : 'F'); - START(HTML_H2); - if (dir_list_style != MIXED_STYLE) { - START(HTML_EM); - PUTS(state == 'D' ? - "Subdirectories:" : "Files:"); - END(HTML_EM); - } - END(HTML_H2); -#ifndef LONG_LIST - START(HTML_DIR); -#endif /* !LONG_LIST */ - } -#else - if (state != *(char *)(HTBTree_object( - next_element))) { -#ifndef LONG_LIST - if (state == 'D') - END(HTML_DIR); -#endif /* !LONG_LIST */ - state = - (*(char *)(HTBTree_object(next_element)) - == 'D' ? 'D' : 'F'); - START(HTML_H2); - START(HTML_EM); - PUTS(state == 'D' ? - "Subdirectories:" : "Files:"); - END(HTML_EM); - END(HTML_H2); -#ifndef LONG_LIST - START(HTML_DIR); -#endif /* !LONG_LIST */ - } -#endif /* DIRED_SUPPORT */ -#ifndef LONG_LIST - START(HTML_LI); -#endif /* !LONG_LIST */ - } - entry = (char*)HTBTree_object(next_element)+1; - file_extra = NULL; - -#ifdef LONG_LIST - LYListFmtParse(list_format, tmpfilename, target, - entry, tail); -#else - HTDirEntry(target, tail, entry); - PUTS(entry); - END(HTML_A); - if (file_extra) { - PUTS(file_extra); - FREE(file_extra); - } - MAYBE_END(HTML_LI); -#endif /* LONG_LIST */ - - next_element = HTBTree_next(bt, next_element); - /* pick up the next element of the list; - if none, return NULL*/ - } - if (state == 'I') { - START(HTML_P); - PUTS("Empty Directory"); - } -#ifndef LONG_LIST - else - END(HTML_DIR); -#endif /* !LONG_LIST */ - } - /* end while directory entries left to read */ - closedir(dp); - FREE(logical); - FREE(tmpfilename); - FREE(tail); - HTBTreeAndObject_free(bt); - - if (HTDirReadme == HT_DIR_README_BOTTOM) - do_readme(target, localname); - FREE_TARGET; - FREE(localname); - FREE(nodename); - return HT_LOADED; /* document loaded */ - } + status = print_local_dir(dp, localname, + anchor, format_out, sink); + FREE(localname); + FREE(nodename); + return status; /* document loaded, maybe partial */ - } /* end if localname is directory */ + } /* end if localname is a directory */ } /* end if file stat worked */ @@ -2243,10 +2363,15 @@ PUBLIC int HTLoadFile ARGS4( */ #endif /* HAVE_READDIR */ { +# ifdef __EMX__ + int len = strlen(localname); + int bin = ((len > 3) && !strcasecomp(localname + len - 3, ".gz")); + FILE * fp = fopen(localname, (bin ? "rb" : "r")); +# else /* !( defined __EMX__ ) */ FILE * fp = fopen(localname, "r"); +# endif - if (TRACE) - fprintf (stderr, "HTLoadFile: Opening `%s' gives %p\n", + CTRACE (tfp, "HTLoadFile: Opening `%s' gives %p\n", localname, (void*)fp); if (fp) { /* Good! */ int len; @@ -2275,9 +2400,7 @@ PUBLIC int HTLoadFile ARGS4( fclose(fp); gzfp = gzopen(localname, "rb"); - if (TRACE) - fprintf(stderr, - "HTLoadFile: gzopen of `%s' gives %p\n", + CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", localname, (void*)gzfp); use_gzread = YES; } else @@ -2316,9 +2439,7 @@ PUBLIC int HTLoadFile ARGS4( fclose(fp); gzfp = gzopen(localname, "rb"); - if (TRACE) - fprintf(stderr, - "HTLoadFile: gzopen of `%s' gives %p\n", + CTRACE(tfp, "HTLoadFile: gzopen of `%s' gives %p\n", localname, (void*)gzfp); use_gzread = YES; } @@ -2358,7 +2479,7 @@ PUBLIC int HTLoadFile ARGS4( } else { status = HTLoadError(NULL, -(HT_ERROR), - "Could not open file for decompression!"); + FAILED_OPEN_COMPRESSED_FILE); } } else #endif /* USE_ZLIB */ @@ -2394,7 +2515,11 @@ PUBLIC int HTLoadFile ARGS4( * is file://localhost */ } else { +#ifndef DISABLE_FTP return HTFTPLoad(addr, anchor, format_out, sink); +#else + return -1; +#endif /* DISABLE_FTP */ } } FREE(nodename); @@ -2405,10 +2530,9 @@ PUBLIC int HTLoadFile ARGS4( ** All attempts have failed. */ { - if (TRACE) - fprintf(stderr, "Can't open `%s', errno=%d\n", addr, SOCKET_ERRNO); + CTRACE(tfp, "Can't open `%s', errno=%d\n", addr, SOCKET_ERRNO); - return HTLoadError(sink, 403, "Can't access requested file."); + return HTLoadError(sink, 403, FAILED_FILE_UNREADABLE); } } |
