void initvar(void) { char ppid[20]; const struct varinit *ip; struct var *vp; struct var **vpp; for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { if ((vp->flags & VEXPORT) == 0) { vpp = hashvar(ip->text); vp->next = *vpp; *vpp = vp; vp->text = ip->text; vp->flags = ip->flags; vp->func = ip->func; } } /* * PS1 depends on uid */ if ((vps1.flags & VEXPORT) == 0) { vpp = hashvar("PS1="); vps1.next = *vpp; *vpp = &vps1; vps1.text = geteuid() ? "PS1=$ " : "PS1=# "; vps1.flags = VSTRFIXED|VTEXTFIXED; } if ((vppid.flags & VEXPORT) == 0) { fmtstr(ppid, sizeof(ppid), "%d", (int)getppid()); setvarsafe("PPID", ppid, 0); } }
// вызываем функцию на lua // указываем тип входящих аргументов через d(oble),i(nteger),s(tring) // символ > отделяет аргументы входащих от результата //void call_va(lua_State *L, const char *func, const char *sig, ...) { //int cbsdlua_funccmd(const char *func, const char *sig, ...) { int cbsdlua_funccmd(int argc, char **argv) { //const char *func, const char *sig, ...) { char *func=argv[1]; char *sig=argv[2]; int narg, nres, npos; lua_getglobal(L,func); // out2fmt_flush("func: %s\n", func); //push args for (narg=0; *sig; narg++ ) { npos=3 + narg; // 3 -$0, func, sig luaL_checkstack(L, 1, "too many arguments"); switch (*sig++) { case 'd': /* double */ // lua_pushnumber(L, va_arg(vl,double)); break; case 'i': /* integer */ lua_pushinteger(L, atoi(argv[npos])); break; case 's': /* string */ lua_pushstring(L, argv[npos]); break; case '>': /* end of argument */ goto endargs; default: cbsdlua_error(L,"invalid option (%c)", *(sig - 1 )); } } endargs: nres=strlen(sig); if (lua_pcall(L, narg, nres, 0)!= 0) cbsdlua_error(L, "error calling '%s': %s",func, lua_tostring(L,-1)); //get result nres = -nres; while (*sig) { switch (*sig++) { case 'd': { int isnum; double n = lua_tonumberx(L, nres, &isnum); if (!isnum) cbsdlua_error(L,"wrong result type"); // *va_arg(vl, double *) = n; break; } case 'i': { int isnum; int n = lua_tointegerx(L, nres, &isnum); if (!isnum) cbsdlua_error(L,"wrong result type"); // *va_arg(vl, int *) = n; // out2fmt_flush("LUA Return for %s: %d\n", argv[npos], n); char str[100]; fmtstr(str, sizeof(str), "%d", n); setvarsafe(argv[npos],str, 0); break; } case 's': { const char *s = lua_tostring(L, nres); if (s == NULL) cbsdlua_error(L,"wrong result type"); // *va_arg(vl, const char **) = s; // out2fmt_flush("LUA Return for %s: %s\n", argv[npos], s); setvarsafe(argv[npos],s, 0); break; } default: cbsdlua_error(L,"invalid option (%c)", *(sig - 1 )); } nres++; } 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; }
STATIC int getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, char **optpptr) { char *p, *q; char c = '?'; int done = 0; int ind = 0; int err = 0; char s[12]; if ((p = *optpptr) == 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'; err |= setvarsafe("OPTARG", s, 0); } else { outfmt(&errout, "Illegal option -%c\n", c); (void) unsetvar("OPTARG", 0); } c = '?'; goto bad; } if (*++q == ':') q++; } if (*++q == ':') { if (*p == '\0' && (p = **optnext) == NULL) { if (optstr[0] == ':') { s[0] = c; s[1] = '\0'; err |= setvarsafe("OPTARG", s, 0); c = ':'; } else { outfmt(&errout, "No arg for -%c option\n", c); (void) unsetvar("OPTARG", 0); c = '?'; } goto bad; } if (p == **optnext) (*optnext)++; err |= setvarsafe("OPTARG", p, 0); p = NULL; } else err |= setvarsafe("OPTARG", "", 0); ind = *optnext - optfirst + 1; goto out; bad: ind = 1; *optnext = NULL; p = NULL; out: *optpptr = p; 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; *optpptr = 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; }