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

📄 lylocal.c

📁 基于rtos开发的浏览器!
💻 C
📖 第 1 页 / 共 4 页
字号:
/***  Routines to manipulate the local filesystem.**  Written by: Rick Mallett, Carleton University**  Report problems to rmallett@ccs.carleton.ca**  Modified 18-Dec-95 David Trueman (david@cs.dal.ca):**	Added OK_PERMIT compilation option.**	Support replacement of compiled-in f)ull menu configuration via**	  DIRED_MENU definitions in lynx.cfg, so that more than one menu**	  can be driven by the same executable.**  Modified Oct-96 Klaus Weide (kweide@tezcat.com):**	Changed to use the library's HTList_* functions and macros for**	  managing the list of tagged file URLs.**	Keep track of proper level of URL escaping, so that unusual filenames**	  which contain #% etc. are handled properly (some HTUnEscapeSome()'s**	  left in to be conservative, and to document where superfluous**	  unescaping took place before).**	Dynamic memory instead of fixed length buffers in a few cases.**	Other minor changes to make things work as intended.**  Modified Jun-97 Klaus Weide (kweide@tezcat.com) & FM:**	Modified the code handling DIRED_MENU to do more careful**	  checking of the selected file.  In addition to "TAG", "FILE", and**	  "DIR", DIRED_MENU definitions in lynx.cfg now also recognize LINK as**	  a type.  DIRED_MENU definitions with a type field of "LINK" are only**	  used if the current selection is a symbolic link ("FILE" and "DIR"**	  definitions are not used in that case).  The default menu**	  definitions have been updated to reflect this change, and to avoid**	  the showing of menu items whose action would always fail - KW**	Cast all code into the Lynx programming style. - FM*/#include "HTUtils.h"#include "tcp.h"#include "HTAlert.h"#include "HTParse.h"#include "LYCurses.h"#include "LYGlobalDefs.h"#include "LYUtils.h"#include "LYStrings.h"#include "LYCharUtils.h"#include "LYStructs.h"#include "LYGetFile.h"#include "LYHistory.h"#include "LYUpload.h"#include "LYLocal.h"#include "LYSystem.h"#ifndef VMS#ifndef _WINDOWS#ifdef HAVE_SYS_WAIT_H#include <sys/wait.h>#endif#include <errno.h>#include <grp.h>#endif /*_WINDOWS */#endif /* VMS */#ifndef WEXITSTATUS# if HAVE_TYPE_UNIONWAIT#  define	WEXITSTATUS(status)	(status.w_retcode)# else#  define	WEXITSTATUS(status)	(((status) & 0xff00) >> 8)# endif#endif#ifndef WTERMSIG# if HAVE_TYPE_UNIONWAIT#  define	WTERMSIG(status)	(status.w_termsig)# else#  define	WTERMSIG(status)	((status) & 0x7f)# endif#endif#include "LYLeaks.h"#define FREE(x) if (x) {free(x); x = NULL;}PRIVATE int LYExecv PARAMS((	char *		path,	char ** 	argv,	char *		msg));#ifdef DIRED_SUPPORTPUBLIC char LYPermitFileURL[256] = "\0";PUBLIC char LYDiredFileURL[256] = "\0";PRIVATE char *filename PARAMS((	char *		prompt,	char *		buf,	size_t		bufsize));#ifdef OK_PERMITPRIVATE BOOLEAN permit_location PARAMS((	char *		destpath,	char *		srcpath,	char ** 	newpath));#endif /* OK_PERMIT */PRIVATE char *render_item PARAMS((	char *		s,	char *		path,	char *		dir,	char *		buf,	int		bufsize,	BOOLEAN 	url_syntax));PRIVATE struct dired_menu *menu_head = NULL;struct dired_menu {    int cond;#define DE_TAG     1#define DE_DIR     2#define DE_FILE    3#define DE_SYMLINK 4    char *sfx;    char *link;    char *rest;    char *href;    struct dired_menu *next;} defmenu[] = {/* *  The following initializations determine the contents of the f)ull menu *  selection when in dired mode.  If any menu entries are defined in the *  configuration file via DIRED_MENU lines, then these default entries *  are discarded entirely. */{ 0,		      "", "New File","(in current directory)", "LYNXDIRED://NEW_FILE%d",		NULL },{ 0,		      "", "New Directory","(in current directory)", "LYNXDIRED://NEW_FOLDER%d",		NULL },{ DE_FILE,	      "", "Install","(of current selection)", "LYNXDIRED://INSTALL_SRC%p",		NULL },{ DE_DIR,	      "", "Install","(of current selection)", "LYNXDIRED://INSTALL_SRC%p",		NULL },{ DE_FILE,	      "", "Modify File Name","(of current selection)", "LYNXDIRED://MODIFY_NAME%p",		NULL },{ DE_DIR,	      "", "Modify Directory Name","(of current selection)", "LYNXDIRED://MODIFY_NAME%p",		NULL },{ DE_SYMLINK,	      "", "Modify Name","(of selected symbolic link)", "LYNXDIRED://MODIFY_NAME%p",		NULL },#ifdef OK_PERMIT{ DE_FILE,	      "", "Modify File Permissions","(of current selection)", "LYNXDIRED://PERMIT_SRC%p",		NULL },{ DE_DIR,	      "", "Modify Directory Permissions","(of current selection)", "LYNXDIRED://PERMIT_SRC%p",		NULL },#endif /* OK_PERMIT */{ DE_FILE,	      "", "Change Location","(of selected file)"	, "LYNXDIRED://MODIFY_LOCATION%p",	NULL },{ DE_DIR,	      "", "Change Location","(of selected directory)", "LYNXDIRED://MODIFY_LOCATION%p",	NULL },{ DE_SYMLINK,	      "", "Change Location","(of selected symbolic link)", "LYNXDIRED://MODIFY_LOCATION%p", NULL },{ DE_FILE,	      "", "Remove File",   "(current selection)", "LYNXDIRED://REMOVE_SINGLE%p",	NULL },{ DE_DIR,	      "", "Remove Directory",   "(current selection)", "LYNXDIRED://REMOVE_SINGLE%p",	NULL },{ DE_SYMLINK,	      "", "Remove Symbolic Link",   "(current selection)", "LYNXDIRED://REMOVE_SINGLE%p",	NULL },#if defined(OK_UUDECODE) && !defined(ARCHIVE_ONLY){ DE_FILE,	      "", "UUDecode",   "(current selection)", "LYNXDIRED://UUDECODE%p",		NULL },#endif /* OK_UUDECODE && !ARCHIVE_ONLY */#if defined(OK_TAR) && !defined(ARCHIVE_ONLY){ DE_FILE,	".tar.Z", "Expand",   "(current selection)", "LYNXDIRED://UNTAR_Z%p",		NULL },#endif /* OK_TAR && !ARCHIVE_ONLY */#if defined(OK_TAR) && defined(OK_GZIP) && !defined(ARCHIVE_ONLY){ DE_FILE,     ".tar.gz", "Expand",   "(current selection)", "LYNXDIRED://UNTAR_GZ%p",		NULL },{ DE_FILE,	  ".tgz", "Expand",   "(current selection)", "LYNXDIRED://UNTAR_GZ%p",		NULL },#endif /* OK_TAR && OK_GZIP && !ARCHIVE_ONLY */#ifndef ARCHIVE_ONLY{ DE_FILE,	    ".Z", "Uncompress",   "(current selection)", "LYNXDIRED://DECOMPRESS%p",		NULL },#endif /* ARCHIVE_ONLY */#if defined(OK_GZIP) && !defined(ARCHIVE_ONLY){ DE_FILE,	   ".gz", "Uncompress",   "(current selection)", "LYNXDIRED://UNGZIP%p",		NULL },#endif /* OK_GZIP && !ARCHIVE_ONLY */#if defined(OK_ZIP) && !defined(ARCHIVE_ONLY){ DE_FILE,	  ".zip", "Uncompress",   "(current selection)", "LYNXDIRED://UNZIP%p",		NULL },#endif /* OK_ZIP && !ARCHIVE_ONLY */#if defined(OK_TAR) && !defined(ARCHIVE_ONLY){ DE_FILE,	  ".tar", "UnTar",   "(current selection)", "LYNXDIRED://UNTAR%p",		NULL },#endif /* OK_TAR && !ARCHIVE_ONLY */#ifdef OK_TAR{ DE_DIR,	      "", "Tar",   "(current selection)", "LYNXDIRED://TAR%p",			NULL },#endif /* OK_TAR */#if defined(OK_TAR) && defined(OK_GZIP){ DE_DIR,	      "", "Tar and compress",      "(using GNU gzip)", "LYNXDIRED://TAR_GZ%p",		NULL },#endif /* OK_TAR && OK_GZIP */#ifdef OK_ZIP{ DE_DIR,	      "", "Package and compress",	   "(using zip)", "LYNXDIRED://ZIP%p",			NULL },#endif /* OK_ZIP */{ DE_FILE,	      "", "Compress", "(using Unix compress)", "LYNXDIRED://COMPRESS%p",		NULL },#ifdef OK_GZIP{ DE_FILE,	      "", "Compress",	  "(using gzip)", "LYNXDIRED://GZIP%p", 		NULL },#endif /* OK_GZIP */#ifdef OK_ZIP{ DE_FILE,	      "", "Compress",	   "(using zip)", "LYNXDIRED://ZIP%p",			NULL },#endif /* OK_ZIP */{ DE_TAG,	      "", "Move all tagged items to another location.",		      "", "LYNXDIRED://MOVE_TAGGED%d",		NULL },{ DE_TAG,	      "", "Remove all tagged files and directories.",		      "", "LYNXDIRED://REMOVE_TAGGED",		NULL },{ DE_TAG,	      "", "Untag all tagged files and directories.",		      "", "LYNXDIRED://CLEAR_TAGGED",		NULL },{ 0,		    NULL, NULL,		    NULL, NULL, 				NULL }};/* *  Remove all tagged files and directories. */PRIVATE BOOLEAN remove_tagged NOARGS{    int c, ans;    char *cp, *tp;    char tmpbuf[1024];    char *testpath = NULL;    struct stat dir_info;    int count, i;    HTList *tag;    char *args[5];    if (HTList_isEmpty(tagged))  /* should never happen */	return 0;    _statusline("Remove all tagged files and directories (y or n): ");    c = LYgetch();    ans = TOUPPER(c);    count = 0;    tag = tagged;    while (ans == 'Y' && (cp = (char *)HTList_nextObject(tag)) != NULL) {	if (is_url(cp) == FILE_URL_TYPE) { /* unecessary check */	    tp = cp;	    if (!strncmp(tp, "file://localhost", 16)) {		tp += 16;	    } else if (!strncmp(tp, "file:", 5)) {		tp += 5;	    }	    StrAllocCopy(testpath, tp);	    HTUnEscape(testpath);	    if ((i = strlen(testpath)) && testpath[i-1] == '/')		testpath[(i - 1)] = '\0';	    /*	     *	Check the current status of the path to be deleted.	     */	    if (stat(testpath,&dir_info) == -1) {		sprintf(tmpbuf,			"System error - failed to get status of '%s'.",			testpath);		_statusline(tmpbuf);		sleep(AlertSecs);		return count;	    } else {		args[0] = "rm";		args[1] = "-rf";		args[2] = testpath;		args[3] = (char *) 0;		sprintf(tmpbuf, "remove %s", testpath);		if (LYExecv(RM_PATH, args, tmpbuf) <= 0) {		    FREE(testpath);		    return ((count == 0) ? -1 : count);		}		++count;	    }	}    }    FREE(testpath);    clear_tags();    return count;}/* *  Move all tagged files and directories to a new location. *  Input is current directory. *  The tests in this function can, at best, prevent some user mistakes - *   anybody who relies on them for security is seriously misguided. *  If a user has enough permissions to move a file somewhere, the same *   uid with Lynx & dired can do the same thing. */PRIVATE BOOLEAN modify_tagged ARGS1(	char *, 	testpath){    char *cp;    dev_t dev;    ino_t inode;    uid_t owner;    char tmpbuf[1024];    char *savepath = NULL;    char *srcpath = NULL;    struct stat dir_info;    char *args[5];    int count = 0;    HTList *tag;    if (HTList_isEmpty(tagged))  /* should never happen */	return 0;    _statusline("Enter new location for tagged items: ");    tmpbuf[0] = '\0';    LYgetstr(tmpbuf, VISIBLE, sizeof(tmpbuf), NORECALL);    if (strlen(tmpbuf)) {    /*     *	Determine the ownership of the current location.     */	/*	 *  This test used to always fail from the dired menu...	 *  changed to something that hopefully makes more sense - KW	 */	if (testpath && *testpath && 0!=strcmp(testpath,"/")) {	    /*	     *	testpath passed in and is not empty and not a single "/"	     *	(which would probably be bogus) - use it.	     */	    cp = testpath;	} else {	    /*	     *	Prepare to get directory path from one of the tagged files.	     */	    cp = HTList_lastObject(tagged);	    testpath = NULL;	/* Won't be needed any more in this function,				   set to NULL as a flag. */	    if (!cp)	/* Last resort, should never happen. */		cp = "/";	}	if (!strncmp(cp, "file://localhost", 16)) {	    cp += 16;	} else if (!strncmp(cp, "file:", 5)) {	    cp += 5;	}	if (testpath == NULL) {	    /*	     *	Get the directory containing the file or subdir.	     */	    cp = strip_trailing_slash(cp);	    savepath = HTParse(".", cp, PARSE_PATH+PARSE_PUNCTUATION);	} else {	    StrAllocCopy(savepath, cp);	}	HTUnEscape(savepath);	if (stat(savepath, &dir_info) == -1) {	    sprintf(tmpbuf, "Unable to get status of '%s'.", savepath);	    _statusline(tmpbuf);	    sleep(AlertSecs);	    FREE(savepath);	    return 0;	}	/*	 *  Save the owner of the current location for later use.	 *  Also save the device and inode for location checking/	 */	dev = dir_info.st_dev;	inode = dir_info.st_ino;	owner = dir_info.st_uid;	/*	 *  Replace ~/ references to the home directory.	 */	if (!strncmp(tmpbuf, "~/", 2)) {	    char *cp1 = NULL;	    StrAllocCopy(cp1, Home_Dir());	    StrAllocCat(cp1, (tmpbuf + 1));	    if (strlen(cp1) > (sizeof(tmpbuf) - 1)) {		sprintf(tmpbuf, "%s", "Path too long");		_statusline(tmpbuf);		sleep(AlertSecs);		FREE(savepath);		FREE(cp1);		return 0;	    }	    strcpy(tmpbuf, cp1);	    FREE(cp1);	}	/*	 *  If path is relative, prefix it with current location.	 */	if (tmpbuf[0] != '/') {	    if (savepath[(strlen(savepath) - 1)] != '/')		StrAllocCat(savepath,"/");	    StrAllocCat(savepath,tmpbuf);	} else {	    StrAllocCopy(savepath,tmpbuf);	}	/*	 *  stat() the target location to determine type and ownership.	 */	if (stat(savepath, &dir_info) == -1) {	    sprintf(tmpbuf,"Unable to get status of '%s'.",savepath);	    _statusline(tmpbuf);	    sleep(AlertSecs);	    FREE(savepath);	    return 0;	}	/*	 *  Make sure the source and target locations are not the same place.	 */	if (dev == dir_info.st_dev && inode == dir_info.st_ino) {	    _statusline(	   "Source and destination are the same location - request ignored!");	    sleep(AlertSecs);	    FREE(savepath);	    return 0;	}	/*	 *  Make sure the target location is a directory which is owned	 * by the same uid as the owner of the current location.	 */	if ((dir_info.st_mode & S_IFMT) == S_IFDIR) {	    if (dir_info.st_uid == owner) {		count = 0;		tag = tagged;		/*		 *  Move all tagged items to the target location.		 */		while ((cp = (char *)HTList_nextObject(tag)) != NULL) {		    if (!strncmp(cp, "file://localhost", 16)) {			cp += 16;		    } else if (!strncmp(cp, "file:", 5)) {			cp += 5;		    }		    StrAllocCopy(srcpath, cp);		    HTUnEscape(srcpath);		    sprintf(tmpbuf, "move %s to %s", srcpath, savepath);		    args[0] = "mv";		    args[1] = srcpath;		    args[2] = savepath;		    args[3] = (char *) 0;		    if (LYExecv(MV_PATH, args, tmpbuf) <= 0) {			if (count == 0)			    count = -1;			break;		    }		    ++count;		}		FREE(srcpath);		FREE(savepath);		clear_tags();		return count;	    } else {		_statusline(			"Destination has different owner! Request denied.");		sleep(AlertSecs);		FREE(srcpath);		FREE(savepath);		return 0;	    }	} else {	    _statusline(		   "Destination is not a valid directory! Request denied.");	    sleep(AlertSecs);	    FREE(savepath);	    return 0;	}    }    return 0;}/* *  Modify the name of the specified item. */PRIVATE BOOLEAN modify_name ARGS1(	char *, 	testpath){    char *cp;    char tmpbuf[512];    char newpath[512];    char savepath[512];    struct stat dir_info;    char *args[5];    /*     *	Determine the status of the selected item.     */    testpath = strip_trailing_slash(testpath);    if (stat(testpath, &dir_info) == -1) {	sprintf(tmpbuf, "Unable to get status of '%s'.", testpath);	_statusline(tmpbuf);	sleep(AlertSecs);    } else {	/*	 *  Change the name of the file or directory.	 */	if ((dir_info.st_mode & S_IFMT) == S_IFDIR) {	     cp = "Enter new name for directory: ";	} else if ((dir_info.st_mode & S_IFMT) == S_IFREG) {	     cp = "Enter new name for file: ";	} else {	     _statusline(	 "The selected item is not a file or a directory! Request ignored.");	     sleep(AlertSecs);	     return 0;	}	if (filename(cp, tmpbuf, sizeof(tmpbuf)) == NULL)	    return 0;	/*	 *  Do not allow the user to also change the location at this time.	 */	if (strchr(tmpbuf, '/') != NULL) {	    _statusline("Illegal character \"/\" found! Request ignored.");	    sleep(AlertSecs);	} else if (strlen(tmpbuf) &&		   (cp = strrchr(testpath, '/')) != NULL) {	    strcpy(savepath,testpath);	    *(++cp) = '\0';	    strcpy(newpath,testpath);	    strcat(newpath,tmpbuf);	    /*	     *	Make sure the destination does not already exist.	     */	    if (stat(newpath, &dir_info) == -1) {		if (errno != ENOENT) {		    sprintf(tmpbuf,			    "Unable to determine status of '%s'.", newpath);		    _statusline(tmpbuf);		    sleep(AlertSecs);		} else {		    sprintf(tmpbuf, "move %s to %s", savepath, newpath);		    args[0] = "mv";		    args[1] = savepath;		    args[2] = newpath;		    args[3] = (char *) 0;		    if (LYExecv(MV_PATH, args, tmpbuf) <= 0)			return (-1);		    return 1;		}

⌨️ 快捷键说明

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