📄 htfile.c
字号:
(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(UCH(*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) { /* ** No charset parameter is present. ** Ignore all other parameters, as ** we do when charset is present. - FM */ *cp1 = '\0'; format = HTAtom_for(cp); } FREE(cp); /* ** Set up defaults, if needed. - FM */ if (!chartrans_ok && !anchor->charset && default_LYhndl >= 0) { HTAnchor_setUCInfoStage(anchor, default_LYhndl, UCT_STAGE_MIME, UCT_SETBY_DEFAULT); } HTAnchor_copyUCInfoStage(anchor, UCT_STAGE_PARSER, UCT_STAGE_MIME, -1); return format;}/* Get various pieces of meta info from file name.** -----------------------------------------------**** LYGetFileInfo fills in information that can be determined without** an actual (new) access to the filesystem, based on current suffix** and character set configuration. If the file has been loaded and** parsed before (with the same URL generated here!) and the anchor** is still around, some results may be influenced by that (in** particular, charset info from a META tag - this is not actually** tested!).** The caller should not keep pointers to the returned objects around** for too long, the valid lifetimes vary. In particular, the returned** charset string should be copied if necessary. If return of the** file_anchor is requested, that one can be used to retrieve** additional bits of info that are stored in the anchor object and** are not covered here; as usual, don't keep pointers to the** file_anchor longer than necessary since the object may disappear** through HTuncache_current_document or at the next document load.** - kw*/PUBLIC void LYGetFileInfo ARGS7( CONST char *, filename, HTParentAnchor **, pfile_anchor, HTFormat *, pformat, HTAtom **, pencoding, CONST char**, pdesc, CONST char**, pcharset, int *, pfile_cs){ char *Afn; char *Aname = NULL; HTFormat format; HTAtom * myEnc = NULL; HTParentAnchor *file_anchor; CONST char *file_csname; int file_cs; /* * Convert filename to URL. Note that it is always supposed to * be a filename, not maybe-filename-maybe-URL, so we don't * use LYFillLocalFileURL and LYEnsureAbsoluteURL. - kw */ Afn = HTEscape(filename, URL_PATH); LYLocalFileToURL(&Aname, Afn); file_anchor = HTAnchor_findSimpleAddress(Aname); file_csname = file_anchor->charset; format = HTFileFormat(filename, &myEnc, pdesc); format = HTCharsetFormat(format, file_anchor, UCLYhndl_HTFile_for_unspec); file_cs = HTAnchor_getUCLYhndl(file_anchor, UCT_STAGE_MIME); if (!file_csname) { if (file_cs >= 0) file_csname = LYCharSet_UC[file_cs].MIMEname; else file_csname = "display character set"; } CTRACE((tfp, "GetFileInfo: '%s' is a%s %s %s file, charset=%s (%d).\n", filename, ((myEnc && *HTAtom_name(myEnc) == '8') ? "n" : myEnc ? "" : *HTAtom_name(format) == 'a' ? "n" : ""), myEnc ? HTAtom_name(myEnc) : "", HTAtom_name(format), file_csname, file_cs)); FREE(Afn); FREE(Aname); if (pfile_anchor) *pfile_anchor = file_anchor; if (pformat) *pformat = format; if (pencoding) *pencoding = myEnc; if (pcharset) *pcharset = file_csname; if (pfile_cs) *pfile_cs = file_cs; }/* Determine value from file name.** -------------------------------***/PUBLIC float HTFileValue ARGS1( CONST char *, filename){ HTSuffix * suff; int n; int i; int lf = strlen(filename);#ifndef NO_INIT if (!HTSuffixes) HTFileInit();#endif /* !NO_INIT */ n = HTList_count(HTSuffixes); for (i = 0; i < n; i++) { int ls; suff = (HTSuffix *)HTList_objectAt(HTSuffixes, i); ls = strlen(suff->suffix); if ((ls <= lf) && 0==strcmp(suff->suffix, filename + lf - ls)) { CTRACE((tfp, "File: Value of %s is %.3f\n", filename, suff->quality)); return suff->quality; /* OK -- found */ } } return (float)0.3; /* Dunno! */}/*** Determine compression type from file name, by looking at its suffix.** Sets as side-effect a pointer to the "dot" that begins the suffix.*/PUBLIC CompressFileType HTCompressFileType ARGS3( char *, filename, char *, dots, char **, suffix){ CompressFileType result = cftNone; size_t len = strlen(filename); char *ftype = filename + len; if ((len > 4) && !strcasecomp((ftype - 3), "bz2") && strchr(dots, ftype[-4]) != 0) { result = cftBzip2; ftype -= 4; } else if ((len > 3) && !strcasecomp((ftype - 2), "gz") && strchr(dots, ftype[-3]) != 0) { result = cftGzip; ftype -= 3; } else if ((len > 2) && !strcmp((ftype - 1), "Z") && strchr(dots, ftype[-2]) != 0) { result = cftCompress; ftype -= 2; } *suffix = ftype; CTRACE((tfp, "HTCompressFileType(%s) returns %d:%s\n", filename, result, *suffix)); return result;}/* Determine write access to a file.** ---------------------------------**** On exit:** Returns YES if file can be accessed and can be written to.**** Bugs:** 1. No code for non-unix systems.** 2. Isn't there a quicker way?*/PUBLIC BOOL HTEditable ARGS1( CONST char *, filename){#ifndef NO_GROUPS GETGROUPS_T groups[NGROUPS]; uid_t myUid; int ngroups; /* The number of groups */ struct stat fileStatus; int i; if (stat(filename, &fileStatus)) /* Get details of filename */ return NO; /* Can't even access file! */ ngroups = getgroups(NGROUPS, groups); /* Groups to which I belong */ myUid = geteuid(); /* Get my user identifier */ if (TRACE) { int i2; fprintf(tfp, "File mode is 0%o, uid=%d, gid=%d. My uid=%d, %d groups (", (unsigned int) fileStatus.st_mode, (int) fileStatus.st_uid, (int) fileStatus.st_gid, (int) myUid, (int) ngroups); for (i2 = 0; i2 < ngroups; i2++) fprintf(tfp, " %d", (int) groups[i2]); fprintf(tfp, ")\n"); } if (fileStatus.st_mode & 0002) /* I can write anyway? */ return YES; if ((fileStatus.st_mode & 0200) /* I can write my own file? */ && (fileStatus.st_uid == myUid)) return YES; if (fileStatus.st_mode & 0020) /* Group I am in can write? */ { for (i = 0; i < ngroups; i++) { if (groups[i] == fileStatus.st_gid) return YES; } } CTRACE((tfp, "\tFile is not editable.\n"));#endif /* NO_GROUPS */ return NO; /* If no excuse, can't do */}/* Make a save stream.** -------------------**** The stream must be used for writing back the file.** @@@ no backup done*/PUBLIC HTStream * HTFileSaveStream ARGS1( HTParentAnchor *, anchor){ CONST char * addr = anchor->address; char * localname = HTLocalName(addr); FILE * fp = fopen(localname, BIN_W); FREE(localname); if (!fp) return NULL; return HTFWriter_new(fp);}/* Output one directory entry.** ---------------------------*/PUBLIC void HTDirEntry ARGS3( HTStructured *, target, CONST char *, tail, CONST char *, entry){ char * relative = NULL; char * stripped = NULL; char * escaped = NULL; int len; StrAllocCopy(escaped, entry); LYTrimPathSep(escaped); if (strcmp(escaped, "..") != 0) { stripped = escaped; escaped = HTEscape(stripped, URL_XPALPHAS); if (((len = strlen(escaped)) > 2) && escaped[(len - 3)] == '%' && escaped[(len - 2)] == '2' && TOUPPER(escaped[(len - 1)]) == 'F') { escaped[(len - 3)] = '\0'; } } if (tail == NULL || *tail == '\0') { /* ** Handle extra slash at end of path. */ HTStartAnchor(target, NULL, (escaped[0] != '\0' ? escaped : "/")); } else { /* ** If empty tail, gives absolute ref below. */ relative = 0; HTSprintf0(&relative, "%s%s%s", tail, (*escaped != '\0' ? "/" : ""), escaped); HTStartAnchor(target, NULL, relative); FREE(relative); } FREE(stripped); FREE(escaped);}/* Output parent directory entry.** ------------------------------**** This gives the TITLE and H1 header, and also a link** to the parent directory if appropriate.**** On exit:** Returns TRUE if an "Up to <parent>" link was not created** for a readable local directory because LONG_LIST is defined** and NO_PARENT_DIR_REFERENCE is not defined, so that the** calling function should use LYListFmtParse() to create a link** to the parent directory. Otherwise, it returns FALSE. - FM*/PUBLIC BOOL HTDirTitles ARGS3( HTStructured *, target, HTParentAnchor *, anchor, BOOL, tildeIsTop){ CONST char * logical = anchor->address; char * path = HTParse(logical, "", PARSE_PATH + PARSE_PUNCTUATION); char * current; char * cp = NULL; BOOL need_parent_link = FALSE; int i;#if defined(USE_DOS_DRIVES) BOOL local_link = (strlen(logical) > 18 && !strncasecomp(logical, "file://localhost/", 17) && LYIsDosDrive(logical + 17)); BOOL is_remote = !local_link;#else#define is_remote TRUE#endif /* ** Check tildeIsTop for treating home directory as Welcome ** (assume the tilde is not followed by a username). - FM */ if (tildeIsTop && !strncmp(path, "/~", 2)) { if (path[2] == '\0') { path[1] = '\0'; } else { for (i = 0; path[(i + 2)]; i++) { path[i] = path[(i + 2)]; } path[i] = '\0'; } } /* ** Trim out the ;type= parameter, if present. - FM */ if ((cp = strrchr(path, ';')) != NULL) { if (!strncasecomp((cp+1), "type=", 5)) { if (TOUPPER(*(cp+6)) == 'D' || TOUPPER(*(cp+6)) == 'A' || TOUPPER(*(cp+6)) == 'I') *cp = '\0'; } cp = NULL; } current = LYPathLeaf (path); /* last part or "" */ { char * printable = NULL;#ifdef DIRED_SUPPORT printable = HTURLPath_toFile( (0 == strncasecomp(path, "/%2F", 4)) /* "//" ? */ ? (path+1) : path, TRUE, is_remote); if (0 == strncasecomp(printable, "/vmsysu:", 8) || 0 == strncasecomp(printable, "/anonymou.", 10)) { StrAllocCopy(cp, (printable+1)); StrAllocCopy(printable, cp); FREE(cp); }#else StrAllocCopy(printable, current); HTUnEscape(printable);#endif /* DIRED_SUPPORT */ START(HTML_HEAD); PUTC('\n'); START(HTML_TITLE); PUTS(*printable ? printable : WELCOME_MSG); PUTS(SEGMENT_DIRECTORY); END(HTML_TITLE); PUTC('\n'); END(HTML_HEAD); PUTC('\n');#ifdef DIRED_SUPPORT START(HTML_H2); PUTS(*printable ? SEGMENT_CURRENT_DIR : ""); PUTS(*printable ? printable : WELCOME_MSG); END(HTML_H2); PUTC('\n');#else START(HTML_H1); PUTS(*printable ? printable : WELCOME_MSG); END(HTML_H1); PUTC('\n');#endif /* DIRED_SUPPORT */ if (((0 == strncasecomp(printable, "vmsysu:", 7)) && (cp = strchr(printable, '.')) != NULL && strchr(cp, '/') == NULL) || (0 == strncasecomp(printable, "anonymou.", 9) && strchr(printable, '/') == NULL)) { FREE(printable); FREE(path); return(need_parent_link); } FREE(printable); }#ifndef NO_PARENT_DIR_REFERENCE /* ** Make link back to parent directory. */ if (current - path > 0 && LYIsPathSep(current[-1]) && current[0] != '\0') { /* was a slash AND something else too */ char * parent = NULL; char * relative = NULL; current[-1] = '\0'; parent = strrchr(path, '/'); /* penultimate slash */ if ((parent && (!strcmp(parent, "/..") || !strncasecomp(parent, "/%2F", 4))) || !strncasecomp(current, "%2F", 3)) { FREE(path); return(need_parent_link); } relative = 0; HTSprintf0(&relative, "%s/..", current);#if defined(DOSPATH) || defined(__EMX__) if (local_link) { if (parent != 0 && strlen(parent) == 3 ) { StrAllocCat(relative, "/."); } } else#endif#if !defined (VMS) { /* ** On Unix, if it's not ftp and the directory cannot ** be read, don't put out a link. ** ** On VMS, this problem is dealt with internally by ** HTVMSBrowseDir(). */ DIR * dp = NULL; if (LYisLocalFile(logical)) { /* ** We need an absolute file path for the opendir. ** We also need to unescape for this test. ** Don't worry about %2F now, they presumably have been ** dealt with above, and shouldn't appear for local ** files anyway... Assume OS / filesystem will just ** ignore superfluous slashes. - KW */ char * fullparentpath = NULL; /* ** Path has been shortened above. */ StrAllocCopy(fullparentpath, *path ? path : "/"); /* ** Guard against weirdness. */ if (0 == strcmp(current,"..")) { StrAllocCat(fullparentpath,"/../.."); } else if (0 == strcmp(current,".")) { StrAllocCat(fullparentpath,"/.."); } HTUnEscape(fullparentpath); if ((dp = opendir(fullparentpath)) == NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -