da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * bash specific extensions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * originally provided by Karsten Fleischer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "name.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef BASH_MAJOR
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define BASH_MAJOR "1"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define BASH_MINOR "0"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define BASH_PATCH "0"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define BASH_BUILD "0"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define BASH_RELEASE "experimental"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define BASH_VERSION BASH_MAJOR "." BASH_MINOR "." BASH_PATCH "(" BASH_BUILD ")-" BASH_RELEASE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern const char bash_pre_rc[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *login_files[4];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char sh_bash1[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[B?Enable brace group expansion. This option is only availabe in bash "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "compatibility mode. In ksh mode, brace group expansion is always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[P?Do not follow symbolic links, use physical directory structure "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "instead. Only available in bash compatibility mode.]";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char sh_bash2[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[O]:?[shopt_option?\ashopt_option\a is one of the shell options accepted by "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the \bshopt\b builtin. If \ashopt_option\a is present, \b-O\b sets "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the value of that option; \b+O\b unsets it. If \ashopt_option\a is "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "not supplied, the names and values of the shell options accepted by "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\bshopt\b are printed on the standard output. If the invocation "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "option is \b+O\b, the output is displayed in a format that may be "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "reused as input. Only available if invoked as \bbash\b.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[01:init-file|rcfile]:[file?Execute commands from \afile\a instead of the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "standard personal initialization file ~/.bashrc if the shell is "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "interactive. Only available if invoked as \bbash\b.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[02:editing?For option compatibility with \bbash\b only. Ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[03:profile?Read either the system-wide startup file or any of the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "personal initialization files. On by default for interactive "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "shells. Only available if invoked as \bbash\b.]"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"[04:posix?If invoked as \bbash\b, turn on POSIX compatibility. \bBash\b in "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "POSIX mode is not the same as \bksh\b.]"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin"[05:version?Print version number and exit.]";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst char sh_optshopt[] =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"+[-1c?\n@(#)$Id: shopt (AT&T Research) 2003-02-13 $\n]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[-author?Karsten Fleischer <K.Fleischer@omnium.de>]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinUSAGE_LICENSE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+NAME?shopt - set/unset variables controlling optional shell behavior]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+DESCRIPTION?\bshopt\b sets or unsets variables controlling optional shell "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "behavior. With no options, or with the \b-p\b option, a list of all "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "settable options is displayed, with an indication of whether or not "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "each is set.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[p?Causes output to be displayed in a form that may be reused as input.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[s?Set each \aoptname\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[u?Unset each \aoptname\a.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[q?Suppress output (quiet mode). The return status indicates whether the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "\aoptname\a is set or unset. If multiple \aoptname\a arguments are "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "given with \b-q\b, the return status is zero if all \aoptname\as are "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "enabled; non-zero otherwise.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[o?Restricts the values of \aoptname\a to be those defined for the \b-o\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "option to the set builtin.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?If either \b-s\b or \b-u\b is used with no \aoptname\a arguments, the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "display is limited to those options which are set or unset.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?\bshopt\b supports all bash options. Some settings do not have any effect "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "or are are always on and cannot be changed.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+?The value of \aoptname\a must be one of the following:]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+cdable_vars?If set, arguments to the \bcd\b command are "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "assumed to be names of variables whose values are to "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "be used if the usual \bcd\b proceeding fails.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+cdspell?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+checkhash?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+checkwinsize?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+cmdhist?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+dotglob?If set, include filenames beginning with a \b.\b "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "in the results of pathname expansion.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+execfail?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+expand_aliases?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+extglob?Enable extended pattern matching features.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+histappend?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+histreedit?If set and an edit mode is selected, the user "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "is given the opportunity to re-edit a failed history "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "substitution.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+histverify?If set and an edit mode is selected, the result "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "of a history substitution will not be executed "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "immediately but be placed in the edit buffer for "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "further modifications.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+hostcomplete?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+huponexit?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+interactive_comments?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+lithist?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+login_shell?This option is set if the shell is started as "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "a login shell. The value cannot be changed.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+mailwarn?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+no_empty_cmd_completion?Always on.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+nocaseglob?Match filenames in a case-insensitive fashion "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "when performing filename expansion.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+nullglob?Allows filename patterns which match no files to "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "expand to a null string, rather than themselves.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+progcomp?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+promptvars?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+restricted_shell?This option is set if the shell is started "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "as a restricted shell. The value cannot be changed. "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "It is not reset during execution of startup files, "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "allowing the startup files to determine whether the "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "shell is restricted.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+shift_verbose?Currently ignored.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+sourcepath?If set, the \b.\b builtin uses the value of PATH "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "to find the directory containing the file supplied "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "as an argument.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+xpg_echo?If set, the \becho\b and \bprint\b builtins "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "expand backslash-escape sequences.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n[optname ...]\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"\n"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+EXIT STATUS?]{"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "[+?The return status when listing options is zero if all \aoptnames\a "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "are enabled, non-zero otherwise. When setting or unsetting options, "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "the return status is zero unless an \aoptname\a is not a valid shell "
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin "option.]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"}"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin"[+SEE ALSO?\bset\b(1)]"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* GLOBIGNORE discipline. Turn on SH_DOTGLOB on set, turn off on unset. */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_globignore(register Namval_t* np, const char *val, int flags, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_DOTGLOB);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_DOTGLOB);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst Namdisc_t SH_GLOBIGNORE_disc = { sizeof(Namfun_t), put_globignore };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* FUNCNAME discipline */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct funcname
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t hdr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_funcname(register Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* bash silently returns with an error when FUNCNAME is set,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsetting FUNCNAME is allowed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val && !(flags&NV_RDONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.exit(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst Namdisc_t SH_FUNCNAME_disc = { sizeof(struct funcname), put_funcname };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SET_SET 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SET_UNSET 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define SET_NOARGS 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* shopt builtin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint b_shopt(int argc,register char *argv[],void *extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp = (Shell_t*)extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n, f, ret=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shopt_t newflags=shp->options, opt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int verbose=PRINT_SHOPT|PRINT_ALL|PRINT_NO_HEADER|PRINT_VERBOSE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int setflag=0, quietflag=0, oflag=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&opt,0,sizeof(opt));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_RAWONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&newflags,SH_VIRAW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n = optget(argv,sh_optshopt)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'p':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin verbose&=~PRINT_VERBOSE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setflag|=n=='s'?SET_SET:SET_UNSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag==(SET_SET|SET_UNSET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_ERROR,"cannot set and unset options simultaneously");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.errors++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'q':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin quietflag=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oflag=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin verbose&=~PRINT_SHOPT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ':':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2, "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '?':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(error_info.errors)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc -= opt_info.index;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argc==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* no args, -s => mask=current options, -u mask=~(current options)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else mask=all bits */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag&SET_SET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt=newflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(setflag&SET_UNSET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0;n<4;n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt.v[n]=~newflags.v[n];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&opt,0xff,sizeof(opt));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin setflag=SET_NOARGS;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argc>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin f=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=sh_lookopt(argv[opt_info.index],&f);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n<=0||(setflag
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin && (is_option(&opt,SH_INTERACTIVE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || is_option(&opt,SH_RESTRICTED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || is_option(&opt,SH_RESTRICTED2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || is_option(&opt,SH_BASH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin || is_option(&opt,SH_LOGIN_SHELL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ||(oflag&&(n&SH_BASHOPT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_ERROR, e_option, argv[opt_info.index]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin error_info.errors++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ret=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(f)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin on_option(&opt,n&0xff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&opt,n&0xff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin opt_info.index++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argc--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag&(SET_SET|SET_UNSET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(setflag&SET_SET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_INTERACTIVE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&opt,SH_NOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_option(&opt,SH_VI)||is_option(&opt,SH_EMACS)||is_option(&opt,SH_GMACS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_VI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_EMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_option(&newflags,SH_GMACS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0;n<4;n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newflags.v[n] |= opt.v[n];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(setflag&SET_UNSET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0;n<4;n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newflags.v[n] &= ~opt.v[n];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_applyopts(shp,newflags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->options = newflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_option(&newflags,SH_XTRACE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_trace(argv,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(setflag&SET_NOARGS)) /* no -s,-u but args, ret=0 if opt&mask==mask */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0;n<4;n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ret+=((newflags.v[n]&opt.v[n])!=opt.v[n]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!quietflag&&!(setflag&(SET_SET|SET_UNSET)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_printopts(newflags,verbose,&opt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ret);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* mode = 0: init, called two times
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin before parsing shell args with SH_PREINIT state turned on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin second time after sh_init() is through and with SH_PREINIT state turned off
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode > 1: re-init
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode < 0: shutdown
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid bash_init(int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n=0,xtrace,verbose;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto reinit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* termination code */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_LOGIN_SHELL) && !sh_isoption(SH_POSIX))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_source(shp, NiL, sh_mactry(shp,(char*)e_bash_logout));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_PREINIT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin { /* pre-init stage */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_RESTRICTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_RESTRICTED2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_HISTORY2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_INTERACTIVE_COMM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_SOURCEPATH);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_HISTAPPEND);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_CMDHIST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_LITHIST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_NOEMPTYCMDCOMPL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->login_sh==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_LOGIN_SHELL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(astconf("CONFORMANCE",0,0),"standard")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_POSIX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(astconf("UNIVERSE",0,0),"att")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_XPG_ECHO);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_XPG_ECHO);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(astconf("PATH_RESOLVE",0,0),"physical")==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_PHYSICAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_PHYSICAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add builtins */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_addbuiltin("shopt", b_shopt, &sh);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set up some variables needed for --version
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * needs to go here because --version option is parsed before the init script.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np=nv_open("HOSTTYPE",shp->var_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, BASH_HOSTTYPE, NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np=nv_open("MACHTYPE",shp->var_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, BASH_MACHTYPE, NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np=nv_open("BASH_VERSION",shp->var_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, BASH_VERSION, NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np=nv_open("BASH_VERSINFO",shp->var_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *argv[7];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[0] = BASH_MAJOR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[1] = BASH_MINOR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[2] = BASH_PATCH;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[3] = BASH_BUILD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[4] = BASH_RELEASE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[5] = BASH_MACHTYPE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argv[6] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setvec(np, 0, 6, argv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* rest of init stage */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restrict BASH_ENV */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np=nv_open("BASH_ENV",shp->var_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const Namdisc_t *dp = nv_discfun(NV_DCRESTRICT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *fp = calloc(dp->dsize,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->disc = dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_disc(np, fp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* open GLOBIGNORE node */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np=nv_open("GLOBIGNORE",shp->var_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const Namdisc_t *dp = &SH_GLOBIGNORE_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *fp = calloc(dp->dsize,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->disc = dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_disc(np, fp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set startup files */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_isoption(SH_LOGIN_SHELL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_POSIX))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin login_files[n++] = (char*)e_bash_profile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin login_files[n++] = (char*)e_bash_login;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin login_files[n++] = (char*)e_profile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->login_files = login_files;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinreinit:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xtrace = sh_isoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin verbose = sh_isoption(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_VERBOSE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np = nv_open("SHELLOPTS", shp->var_tree, NV_NOADD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sfopen(NULL, bash_pre_rc, "s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_eval(iop,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(xtrace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_XTRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(verbose)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_VERBOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}