lylocal.c

来自「基于rtos开发的浏览器!」· C语言 代码 · 共 2,288 行 · 第 1/4 页

C
2,288
字号
    /*     *	Open the tempfile for writing and set its     *	protection in case this wasn't done via an     *	external umask. - FM     */    if ((fp0 = LYNewTxtFile(tempfile)) == NULL) {	_statusline("Unable to open file management menu file.");	sleep(AlertSecs);	return(0);    }    if (first) {	/*	 *  Make the tempfile a URL.	 */	strcpy(LYDiredFileURL, "file://localhost");	strcat(LYDiredFileURL, tempfile);	first = FALSE;    }    StrAllocCopy(*newfile, LYDiredFileURL);    cp = doc->address;    if (!strncmp(cp, "file://localhost", 16)) {	cp += 16;    } else if (!strncmp(cp, "file:", 5)) {	cp += 5;    }    strcpy(dir, cp);    StrAllocCopy(dir_url, cp);    if (dir_url[(strlen(dir_url) - 1)] == '/')	dir_url[(strlen(dir_url) - 1)] = '\0';    HTUnEscape(dir);    if (dir[(strlen(dir) - 1)] == '/')	dir[(strlen(dir) - 1)] = '\0';    if (doc->link > -1 && doc->link < (nlinks+1)) {	cp = links[doc->link].lname;	if (!strncmp(cp, "file://localhost", 16)) {	    cp += 16;	} else if (!strncmp(cp, "file:", 5)) {	    cp += 5;	}	strcpy(path, cp);	StrAllocCopy(path_url, cp);	if (*path_url && path_url[1] && path_url[(strlen(path_url) - 1)] == '/')	    path_url[(strlen(path_url) - 1)] = '\0';	HTUnEscape(path);	if (*path && path[1] && path[(strlen(path) - 1)] == '/')	    path[(strlen(path) - 1)] = '\0';	if (lstat(path, &dir_info) == -1 && stat(path, &dir_info) == -1) {	    sprintf(tmpbuf, "Unable to get status of '%s'.", path);	    _statusline(tmpbuf);	    sleep(AlertSecs);	    FREE(dir_url);	    FREE(path_url);	    return 0;	}    } else {	path[0] = '\0';	StrAllocCopy(path_url, path);    }    nothing_tagged = (HTList_isEmpty(tagged));    fprintf(fp0,	    "<head>\n<title>%s</title></head>\n<body>\n", DIRED_MENU_TITLE);    fprintf(fp0,	    "\n<h1>File Management Options (%s Version %s)</h1>",	    LYNX_NAME, LYNX_VERSION);    fprintf(fp0, "Current directory is %s<br>\n", dir);    if (nothing_tagged) {	if (strlen(path)) {	    fprintf(fp0, "Current selection is %s<p>\n", path);	} else {	    fprintf(fp0, "Nothing currently selected.<p>\n");	}    } else {	/*	 *  Write out number of tagged items, and names of first	 *  few of them relative to current (in the DIRED sense)	 *  directory.	 */	int n = HTList_count(tagged);	char *cp1 = NULL;	char *cd = NULL;	int i, m;#define NUM_TAGS_TO_WRITE 10	fprintf(fp0, "Current selection is %d tagged item%s",		     n, ((n == 1) ? ":" : "s:"));	StrAllocCopy(cd, doc->address);	HTUnEscapeSome(cd, "/");	if (*cd && cd[(strlen(cd) - 1)] != '/')	    StrAllocCat(cd, "/");	m = (n < NUM_TAGS_TO_WRITE) ? n : NUM_TAGS_TO_WRITE;	for (i = 1; i <= m; i++) {	    cp1 = HTRelative(HTList_objectAt(tagged, i-1),			     (*cd ? cd : "file://localhost"));	    HTUnEscape(cp1);	    LYEntify(&cp1, TRUE); /* _should_ do this everywhere... */	    fprintf(fp0, "%s <br>\n &nbsp;&nbsp;&nbsp;%s",			 (i == 1 ? "" : " ,"), cp1);	    FREE(cp1);	}	if (n > m) {	    fprintf(fp0," , ...");	}	fprintf(fp0, "<p>\n");	FREE(cd);    }    /*     *	If menu_head is NULL then use defaults and link them together now.     */    if (menu_head == NULL) {	for (mp = defmenu; mp->href != NULL; mp++)	    mp->next = (mp + 1);	(--mp)->next = NULL;	menu_head = defmenu;    }    for (mp = menu_head; mp != NULL; mp = mp->next) {	if (mp->cond != DE_TAG && !nothing_tagged)	    continue;	if (mp->cond == DE_TAG && nothing_tagged)	    continue;	if (mp->cond == DE_DIR &&	    (!*path || (dir_info.st_mode & S_IFMT) != S_IFDIR))	    continue;	if (mp->cond == DE_FILE &&	    (!*path || (dir_info.st_mode & S_IFMT) != S_IFREG))	    continue;#ifdef S_IFLNK	if (mp->cond == DE_SYMLINK &&	    (!*path || (dir_info.st_mode & S_IFMT) != S_IFLNK))	    continue;#endif	if (*mp->sfx &&	    (strlen(path) < strlen(mp->sfx) ||	     strcmp(mp->sfx, &path[(strlen(path) - strlen(mp->sfx))]) != 0))	    continue;	fprintf(fp0, "<a href=\"%s",		render_item(mp->href, path_url, dir_url, buf,2048, YES));	fprintf(fp0, "\">%s</a> ",		render_item(mp->link, path, dir, buf,2048, NO));	fprintf(fp0, "%s<br>\n",		render_item(mp->rest, path, dir, buf,2048, NO));    }    if (uploaders != NULL) {	fprintf(fp0, "<p>Upload to current directory:<p>\n");	for (count = 0, nxt = uploaders;	     nxt != NULL;	     nxt = nxt->next, count++) {	    fprintf(fp0,		"<a href=\"LYNXDIRED://UPLOAD=%d/TO=%s\"> %s </a><br>\n",		    count, dir, nxt->name);	}    }    fprintf(fp0, "</body>\n");    fclose(fp0);    FREE(dir_url);    FREE(path_url);    LYforce_no_cache = TRUE;    return(0);}/* *  Check DIRED filename. */PRIVATE char *filename ARGS3(	char *, 	prompt,	char *, 	buf,	size_t,		bufsize){    char *cp;    _statusline(prompt);    *buf = '\0';    LYgetstr(buf, VISIBLE, bufsize, NORECALL);    if (strstr(buf, "../") != NULL) {	_statusline("Illegal filename; request ignored.");	sleep(AlertSecs);	return NULL;    }    if (no_dotfiles || !show_dotfiles) {	cp = strrchr(buf, '/'); /* find last slash */	if (cp)	    cp += 1;	else	    cp = buf;	if (*cp == '.') {	    _statusline("Illegal filename; request ignored.");	    sleep(AlertSecs);	    return NULL;	}    }    return buf;}/* *  Install the specified file or directory. */PUBLIC BOOLEAN local_install ARGS3(	char *, 	destpath,	char *, 	srcpath,	char **,	newpath){    char tmpbuf[512];    static char savepath[512]; /* This will be the link that				  is to be installed. */    struct stat dir_info;    char *args[6];    HTList *tag;    int count = 0;    int n = 0, src;	/* indices into 'args[]' */    /*     *	Determine the status of the selected item.     */    if (srcpath) {	srcpath = strip_trailing_slash(srcpath);	if (strncmp(srcpath, "file://localhost", 16) == 0)	    srcpath += 16;	if (stat(srcpath, &dir_info) == -1) {	    sprintf(tmpbuf, "Unable to get status of '%s'.", srcpath);	    _statusline(tmpbuf);	    sleep(AlertSecs);	    return 0;	} else if ((dir_info.st_mode & S_IFMT) != S_IFDIR &&		   (dir_info.st_mode & S_IFMT) != S_IFREG) {	    _statusline(	  "The selected item is not a file or a directory! Request ignored.");	    sleep(AlertSecs);	    return 0;	}	strcpy(savepath, srcpath);	LYforce_no_cache = TRUE;	strcpy(tmpbuf, "file://localhost");	strcat(tmpbuf, Home_Dir());	strcat(tmpbuf, "/.installdirs.html");	StrAllocCopy(*newpath, tmpbuf);	return 0;    }    destpath = strip_trailing_slash(destpath);    if (stat(destpath,&dir_info) == -1) {	sprintf(tmpbuf,"Unable to get status of '%s'.",destpath);	_statusline(tmpbuf);	sleep(AlertSecs);	return 0;    } else if ((dir_info.st_mode & S_IFMT) != S_IFDIR) {	_statusline(		"The selected item is not a directory! Request ignored.");	sleep(AlertSecs);	return 0;    } else if (0 /*directory not writeable*/) {	_statusline("Install in the selected directory not permitted.");	sleep(AlertSecs);	return 0;    }    statusline("Just a moment, ...");    args[n++] = "install";#ifdef INSTALL_ARGS    args[n++] = INSTALL_ARGS;#endif /* INSTALL_ARGS */    src = n++;    args[n++] = destpath;    args[n] = (char *)0;    sprintf(tmpbuf, "install %s", destpath);    tag = tagged;    if (HTList_isEmpty(tagged)) {	args[src] = savepath;	if (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0)	    return (-1);	count++;    } else {	char *name;	while ((name = (char *)HTList_nextObject(tag))) {	    args[src] = name;	    if (strncmp("file://localhost", args[src], 16) == 0)		 args[src] = (name + 16);	    if (LYExecv(INSTALL_PATH, args, tmpbuf) <= 0)		return ((count == 0) ? -1 : count);	    count++;	}	clear_tags();    }    statusline("Installation complete");    sleep(InfoSecs);    return count;}/* *  Clear DIRED tags. */PUBLIC void clear_tags NOARGS{    char *cp = NULL;    while ((cp = HTList_removeLastObject(tagged)) != NULL) {	FREE(cp);    }    if (HTList_isEmpty(tagged))	FREE(tagged);}/* *  Handle DIRED menu item. */PUBLIC void add_menu_item ARGS1(	char *, 	str){    struct dired_menu *new, *mp;    char *cp;    /*     *	First custom menu definition causes entire default menu to be     *	discarded.     */    if (menu_head == defmenu)	menu_head = NULL;    new = (struct dired_menu *)calloc(1, sizeof(*new));    /*     *	Conditional on tagged != NULL ?     */    cp = strchr(str, ':');    *cp++ = '\0';    if (strcasecomp(str, "tag") == 0) {	new->cond = DE_TAG;    } else if (strcasecomp(str, "dir") == 0) {	new->cond = DE_DIR;    } else if (strcasecomp(str, "file") == 0) {	new->cond = DE_FILE;    } else if (strcasecomp(str, "link") == 0) {	new->cond = DE_SYMLINK;    }    /*     *	Conditional on matching suffix.     */    str = cp;    cp = strchr(str, ':');    *cp++ = '\0';    StrAllocCopy(new->sfx, str);    str = cp;    cp = strchr(str, ':');    *cp++ = '\0';    StrAllocCopy(new->link, str);    str = cp;    cp = strchr(str, ':');    *cp++ = '\0';    StrAllocCopy(new->rest, str);    StrAllocCopy(new->href, cp);    if (menu_head) {	for (mp = menu_head; mp && mp->next != NULL; mp = mp->next)	    ;	mp->next = new;    } else	menu_head = new;}/* *  Create URL for DIRED HREF value. */PRIVATE char * render_item ARGS6(	char *, 	s,	char *, 	path,	char *, 	dir,	char *, 	buf,	int,		bufsize,	BOOLEAN,	url_syntax){    char *cp;    char *bp;    char overrun = '\0';    char *taglist = NULL;#define BP_INC (bp>buf+bufsize-2 ?  &overrun : bp++)				/* Buffer overrun could happen for very long				   tag list, if %l or %t are used */    bp = buf;    while (*s && !overrun) {	if (*s == '%') {	    s++;	    switch (*s) {		case '%':		    *BP_INC = '%';#ifdef NOTDEFINED		    /*		     *	These chars come from lynx.cfg or the default, let's		     *	just assume there won't be any improper %'s there that		     *	would need escaping.		     */		    if(url_syntax) {			*BP_INC = '2';			*BP_INC = '5';		    }#endif /* NOTDEFINED */		    break;		case 'p':		    cp = path;		    while (*cp)			*BP_INC = *cp++;		    break;		case 'd':		    cp = dir;		    while (*cp)			*BP_INC = *cp++;		    break;		case 'f':		    cp = strrchr(path, '/');		    if (cp)			cp++;		    else			cp = path;		    while (*cp)			*BP_INC = *cp++;		    break;		case 'l':		case 't':		    if (!HTList_isEmpty(tagged)) {			HTList *cur = tagged;			char *name;			while (!overrun &&			       (name = (char *)HTList_nextObject(cur))!=NULL) {			    if (*s == 'l' && (cp = strrchr(name, '/')))				cp++;			    else				cp = name;			    StrAllocCat(taglist, cp);			    StrAllocCat(taglist, " "); /* should this be %20?*/			}		    }		    if (taglist) {			/* could HTUnescape here... */			cp = taglist;			while (*cp)			    *BP_INC = *cp++;			FREE(taglist);		    }		    break;		default:		    *BP_INC = '%';#ifdef NOTDEFINED		    if (url_syntax) {			*BP_INC = '2';			*BP_INC = '5';		    }#endif /* NOTDEFINED */		    *BP_INC =*s;		    break;	    }	} else {	    /*	     *	Other chars come from the lynx.cfg or	     *	the default. Let's assume there isn't	     *	anything weird there that needs escaping.	     */	    *BP_INC =*s;	}	s++;    }    if (overrun & url_syntax) {	sprintf(buf,"Temporary URL or list would be too long.");	_statusline(buf);	sleep(AlertSecs);	bp = buf;	/* set to start, will return empty string as URL */    }    *bp = '\0';    return buf;}#endif /* DIRED_SUPPORT *//* *  Execute DIRED command. */PRIVATE int LYExecv ARGS3(	char *, 	path,	char **,	argv,	char *, 	msg){#if defined(VMS) || defined(_WINDOWS)    if (TRACE) {	fprintf(stderr, "LYExecv:  Called inappropriately!\n");    }    return(0);#else    int rc;    char tmpbuf[512];    pid_t pid;#if HAVE_TYPE_UNIONWAIT    union wait wstatus;#else    int wstatus;#endif    rc = 1;		/* It will work */    tmpbuf[0] = '\0';	/* empty buffer for alert messages */    stop_curses();    pid = fork();	/* fork and execute rm */    switch (pid) {	case -1:	    sprintf(tmpbuf, "Unable to %s due to system error!", msg);	    rc = 0;	    break;	/* don't fall thru! - KW */	case 0:  /* child */	    execv(path, argv);	    exit(-1);	/* execv failed, give wait() something to look at */	default:  /* parent */#if !HAVE_WAITPID	    while (wait(&wstatus) != pid)		; /* do nothing */#else	    while (-1 == waitpid(pid, &wstatus, 0)) { /* wait for child */#ifdef EINTR		if (errno == EINTR)		    continue;#endif /* EINTR */#ifdef ERESTARTSYS		if (errno == ERESTARTSYS)		    continue;#endif /* ERESTARTSYS */		break;	    }#endif /* !HAVE_WAITPID */	    if (WEXITSTATUS(wstatus) != 0 ||		WTERMSIG(wstatus) > 0)	{ /* error return */		sprintf(tmpbuf, "Probable failure to %s due to system error!",				msg);		rc = 0;	    }    }    if (rc == 0) {	/*	 *  Screen may have message from the failed execv'd command.	 *  Give user time to look at it before screen refresh.	 */	sleep(AlertSecs);    }    start_curses();    if (tmpbuf[0]) {	_statusline(tmpbuf);	sleep(AlertSecs);    }    return(rc);#endif /* VMS */}

⌨️ 快捷键说明

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