⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htvmsutils.c

📁 elinks下lynx是最重要的二个文本浏览器, 在linux下非常实用, lynx比elinks早的多, 目前好像停止开发, 这是lynx源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
#define PUTC(c) (*targetClass.put_character)(target, c)#define PUTS(s) (*targetClass.put_string)(target, s)#define START(e) (*targetClass.start_element)(target, e, 0, 0, -1, 0)#define END(e) (*targetClass.end_element)(target, e, 0)#define FREE_TARGET (*targetClass._free)(target)#define ABORT_TARGET (*targetClass._free)(target)struct _HTStructured {	CONST HTStructuredClass *	isa;	/* ... */};#define STRUCT_DIRENT struct direntPRIVATE char * months[12] = {    "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};typedef struct _VMSEntryInfo {    char *       filename;    char *       type;    char *       date;    unsigned int size;    BOOLEAN      display;  /* show this entry? */} VMSEntryInfo;PRIVATE void free_VMSEntryInfo_contents ARGS1(VMSEntryInfo *,entry_info){    if (entry_info) {	FREE(entry_info->filename);	FREE(entry_info->type);	FREE(entry_info->date);    }   /* dont free the struct */}PUBLIC int compare_VMSEntryInfo_structs ARGS2(VMSEntryInfo *,entry1,					      VMSEntryInfo *,entry2){    int i, status;    char date1[16], date2[16], time1[8], time2[8], month[4];    switch(HTfileSortMethod)      {	case FILE_BY_SIZE:			/* both equal or both 0 */			if(entry1->size == entry2->size)			    return(strcasecomp(entry1->filename,					       entry2->filename));			else			    if(entry1->size > entry2->size)				return(1);			    else				return(-1);	case FILE_BY_TYPE:			if(entry1->type && entry2->type) {			    status = strcasecomp(entry1->type, entry2->type);			    if(status)				return(status);			    /* else fall to filename comparison */			}			return (strcasecomp(entry1->filename,					    entry2->filename));	case FILE_BY_DATE:			if(entry1->date && entry2->date) {			    /*			    ** Make sure we have the correct length. - FM			    */			    if (strlen(entry1->date) != 12 ||				strlen(entry2->date) != 12) {				return (strcasecomp(entry1->filename,						    entry2->filename));			    }			    /*			    ** Set up for sorting in reverse			    ** chronological order. - FM			    */			    if (entry1->date[7] != ' ') {				strcpy(date1, "9999");				strcpy(time1, (char *)&entry1->date[7]);			    } else {				strcpy(date1, (char *)&entry1->date[8]);				strcpy(time1, "00:00");			    }			    strncpy(month, entry1->date, 3);			    month[3] = '\0';			    for (i = 0; i < 12; i++) {				if (!strcasecomp(month, months[i])) {				    break;				}			    }			    i++;			    sprintf(month, "%02d", i);			    strcat(date1, month);			    strncat(date1, (char *)&entry1->date[4], 2);			    date1[8] = '\0';			    if (date1[6] == ' ') {				date1[6] = '0';			    }			    strcat(date1, time1);			    if (entry2->date[7] != ' ') {				strcpy(date2, "9999");				strcpy(time2, (char *)&entry2->date[7]);			    } else {				strcpy(date2, (char *)&entry2->date[8]);				strcpy(time2, "00:00");			    }			    strncpy(month, entry2->date, 3);			    month[3] = '\0';			    for (i = 0; i < 12; i++) {				if (!strcasecomp(month, months[i])) {				    break;				}			    }			    i++;			    sprintf(month, "%02d", i);			    strcat(date2, month);			    strncat(date2, (char *)&entry2->date[4], 2);			    date2[8] = '\0';			    if (date2[6] == ' ') {				date2[6] = '0';			    }			    strcat(date2, time2);			    /*			    ** Do the comparison. - FM			    */			    status = strcasecomp(date2, date1);			    if(status)				return(status);			    /* else fall to filename comparison */			}			return (strcasecomp(entry1->filename,					    entry2->filename));	case FILE_BY_NAME:	default:			return (strcmp(entry1->filename,					    entry2->filename));      }}/*							HTVMSBrowseDir()****	This function generates a directory listing as an HTML-object**	for local file URL's.  It assumes the first two elements of**	of the path are a device followed by a directory:****		file://localhost/device/directory[/[foo]]****	Will not accept 000000 as a directory name.**	Will offer links to parent through the top directory, unless**	a terminal slash was included in the calling URL.****	Returns HT_LOADED on success, HTLoadError() messages on error.****	Developed for Lynx by Foteos Macrides (macrides@sci.wfeb.edu).*/PUBLIC int HTVMSBrowseDir ARGS4(	CONST char *,		address,	HTParentAnchor *,	anchor,	HTFormat,		format_out,	HTStream *,		sink){    HTStructured* target;    HTStructuredClass targetClass;    char *pathname = HTParse(address, "", PARSE_PATH + PARSE_PUNCTUATION);    char *tail = NULL;    char *title = NULL;    char *header = NULL;    char *parent = NULL;    char *relative = NULL;    char *cp, *cp1;    int  pathend, len;    DIR *dp;    struct stat file_info;    time_t NowTime;    static char ThisYear[8];    VMSEntryInfo *entry_info = 0;    char string_buffer[64];    HTUnEscape(pathname);    CTRACE((tfp,"HTVMSBrowseDir: Browsing `%s\'\n", pathname));    /*     *  Require at least two elements (presumably a device and directory)     *  and disallow the device root (000000 directory).  Symbolic paths     *  (e.g., sys$help) should have been translated and expanded (e.g.,     *  to /sys$sysroot/syshlp) before calling this routine.     */    if (((*pathname != '/') ||	 (cp = strchr(pathname+1, '/')) == NULL ||	 *(cp + 1) == '\0' ||	 0 == strncmp((cp + 1), "000000", 6)) ||	(dp = HTVMSopendir(pathname)) == NULL) {	FREE(pathname);	return HTLoadError(sink, 403, COULD_NOT_ACCESS_DIR);    }    /*     *  Set up the output stream.     */    _HTProgress (BUILDING_DIR_LIST);    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);    /*     *  Set up the offset string of the anchor reference,     *  and strings for the title and header.     */    cp = strrchr(pathname, '/');  /* find lastslash */    StrAllocCopy(tail, (cp+1)); /* take slash off the beginning */    if (*tail != '\0') {	StrAllocCopy(title, tail);	*cp = '\0';	if ((cp1=strrchr(pathname, '/')) != NULL &&	    cp1 != pathname &&	    strncmp((cp1+1), "000000", 6))	    StrAllocCopy(parent, (cp1+1));	*cp = '/';    } else {	pathname[strlen(pathname)-1] = '\0';	cp = strrchr(pathname, '/');	StrAllocCopy(title, (cp+1));	pathname[strlen(pathname)] = '/';    }    StrAllocCopy(header, pathname);    /*     *  Initialize path name for HTStat().     */    pathend = strlen(pathname);    if (*(pathname+pathend-1) != '/') {	StrAllocCat(pathname, "/");	pathend++;    }    /*     *  Output the title and header.     */    START(HTML_HTML);    PUTC('\n');    START(HTML_HEAD);    PUTC('\n');    HTUnEscape(title);    START(HTML_TITLE);    PUTS(title);    PUTS(" directory");    END(HTML_TITLE);    PUTC('\n');    FREE(title);    END(HTML_HEAD);    PUTC('\n');    START(HTML_BODY);    PUTC('\n');    HTUnEscape(header);    START(HTML_H1);    PUTS(header);    END(HTML_H1);    PUTC('\n');    if (HTDirReadme == HT_DIR_README_TOP) {	FILE * fp;	if (header[strlen(header)-1] != '/')	    StrAllocCat(header, "/");	StrAllocCat(header, HT_DIR_README_FILE);	if ((fp = fopen(header,	 "r")) != NULL) {	    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;		    default:			PUTC(c);		}#else		PUTC(c);#endif /* NOTDEFINED */	    }	    END(HTML_PRE);	    fclose(fp);	}    }    FREE(header);    if (parent) {	HTSprintf0(&relative, "%s/..", tail);	HTStartAnchor(target, "", relative);	PUTS("Up to ");	HTUnEscape(parent);	PUTS(parent);	END(HTML_A);	START(HTML_P);	PUTC('\n');	FREE(relative);	FREE(parent);    }    /*     *  Set up the date comparison.     */    NowTime = time(NULL);    strcpy(ThisYear, (char *)ctime(&NowTime)+20);    ThisYear[4] = '\0';    /*     * Now, generate the Btree and put it out to the output stream.     */    {	char dottest = 2;	/* To avoid two strcmp() each time */	STRUCT_DIRENT *dirbuf;	HTBTree *bt;	/* Set up sort key and initialize BTree */	bt = HTBTree_new((HTComparer) compare_VMSEntryInfo_structs);	/* Build tree */	while ((dirbuf = HTVMSreaddir(dp))) {	    HTAtom *encoding = NULL;	    HTFormat format;	    /* Skip if not used */	    if (!dirbuf->d_ino)	{		continue;	    }	    /* Current and parent directories are never shown in list */	    if (dottest && (!strcmp(dirbuf->d_name, ".") ||			    !strcmp(dirbuf->d_name, ".."))) {		dottest--;		continue;	    }	    /* Don't show the selective enabling file	     * unless version numbers are included */	    if (!strcasecomp(dirbuf->d_name, HT_DIR_ENABLE_FILE)) {		continue;	    }	    /* Skip files beginning with a dot? */	    if ((no_dotfiles || !show_dotfiles) && *dirbuf->d_name == '.') {		continue;	    }	    /* OK, make an lstat() and get a key ready. */	    *(pathname+pathend) = '\0';	    StrAllocCat(pathname, dirbuf->d_name);	    if (HTStat(pathname, &file_info)) {		/* for VMS the failure here means the file is not readable...		   we however continue to browse through the directory... */		continue;	    }	    entry_info = (VMSEntryInfo *)malloc(sizeof(VMSEntryInfo));	    if (entry_info == NULL)		outofmem(__FILE__, "HTVMSBrowseDir");	    entry_info->type = 0;	    entry_info->size = 0;	    entry_info->date = 0;	    entry_info->filename = 0;	    entry_info->display = TRUE;	    /* Get the type */	    format = HTFileFormat(dirbuf->d_name, &encoding,				  (CONST char **)&cp);	    if (!cp) {		if(!strncmp(HTAtom_name(format), "application",11))		{		    cp = HTAtom_name(format) + 12;		    if(!strncmp(cp,"x-", 2))			cp += 2;		}		else		    cp = HTAtom_name(format);	    }	    StrAllocCopy(entry_info->type, cp);	    StrAllocCopy(entry_info->filename, dirbuf->d_name);	    if (S_ISDIR(file_info.st_mode)) {		/* strip .DIR part... */		char *dot;		dot = strstr(entry_info->filename, ".DIR");		if (dot)		   *dot = '\0';		LYLowerCase(entry_info->filename);		StrAllocCopy(entry_info->type, "Directory");	    } else {		if ((cp = strstr(entry_info->filename, "READ")) == NULL) {		    cp = entry_info->filename;		} else {		    cp += 4;		    if (!strncmp(cp, "ME", 2)) {			cp += 2;			while (cp && *cp && *cp != '.') {			    cp++;			}		    } else if (!strncmp(cp, ".ME", 3)) {			cp = (entry_info->filename +			      strlen(entry_info->filename));		    } else {			cp = entry_info->filename;		    }		}		LYLowerCase(cp);		if (((len = strlen(entry_info->filename)) > 2) &&		    entry_info->filename[len-1] == 'z') {		    if (entry_info->filename[len-2] == '.' ||			entry_info->filename[len-2] == '_')			entry_info->filename[len-1] = 'Z';		}	    }	    /* Get the date */	    {		char *t = (char *)ctime((CONST time_t *)&file_info.st_ctime);		*(t+24) = '\0';		StrAllocCopy(entry_info->date, (t+4));		*((entry_info->date)+7) = '\0';		if ((atoi((t+19))) < atoi(ThisYear))		    StrAllocCat(entry_info->date,  (t+19));		else {		    StrAllocCat(entry_info->date, (t+11));		    *((entry_info->date)+12) = '\0';		}	    }	    /* Get the size */	    if (!S_ISDIR(file_info.st_mode))		entry_info->size = (unsigned int)file_info.st_size;	    else		entry_info->size = 0;	    /* Now, update the BTree etc. */	    if(entry_info->display)	      {		 CTRACE((tfp,"Adding file to BTree: %s\n",						      entry_info->filename));		 HTBTree_add(bt, entry_info);	      }	} /* End while HTVMSreaddir() */	FREE(pathname);	HTVMSclosedir(dp);	START(HTML_PRE);	/*	 * Run through the BTree printing out in order	 */	{	    HTBTElement * ele;	    int i;	    for (ele = HTBTree_next(bt, NULL);		 ele != NULL;		 ele = HTBTree_next(bt, ele))	    {		entry_info = (VMSEntryInfo *)HTBTree_object(ele);		/* Output the date */		if(entry_info->date)		       {			     PUTS(entry_info->date);			     PUTS("  ");		       }		else			PUTS("     * ");		/* Output the type */		if(entry_info->type)		  {		    for(i = 0; entry_info->type[i] != '\0' && i < 15; i++)			PUTC(entry_info->type[i]);		    for(; i < 17; i++)			PUTC(' ');		  }		/* Output the link for the name */		HTDirEntry(target, tail, entry_info->filename);		PUTS(entry_info->filename);		END(HTML_A);		/* Output the size */		if(entry_info->size)		  {			  if(entry_info->size < 1024)			      sprintf(string_buffer,"  %d bytes",							entry_info->size);			  else			      sprintf(string_buffer,"  %dKb",							entry_info->size/1024);			  PUTS(string_buffer);		  }		PUTC('\n'); /* end of this entry */		free_VMSEntryInfo_contents(entry_info);	    }	}	HTBTreeAndObject_free(bt);    } /* End of both BTree loops */    /*     *  Complete the output stream.     */    END(HTML_PRE);    PUTC('\n');    END(HTML_BODY);    PUTC('\n');    END(HTML_HTML);    PUTC('\n');    FREE(tail);    FREE_TARGET;    return HT_LOADED;} /* End of directory reading section *//* * Remove all versions of the given file.  We assume there are no permissions * problems, since we do this mainly for removing temporary files. */int HTVMS_remove(char *filename){    int code = remove(filename);	/* return the first status code */    while (remove(filename) == 0)	;    return code;}/* * Remove all older versions of the given file.  We may fail to remove some * version due to permissions -- the loop stops either at that point, or when * we run out of older versions to remove. */void HTVMS_purge(char *filename){    char *older_file = 0;    char *oldest_file = 0;    struct stat sb;    StrAllocCopy(older_file, filename);    StrAllocCat(older_file, ";-1");    while (remove(older_file) == 0)	;    /*     * If we do not have any more older versions, it is safe to rename the     * current file to version #1.     */    if (stat(older_file, &sb) != 0) {	StrAllocCopy(oldest_file, filename);	StrAllocCat(oldest_file, ";1");	rename(older_file, oldest_file);	FREE(oldest_file);    }    FREE(older_file);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -