00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef lint
00034 static char const copyright[] =
00035 "@(#) Copyright (c) 1991, 1993\n\
00036 The Regents of the University of California. All rights reserved.\n";
00037 #endif
00038
00039 #ifndef lint
00040 #if 0
00041 static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/28/95";
00042 #endif
00043 #endif
00044
00045
00046
00047
00048
00049 #include <stdio.h>
00050 #include <signal.h>
00051 #include <sys/stat.h>
00052 #include <unistd.h>
00053 #include <fcntl.h>
00054 #include <locale.h>
00055 #include <errno.h>
00056
00057 #include "shell.h"
00058 #include "main.h"
00059 #include "mail.h"
00060 #include "options.h"
00061 #include "output.h"
00062 #include "parser.h"
00063 #include "nodes.h"
00064 #include "expand.h"
00065 #include "eval.h"
00066 #include "jobs.h"
00067 #include "input.h"
00068 #include "trap.h"
00069 #include "var.h"
00070 #include "show.h"
00071 #include "memalloc.h"
00072 #include "error.h"
00073 #include "init.h"
00074 #include "mystring.h"
00075 #include "exec.h"
00076 #include "cd.h"
00077 #include "builtins.h"
00078
00079 int rootpid;
00080 int rootshell;
00081
00082 STATIC void read_profile(char *);
00083 STATIC char *find_dot_file(char *);
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 int
00094 main(int argc, char *argv[])
00095 {
00096 struct jmploc jmploc;
00097 struct stackmark smark;
00098 volatile int state;
00099 char *shinit;
00100
00101 (void) setlocale(LC_ALL, "");
00102 state = 0;
00103 if (setjmp(jmploc.loc)) {
00104
00105
00106
00107
00108
00109 switch (exception) {
00110 case EXSHELLPROC:
00111 rootpid = getpid();
00112 rootshell = 1;
00113 minusc = NULL;
00114 state = 3;
00115 break;
00116
00117 case EXEXEC:
00118 exitstatus = exerrno;
00119 break;
00120
00121 case EXERROR:
00122 exitstatus = 2;
00123 break;
00124
00125 default:
00126 break;
00127 }
00128
00129 if (exception != EXSHELLPROC) {
00130 if (state == 0 || iflag == 0 || ! rootshell)
00131 exitshell(exitstatus);
00132 }
00133 reset();
00134 if (exception == EXINT) {
00135 out2c('\n');
00136 flushout(&errout);
00137 }
00138 popstackmark(&smark);
00139 FORCEINTON;
00140 if (state == 1)
00141 goto state1;
00142 else if (state == 2)
00143 goto state2;
00144 else if (state == 3)
00145 goto state3;
00146 else
00147 goto state4;
00148 }
00149 handler = &jmploc;
00150 #if DEBUG
00151 opentrace();
00152 trputs("Shell args: "); trargs(argv);
00153 #endif
00154 rootpid = getpid();
00155 rootshell = 1;
00156 init();
00157 setstackmark(&smark);
00158 procargs(argc, argv);
00159 if (getpwd() == NULL && iflag)
00160 out2str("sh: cannot determine working directory\n");
00161 if (argv[0] && argv[0][0] == '-') {
00162 state = 1;
00163 read_profile("/etc/profile");
00164 state1:
00165 state = 2;
00166 if (privileged == 0)
00167 read_profile(".profile");
00168 else
00169 read_profile("/etc/suid_profile");
00170 }
00171 state2:
00172 state = 3;
00173 if (!privileged && iflag) {
00174 if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
00175 state = 3;
00176 read_profile(shinit);
00177 }
00178 }
00179 state3:
00180 state = 4;
00181 if (minusc) {
00182 evalstring(minusc);
00183 }
00184 if (sflag || minusc == NULL) {
00185 state4:
00186 cmdloop(1);
00187 }
00188 exitshell(exitstatus);
00189
00190 return 0;
00191 }
00192
00193
00194
00195
00196
00197
00198
00199 void
00200 cmdloop(int top)
00201 {
00202 union node *n;
00203 struct stackmark smark;
00204 int inter;
00205 int numeof = 0;
00206
00207 TRACE(("cmdloop(%d) called\n", top));
00208 setstackmark(&smark);
00209 for (;;) {
00210 if (pendingsigs)
00211 dotrap();
00212 inter = 0;
00213 if (iflag && top) {
00214 inter++;
00215 showjobs(1, 0, 0);
00216 chkmail(0);
00217 flushout(&output);
00218 }
00219 n = parsecmd(inter);
00220
00221 if (n == NEOF) {
00222 if (!top || numeof >= 50)
00223 break;
00224 if (!stoppedjobs()) {
00225 if (!Iflag)
00226 break;
00227 out2str("\nUse \"exit\" to leave shell.\n");
00228 }
00229 numeof++;
00230 } else if (n != NULL && nflag == 0) {
00231 job_warning = (job_warning == 2) ? 1 : 0;
00232 numeof = 0;
00233 evaltree(n, 0);
00234 }
00235 popstackmark(&smark);
00236 setstackmark(&smark);
00237 if (evalskip == SKIPFILE) {
00238 evalskip = 0;
00239 break;
00240 }
00241 }
00242 popstackmark(&smark);
00243 }
00244
00245
00246
00247
00248
00249
00250
00251 STATIC void
00252 read_profile(char *name)
00253 {
00254 int fd;
00255
00256 INTOFF;
00257 if ((fd = open(name, O_RDONLY)) >= 0)
00258 setinputfd(fd, 1);
00259 INTON;
00260 if (fd < 0)
00261 return;
00262 cmdloop(0);
00263 popfile();
00264 }
00265
00266
00267
00268
00269
00270
00271
00272 void
00273 readcmdfile(char *name)
00274 {
00275 int fd;
00276
00277 INTOFF;
00278 if ((fd = open(name, O_RDONLY)) >= 0)
00279 setinputfd(fd, 1);
00280 else
00281 error("Can't open %s: %s", name, strerror(errno));
00282 INTON;
00283 cmdloop(0);
00284 popfile();
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295 STATIC char *
00296 find_dot_file(char *basename)
00297 {
00298 static char localname[FILENAME_MAX+1];
00299 char *fullname;
00300 char *path = pathval();
00301 struct stat statb;
00302
00303
00304 if( strchr(basename, '/'))
00305 return basename;
00306
00307 while ((fullname = padvance(&path, basename)) != NULL) {
00308 strcpy(localname, fullname);
00309 stunalloc(fullname);
00310 if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode))
00311 return localname;
00312 }
00313 return basename;
00314 }
00315
00316 int
00317 dotcmd(int argc, char **argv)
00318 {
00319 struct strlist *sp;
00320 exitstatus = 0;
00321
00322 for (sp = cmdenviron; sp ; sp = sp->next)
00323 setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
00324
00325 if (argc >= 2) {
00326 char *fullname = find_dot_file(argv[1]);
00327
00328 setinputfile(fullname, 1);
00329 commandname = fullname;
00330 cmdloop(0);
00331 popfile();
00332 }
00333 return exitstatus;
00334 }
00335
00336
00337 int
00338 exitcmd(int argc, char **argv)
00339 {
00340 extern int oexitstatus;
00341
00342 if (stoppedjobs())
00343 return 0;
00344 if (argc > 1)
00345 exitstatus = number(argv[1]);
00346 else
00347 exitstatus = oexitstatus;
00348 exitshell(exitstatus);
00349
00350 return 0;
00351 }
00352
00353
00354
00355