📄 htfile.c
字号:
/* File Access HTFile.c** ===========**** This is unix-specific code in general, with some VMS bits.** These are routines for file access used by browsers.** Development of this module for Unix DIRED_SUPPORT in Lynx** regrettably has has been conducted in a manner with now** creates a major impediment for hopes of adapting Lynx to** a newer version of the library.**** History:** Feb 91 Written Tim Berners-Lee CERN/CN** Apr 91 vms-vms access included using DECnet syntax** 26 Jun 92 (JFG) When running over DECnet, suppressed FTP.** Fixed access bug for relative names on VMS.** Sep 93 (MD) Access to VMS files allows sharing.** 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.*/#include <HTUtils.h>#ifndef VMS#if defined(DOSPATH)#undef LONG_LIST#define LONG_LIST /* Define this for long style unix listings (ls -l), the actual style is configurable from lynx.cfg */#endif/* #define NO_PARENT_DIR_REFERENCE */ /* Define this for no parent links */#endif /* !VMS */#if defined(DOSPATH)#define HAVE_READDIR 1#define USE_DIRENT#endif#if defined(USE_DOS_DRIVES)#include <HTDOS.h>#endif#include <HTFile.h> /* Implemented here */#ifdef VMS#include <stat.h>#endif /* VMS */#if defined (USE_ZLIB) || defined (USE_BZLIB)#include <GridText.h>#endif#define MULTI_SUFFIX ".multi" /* Extension for scanning formats */#include <HTParse.h>#include <HTTCP.h>#ifndef DECNET#include <HTFTP.h>#endif /* !DECNET */#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; HTAtom * rep; HTAtom * encoding; char * desc; float quality;} HTSuffix;typedef struct { struct stat file_info; char sort_tags; char file_name[1]; /* on the end of the struct, since its length varies */} DIRED;#ifndef NGROUPS#ifdef NGROUPS_MAX#define NGROUPS NGROUPS_MAX#else#define NGROUPS 32#endif /* NGROUPS_MAX */#endif /* NGROUPS */#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)#define START(e) (*target->isa->start_element)(target, e, 0, 0, -1, 0)#define END(e) (*target->isa->end_element)(target, e, 0)#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; /* ... */};/*** Controlling globals.*/PUBLIC int HTDirAccess = HT_DIR_OK;#ifdef DIRED_SUPPORTPUBLIC int HTDirReadme = HT_DIR_README_NONE;#elsePUBLIC int HTDirReadme = HT_DIR_README_TOP;#endif /* DIRED_SUPPORT */PRIVATE char *HTMountRoot = "/Net/"; /* Where to find mounts */#ifdef VMSPRIVATE char *HTCacheRoot = "/WWW$SCRATCH"; /* Where to cache things */#elsePRIVATE char *HTCacheRoot = "/tmp/W3_Cache_"; /* Where to cache things */#endif /* VMS *//*** Suffix registration.*/PRIVATE HTList * HTSuffixes = 0;PRIVATE HTSuffix no_suffix = { "*", NULL, NULL, NULL, 1.0 };PRIVATE HTSuffix unknown_suffix = { "*.*", NULL, NULL, NULL, 1.0};/* To free up the suffixes at program exit.** ----------------------------------------*/#ifdef LY_FIND_LEAKSPRIVATE void free_suffixes NOPARAMS;#endif#ifdef LONG_LISTPRIVATE 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 if (*bufp && !(entry && *entry)) { **bufp = '\0'; } else if (entry) { StrAllocCopy(*bufp, 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); StrAllocCopy(*bufp, fmt); } return *bufp;}PRIVATE void LYListFmtParse ARGS5( char *, fmtstr, DIRED *, data, char *, file, HTStructured *, target, char *, tail){ char c; char *s; char *end; char *start; char *str = NULL; char *buf = NULL; char tmp[LY_MAXPATH]; char type;#ifndef NOUSERS char *name;#endif time_t now; char *datestr;#ifdef S_IFLNK int len;#endif#define SEC_PER_YEAR (60 * 60 * 24 * 365)#ifdef _WINDOWS /* 1998/01/06 (Tue) 21:20:53 */ static char *pbits[] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx", 0 };#define PBIT(a, n, s) pbits[((a) >> (n)) & 0x7]#else static char *pbits[] = { "---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx", 0 }; static char *psbits[] = { "--S", "--s", "-wS", "-ws", "r-S", "r-s", "rwS", "rws", 0 };#define PBIT(a, n, s) (s) ? psbits[((a) >> (n)) & 0x7] : \ pbits[((a) >> (n)) & 0x7]#endif#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 (data->file_info.st_mode == 0) fmtstr = " %a"; /* can't stat so just do anchor */ StrAllocCopy(str, fmtstr); s = str; end = str + strlen(str); START(HTML_PRE); while (*s) { start = s; while (*s) { if (*s == '%') { if (*(s+1) == '%') /* literal % */ s++; else break; } s++; } /* s is positioned either at a % or at \0 */ *s = '\0'; if (s > start) { /* some literal chars. */ PUTS(start); } if (s == end) break; start = ++s; while (isdigit(UCH(*s)) || *s == '.' || *s == '-' || *s == ' ' || *s == '#' || *s == '+' || *s == '\'') s++; c = *s; /* the format char. or \0 */ *s = '\0'; switch (c) { case '\0': PUTS(start); continue; case 'A': case 'a': /* anchor */ HTDirEntry(target, tail, data->file_name); FormatStr(&buf, start, data->file_name); PUTS(buf); END(HTML_A); *buf = '\0';#ifdef S_IFLNK if (c != 'A' && S_ISLNK(data->file_info.st_mode) && (len = readlink(file, tmp, sizeof(tmp) - 1)) >= 0) { PUTS(" -> "); tmp[len] = '\0'; PUTS(tmp); }#endif break; case 'T': /* MIME type */ case 't': /* MIME type description */ if (S_ISDIR(data->file_info.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(&data->file_info.st_mtime); if ((now - data->file_info.st_mtime) < SEC_PER_YEAR/2) /* ** MMM DD HH:MM */ sprintf(tmp, "%.12s", datestr + 4); else /* ** MMM DD YYYY */ sprintf(tmp, "%.7s %.4s ", datestr + 4, datestr + 20); FormatStr(&buf, start, tmp); break; case 's': /* size in bytes */ FormatNum(&buf, start, (int) data->file_info.st_size); break; case 'K': /* size in Kilobytes but not for directories */ if (S_ISDIR(data->file_info.st_mode)) { FormatStr(&buf, start, ""); StrAllocCat(buf, " "); break; } /* FALL THROUGH */ case 'k': /* size in Kilobytes */ FormatNum(&buf, start, (int)((data->file_info.st_size+1023)/1024)); StrAllocCat(buf, "K"); break; case 'p': /* unix-style permission bits */ switch(data->file_info.st_mode & S_IFMT) {#if defined(_MSC_VER) && defined(_S_IFIFO) case _S_IFIFO: type = 'p'; break;#else case S_IFIFO: type = 'p'; break;#endif case S_IFCHR: type = 'c'; break; case S_IFDIR: type = 'd'; break; case S_IFREG: type = '-'; break;#ifdef S_IFBLK case S_IFBLK: type = 'b'; break;#endif#ifdef S_IFLNK case S_IFLNK: type = 'l'; break;#endif#ifdef S_IFSOCK# ifdef S_IFIFO /* some older machines (e.g., apollo) have a conflict */# if S_IFIFO != S_IFSOCK case S_IFSOCK: type = 's'; break;# endif# else case S_IFSOCK: type = 's'; break;# endif#endif /* S_IFSOCK */ default: type = '?'; break; }#ifdef _WINDOWS sprintf(tmp, "%c%s", type, PBIT(data->file_info.st_mode, 6, data->file_info.st_mode & S_IRWXU));#else sprintf(tmp, "%c%s%s%s", type, PBIT(data->file_info.st_mode, 6, data->file_info.st_mode & S_ISUID), PBIT(data->file_info.st_mode, 3, data->file_info.st_mode & S_ISGID), PTBIT(data->file_info.st_mode, data->file_info.st_mode & S_ISVTX));#endif FormatStr(&buf, start, tmp); break; case 'o': /* owner */#ifndef NOUSERS name = HTAA_UidToName (data->file_info.st_uid); if (*name) { FormatStr(&buf, start, name); } else { FormatNum(&buf, start, (int) data->file_info.st_uid); }#endif break; case 'g': /* group */#ifndef NOUSERS name = HTAA_GidToName(data->file_info.st_gid); if (*name) { FormatStr(&buf, start, name); } else { FormatNum(&buf, start, (int) data->file_info.st_gid); }#endif break; case 'l': /* link count */ FormatNum(&buf, start, (int) data->file_info.st_nlink); break; case '%': /* literal % with flags/width */ FormatStr(&buf, start, "%"); break; default: fprintf(stderr, "Unknown format character `%c' in list format\n", c); break; } if (buf) PUTS(buf); s++; } FREE(buf); END(HTML_PRE); PUTC('\n'); FREE(str);}#endif /* LONG_LIST *//* Define the representation associated with a file suffix.** --------------------------------------------------------**** Calling this with suffix set to "*" will set the default** representation.** Calling this with suffix set to "*.*" will set the default** representation for unknown suffix files which contain a ".".**** The encoding parameter can give a trivial (8bit, 7bit, binary)** or real (gzip, compress) encoding.**** If filename suffix is already defined with the same encoding** its previous definition is overridden.*/PUBLIC void HTSetSuffix5 ARGS5( CONST char *, suffix, CONST char *, representation, CONST char *, encoding, CONST char *, desc, double, value){ HTSuffix * suff; BOOL trivial_enc = (BOOL) IsUnityEncStr(encoding); if (strcmp(suffix, "*") == 0) suff = &no_suffix; else if (strcmp(suffix, "*.*") == 0) suff = &unknown_suffix; else { HTList *cur = HTSuffixes; while (NULL != (suff = (HTSuffix*)HTList_nextObject(cur))) { if (suff->suffix && 0 == strcmp(suff->suffix, suffix) && ((trivial_enc && IsUnityEnc(suff->encoding)) || (!trivial_enc && !IsUnityEnc(suff->encoding) && strcmp(encoding, HTAtom_name(suff->encoding)) == 0))) break; } if (!suff) { /* Not found -- create a new node */ suff = typecalloc(HTSuffix); if (suff == NULL) outofmem(__FILE__, "HTSetSuffix"); /* ** Memory leak fixed. ** 05-28-94 Lynx 2-3-1 Garrett Arch Blythe */ if (!HTSuffixes) { HTSuffixes = HTList_new();#ifdef LY_FIND_LEAKS atexit(free_suffixes);#endif } HTList_addObject(HTSuffixes, suff); StrAllocCopy(suff->suffix, suffix); } } if (representation) suff->rep = HTAtom_for(representation); /* ** Memory leak fixed. ** 05-28-94 Lynx 2-3-1 Garrett Arch Blythe ** Invariant code removed. */ suff->encoding = HTAtom_for(encoding);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -