📄 htp.c
字号:
/* convert the dependency and target filenames for this filesystem */ if((dependName = ConvertDirDelimiter(dependency)) == NULL) { return ERROR; } if((targetName = ConvertDirDelimiter(target)) == NULL) { FreeMemory(dependName); return ERROR; } /* get information on the dependency file */ if(stat(dependName, &dependStat) != 0) { /* dependency file needs to exist */ FreeMemory(dependName); FreeMemory(targetName); return ERROR; } /* get information on the target file */ if(stat(targetName, &targetStat) != 0) { /* target file does not exist, dependency needs to be updated */ FreeMemory(dependName); FreeMemory(targetName); return FALSE; } FreeMemory(dependName); FreeMemory(targetName); /* compare modification times to determine if up-to-date */ return (dependStat.st_mtime <= targetStat.st_mtime) ? TRUE : FALSE;}/*// converts directory delimiters for any pathname into one supporting the// delimiters used by the present filesystem ... it is encumbent on the// caller to free() the string returned once finished*/char *ConvertDirDelimiter(const char *pathname){ char *newPathname; char *strptr; if(pathname == NULL) { return NULL; } /* duplicate the pathname for conversion */ if((newPathname = DuplicateString(pathname)) == NULL) { return NULL; } /* walk the string, looking for delimiters belonging to other filesystems */ /* replace with native filesystems delimiter */ strptr = newPathname; while(*strptr != NUL) { if(strchr(OTHER_FILESYSTEM_DELIMITER, *strptr) != NULL) { *strptr = DIR_DELIMITER; } strptr++; } return newPathname;}/*// uses stat() to check for file existance ... maybe not the best way?*/BOOL FileExists(const char *pathname){ struct stat dummy; return (stat(pathname, &dummy) == 0) ? TRUE : FALSE;}/*// searches for the specified file in the search path ... this function is// very stupid, it simply gets the first directory in the search string,// appends the file directly to the end, and tests for existance. Repeat.*/BOOL SearchForFile(const char *filename, char *fullPathname, uint size){ char *searchPathCopy; char *ptr; char *convertedName; FIND_TOKEN findToken; /* quick check for search path even being defined */ if(searchPath[0] == NUL) { return FALSE; } /* need to make a copy of the search path for String...Token() to butcher up */ if((searchPathCopy = DuplicateString(searchPath)) == NULL) { printf("%s: unable to allocate temporary buffer for include path (out of memory?)\n", PROGRAM_NAME); return FALSE; } /* look for ';' delimiter */ ptr = StringFirstToken(&findToken, searchPathCopy, ";"); while(ptr != NULL) { StringCopy(fullPathname, ptr, size); /* if the last character is not a directory delimiter, add it */ if(strchr(ALL_FILESYSTEM_DELIMITERS, fullPathname[strlen(fullPathname) - 1]) == NULL) { strncat(fullPathname, DIR_DELIMITER_STRING, size); } /* append the file name */ strncat(fullPathname, filename, size); /* need to do a complete conversion of delimiters in the filename, but */ /* ConvertDirDelimiter() returns a AllocMemory()'d copy of the string ... */ convertedName = ConvertDirDelimiter(fullPathname); /* check for existance */ if(FileExists(convertedName) == TRUE) { /* clean up and get outta here */ StringCopy(fullPathname, convertedName, size); FreeMemory(searchPathCopy); FreeMemory(convertedName); return TRUE; } FreeMemory(convertedName); convertedName = NULL; ptr = StringNextToken(&findToken); } /* clean up */ FreeMemory(searchPathCopy); return FALSE;}/*// HTML file stream functions*//*// returns the markup type flag ... either the closing or opening delimiter// in the markup can be passed in*/uint MarkupType(char delim){ uint markupType; markupType = 0; if((delim == HTML_OPEN_MARKUP) || (delim == HTML_CLOSE_MARKUP)) { markupType |= MARKUP_TYPE_HTML; } if((delim == htpOpenMarkup) || (delim == htpCloseMarkup)) { markupType |= MARKUP_TYPE_HTP; } return markupType;}/*// TRUE = plaintext is filled with new plain text markup, FALSE if end of file,// ERROR if a problem// !! Don't like using ERROR in any BOOL return values*/BOOL ReadHtmlFile(TEXTFILE *infile, TEXTFILE *outfile, char **plaintext, uint *markupType){ char ch; uint ctr; char *buffer; char *newbuffer; uint size; uint bytesReadPrevLine; BOOL inQuotes; uint startLine; assert(infile != NULL); assert(plaintext != NULL); /* if outfile is NULL, then the input stream is just being walked and */ /* not parsed for output ... i.e., don't assert outfile != NULL */ /* allocate some space for markup plaintext ... this will dynamically */ /* expand if necessary, and has to be freed by the caller */ if((buffer = AllocMemory(MIN_PLAINTEXT_SIZE)) == NULL) { HtpMsg(MSG_ERROR, NULL, "unable to allocate memory to read HTML file"); return ERROR; } /* track the buffer size */ size = MIN_PLAINTEXT_SIZE; for(;;) { /* GetFileChar() will reset bytesReadThisLine if a EOL char is read */ /* so save it for later evaluation ... (bytesReadPrevLine is named */ /* to indicate it is only evaluated if a EOL char is read) */ bytesReadPrevLine = infile->bytesReadThisLine; if(GetFileChar(infile, &ch) == FALSE) { break; } if(IS_OPEN_MARKUP(ch) == FALSE) { /* normal text, just copy it to the output file (if there is one) */ if(outfile != NULL) { /* this is used to catch spurious EOLs sneaking into the final output */ /* essentially, if bytes were read but none were written, it */ /* is assumed that the only text on the line were htp directives */ /* and therefore it is unnecessary (and ugly) to write out the */ /* EOL at the end of the line */ if(ch == '\n') { if((bytesReadPrevLine > 0) && (outfile->bytesWrittenThisLine == 0)) { continue; } } PutFileChar(outfile, ch); } } else { /* get the type of markup for caller */ *markupType = MarkupType(ch); /* copy the markup into the buffer */ ctr = 0; inQuotes = FALSE; startLine = infile->lineNumber; for(;;) { if(GetFileChar(infile, &ch) == FALSE) { /* EOF ... this is not acceptable before the markup is */ /* terminated */ FreeMemory(buffer); HtpMsg(MSG_ERROR, infile, "EOF encountered inside markup tag (started on line %u)", startLine); return ERROR; } if((IS_CLOSE_MARKUP(ch)) && (inQuotes == FALSE) && (MarkupType(ch) == *markupType)) { /* end of markup, terminate string and exit */ buffer[ctr] = NUL; break; } /* track quotation marks ... can only close markup when */ /* all quotes have been closed */ if(ch == '\"') { inQuotes = (inQuotes == TRUE) ? FALSE : TRUE; } /* copy it into the plaintext buffer */ buffer[ctr++] = ch; /* check for overflow ... resize buffer if necessary */ if(ctr == size) { newbuffer = ResizeMemory(buffer, size + PLAINTEXT_GROW_SIZE); if(newbuffer == NULL) { /* unable to enlarge buffer area */ HtpMsg(MSG_ERROR, NULL, "unable to reallocate memory for reading HTML file"); FreeMemory(buffer); return ERROR; } buffer = newbuffer; size += PLAINTEXT_GROW_SIZE; } } /* give the buffer pointer to the caller */ *plaintext = buffer; return TRUE; } } /* no markup found, end of file */ FreeMemory(buffer); return FALSE;} /*// specialized markup processors*/uint ImageProcessor(TASK *task, HTML_MARKUP *htmlMarkup, char **newPlaintext){ const char *imgfilename; char str[32]; IMAGEFILE imageFile; WORD width, height; char *imgSource; const char *originalSource; char *imgFilename; const char *imgText; UNREF_PARAM(newPlaintext); /* try to find ALT text in store */ /* first: is there already ALT attribute? if so, skip this step */ if(IsAttributeInMarkup(htmlMarkup, "ALT") == FALSE) { /* parse down the image source to just the filename */ originalSource = MarkupAttributeValue(htmlMarkup, "SRC"); if(originalSource == NULL) { HtpMsg(MSG_WARNING, task->infile, "image SRC not specified, skipping"); return MARKUP_OKAY; } imgSource = DuplicateString(originalSource); if(imgSource == NULL) { HtpMsg(MSG_ERROR, task->infile, "out of memory processing IMG tag"); return MARKUP_ERROR; } /* parse the image name, just find the filename */ imgFilename = FindFilename(imgSource); /* is the image in the ALT text store? */ if(VariableExists(&altTextVarStore, imgFilename) == TRUE) { /* add the specified text to the image */ imgText = GetVariableValue(&altTextVarStore, imgFilename); assert(imgText != NULL); AddAttributeToMarkup(htmlMarkup, "ALT", imgText, TRUE); HtpMsg(MSG_INFO, task->infile, "ALT text \"%s\" added to IMG \"%s\"", imgText, imgSource); } FreeMemory(imgSource); imgSource = NULL; } /* if option is turned off, then just include the markup as-is */ if(IMGXY == FALSE) { return MARKUP_OKAY; } /* if width and/or height are already specified, then include the */ /* markup as-is with no modifications */ if(IsAttributeInMarkup(htmlMarkup, "HEIGHT") || IsAttributeInMarkup(htmlMarkup, "WIDTH")) { return MARKUP_OKAY; } /* get the filename of the image */ if((imgfilename = MarkupAttributeValue(htmlMarkup, "SRC")) == NULL) { HtpMsg(MSG_ERROR, task->infile, "unable to retrieve image source name"); return MARKUP_ERROR; } /* open the image file, get its dimensions, and close the file */ if(OpenImageFile(imgfilename, &imageFile) == FALSE) { HtpMsg(MSG_WARNING, task->infile, "unable to open image file \"%s\"", imgfilename); return MARKUP_OKAY; } if(GetImageDimensions(&imageFile, &width, &height) == FALSE) { HtpMsg(MSG_WARNING, task->infile, "unable to determine image file \"%s\" dimensions", imgfilename); CloseImageFile(&imageFile); return MARKUP_OKAY; } CloseImageFile(&imageFile); /* add the width and height specifier for the image */ sprintf(str, "%u", width); AddAttributeToMarkup(htmlMarkup, "WIDTH", str, TRUE); sprintf(str, "%u", height); AddAttributeToMarkup(htmlMarkup, "HEIGHT", str, TRUE); /* print out an informational message to the user */ HtpMsg(MSG_INFO, task->outfile, "image file \"%s\" dimensions (%u x %u) added", imgfilename, width, height); /* include the markup in the final output */ return MARKUP_OKAY;} BOOL OptionCallback(const char *name, const char *value, ulong userParam){ TASK *task; BOOL printMsg; task = (TASK *) userParam; printMsg = (task == NULL) ? FALSE : TRUE; if(name == NULL) { /* dont like it, but dont stop processing either */ if(printMsg) { HtpMsg(MSG_WARNING, task->infile, "unknown option \"%s\" specified", value); } else { HtpMsg(MSG_WARNING, NULL, "unknown option \"%s\" specified", value); } return TRUE; } if(stricmp(name, OPT_N_QUIET) == 0) { if(stricmp(value, OPT_V_TRUE) == 0) { SetMessageSeverityLevel(MSG_WARNING); } else { SetMessageSeverityLevel(MSG_INFO); } } if(stricmp(name, OPT_N_IMGXY) == 0) { if(stricmp(value, OPT_V_TRUE) == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -