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 %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 + -
显示快捷键?