void cbsdlua_error( lua_State *L, const char *fmt, ... ) { va_list argp; va_start(argp, fmt); out2fmt_flush("lua error:"); vfprintf(stderr, fmt, argp); out2fmt_flush("\n"); va_end(argp); // lua_close(L); // exit(EXIT_FAILURE); }
void setjobctl(int on) { int i; if (on == jobctl || rootshell == 0) return; if (on) { if (ttyfd != -1) close(ttyfd); if ((ttyfd = open(_PATH_TTY, O_RDWR | O_CLOEXEC)) < 0) { i = 0; while (i <= 2 && !isatty(i)) i++; if (i > 2 || (ttyfd = fcntl(i, F_DUPFD_CLOEXEC, 10)) < 0) goto out; } if (ttyfd < 10) { /* * Keep our TTY file descriptor out of the way of * the user's redirections. */ if ((i = fcntl(ttyfd, F_DUPFD_CLOEXEC, 10)) < 0) { close(ttyfd); ttyfd = -1; goto out; } close(ttyfd); ttyfd = i; } do { /* while we are in the background */ initialpgrp = tcgetpgrp(ttyfd); if (initialpgrp < 0) { out: out2fmt_flush("sh: can't access tty; job control turned off\n"); mflag = 0; return; } if (initialpgrp != getpgrp()) { kill(0, SIGTTIN); continue; } } while (0); setsignal(SIGTSTP); setsignal(SIGTTOU); setsignal(SIGTTIN); setpgid(0, rootpid); tcsetpgrp(ttyfd, rootpid); } else { /* turning job control off */ setpgid(0, initialpgrp); tcsetpgrp(ttyfd, initialpgrp); close(ttyfd); ttyfd = -1; setsignal(SIGTSTP); setsignal(SIGTTOU); setsignal(SIGTTIN); } jobctl = on; }
static void vwarning(const char *msg, va_list ap) { if (commandname) outfmt(out2, "%s: ", commandname); doformat(out2, msg, ap); out2fmt_flush("\n"); }
static int preadfd(void) { int nr; parsenextc = parsefile->buf; #ifndef NO_HISTORY if (el != NULL && gotwinch) { gotwinch = 0; el_resize(el); } #endif retry: #ifndef NO_HISTORY if (parsefile->fd == 0 && el) { static const char *rl_cp; static int el_len; if (rl_cp == NULL) rl_cp = el_gets(el, &el_len); if (rl_cp == NULL) nr = 0; else { nr = el_len; if (nr > BUFSIZ) nr = BUFSIZ; memcpy(parsenextc, rl_cp, nr); if (nr != el_len) { el_len -= nr; rl_cp += nr; } else rl_cp = NULL; } } else #endif nr = read(parsefile->fd, parsenextc, BUFSIZ); if (nr <= 0) { if (nr < 0) { if (errno == EINTR) goto retry; if (parsefile->fd == 0 && errno == EWOULDBLOCK) { int flags = fcntl(0, F_GETFL, 0); if (flags >= 0 && flags & O_NONBLOCK) { flags &=~ O_NONBLOCK; if (fcntl(0, F_SETFL, flags) >= 0) { out2fmt_flush("sh: turning off NDELAY mode\n"); goto retry; } } } } nr = -1; } return nr; }
int bltincmd(int argc, char **argv) { if (argc > 1) { out2fmt_flush("%s: not found\n", argv[1]); return 127; } /* * Preserve exitstatus of a previous possible redirection * as POSIX mandates */ return exitstatus; }
static void cmdloop(int top) { union node *n; struct stackmark smark; int inter; int numeof = 0; TRACE(("cmdloop(%d) called\n", top)); setstackmark(&smark); for (;;) { if (pendingsig) dotrap(); inter = 0; if (iflag && top) { inter++; showjobs(1, SHOWJOBS_DEFAULT); #ifndef CBSD chkmail(0); #endif flushout(&output); } n = parsecmd(inter); /* showtree(n); DEBUG */ if (n == NEOF) { if (!top || numeof >= 50) break; if (!stoppedjobs()) { if (!Iflag) break; out2fmt_flush("\nUse \"exit\" to leave shell.\n"); } numeof++; } else if (n != NULL && nflag == 0) { job_warning = (job_warning == 2) ? 1 : 0; numeof = 0; evaltree(n, 0); } popstackmark(&smark); setstackmark(&smark); if (evalskip != 0) { if (evalskip == SKIPRETURN) evalskip = 0; break; } } popstackmark(&smark); }
static void jobctl_notty(void) { if (ttyfd >= 0) { close(ttyfd); ttyfd = -1; } if (!iflag) { setsignal(SIGTSTP); setsignal(SIGTTOU); setsignal(SIGTTIN); jobctl = 1; return; } out2fmt_flush("sh: can't access tty; job control turned off\n"); mflag = 0; }
int cbsdluacmd(void) { char buff[256]; int error; // lua_State *L = luaL_newstate(); luaL_openlibs(L); while (fgets(buff,sizeof(buff), stdin) != NULL ) { error = luaL_loadstring(L,buff) || lua_pcall(L,0,0,0); if (error) { out2fmt_flush("%s\n", lua_tostring(L, -1 )); lua_pop(L,1); } } // lua_close(L); return 0; }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit(void) { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2fmt_flush("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ char *term; INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_err == NULL) el_err = fdopen(1, "w"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_err == NULL || el_out == NULL) goto bad; term = lookupvar("TERM"); if (term) { if (setenv("TERM", term, 1) == -1) error("setenv: cannot set TERM=1"); } else unsetenv("TERM"); el = el_init(arg0, el_in, el_out, el_err); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); el_set(el, EL_ADDFN, "rl-complete", "ReadLine compatible completion function", _el_fn_complete); } else { bad: out2fmt_flush("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_BIND, "^I", tabcomplete ? "rl-complete" : "ed-insert", NULL); el_source(el, NULL); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }
int cbsd_fwatchcmd(int argc, char *argv[]) { int fd, kq, nev; struct kevent ev; int optcode = 0; int option_index = 0; struct timespec tv; char *watchfile = NULL; int timeout = 10; char cmd[10]; struct option long_options[] = { { "file", required_argument, 0, C_FILE }, { "timeout", required_argument, 0, C_TIMEOUT }, /* End of options marker */ { 0, 0, 0, 0 } }; if (argc < 2) { cbsd_fwatch_usage(); return 0; } while (TRUE) { optcode = getopt_long_only(argc, argv, "", long_options, &option_index); if (optcode == -1) break; switch (optcode) { case C_FILE: watchfile = malloc(strlen(optarg) + 1); memset(watchfile, 0, strlen(optarg) + 1); strcpy(watchfile, optarg); break; case C_TIMEOUT: timeout = atoi(optarg); break; } } //while //zero for getopt *variables for next execute optarg = NULL; optind = 0; optopt = 0; opterr = 0; optreset = 0; if (!watchfile) { cbsd_fwatch_usage(); return 1; } if ((fd = open(watchfile, O_RDONLY)) == -1) { out2fmt_flush("Cannot open: %s\n", watchfile); ckfree(watchfile); return(1); } if ((kq = kqueue()) == -1) { out2fmt_flush("Cannot create kqueue\n"); close(fd); ckfree(watchfile); return 1; } EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, NOTE_DELETE|NOTE_WRITE|NOTE_EXTEND|NOTE_ATTRIB|NOTE_LINK| NOTE_RENAME|NOTE_REVOKE, 0, 0); if (kevent(kq, &ev, 1, NULL, 0, NULL) == -1) { out2fmt_flush("kevent\n"); close(fd); ckfree(watchfile); close(kq); return 1; } tv.tv_sec = timeout; tv.tv_nsec = 0; memset(cmd,0,sizeof(cmd)); if (timeout == 0) nev = kevent(kq, NULL, 0, &ev, 1, NULL); else nev = kevent(kq, NULL, 0, &ev, 1, &tv); if (nev == -1) { out2fmt_flush("kevent\n"); close(fd); ckfree(watchfile); close(kq); return 1; } close(kq); close(fd); if (nev != 0) { if (ev.fflags & NOTE_DELETE) { out2fmt_flush("deleted\n"); ev.fflags &= ~NOTE_DELETE; } if (ev.fflags & NOTE_WRITE) { out2fmt_flush("written\n"); ev.fflags &= ~NOTE_WRITE; } if (ev.fflags & NOTE_EXTEND) { out2fmt_flush("extended\n"); ev.fflags &= ~NOTE_EXTEND; } if (ev.fflags & NOTE_ATTRIB) { out2fmt_flush("chmod/chown/utimes\n"); ev.fflags &= ~NOTE_ATTRIB; } if (ev.fflags & NOTE_LINK) { out2fmt_flush("hardlinked\n"); ev.fflags &= ~NOTE_LINK; } if (ev.fflags & NOTE_RENAME) { out2fmt_flush("renamed\n"); ev.fflags &= ~NOTE_RENAME; } if (ev.fflags & NOTE_REVOKE) { out2fmt_flush("revoked\n"); ev.fflags &= ~NOTE_REVOKE; } } ckfree(watchfile); return 0; }
int main(int argc, char *argv[]) { struct stackmark smark, smark2; volatile int state; char *shinit; (void) setlocale(LC_ALL, ""); initcharset(); state = 0; if (setjmp(main_handler.loc)) { switch (exception) { case EXEXEC: exitstatus = exerrno; break; case EXERROR: exitstatus = 2; break; default: break; } if (state == 0 || iflag == 0 || ! rootshell || exception == EXEXIT) exitshell(exitstatus); reset(); if (exception == EXINT) out2fmt_flush("\n"); popstackmark(&smark); FORCEINTON; /* enable interrupts */ if (state == 1) goto state1; else if (state == 2) goto state2; else if (state == 3) goto state3; else goto state4; } handler = &main_handler; #ifdef DEBUG opentrace(); trputs("Shell args: "); trargs(argv); #endif rootpid = getpid(); rootshell = 1; init(); setstackmark(&smark); setstackmark(&smark2); procargs(argc, argv); pwd_init(iflag); if (iflag) chkmail(1); if (argv[0] && argv[0][0] == '-') { state = 1; read_profile("/etc/profile"); state1: state = 2; if (privileged == 0) read_profile("${HOME-}/.profile"); else read_profile("/etc/suid_profile"); } state2: state = 3; if (!privileged && iflag) { if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { state = 3; read_profile(shinit); } } state3: state = 4; popstackmark(&smark2); if (minusc) { evalstring(minusc, sflag ? 0 : EV_EXIT); } if (sflag || minusc == NULL) { state4: /* XXX ??? - why isn't this before the "if" statement */ cmdloop(1); } exitshell(exitstatus); /*NOTREACHED*/ return 0; }
static int getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, char **optptr) { char *p, *q; char c = '?'; int done = 0; int ind = 0; int err = 0; char s[10]; const char *newoptarg = NULL; if ((p = *optptr) == NULL || *p == '\0') { /* Current word is done, advance */ if (*optnext == NULL) return 1; p = **optnext; if (p == NULL || *p != '-' || *++p == '\0') { atend: ind = *optnext - optfirst + 1; *optnext = NULL; p = NULL; done = 1; goto out; } (*optnext)++; if (p[0] == '-' && p[1] == '\0') /* check for "--" */ goto atend; } c = *p++; for (q = optstr; *q != c; ) { if (*q == '\0') { if (optstr[0] == ':') { s[0] = c; s[1] = '\0'; newoptarg = s; } else out2fmt_flush("Illegal option -%c\n", c); c = '?'; goto out; } if (*++q == ':') q++; } if (*++q == ':') { if (*p == '\0' && (p = **optnext) == NULL) { if (optstr[0] == ':') { s[0] = c; s[1] = '\0'; newoptarg = s; c = ':'; } else { out2fmt_flush("No arg for -%c option\n", c); c = '?'; } goto out; } if (p == **optnext) (*optnext)++; newoptarg = p; p = NULL; } out: if (*optnext != NULL) ind = *optnext - optfirst + 1; *optptr = p; if (newoptarg != NULL) err |= setvarsafe("OPTARG", newoptarg, 0); else { INTOFF; err |= unsetvar("OPTARG"); INTON; } fmtstr(s, sizeof(s), "%d", ind); err |= setvarsafe("OPTIND", s, VNOFUNC); s[0] = c; s[1] = '\0'; err |= setvarsafe(optvar, s, 0); if (err) { *optnext = NULL; *optptr = NULL; flushall(); exraise(EXERROR); } return done; }
int main(int argc, char *argv[]) { struct stackmark smark, smark2; volatile int state; char *shinit; #ifdef CBSD char *MY_APP = NULL; char *cbsdpath = NULL; char *workdir = NULL; char *cbsd_disable_history = NULL; //getenv chdir("/var/empty"); /* Only use history when stdin is a tty. */ if ( isatty(0) && isatty(1) ) { cbsd_enable_history = 1; } #endif (void) setlocale(LC_ALL, ""); initcharset(); state = 0; if (setjmp(main_handler.loc)) { switch (exception) { case EXEXEC: exitstatus = exerrno; break; case EXERROR: exitstatus = 2; break; default: break; } if (state == 0 || iflag == 0 || ! rootshell || exception == EXEXIT) exitshell(exitstatus); reset(); if (exception == EXINT) out2fmt_flush("\n"); popstackmark(&smark); FORCEINTON; /* enable interrupts */ if (state == 1) goto state1; else if (state == 2) goto state2; else if (state == 3) goto state3; else goto state4; } handler = &main_handler; #ifdef DEBUG opentrace(); trputs("Shell args: "); trargs(argv); #endif rootpid = getpid(); rootshell = 1; INTOFF; initvar(); setstackmark(&smark); setstackmark(&smark2); #ifdef CBSD if (argc>1) { if (!strcmp(argv[1],"--help")) { system("/usr/local/bin/cbsd help"); exit(0); } else { if (!strcmp(argv[1],"version")) { printf("%s\n",VERSION); exit(0); } } } cbsd_disable_history=lookupvar("NO_CBSD_HISTORY"); if ( cbsd_disable_history != NULL ) cbsd_enable_history=0; workdir=lookupvar("workdir"); if ( workdir == NULL ) { read_profile("/etc/rc.conf"); setvarsafe("workdir", lookupvar("cbsd_workdir"), 0); } workdir=lookupvar("workdir"); if ( workdir == NULL ) { out2fmt_flush("cbsd: no workdir defined\n"); exitshell(1); } setvarsafe("PS1","cbsd@\\h> ",1); setvarsafe("workdir",workdir,1); workdir=lookupvar("workdir"); // ^^ after "setsave*" original is free cbsdpath = calloc(MAXPATHLEN, sizeof(char *)); if (argv[1]) { setvarsafe("CBSD_APP",basename(argv[1]),1); } if (cbsdpath == NULL) { out2fmt_flush("cbsd: out of memory for cbsdpath\n"); exitshell(1); } // %s/modules must be first for opportunity to have a module commands greater priority than the original CBSD command. // This makes it possible to write a 3rd party modules with altered functionality of the original code. sprintf(cbsdpath,"%s/modules:%s/bin:%s/sbin:%s/tools:%s/jailctl:%s/nodectl:%s/system:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin",workdir,cbsd_distdir,cbsd_distdir,cbsd_distdir,cbsd_distdir,cbsd_distdir,cbsd_distdir); setvarsafe("PATH",cbsdpath,1); ckfree(cbsdpath); // read global params first (disable/enable colors, repos etc..) read_profile("${workdir}/etc/defaults/global.conf"); read_profile("${workdir}/etc/global.conf"); if (lookupvar("NOCOLOR") != NULL ) { putenv("NOCOLOR=1"); } // non-interactive global env if (lookupvar("NOINTER") != NULL ) { setvarsafe("inter","1",1); putenv("inter=0"); } read_profile("/usr/local/cbsd/cbsd.conf"); read_profile("${workdir}/etc/defaults/logger.conf"); read_profile("${workdir}/etc/logger.conf"); if (cbsd_enable_history==1) { cbsd_history_file=calloc(MAXPATHLEN, sizeof(char *)); sprintf(cbsd_history_file,"%s/%s",workdir,CBSD_HISTORYFILE); } #endif procargs(argc, argv); pwd_init(iflag); INTON; #ifndef CBSD if (iflag) chkmail(1); #endif if (argv[0] && argv[0][0] == '-') { state = 1; read_profile("/etc/profile"); state1: state = 2; if (privileged == 0) read_profile("${HOME-}/.profile"); else read_profile("/etc/suid_profile"); } state2: state = 3; if (!privileged && iflag) { if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { state = 3; read_profile(shinit); } } state3: state = 4; popstackmark(&smark2); if (minusc) { evalstring(minusc, sflag ? 0 : EV_EXIT); } state4: if (sflag || minusc == NULL) { cmdloop(1); } exitshell(exitstatus); /*NOTREACHED*/ return 0; }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit(void) { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2fmt_flush("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ char *term; INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_out == NULL) goto bad; term = lookupvar("TERM"); if (term) setenv("TERM", term, 1); else unsetenv("TERM"); el = el_init(arg0, el_in, el_out, el_out); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); el_set(el, EL_ADDFN, "sh-complete", "Filename completion", _el_fn_sh_complete); } else { bad: out2fmt_flush("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); /* * Set CTRL+R to history search for compatibility with * other operating systems' default shells. */ el_set(el, EL_BIND, "^R", "em-inc-search-prev", NULL); el_set(el, EL_BIND, "^I", "sh-complete", NULL); el_source(el, NULL); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }