📄 script.c
字号:
/* * Spawn a shell with file descriptors that look like this: * * + ---> screen (& virtual screen) * | * +---------+ +-----------+ * | | <---> cmd IPC <---> | pcomm_cmd | * | Pcomm | +-----------+ * TTYin ---> | | ---> pipe --> stdin | | * +---------+ | shell | * TTYout <--------------------------- stdout | | * +-----------+ * * This allows the characters to appear on the screen *and* be interpreted * by the shell script. */#include <stdio.h>#include <curses.h>#include <signal.h>#include <errno.h>#include "config.h"#include "dial_dir.h"#include "misc.h"#include "modem.h"#include "status.h"static int epid, dup_pipe[2];static char **fixup_env();voiddo_script(script)char *script;{ extern int fd; char buf[80], *path, *findfile(), **envp, *ipc_key(), *strcpy(); void _exit(), error_win(), ipc_update(); if (*script == '\0') return; /* * Chaining of scripts, is not allowed. If a script performs the * "pcomm_cmd dial" command and that dialing directory entry has * something in the script field, then ignore the second script. */ if (status->dup_fd != -1) return; /* find the script file */ if ((path = findfile(script)) == NULL) { /* * Fail quietly, if the script is actually a TTY or a * modem */ if (chk_aux(script) != IS_SCRIPT) return; sprintf(buf, "Can't locate script \"%s\"", script); error_win(0, buf, ""); return; } /* execute permission ? */ if (access(path, 1)) { sprintf(buf, "\"%s\"", path); error_win(0, "No execute permission on script file", buf); return; } /* * If a script is invoked prior to dialing, then we need to * pass a valid "fd" to the child process. If the script * then does a "pcomm_cmd dial", it *must* use that fd. */ if (fd == -1) { dir->d_cur = 0; dir->q_num[0] = 0; if (get_port()) return; } /* create a fd for duplicating input */ if (pipe(dup_pipe) < 0) { error_win(0, "Out of pipe resources", ""); return; } status->dup_fd = dup_pipe[1]; /* open an IPC channel */ if ((status->cmd_ipc = ipc_open()) < 0) { close(dup_pipe[0]); close(dup_pipe[1]); status->dup_fd = -1; error_win(0, "Can't open IPC channel", ""); return; } ipc_update(fd, status->cmd_ipc); /* pass the "key" in the environment */ strcpy(buf, ipc_key(status->cmd_ipc)); envp = fixup_env(buf); if (!(epid = fork())) { /* create a new process group ID */#ifdef BSD setpgrp(0, getpid());#else /* BSD */ setpgrp();#endif /* BSD */ /* swap the stdin and stdout */ close(0); dup(dup_pipe[0]); close(1); dup(fd); setgid(getgid()); setuid(getuid()); execle("/bin/sh", "sh", "-c", path, (char *) 0, envp); _exit(1); } return;}/* * See if the script process is still active */voidis_active(){ extern int errno, fd; int dummy; void ipc_update();#ifdef BSD if ((kill(epid, 0) == -1) && errno == ESRCH) {#else /* BSD */ if ((kill(-epid, 0) == -1) && errno == ESRCH) {#endif /* BSD */ /* shut down the duplication of input */ close(dup_pipe[0]); close(dup_pipe[1]); ipc_close(status->cmd_ipc); status->dup_fd = -1; status->cmd_ipc = -1; ipc_update(fd, status->cmd_ipc); wait(&dummy); beep(); } return;}/* * Abort the script prematurely. */voidstop_script(){ extern int fd; int dummy; unsigned int sleep(); void ipc_update();#ifdef BSD killpg(epid, SIGKILL);#else /* BSD */ kill(-epid, SIGKILL);#endif /* BSD */ sleep(1); close(dup_pipe[0]); close(dup_pipe[1]); ipc_close(status->cmd_ipc); status->dup_fd = -1; status->cmd_ipc = -1; ipc_update(fd, status->cmd_ipc); wait(&dummy); return;}/* * Prompt the user for a shell script. */char *script_menu(){ extern int fd; WINDOW *sc_win, *newwin(); char *ans, *script, *get_str(), *findfile(), *str_dup(), *path; char *strchr(), buf[80], *strcpy(); void free_ptr(), error_win(); if (status->dup_fd != -1) { error_win(0, "A script is already running", "Concurrent scripts are not allowed"); return(NULL); } sc_win = newwin(5, 55, 4, 7); box(sc_win, VERT, HORZ); mvwaddstr(sc_win, 2, 4, "Shell script: "); mvwattrstr(sc_win, 0, 3, A_BOLD, " Command Files "); wmove(sc_win, 2, 18); wrefresh(sc_win); script = NULL; strcpy(buf, "Shell script not found"); /* get the answer */ while ((ans = get_str(sc_win, 80, "", " \t\n")) != NULL) { /* a CR means exit */ if (*ans == '\0') break; /* see if we can find it */ if ((path = findfile(ans)) != NULL) { if (!access(path, 1)) { free_ptr(path); script = str_dup(ans); break; } else strcpy(buf, "No execute permission"); } beep(); if (strchr(ans, '/')) strcpy(buf, "Don't include the path"); mvwattrstr(sc_win, 3, 16, A_BOLD, buf); wrefresh(sc_win); wait_key(sc_win, 3); /* clean up the mess */ clear_line(sc_win, 2, 18, TRUE); clear_line(sc_win, 3, 16, TRUE); wmove(sc_win, 2, 18); wrefresh(sc_win); free_ptr(path); } if (fd == -1) { werase(sc_win); wrefresh(sc_win); } delwin(sc_win); return(script);}/* * Put PCOMM_CMD into a new environmental variable array. */static char **fixup_env(key)char *key;{ int n; extern char **environ; char **envp, buf[80], **temp, *malloc(), *str_dup(); /* how many variables do we have? */ temp = environ; n = 0; while (*temp != NULL) { n++; temp++; } envp = (char **) malloc((n+2) * sizeof(char *)); temp = envp; while (*environ != NULL) { /* don't copy an old value */ if (strncmp(*environ, "PCOMM_CMD=", 10)) { *temp = str_dup(*environ); temp++; } environ++; } sprintf(buf, "PCOMM_CMD=%s", key); *temp = str_dup(buf); temp++; *temp = NULL; return(envp);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -