void set1(const Char *var, Char **vec, struct varent *head, int flags) { Char **oldv = vec; if ((flags & VAR_NOGLOB) == 0) { int gflag; gflag = tglob(oldv); if (gflag) { vec = globall(oldv, gflag); if (vec == 0) { blkfree(oldv); stderror(ERR_NAME | ERR_NOMATCH); } blkfree(oldv); } } /* * Uniqueness addition from: Michael Veksler <*****@*****.**> */ if ( flags & (VAR_FIRST | VAR_LAST) ) { /* * Code for -f (VAR_FIRST) and -l (VAR_LAST) options. * Method: * Delete all duplicate words leaving "holes" in the word array (vec). * Then remove the "holes", keeping the order of the words unchanged. */ if (vec && vec[0] && vec[1]) { /* more than one word ? */ int i, j; int num_items; for (num_items = 0; vec[num_items]; num_items++) continue; if (flags & VAR_FIRST) { /* delete duplications, keeping first occurance */ for (i = 1; i < num_items; i++) for (j = 0; j < i; j++) /* If have earlier identical item, remove i'th item */ if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { xfree(vec[i]); vec[i] = NULL; break; } } else if (flags & VAR_LAST) { /* delete duplications, keeping last occurance */ for (i = 0; i < num_items - 1; i++) for (j = i + 1; j < num_items; j++) /* If have later identical item, remove i'th item */ if (vec[i] && vec[j] && Strcmp(vec[j], vec[i]) == 0) { /* remove identical item (the first) */ xfree(vec[i]); vec[i] = NULL; } } /* Compress items - remove empty items */ for (j = i = 0; i < num_items; i++) if (vec[i]) vec[j++] = vec[i]; /* NULL-fy remaining items */ for (; j < num_items; j++) vec[j] = NULL; } /* don't let the attribute propagate */ flags &= ~(VAR_FIRST|VAR_LAST); } setq(var, vec, head, flags); }
The default action is to shutdown without a reboot.\n\"now\" must be \ specified to actually shutdown or reboot\n"}; void doshutdown(Char **vc, struct command *c) { unsigned int flags = 0; unsigned char reboot,shutdown,logoff,shutdown_ok; char **v; char *ptr; char errbuf[128]; int k; HANDLE hToken; TOKEN_PRIVILEGES tp,tpPrevious; LUID luid; DWORD cbPrevious = sizeof(TOKEN_PRIVILEGES); if (gdwPlatform != VER_PLATFORM_WIN32_NT) { stderror(ERR_SYSTEM,"shutdown","Sorry,not supported on win95"); } shutdown_ok = reboot = shutdown = logoff = 0; gflag = 0; tglob(vc); if (gflag) { vc = globall(vc); if (vc == 0) stderror(ERR_NAME | ERR_NOMATCH); } else vc = gargv = saveblk(vc); trim(vc); v = short2blk(vc); for (k = 0; v[k] != NULL ; k++){ if ( v[k][0] == '-' ) { ptr = v[k]; ptr++; while( ptr && *ptr) { if (*ptr == 'f') flags |= EWX_FORCE; if (*ptr == 'r') reboot =1; else if (*ptr == 'l') logoff =1; else { blkfree((Char **)v); stderror(ERR_SYSTEM,"Usage",shutdown_usage); } ptr++; } } else if (!lstrcmpi(v[k],"now")) { shutdown_ok = 1; } } if (k == 0) { blkfree((Char**)v); stderror(ERR_SYSTEM,"Usage",shutdown_usage); } if (!reboot && !logoff){ flags |= EWX_SHUTDOWN; shutdown = 1; } if (reboot && logoff ) { blkfree((Char **)v); stderror(ERR_SYSTEM,"Usage",shutdown_usage); } if (reboot) flags |= EWX_REBOOT; if (logoff) flags |= EWX_LOGOFF; if ((reboot || shutdown) && (!shutdown_ok) ) { blkfree((Char **)v); stderror(ERR_SYSTEM,"shutdown","Specify \"now\" to really shutdown"); } if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES| TOKEN_QUERY, &hToken) ){ make_err_str(GetLastError(),errbuf,128); blkfree((Char **)v); stderror(ERR_SYSTEM,"shutdown failed",errbuf); } if (!LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&luid)) { make_err_str(GetLastError(),errbuf,128); blkfree((Char **)v); stderror(ERR_SYSTEM,"shutdown failed",errbuf); } tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = 0; if (!AdjustTokenPrivileges(hToken,FALSE,&tp,sizeof(tp),&tpPrevious, &cbPrevious)){ make_err_str(GetLastError(),errbuf,128); blkfree((Char **)v); stderror(ERR_SYSTEM,"shutdown failed",errbuf); } tpPrevious.PrivilegeCount = 1; tpPrevious.Privileges[0].Luid = luid; tpPrevious.Privileges[0].Attributes |= SE_PRIVILEGE_ENABLED; if (!AdjustTokenPrivileges(hToken,FALSE,&tpPrevious,cbPrevious,NULL, NULL)){ make_err_str(GetLastError(),errbuf,128); blkfree((Char **)v); stderror(ERR_SYSTEM,"shutdown failed",errbuf); } if ( !ExitWindowsEx(flags,0) ) { make_err_str(GetLastError(),errbuf,128); blkfree((Char **)v); stderror(ERR_SYSTEM,"shutdown failed",errbuf); } }
void doexec(struct command *t) { tchar *sav; tchar *dp, **pv, **av; struct varent *v; bool slash; int hashval, hashval1, i; tchar *blk[2]; #ifdef TRACE tprintf("TRACE- doexec()\n"); #endif /* * Glob the command name. If this does anything, then we * will execute the command only relative to ".". One special * case: if there is no PATH, then we execute only commands * which start with '/'. */ dp = globone(t->t_dcom[0]); sav = t->t_dcom[0]; exerr = 0; t->t_dcom[0] = dp; setname(dp); xfree(sav); v = adrof(S_path /* "path" */); if (v == 0 && dp[0] != '/') { pexerr(); } slash = gflag; /* * Glob the argument list, if necessary. * Otherwise trim off the quote bits. */ gflag = 0; av = &t->t_dcom[1]; tglob(av); if (gflag) { av = glob(av); if (av == 0) error("No match"); } blk[0] = t->t_dcom[0]; blk[1] = 0; av = blkspl(blk, av); #ifdef VFORK Vav = av; #endif trim(av); slash |= any('/', av[0]); xechoit(av); /* Echo command if -x */ /* * Since all internal file descriptors are set to close on exec, * we don't need to close them explicitly here. Just reorient * ourselves for error messages. */ SHIN = 0; SHOUT = 1; SHDIAG = 2; OLDSTD = 0; /* * We must do this AFTER any possible forking (like `foo` * in glob) so that this shell can still do subprocesses. */ (void) sigsetmask(0); /* * If no path, no words in path, or a / in the filename * then restrict the command search. */ if (v == 0 || v->vec[0] == 0 || slash) pv = justabs; else pv = v->vec; sav = strspl(S_SLASH /* "/" */, *av); /* / command name for postpending */ #ifdef VFORK Vsav = sav; #endif if (havhash) hashval = hashname(*av); i = 0; #ifdef VFORK hits++; #endif do { if (!slash && pv[0][0] == '/' && havhash) { hashval1 = hash(hashval, i); if (!bit(xhash, hashval1)) goto cont; } if (pv[0][0] == 0 || eq(pv[0], S_DOT /* "." */)) { /* don't make ./xxx */ texec(t, *av, av); } else { dp = strspl(*pv, sav); #ifdef VFORK Vdp = dp; #endif texec(t, dp, av); #ifdef VFORK Vdp = 0; #endif xfree(dp); } #ifdef VFORK misses++; #endif cont: pv++; i++; } while (*pv); #ifdef VFORK hits--; #endif #ifdef VFORK Vsav = 0; Vav = 0; #endif xfree(sav); xfree((char *)av); pexerr(); }
int nt_try_fast_exec(struct command *t) { register Char **pv, **av; register Char *dp,*sav; register char **tt; register char *f; register struct varent *v; register int hashval,i; register int slash; int rc = 0, gflag; Char *vp; Char *blk[2]; vp = varval(STRNTslowexec); if (vp != STRNULL) return 1; blk[0] = t->t_dcom[0]; blk[1] = 0; // don't do backtick if(Strchr(t->t_dcom[0],'`') ) return 1; gflag = tglob(blk); if (gflag) { pv = globall(blk, gflag); if (pv == 0) { return 1; } } else pv = saveblk(blk); trim(pv); epath = Strsave(pv[0]); v = adrof(STRpath); if (v == 0 && epath[0] != '/' && epath[0] != '.') { blkfree(pv); return 1; } slash = any(short2str(epath),'/'); /* * Glob the argument list, if necessary. Otherwise trim off the quote bits. */ av = &t->t_dcom[1]; gflag = tglob(av); if (gflag) { av = globall(av, gflag);/*FIXRESET*/ if (av == 0) { blkfree(pv); return 1; } } else av = saveblk(av); blkfree(t->t_dcom); t->t_dcom = blkspl(pv, av); xfree((ptr_t) pv); xfree((ptr_t) av); av = t->t_dcom; //trim(av); if (*av == NULL || **av == '\0') return 1; xechoit(av);/*FIXRESET*/ /* Echo command if -x */ if (v == 0 || v->vec[0] == 0 || slash) pv = abspath; else pv = v->vec; sav = Strspl(STRslash,*av); hashval = hashval_extern(*av); i = 0; do { #pragma warning(disable:4310) if (!slash && ABSOLUTEP(pv[0]) && havhash) { #pragma warning(default:4310) if (!bit_extern(hashval,i)){ pv++;i++; continue; } } if (pv[0][0] == 0 || eq(pv[0],STRdot)) { tt = short2blk(av); f = short2str(*av); rc = nt_texec(f, tt); blkfree((Char**)tt); if (!rc) break; } else { dp = Strspl(*pv,sav); tt = short2blk(av); f = short2str(dp); rc = nt_texec(f, tt); blkfree((Char**)tt); xfree((ptr_t)dp); if (!rc) break; } pv++; i++; }while(*pv); return rc; }
void /*ARGSUSED*/ doexec(Char **v, struct command *t) { Char *dp, **pv, **av, *sav; struct varent *pathv; bool slash; int hashval = 0, hashval1, i; Char *blk[2]; sigset_t sigset; /* * Glob the command name. We will search $path even if this does something, * as in sh but not in csh. One special case: if there is no PATH, then we * execute only commands which start with '/'. */ blk[0] = t->t_dcom[0]; blk[1] = 0; gflag = 0, tglob(blk); if (gflag) { pv = globall(blk); if (pv == 0) { setname(vis_str(blk[0])); stderror(ERR_NAME | ERR_NOMATCH); } gargv = 0; } else pv = saveblk(blk); trim(pv); exerr = 0; expath = Strsave(pv[0]); Vexpath = expath; pathv = adrof(STRpath); if (pathv == 0 && expath[0] != '/') { blkfree(pv); pexerr(); } slash = any(short2str(expath), '/'); /* * Glob the argument list, if necessary. Otherwise trim off the quote bits. */ gflag = 0; av = &t->t_dcom[1]; tglob(av); if (gflag) { av = globall(av); if (av == 0) { blkfree(pv); setname(vis_str(expath)); stderror(ERR_NAME | ERR_NOMATCH); } gargv = 0; } else av = saveblk(av); blkfree(t->t_dcom); t->t_dcom = blkspl(pv, av); xfree(pv); xfree(av); av = t->t_dcom; trim(av); if (*av == NULL || **av == '\0') pexerr(); xechoit(av); /* Echo command if -x */ /* * Since all internal file descriptors are set to close on exec, we don't * need to close them explicitly here. Just reorient ourselves for error * messages. */ SHIN = 0; SHOUT = 1; SHERR = 2; OLDSTD = 0; /* * We must do this AFTER any possible forking (like `foo` in glob) so that * this shell can still do subprocesses. */ sigemptyset(&sigset); sigprocmask(SIG_SETMASK, &sigset, NULL); /* * If no path, no words in path, or a / in the filename then restrict the * command search. */ if (pathv == 0 || pathv->vec[0] == 0 || slash) pv = justabs; else pv = pathv->vec; sav = Strspl(STRslash, *av);/* / command name for postpending */ Vsav = sav; if (havhash) hashval = hashname(*av); i = 0; hits++; do { /* * Try to save time by looking at the hash table for where this command * could be. If we are doing delayed hashing, then we put the names in * one at a time, as the user enters them. This is kinda like Korn * Shell's "tracked aliases". */ if (!slash && pv[0][0] == '/' && havhash) { hashval1 = hash(hashval, i); if (!bit(xhash, hashval1)) goto cont; } if (pv[0][0] == 0 || eq(pv[0], STRdot)) /* don't make ./xxx */ texec(*av, av); else { dp = Strspl(*pv, sav); Vdp = dp; texec(dp, av); Vdp = 0; xfree(dp); } misses++; cont: pv++; i++; } while (*pv); hits--; Vsav = 0; xfree(sav); pexerr(); }