3 * Copyright (c) 1987-1996 Larry Wall
5 * You may distribute under the terms of either the GNU General Public
6 * License or the Artistic License, as specified in the README file.
11 * "A ship then new they built for him/of mithril and of elven glass" --Bilbo
16 #include "patchlevel.h"
18 /* Omit -- it causes too much grief on mixed systems.
24 dEXT char rcsid[] = "perl.c\nPatch level: ###\n";
32 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
38 static void find_beginning _((void));
39 static void incpush _((char *));
40 static void init_ids _((void));
41 static void init_debugger _((void));
42 static void init_lexer _((void));
43 static void init_main_stash _((void));
44 static void init_perllib _((void));
45 static void init_postdump_symbols _((int, char **, char **));
46 static void init_predump_symbols _((void));
47 static void init_stacks _((void));
48 static void open_script _((char *, bool, SV *));
49 static void usage _((char *));
50 static void validate_suid _((char *, char*));
52 static int fdscript = -1;
57 PerlInterpreter *sv_interp;
60 New(53, sv_interp, 1, PerlInterpreter);
65 perl_construct( sv_interp )
66 register PerlInterpreter *sv_interp;
68 if (!(curinterp = sv_interp))
72 Zero(sv_interp, 1, PerlInterpreter);
75 /* Init the real globals? */
77 linestr = NEWSV(65,80);
78 sv_upgrade(linestr,SVt_PVIV);
80 SvREADONLY_on(&sv_undef);
84 SvREADONLY_on(&sv_no);
86 sv_setpv(&sv_yes,Yes);
88 SvREADONLY_on(&sv_yes);
90 nrs = newSVpv("\n", 1);
91 rs = SvREFCNT_inc(nrs);
95 * There is no way we can refer to them from Perl so close them to save
96 * space. The other alternative would be to provide STDAUX and STDPRN
100 (void)fclose(stdprn);
121 #if defined(SUBVERSION) && SUBVERSION > 0
122 sprintf(patchlevel, "%7.5f", 5.0 + (PATCHLEVEL / 1000.0)
123 + (SUBVERSION / 100000.0));
125 sprintf(patchlevel, "%5.3f", 5.0 + (PATCHLEVEL / 1000.0));
128 #if defined(LOCAL_PATCH_COUNT)
129 Ilocalpatches = local_patches; /* For possible -v */
132 fdpid = newAV(); /* for remembering popen pids by fd */
133 pidstatus = newHV();/* for remembering status of dead pids */
140 perl_destruct(sv_interp)
141 register PerlInterpreter *sv_interp;
143 int destruct_level; /* 0=none, 1=full, 2=full with checks */
147 if (!(curinterp = sv_interp))
150 destruct_level = perl_destruct_level;
154 if (s = getenv("PERL_DESTRUCT_LEVEL"))
155 destruct_level = atoi(s);
163 /* We must account for everything. First the syntax tree. */
165 curpad = AvARRAY(comppad);
172 * Try to destruct global references. We do this first so that the
173 * destructors and destructees still exist. Some sv's might remain.
174 * Non-referenced objects are on their own.
181 if (destruct_level == 0){
183 DEBUG_P(debprofdump());
185 /* The exit() function will do everything that needs doing. */
189 /* Prepare to destruct main symbol table. */
195 if (destruct_level >= 2) {
196 if (scopestack_ix != 0)
197 warn("Unbalanced scopes: %d more ENTERs than LEAVEs\n", scopestack_ix);
198 if (savestack_ix != 0)
199 warn("Unbalanced saves: %d more saves than restores\n", savestack_ix);
200 if (tmps_floor != -1)
201 warn("Unbalanced tmps: %d more allocs than frees\n", tmps_floor + 1);
202 if (cxstack_ix != -1)
203 warn("Unbalanced context: %d more PUSHes than POPs\n", cxstack_ix + 1);
206 /* Now absolutely destruct everything, somehow or other, loops or no. */
208 while (sv_count != 0 && sv_count != last_sv_count) {
209 last_sv_count = sv_count;
213 warn("Scalars leaked: %d\n", sv_count);
216 DEBUG_P(debprofdump());
221 PerlInterpreter *sv_interp;
223 if (!(curinterp = sv_interp))
227 #if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
228 char *getenv _((char *)); /* Usually in <stdlib.h> */
232 perl_parse(sv_interp, xsinit, argc, argv, env)
233 PerlInterpreter *sv_interp;
234 void (*xsinit)_((void));
241 char *scriptname = NULL;
242 VOL bool dosearch = FALSE;
246 #ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
249 croak("suidperl is no longer needed since the kernel can now execute\n\
250 setuid perl scripts securely.\n");
254 if (!(curinterp = sv_interp))
259 #ifndef VMS /* VMS doesn't have environ array */
260 origenviron = environ;
266 /* Come here if running an undumped a.out. */
268 origfilename = savepv(argv[0]);
270 cxstack_ix = -1; /* start label stack again */
272 init_postdump_symbols(argc,argv,env);
280 switch (Sigsetjmp(top_env,1)) {
291 return(statusvalue); /* my_exit() was called */
293 fprintf(stderr, "panic: top_env\n");
297 sv_setpvn(linestr,"",0);
298 sv = newSVpv("",0); /* first used for -I flags */
301 for (argc--,argv++; argc > 0; argc--,argv++) {
302 if (argv[0][0] != '-' || !argv[0][1])
306 validarg = " PHOOEY ";
332 if (s = moreswitches(s))
337 if (euid != uid || egid != gid)
338 croak("No -e allowed in setuid scripts");
340 e_tmpname = savepv(TMPPATH);
341 (void)mktemp(e_tmpname);
343 croak("Can't mktemp()");
344 e_fp = fopen(e_tmpname,"w");
346 croak("Cannot open temporary file");
352 (void)putc('\n', e_fp);
360 av_push(GvAVn(incgv),newSVpv(s,0));
363 av_push(GvAVn(incgv),newSVpv(argv[1],0));
364 sv_catpv(sv,argv[1]);
381 preambleav = newAV();
382 av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
384 Sv = newSVpv("print myconfig(),'@INC: '.\"@INC\\n\"",0);
387 Sv = newSVpv("config_vars(qw(",0);
392 av_push(preambleav, Sv);
393 scriptname = BIT_BUCKET; /* don't look for script or read stdin */
407 croak("Unrecognized switch: -%s",s);
412 scriptname = argv[0];
414 if (Fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
415 croak("Can't write to temp file for -e: %s", Strerror(errno));
418 scriptname = e_tmpname;
420 else if (scriptname == Nullch) {
422 if ( isatty(fileno(stdin)) )
430 open_script(scriptname,dosearch,sv);
432 validate_suid(validarg, scriptname);
437 compcv = (CV*)NEWSV(1104,0);
438 sv_upgrade((SV *)compcv, SVt_PVCV);
442 av_push(comppad, Nullsv);
443 curpad = AvARRAY(comppad);
445 comppad_name = padname;
446 comppad_name_fill = 0;
447 min_intro_pending = 0;
450 comppadlist = newAV();
451 AvREAL_off(comppadlist);
452 av_store(comppadlist, 0, (SV*)comppad_name);
453 av_store(comppadlist, 1, (SV*)comppad);
454 CvPADLIST(compcv) = comppadlist;
457 (*xsinit)(); /* in case linked C routines want magical variables */
462 init_predump_symbols();
464 init_postdump_symbols(argc,argv,env);
468 /* now parse the script */
471 if (yyparse() || error_count) {
473 croak("%s had compilation errors.\n", origfilename);
475 croak("Execution of %s aborted due to compilation errors.\n",
479 curcop->cop_line = 0;
483 (void)UNLINK(e_tmpname);
488 /* now that script is parsed, we can modify record separator */
490 rs = SvREFCNT_inc(nrs);
491 sv_setsv(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs);
502 #ifdef DEBUGGING_MSTATS
503 if ((s=getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
504 dump_mstats("after compilation:");
514 PerlInterpreter *sv_interp;
516 if (!(curinterp = sv_interp))
518 switch (Sigsetjmp(top_env,1)) {
520 cxstack_ix = -1; /* start context stack again */
527 #ifdef DEBUGGING_MSTATS
528 if (getenv("PERL_DEBUG_MSTATS"))
529 dump_mstats("after execution: ");
531 return(statusvalue); /* my_exit() was called */
534 fprintf(stderr, "panic: restartop\n");
538 if (stack != mainstack) {
540 SWITCHSTACK(stack, mainstack);
547 DEBUG(fprintf(stderr,"\nEXECUTING...\n\n"));
550 fprintf(stderr,"%s syntax OK\n", origfilename);
553 if (perldb && DBsingle)
554 sv_setiv(DBsingle, 1);
566 else if (main_start) {
579 register CONTEXT *cx;
583 statusvalue = FIXSTATUS(status);
584 if (cxstack_ix >= 0) {
590 Siglongjmp(top_env, 2);
594 perl_get_sv(name, create)
598 GV* gv = gv_fetchpv(name, create, SVt_PV);
605 perl_get_av(name, create)
609 GV* gv = gv_fetchpv(name, create, SVt_PVAV);
618 perl_get_hv(name, create)
622 GV* gv = gv_fetchpv(name, create, SVt_PVHV);
631 perl_get_cv(name, create)
635 GV* gv = gv_fetchpv(name, create, SVt_PVCV);
636 if (create && !GvCV(gv))
637 return newSUB(start_subparse(),
638 newSVOP(OP_CONST, 0, newSVpv(name,0)),
646 /* Be sure to refetch the stack pointer after calling these routines. */
649 perl_call_argv(subname, flags, argv)
651 I32 flags; /* See G_* flags in cop.h */
652 register char **argv; /* null terminated arg list */
659 XPUSHs(sv_2mortal(newSVpv(*argv,0)));
664 return perl_call_pv(subname, flags);
668 perl_call_pv(subname, flags)
669 char *subname; /* name of the subroutine */
670 I32 flags; /* See G_* flags in cop.h */
672 return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags);
676 perl_call_method(methname, flags)
677 char *methname; /* name of the subroutine */
678 I32 flags; /* See G_* flags in cop.h */
684 XPUSHs(sv_2mortal(newSVpv(methname,0)));
687 return perl_call_sv(*stack_sp--, flags);
690 /* May be called with any of a CV, a GV, or an SV containing the name. */
692 perl_call_sv(sv, flags)
694 I32 flags; /* See G_* flags in cop.h */
696 LOGOP myop; /* fake syntax tree node */
698 I32 oldmark = TOPMARK;
703 if (flags & G_DISCARD) {
713 oldscope = scopestack_ix;
715 if (!(flags & G_NOARGS))
716 myop.op_flags = OPf_STACKED;
717 myop.op_next = Nullop;
718 myop.op_flags |= OPf_KNOW;
720 myop.op_flags |= OPf_LIST;
722 if (flags & G_EVAL) {
723 Copy(top_env, oldtop, 1, Sigjmp_buf);
725 cLOGOP->op_other = op;
727 /* we're trying to emulate pp_entertry() here */
729 register CONTEXT *cx;
735 push_return(op->op_next);
736 PUSHBLOCK(cx, CXt_EVAL, stack_sp);
738 eval_root = op; /* Only needed so that goto works right. */
741 if (flags & G_KEEPERR)
744 sv_setpv(GvSV(errgv),"");
749 switch (Sigsetjmp(top_env,1)) {
754 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
760 /* my_exit() was called */
763 Copy(oldtop, top_env, 1, Sigjmp_buf);
765 croak("Callback called exit");
766 my_exit(statusvalue);
774 stack_sp = stack_base + oldmark;
779 *++stack_sp = &sv_undef;
785 if (op == (OP*)&myop)
789 retval = stack_sp - (stack_base + oldmark);
790 if ((flags & G_EVAL) && !(flags & G_KEEPERR))
791 sv_setpv(GvSV(errgv),"");
794 if (flags & G_EVAL) {
795 if (scopestack_ix > oldscope) {
799 register CONTEXT *cx;
808 Copy(oldtop, top_env, 1, Sigjmp_buf);
810 if (flags & G_DISCARD) {
811 stack_sp = stack_base + oldmark;
822 perl_eval_sv(sv, flags)
824 I32 flags; /* See G_* flags in cop.h */
826 UNOP myop; /* fake syntax tree node */
828 I32 oldmark = sp - stack_base;
833 if (flags & G_DISCARD) {
843 oldscope = scopestack_ix;
845 if (!(flags & G_NOARGS))
846 myop.op_flags = OPf_STACKED;
847 myop.op_next = Nullop;
848 myop.op_flags |= OPf_KNOW;
850 myop.op_flags |= OPf_LIST;
852 Copy(top_env, oldtop, 1, Sigjmp_buf);
855 switch (Sigsetjmp(top_env,1)) {
860 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
866 /* my_exit() was called */
869 Copy(oldtop, top_env, 1, Sigjmp_buf);
871 croak("Callback called exit");
872 my_exit(statusvalue);
880 stack_sp = stack_base + oldmark;
885 *++stack_sp = &sv_undef;
890 if (op == (OP*)&myop)
894 retval = stack_sp - (stack_base + oldmark);
895 if ((flags & G_EVAL) && !(flags & G_KEEPERR))
896 sv_setpv(GvSV(errgv),"");
899 Copy(oldtop, top_env, 1, Sigjmp_buf);
900 if (flags & G_DISCARD) {
901 stack_sp = stack_base + oldmark;
909 /* Require a module. */
915 SV* sv = sv_newmortal();
916 sv_setpv(sv, "require '");
919 perl_eval_sv(sv, G_DISCARD);
923 magicname(sym,name,namlen)
930 if (gv = gv_fetchpv(sym,TRUE, SVt_PV))
931 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
935 # define PERLLIB_SEP ';'
938 # define PERLLIB_SEP '|'
940 # define PERLLIB_SEP ':'
953 /* Break at all separators */
955 /* First, skip any consecutive separators */
956 while ( *p == PERLLIB_SEP ) {
957 /* Uncomment the next line for PATH semantics */
958 /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
961 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
962 av_push(GvAVn(incgv), newSVpv(p, (STRLEN)(s - p)));
965 av_push(GvAVn(incgv), newSVpv(p, 0));
972 usage(name) /* XXX move this out into a module ? */
975 /* This message really ought to be max 23 lines.
976 * Removed -h because the user already knows that opton. Others? */
977 printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name);
978 printf("\n -0[octal] specify record separator (\\0, if no argument)");
979 printf("\n -a autosplit mode with -n or -p (splits $_ into @F)");
980 printf("\n -c check syntax only (runs BEGIN and END blocks)");
981 printf("\n -d[:debugger] run scripts under debugger");
982 printf("\n -D[number/list] set debugging flags (argument is a bit mask or flags)");
983 printf("\n -e 'command' one line of script. Several -e's allowed. Omit [programfile].");
984 printf("\n -F/pattern/ split() pattern for autosplit (-a). The //'s are optional.");
985 printf("\n -i[extension] edit <> files in place (make backup if extension supplied)");
986 printf("\n -Idirectory specify @INC/#include directory (may be used more then once)");
987 printf("\n -l[octal] enable line ending processing, specifies line teminator");
988 printf("\n -[mM][-]module.. executes `use/no module...' before executing your script.");
989 printf("\n -n assume 'while (<>) { ... }' loop arround your script");
990 printf("\n -p assume loop like -n but print line also like sed");
991 printf("\n -P run script through C preprocessor before compilation");
993 printf("\n -R enable REXX variable pool");
995 printf("\n -s enable some switch parsing for switches after script name");
996 printf("\n -S look for the script using PATH environment variable");
997 printf("\n -T turn on tainting checks");
998 printf("\n -u dump core after parsing script");
999 printf("\n -U allow unsafe operations");
1000 printf("\n -v print version number and patchlevel of perl");
1001 printf("\n -V[:variable] print perl configuration information");
1002 printf("\n -w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT.");
1003 printf("\n -x[directory] strip off text before #!perl line and perhaps cd to directory\n");
1006 /* This routine handles any switches that can be given during run */
1017 rschar = scan_oct(s, 4, &numlen);
1019 if (rschar & ~((U8)~0))
1021 else if (!rschar && numlen >= 2)
1022 nrs = newSVpv("", 0);
1025 nrs = newSVpv(&ch, 1);
1030 splitstr = savepv(s + 1);
1044 if (*s == ':' || *s == '=') {
1045 sprintf(buf, "use Devel::%s;", ++s);
1047 my_setenv("PERL5DB",buf);
1057 if (isALPHA(s[1])) {
1058 static char debopts[] = "psltocPmfrxuLHXD";
1061 for (s++; *s && (d = strchr(debopts,*s)); s++)
1062 debug |= 1 << (d - debopts);
1066 for (s++; isDIGIT(*s); s++) ;
1068 debug |= 0x80000000;
1070 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
1071 for (s++; isALNUM(*s); s++) ;
1081 inplace = savepv(s+1);
1083 for (s = inplace; *s && !isSPACE(*s); s++) ;
1090 for (e = s; *e && !isSPACE(*e); e++) ;
1091 av_push(GvAVn(incgv),newSVpv(s,e-s));
1096 croak("No space allowed after -I");
1106 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
1111 ors = savepvn("\n\n", 2);
1115 ors = SvPV(nrs, orslen);
1119 taint_not("-M"); /* XXX ? */
1122 taint_not("-m"); /* XXX ? */
1126 /* -M-foo == 'no foo' */
1127 if (*s == '-') { use = "no "; ++s; }
1128 Sv = newSVpv(use,0);
1130 /* We allow -M'Module qw(Foo Bar)' */
1131 while(isALNUM(*s) || *s==':') ++s;
1133 sv_catpv(Sv, start);
1134 if (*(start-1) == 'm') {
1136 croak("Can't use '%c' after -mname", *s);
1137 sv_catpv( Sv, " ()");
1140 sv_catpvn(Sv, start, s-start);
1141 sv_catpv(Sv, " split(/,/,q{");
1146 if (preambleav == NULL)
1147 preambleav = newAV();
1148 av_push(preambleav, Sv);
1151 croak("No space allowed after -%c", *(s-1));
1179 #if defined(SUBVERSION) && SUBVERSION > 0
1180 printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION);
1182 printf("\nThis is perl, version %s",patchlevel);
1185 #if defined(DEBUGGING) || defined(EMBED) || defined(MULTIPLICITY)
1186 fputs(" with", stdout);
1188 fputs(" DEBUGGING", stdout);
1191 fputs(" EMBED", stdout);
1194 fputs(" MULTIPLICITY", stdout);
1198 #if defined(LOCAL_PATCH_COUNT)
1199 if (LOCAL_PATCH_COUNT > 0)
1201 fputs("\n\tLocally applied patches:\n", stdout);
1202 for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
1203 if (Ilocalpatches[i])
1204 fprintf(stdout, "\t %s\n", Ilocalpatches[i]);
1208 printf("\n\tbuilt under %s",OSNAME);
1211 printf(" at %s %s",__DATE__,__TIME__);
1213 printf(" on %s",__DATE__);
1216 fputs("\n\t+ suidperl security patch", stdout);
1217 fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout);
1219 fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
1223 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
1224 "Version 5 port Copyright (c) 1994-1995, Andreas Kaiser\n", stdout);
1227 fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout);
1230 Perl may be copied only under the terms of either the Artistic License or the\n\
1231 GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n",stdout);
1242 if (s[1] == '-') /* Additional switches on #! line. */
1255 croak("Can't emulate -%.1s on #! line",s);
1260 /* compliments of Tom Christiansen */
1262 /* unexec() can be found in the Gnu emacs distribution */
1271 sprintf (buf, "%s.perldump", origfilename);
1272 sprintf (tokenbuf, "%s/perl", BIN);
1274 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
1276 fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
1280 # include <lib$routines.h>
1281 lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */
1283 ABORT(); /* for use with undump */
1292 curstash = defstash = newHV();
1293 curstname = newSVpv("main",4);
1294 gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1295 SvREFCNT_dec(GvHV(gv));
1296 GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
1298 HvNAME(defstash) = savepv("main");
1299 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
1301 defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
1302 errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
1304 curstash = defstash;
1305 compiling.cop_stash = defstash;
1306 debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
1307 /* We must init $/ before switches are processed. */
1308 sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1);
1311 #ifdef CAN_PROTOTYPE
1313 open_script(char *scriptname, bool dosearch, SV *sv)
1316 open_script(scriptname,dosearch,sv)
1322 char *xfound = Nullch;
1323 char *xfailed = Nullch;
1327 #if defined(DOSISH) && !defined(OS2) && !defined(atarist)
1328 #define SEARCH_EXTS ".bat", ".cmd", NULL
1331 # define SEARCH_EXTS ".pl", ".com", NULL
1333 /* additional extensions to try in each dir if scriptname not found */
1335 char *ext[] = { SEARCH_EXTS };
1336 int extidx = (strchr(scriptname,'.')) ? -1 : 0; /* has ext already */
1340 if (dosearch && !strpbrk(scriptname,":[</") && (my_getenv("DCL$PATH"))) {
1343 while (my_trnlnm("DCL$PATH",tokenbuf,idx++)) {
1344 strcat(tokenbuf,scriptname);
1346 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
1348 bufend = s + strlen(s);
1351 s = cpytill(tokenbuf,s,bufend,':',&len);
1354 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
1355 tokenbuf[len] = '\0';
1357 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
1358 tokenbuf[len] = '\0';
1364 if (len && tokenbuf[len-1] != '/')
1367 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
1369 if (len && tokenbuf[len-1] != '\\')
1372 (void)strcat(tokenbuf+len,"/");
1373 (void)strcat(tokenbuf+len,scriptname);
1377 len = strlen(tokenbuf);
1378 if (extidx > 0) /* reset after previous loop */
1382 DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
1383 retval = Stat(tokenbuf,&statbuf);
1385 } while ( retval < 0 /* not there */
1386 && extidx>=0 && ext[extidx] /* try an extension? */
1387 && strcpy(tokenbuf+len, ext[extidx++])
1392 if (S_ISREG(statbuf.st_mode)
1393 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
1394 xfound = tokenbuf; /* bingo! */
1398 xfailed = savepv(tokenbuf);
1401 croak("Can't execute %s", xfailed ? xfailed : scriptname );
1404 scriptname = xfound;
1407 if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
1408 char *s = scriptname + 8;
1417 origfilename = savepv(e_tmpname ? "-e" : scriptname);
1418 curcop->cop_filegv = gv_fetchfile(origfilename);
1419 if (strEQ(origfilename,"-"))
1421 if (fdscript >= 0) {
1422 rsfp = fdopen(fdscript,"r");
1423 #if defined(HAS_FCNTL) && defined(F_SETFD)
1424 fcntl(fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
1427 else if (preprocess) {
1428 char *cpp = CPPSTDIN;
1430 if (strEQ(cpp,"cppstdin"))
1431 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
1433 sprintf(tokenbuf, "%s", cpp);
1435 sv_catpv(sv,PRIVLIB_EXP);
1437 (void)sprintf(buf, "\
1438 sed %s -e \"/^[^#]/b\" \
1439 -e \"/^#[ ]*include[ ]/b\" \
1440 -e \"/^#[ ]*define[ ]/b\" \
1441 -e \"/^#[ ]*if[ ]/b\" \
1442 -e \"/^#[ ]*ifdef[ ]/b\" \
1443 -e \"/^#[ ]*ifndef[ ]/b\" \
1444 -e \"/^#[ ]*else/b\" \
1445 -e \"/^#[ ]*elif[ ]/b\" \
1446 -e \"/^#[ ]*undef[ ]/b\" \
1447 -e \"/^#[ ]*endif/b\" \
1450 (doextract ? "-e \"1,/^#/d\n\"" : ""),
1452 (void)sprintf(buf, "\
1453 %s %s -e '/^[^#]/b' \
1454 -e '/^#[ ]*include[ ]/b' \
1455 -e '/^#[ ]*define[ ]/b' \
1456 -e '/^#[ ]*if[ ]/b' \
1457 -e '/^#[ ]*ifdef[ ]/b' \
1458 -e '/^#[ ]*ifndef[ ]/b' \
1459 -e '/^#[ ]*else/b' \
1460 -e '/^#[ ]*elif[ ]/b' \
1461 -e '/^#[ ]*undef[ ]/b' \
1462 -e '/^#[ ]*endif/b' \
1470 (doextract ? "-e '1,/^#/d\n'" : ""),
1472 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
1474 #ifdef IAMSUID /* actually, this is caught earlier */
1475 if (euid != uid && !euid) { /* if running suidperl */
1477 (void)seteuid(uid); /* musn't stay setuid root */
1480 (void)setreuid((Uid_t)-1, uid);
1482 #ifdef HAS_SETRESUID
1483 (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
1489 if (geteuid() != uid)
1490 croak("Can't do seteuid!\n");
1492 #endif /* IAMSUID */
1493 rsfp = my_popen(buf,"r");
1495 else if (!*scriptname) {
1496 taint_not("program input from stdin");
1500 rsfp = fopen(scriptname,"r");
1501 #if defined(HAS_FCNTL) && defined(F_SETFD)
1502 fcntl(fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
1505 if ((FILE*)rsfp == Nullfp) {
1507 #ifndef IAMSUID /* in case script is not readable before setuid */
1508 if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
1509 statbuf.st_mode & (S_ISUID|S_ISGID)) {
1510 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1511 execv(buf, origargv); /* try again */
1512 croak("Can't do setuid\n");
1516 croak("Can't open perl script \"%s\": %s\n",
1517 SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
1522 validate_suid(validarg, scriptname)
1528 /* do we need to emulate setuid on scripts? */
1530 /* This code is for those BSD systems that have setuid #! scripts disabled
1531 * in the kernel because of a security problem. Merely defining DOSUID
1532 * in perl will not fix that problem, but if you have disabled setuid
1533 * scripts in the kernel, this will attempt to emulate setuid and setgid
1534 * on scripts that have those now-otherwise-useless bits set. The setuid
1535 * root version must be called suidperl or sperlN.NNN. If regular perl
1536 * discovers that it has opened a setuid script, it calls suidperl with
1537 * the same argv that it had. If suidperl finds that the script it has
1538 * just opened is NOT setuid root, it sets the effective uid back to the
1539 * uid. We don't just make perl setuid root because that loses the
1540 * effective uid we had before invoking perl, if it was different from the
1543 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
1544 * be defined in suidperl only. suidperl must be setuid root. The
1545 * Configure script will set this up for you if you want it.
1551 if (Fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
1552 croak("Can't stat script \"%s\"",origfilename);
1553 if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) {
1557 #ifndef HAS_SETREUID
1558 /* On this access check to make sure the directories are readable,
1559 * there is actually a small window that the user could use to make
1560 * filename point to an accessible directory. So there is a faint
1561 * chance that someone could execute a setuid script down in a
1562 * non-accessible directory. I don't know what to do about that.
1563 * But I don't think it's too important. The manual lies when
1564 * it says access() is useful in setuid programs.
1566 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
1567 croak("Permission denied");
1569 /* If we can swap euid and uid, then we can determine access rights
1570 * with a simple stat of the file, and then compare device and
1571 * inode to make sure we did stat() on the same file we opened.
1572 * Then we just have to make sure he or she can execute it.
1575 struct stat tmpstatbuf;
1579 setreuid(euid,uid) < 0
1582 setresuid(euid,uid,(Uid_t)-1) < 0
1585 || getuid() != euid || geteuid() != uid)
1586 croak("Can't swap uid and euid"); /* really paranoid */
1587 if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
1588 croak("Permission denied"); /* testing full pathname here */
1589 if (tmpstatbuf.st_dev != statbuf.st_dev ||
1590 tmpstatbuf.st_ino != statbuf.st_ino) {
1592 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
1594 "User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
1595 (Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
1596 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
1597 statbuf.st_dev, statbuf.st_ino,
1598 SvPVX(GvSV(curcop->cop_filegv)),
1599 statbuf.st_uid, statbuf.st_gid);
1600 (void)my_pclose(rsfp);
1602 croak("Permission denied\n");
1606 setreuid(uid,euid) < 0
1608 # if defined(HAS_SETRESUID)
1609 setresuid(uid,euid,(Uid_t)-1) < 0
1612 || getuid() != uid || geteuid() != euid)
1613 croak("Can't reswap uid and euid");
1614 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
1615 croak("Permission denied\n");
1617 #endif /* HAS_SETREUID */
1618 #endif /* IAMSUID */
1620 if (!S_ISREG(statbuf.st_mode))
1621 croak("Permission denied");
1622 if (statbuf.st_mode & S_IWOTH)
1623 croak("Setuid/gid script is writable by world");
1624 doswitches = FALSE; /* -s is insecure in suid */
1626 if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1627 strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */
1628 croak("No #! line");
1631 while (!isSPACE(*s)) s++;
1632 if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
1633 croak("Not a perl script");
1634 while (*s == ' ' || *s == '\t') s++;
1636 * #! arg must be what we saw above. They can invoke it by
1637 * mentioning suidperl explicitly, but they may not add any strange
1638 * arguments beyond what #! says if they do invoke suidperl that way.
1640 len = strlen(validarg);
1641 if (strEQ(validarg," PHOOEY ") ||
1642 strnNE(s,validarg,len) || !isSPACE(s[len]))
1643 croak("Args must match #! line");
1646 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1647 euid == statbuf.st_uid)
1649 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1650 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1651 #endif /* IAMSUID */
1653 if (euid) { /* oops, we're not the setuid root perl */
1656 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1657 execv(buf, origargv); /* try again */
1659 croak("Can't do setuid\n");
1662 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
1664 (void)setegid(statbuf.st_gid);
1667 (void)setregid((Gid_t)-1,statbuf.st_gid);
1669 #ifdef HAS_SETRESGID
1670 (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
1672 setgid(statbuf.st_gid);
1676 if (getegid() != statbuf.st_gid)
1677 croak("Can't do setegid!\n");
1679 if (statbuf.st_mode & S_ISUID) {
1680 if (statbuf.st_uid != euid)
1682 (void)seteuid(statbuf.st_uid); /* all that for this */
1685 (void)setreuid((Uid_t)-1,statbuf.st_uid);
1687 #ifdef HAS_SETRESUID
1688 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
1690 setuid(statbuf.st_uid);
1694 if (geteuid() != statbuf.st_uid)
1695 croak("Can't do seteuid!\n");
1697 else if (uid) { /* oops, mustn't run as root */
1699 (void)seteuid((Uid_t)uid);
1702 (void)setreuid((Uid_t)-1,(Uid_t)uid);
1704 #ifdef HAS_SETRESUID
1705 (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
1711 if (geteuid() != uid)
1712 croak("Can't do seteuid!\n");
1715 if (!cando(S_IXUSR,TRUE,&statbuf))
1716 croak("Permission denied\n"); /* they can't do this */
1719 else if (preprocess)
1720 croak("-P not allowed for setuid/setgid script\n");
1721 else if (fdscript >= 0)
1722 croak("fd script not allowed in suidperl\n");
1724 croak("Script is not setuid/setgid in suidperl\n");
1726 /* We absolutely must clear out any saved ids here, so we */
1727 /* exec the real perl, substituting fd script for scriptname. */
1728 /* (We pass script name as "subdir" of fd, which perl will grok.) */
1730 for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ;
1731 if (!origargv[which])
1732 croak("Permission denied");
1733 (void)sprintf(buf, "/dev/fd/%d/%.127s", fileno(rsfp), origargv[which]);
1734 origargv[which] = buf;
1736 #if defined(HAS_FCNTL) && defined(F_SETFD)
1737 fcntl(fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */
1740 (void)sprintf(tokenbuf, "%s/perl%s", BIN, patchlevel);
1741 execv(tokenbuf, origargv); /* try again */
1742 croak("Can't do setuid\n");
1743 #endif /* IAMSUID */
1745 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1746 #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
1747 Fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
1748 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1750 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1753 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1754 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1755 #endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1756 /* not set-id, must be wrapped */
1766 /* skip forward in input to the real script? */
1770 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
1771 croak("No Perl script found in input\n");
1772 if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1773 ungetc('\n',rsfp); /* to keep line count right */
1775 if (s = instr(s,"perl -")) {
1778 while (s = moreswitches(s)) ;
1780 if (cddir && chdir(cddir) < 0)
1781 croak("Can't chdir to %s",cddir);
1789 uid = (int)getuid();
1790 euid = (int)geteuid();
1791 gid = (int)getgid();
1792 egid = (int)getegid();
1797 tainting |= (uid && (euid != uid || egid != gid));
1803 curstash = debstash;
1804 dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
1806 DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
1807 DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
1808 DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
1809 DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
1810 sv_setiv(DBsingle, 0);
1811 DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
1812 sv_setiv(DBtrace, 0);
1813 DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
1814 sv_setiv(DBsignal, 0);
1815 curstash = defstash;
1822 mainstack = stack; /* remember in case we switch stacks */
1823 AvREAL_off(stack); /* not a real array */
1824 av_extend(stack,127);
1826 stack_base = AvARRAY(stack);
1827 stack_sp = stack_base;
1828 stack_max = stack_base + 127;
1830 New(54,markstack,64,I32);
1831 markstack_ptr = markstack;
1832 markstack_max = markstack + 64;
1834 New(54,scopestack,32,I32);
1836 scopestack_max = 32;
1838 New(54,savestack,128,ANY);
1840 savestack_max = 128;
1842 New(54,retstack,16,OP*);
1846 cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */
1847 New(50,cxstack,cxstack_max + 1,CONTEXT);
1850 New(50,tmps_stack,128,SV*);
1855 New(51,debname,128,char);
1856 New(52,debdelim,128,char);
1860 static FILE *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
1868 subname = newSVpv("main",4);
1872 init_predump_symbols()
1877 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
1879 stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
1880 GvMULTI_on(stdingv);
1881 IoIFP(GvIOp(stdingv)) = stdin;
1882 tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
1884 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
1886 tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
1888 IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = stdout;
1890 tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
1892 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
1894 othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
1895 GvMULTI_on(othergv);
1896 IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = stderr;
1897 tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
1899 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
1901 statname = NEWSV(66,0); /* last filename we did stat on */
1903 osname = savepv(OSNAME);
1907 init_postdump_symbols(argc,argv,env)
1909 register char **argv;
1910 register char **env;
1916 argc--,argv++; /* skip name of script */
1918 for (; argc > 0 && **argv == '-'; argc--,argv++) {
1921 if (argv[0][1] == '-') {
1925 if (s = strchr(argv[0], '=')) {
1927 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
1930 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
1933 toptarget = NEWSV(0,0);
1934 sv_upgrade(toptarget, SVt_PVFM);
1935 sv_setpvn(toptarget, "", 0);
1936 bodytarget = NEWSV(0,0);
1937 sv_upgrade(bodytarget, SVt_PVFM);
1938 sv_setpvn(bodytarget, "", 0);
1939 formtarget = bodytarget;
1942 if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
1943 sv_setpv(GvSV(tmpgv),origfilename);
1944 magicname("0", "0", 1);
1946 if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV))
1948 if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
1949 sv_setpv(GvSV(tmpgv),origargv[0]);
1950 if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
1952 (void)gv_AVadd(argvgv);
1953 av_clear(GvAVn(argvgv));
1954 for (; argc > 0; argc--,argv++) {
1955 av_push(GvAVn(argvgv),newSVpv(argv[0],0));
1958 if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
1963 #ifndef VMS /* VMS doesn't have environ array */
1964 /* Note that if the supplied env parameter is actually a copy
1965 of the global environ then it may now point to free'd memory
1966 if the environment has been modified since. To avoid this
1967 problem we treat env==NULL as meaning 'use the default'
1971 if (env != environ) {
1972 environ[0] = Nullch;
1973 hv_magic(hv, envgv, 'E');
1975 for (; *env; env++) {
1976 if (!(s = strchr(*env,'=')))
1979 sv = newSVpv(s--,0);
1980 sv_magic(sv, sv, 'e', *env, s - *env);
1981 (void)hv_store(hv, *env, s - *env, sv, 0);
1985 #ifdef DYNAMIC_ENV_FETCH
1986 HvNAME(hv) = savepv(ENV_HV_NAME);
1988 hv_magic(hv, envgv, 'E');
1991 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
1992 sv_setiv(GvSV(tmpgv),(I32)getpid());
2001 s = getenv("PERL5LIB");
2005 incpush(getenv("PERLLIB"));
2009 incpush(APPLLIB_EXP);
2013 incpush(ARCHLIB_EXP);
2016 #define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
2018 incpush(PRIVLIB_EXP);
2021 incpush(SITEARCH_EXP);
2024 incpush(SITELIB_EXP);
2026 #ifdef OLDARCHLIB_EXP /* 5.00[01] compatibility */
2027 incpush(OLDARCHLIB_EXP);
2040 line_t oldline = curcop->cop_line;
2042 Copy(top_env, oldtop, 1, Sigjmp_buf);
2044 while (AvFILL(list) >= 0) {
2045 CV *cv = (CV*)av_shift(list);
2049 switch (Sigsetjmp(top_env,1)) {
2051 SV* atsv = GvSV(errgv);
2053 perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
2054 (void)SvPV(atsv, len);
2056 Copy(oldtop, top_env, 1, Sigjmp_buf);
2057 curcop = &compiling;
2058 curcop->cop_line = oldline;
2059 if (list == beginav)
2060 sv_catpv(atsv, "BEGIN failed--compilation aborted");
2062 sv_catpv(atsv, "END failed--cleanup aborted");
2063 croak("%s", SvPVX(atsv));
2069 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
2075 /* my_exit() was called */
2076 curstash = defstash;
2080 Copy(oldtop, top_env, 1, Sigjmp_buf);
2081 curcop = &compiling;
2082 curcop->cop_line = oldline;
2084 if (list == beginav)
2085 croak("BEGIN failed--compilation aborted");
2087 croak("END failed--cleanup aborted");
2089 my_exit(statusvalue);
2094 fprintf(stderr, "panic: restartop\n");
2098 Copy(oldtop, top_env, 1, Sigjmp_buf);
2099 curcop = &compiling;
2100 curcop->cop_line = oldline;
2101 Siglongjmp(top_env, 3);
2105 Copy(oldtop, top_env, 1, Sigjmp_buf);