main.c revision db397771158a0b9b33b5ab2dee8593e03ee5e994
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* UNIX shell
*/
#include "defs.h"
#include "sym.h"
#include "timeout.h"
#include <stdio.h>
#include "dup.h"
#include "sh_policy.h"
#ifdef RES
#include <sgtty.h>
#endif
int mailchk = 0;
static unsigned char *mailp;
static long *mod_time = 0;
#if vax
char **execargs = (char **)(0x7ffffffc);
#endif
#if pdp11
char **execargs = (char **)(-2);
#endif
static void exfile();
extern unsigned char *simple();
static void Ldup(int, int);
void settmp(void);
void chkmail(void);
void setmail(unsigned char *);
int
main(int c, char *v[], char *e[])
{
struct namnod *n;
/*
* Do locale processing only if /usr is mounted.
*/
/*
* initialize storage allocation
*/
if (stakbot == 0) {
addblok((unsigned)0);
}
/*
* If the first character of the last path element of v[0] is "-"
* (ex. -sh, or /bin/-sh), this is a login shell
*/
if (*simple(v[0]) == '-') {
/*
* As the previous comment states, this is a login shell.
* Therefore, we set the login_shell flag to explicitly
* indicate this condition.
*/
login_shell = TRUE;
}
stdsigs();
/*
* set names from userenv
*/
setup_env();
/*
* LC_MESSAGES is set here so that early error messages will
* come out in the right style.
* Note that LC_CTYPE is done later on and is *not*
* taken from the previous environ
*/
/*
* Do locale processing only if /usr is mounted.
*/
if (localedir_exists)
#if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
#endif
(void) textdomain(TEXT_DOMAIN);
/*
* This is a profile shell if the simple name of argv[0] is
* pfsh or -pfsh
*/
}
/*
* 'rsflag' is zero if SHELL variable is
* set in environment and
* the simple file part of the value.
* is rsh
*/
if (n = findnam("SHELL")) {
rsflag = 0;
}
/*
* a shell is also restricted if the simple name of argv(0) is
* rsh or -rsh in its simple name
*/
#ifndef RES
rflag = 0;
#endif
flags |= monitorflg;
hcreate();
set_dotpath();
/*
* look for options
* dolc is $#
*/
if (dolc < 2) {
{
while (*flagc)
flagc++;
*flagc = 0;
}
}
dolc--;
/*
* Determine all of the user's id #'s for this process and
* then decide if this shell is being entered as a result
* is < 100 and the egid is NOT 1, reset the uid and gid to
* the user originally calling this process.
*/
}
dolc--;
/*
* return here for shell file execution
* but not for parenthesis subshells
*/
freejobs();
}
/*
* number of positional parameters
*/
/*
* set pidname '$$'
*/
/*
* set up temp file names
*/
settmp();
/*
* default internal field separators
* Do not allow importing of IFS from parent shell.
* setup_env() may have set anything from parent shell to IFS.
* Always set the default ifs to IFS.
*/
/* initialize OPTIND for getopt */
n = lookup("OPTIND");
assign(n, (unsigned char *)"1");
/*
* make sure that option parsing starts
* at first character
*/
_sp = 1;
/* initialize multibyte information */
setwidth();
{
/* system profile */
#ifndef RES
#endif
/* user profile */
}
}
while (*flagc)
flagc++;
*flagc++ = 'r';
*flagc = '\0';
}
}
/*
* open input file if specified
*/
if (comdiv) {
input = -1;
}
else
{
input = 0;
} else {
/*
* If the command file specified by 'cmdadr'
* doesn't exist, chkopen() will fail calling
* exitsh(). If this is a login shell and
* the $HOME/.profile file does not exist, the
* above statement "flags &= ~ttyflg" does not
* get executed and this makes exitsh() call
* longjmp() instead of exiting. longjmp() will
* return to the location specified by the last
* active jmpbuffer, which is the one set up in
* the function exfile() called after the system
* profile file is executed (see lines above).
* This would cause an infinite loop, because
* chkopen() will continue to fail and exitsh()
* to call longjmp(). To make exitsh() exit instead
* of calling longjmp(), we then set the flag forcexit
* at this stage.
*/
}
#ifdef ACCT
if (input != 0)
#endif
comdiv--;
}
}
#ifdef pdp11
else
#endif
exfile(0);
done(0);
}
static void
{
/*
* move input
*/
if (input > 0) {
}
(void) endjobs(0);
return;
}
/*
* error return here
*/
fndef = 0;
nohash = 0;
iopend = 0;
if (input >= 0)
/*
* command loop
*/
for (;;) {
tdystak(0);
stakchk(); /* may reduce sbrk */
exitset();
if (mailp) {
chkmail();
}
}
/* necessary to print jobs in a timely manner */
chktrap();
#ifdef TIME_OUT
#endif
}
trapnote = 0;
if (eof) {
if (endjobs(JOB_STOPPED))
return;
eof = 0;
}
#ifdef TIME_OUT
alarm(0);
#endif
{
struct trenod *t;
freejobs();
else
}
}
}
void
chkpr(void)
{
}
void
settmp(void)
{
int len;
serial = 0;
TMPOUTSZ) {
/*
* TMPOUTSZ should be big enough, but if it isn't,
* we'll at least try to create tmp files with
* a truncated tmpfile name at tmpout.
*/
} else {
tmpout_offset = len;
}
}
static void
{
#ifdef RES
#else
if (fa >= 0) {
}
}
#endif
}
void
chkmail(void)
{
unsigned char *s = mailp;
unsigned char *save;
unsigned char *start;
while (*s) {
start = s;
save = 0;
flg = 0;
while (*s) {
if (*s != COLON) {
if (*s == '%' && save == 0)
save = s;
s++;
} else {
flg = 1;
*s = 0;
}
}
if (save)
*save = 0;
if (save) {
newline();
}
else
}
} else if (*ptr == 0)
*ptr = 1;
if (save)
*save = '%';
if (flg)
*s++ = COLON;
ptr++;
}
}
void
{
unsigned char *s = mailpath;
int cnt = 1;
long *ptr;
while (*s) {
if (*s == COLON)
cnt += 1;
s++;
}
while (cnt) {
*ptr = 0;
ptr++;
cnt--;
}
}
}
void
setwidth()
{
/*
* Do locale processing only if /usr is mounted.
*/
if (localedir_exists) {
else
}
}
void
{
/*
* decide whether interactive
*/
{
else
startjobs();
}
else
{
}
}
/*
* A generic call back routine to output error messages from the
* policy backing functions called by pfsh.
*
* msg must contain '\n' if a new line is to be printed.
*/
void
{
switch (level) {
case SECPOLICY_WARN:
default:
return;
case SECPOLICY_ERROR:
break;
}
}