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);
564 else if (main_start) {
577 register CONTEXT *cx;
581 statusvalue = FIXSTATUS(status);
582 if (cxstack_ix >= 0) {
588 Siglongjmp(top_env, 2);
592 perl_get_sv(name, create)
596 GV* gv = gv_fetchpv(name, create, SVt_PV);
603 perl_get_av(name, create)
607 GV* gv = gv_fetchpv(name, create, SVt_PVAV);
616 perl_get_hv(name, create)
620 GV* gv = gv_fetchpv(name, create, SVt_PVHV);
629 perl_get_cv(name, create)
633 GV* gv = gv_fetchpv(name, create, SVt_PVCV);
634 if (create && !GvCV(gv))
635 return newSUB(start_subparse(),
636 newSVOP(OP_CONST, 0, newSVpv(name,0)),
644 /* Be sure to refetch the stack pointer after calling these routines. */
647 perl_call_argv(subname, flags, argv)
649 I32 flags; /* See G_* flags in cop.h */
650 register char **argv; /* null terminated arg list */
657 XPUSHs(sv_2mortal(newSVpv(*argv,0)));
662 return perl_call_pv(subname, flags);
666 perl_call_pv(subname, flags)
667 char *subname; /* name of the subroutine */
668 I32 flags; /* See G_* flags in cop.h */
670 return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags);
674 perl_call_method(methname, flags)
675 char *methname; /* name of the subroutine */
676 I32 flags; /* See G_* flags in cop.h */
682 XPUSHs(sv_2mortal(newSVpv(methname,0)));
685 return perl_call_sv(*stack_sp--, flags);
688 /* May be called with any of a CV, a GV, or an SV containing the name. */
690 perl_call_sv(sv, flags)
692 I32 flags; /* See G_* flags in cop.h */
694 LOGOP myop; /* fake syntax tree node */
696 I32 oldmark = TOPMARK;
701 if (flags & G_DISCARD) {
711 oldscope = scopestack_ix;
713 if (!(flags & G_NOARGS))
714 myop.op_flags = OPf_STACKED;
715 myop.op_next = Nullop;
716 myop.op_flags |= OPf_KNOW;
718 myop.op_flags |= OPf_LIST;
720 if (flags & G_EVAL) {
721 Copy(top_env, oldtop, 1, Sigjmp_buf);
723 cLOGOP->op_other = op;
725 /* we're trying to emulate pp_entertry() here */
727 register CONTEXT *cx;
733 push_return(op->op_next);
734 PUSHBLOCK(cx, CXt_EVAL, stack_sp);
736 eval_root = op; /* Only needed so that goto works right. */
739 if (flags & G_KEEPERR)
742 sv_setpv(GvSV(errgv),"");
747 switch (Sigsetjmp(top_env,1)) {
752 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
758 /* my_exit() was called */
761 Copy(oldtop, top_env, 1, Sigjmp_buf);
763 croak("Callback called exit");
764 my_exit(statusvalue);
772 stack_sp = stack_base + oldmark;
777 *++stack_sp = &sv_undef;
783 if (op == (OP*)&myop)
787 retval = stack_sp - (stack_base + oldmark);
788 if ((flags & G_EVAL) && !(flags & G_KEEPERR))
789 sv_setpv(GvSV(errgv),"");
792 if (flags & G_EVAL) {
793 if (scopestack_ix > oldscope) {
797 register CONTEXT *cx;
806 Copy(oldtop, top_env, 1, Sigjmp_buf);
808 if (flags & G_DISCARD) {
809 stack_sp = stack_base + oldmark;
820 perl_eval_sv(sv, flags)
822 I32 flags; /* See G_* flags in cop.h */
824 UNOP myop; /* fake syntax tree node */
826 I32 oldmark = sp - stack_base;
831 if (flags & G_DISCARD) {
841 oldscope = scopestack_ix;
843 if (!(flags & G_NOARGS))
844 myop.op_flags = OPf_STACKED;
845 myop.op_next = Nullop;
846 myop.op_flags |= OPf_KNOW;
848 myop.op_flags |= OPf_LIST;
850 Copy(top_env, oldtop, 1, Sigjmp_buf);
853 switch (Sigsetjmp(top_env,1)) {
858 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
864 /* my_exit() was called */
867 Copy(oldtop, top_env, 1, Sigjmp_buf);
869 croak("Callback called exit");
870 my_exit(statusvalue);
878 stack_sp = stack_base + oldmark;
883 *++stack_sp = &sv_undef;
888 if (op == (OP*)&myop)
892 retval = stack_sp - (stack_base + oldmark);
893 if ((flags & G_EVAL) && !(flags & G_KEEPERR))
894 sv_setpv(GvSV(errgv),"");
897 Copy(oldtop, top_env, 1, Sigjmp_buf);
898 if (flags & G_DISCARD) {
899 stack_sp = stack_base + oldmark;
907 /* Require a module. */
913 SV* sv = sv_newmortal();
914 sv_setpv(sv, "require '");
917 perl_eval_sv(sv, G_DISCARD);
921 magicname(sym,name,namlen)
928 if (gv = gv_fetchpv(sym,TRUE, SVt_PV))
929 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
933 # define PERLLIB_SEP ';'
936 # define PERLLIB_SEP '|'
938 # define PERLLIB_SEP ':'
951 /* Break at all separators */
953 /* First, skip any consecutive separators */
954 while ( *p == PERLLIB_SEP ) {
955 /* Uncomment the next line for PATH semantics */
956 /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
959 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
960 av_push(GvAVn(incgv), newSVpv(p, (STRLEN)(s - p)));
963 av_push(GvAVn(incgv), newSVpv(p, 0));
970 usage(name) /* XXX move this out into a module ? */
973 /* This message really ought to be max 23 lines.
974 * Removed -h because the user already knows that opton. Others? */
975 printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name);
976 printf("\n -0[octal] specify record separator (\\0, if no argument)");
977 printf("\n -a autosplit mode with -n or -p (splits $_ into @F)");
978 printf("\n -c check syntax only (runs BEGIN and END blocks)");
979 printf("\n -d[:debugger] run scripts under debugger");
980 printf("\n -D[number/list] set debugging flags (argument is a bit mask or flags)");
981 printf("\n -e 'command' one line of script. Several -e's allowed. Omit [programfile].");
982 printf("\n -F/pattern/ split() pattern for autosplit (-a). The //'s are optional.");
983 printf("\n -i[extension] edit <> files in place (make backup if extension supplied)");
984 printf("\n -Idirectory specify @INC/#include directory (may be used more then once)");
985 printf("\n -l[octal] enable line ending processing, specifies line teminator");
986 printf("\n -[mM][-]module.. executes `use/no module...' before executing your script.");
987 printf("\n -n assume 'while (<>) { ... }' loop arround your script");
988 printf("\n -p assume loop like -n but print line also like sed");
989 printf("\n -P run script through C preprocessor before compilation");
991 printf("\n -R enable REXX variable pool");
993 printf("\n -s enable some switch parsing for switches after script name");
994 printf("\n -S look for the script using PATH environment variable");
995 printf("\n -T turn on tainting checks");
996 printf("\n -u dump core after parsing script");
997 printf("\n -U allow unsafe operations");
998 printf("\n -v print version number and patchlevel of perl");
999 printf("\n -V[:variable] print perl configuration information");
1000 printf("\n -w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT.");
1001 printf("\n -x[directory] strip off text before #!perl line and perhaps cd to directory\n");
1004 /* This routine handles any switches that can be given during run */
1015 rschar = scan_oct(s, 4, &numlen);
1017 if (rschar & ~((U8)~0))
1019 else if (!rschar && numlen >= 2)
1020 nrs = newSVpv("", 0);
1023 nrs = newSVpv(&ch, 1);
1028 splitstr = savepv(s + 1);
1042 if (*s == ':' || *s == '=') {
1043 sprintf(buf, "use Devel::%s;", ++s);
1045 my_setenv("PERL5DB",buf);
1055 if (isALPHA(s[1])) {
1056 static char debopts[] = "psltocPmfrxuLHXD";
1059 for (s++; *s && (d = strchr(debopts,*s)); s++)
1060 debug |= 1 << (d - debopts);
1064 for (s++; isDIGIT(*s); s++) ;
1066 debug |= 0x80000000;
1068 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
1069 for (s++; isALNUM(*s); s++) ;
1079 inplace = savepv(s+1);
1081 for (s = inplace; *s && !isSPACE(*s); s++) ;
1088 for (e = s; *e && !isSPACE(*e); e++) ;
1089 av_push(GvAVn(incgv),newSVpv(s,e-s));
1094 croak("No space allowed after -I");
1104 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
1109 ors = savepvn("\n\n", 2);
1113 ors = SvPV(nrs, orslen);
1117 taint_not("-M"); /* XXX ? */
1120 taint_not("-m"); /* XXX ? */
1124 /* -M-foo == 'no foo' */
1125 if (*s == '-') { use = "no "; ++s; }
1126 Sv = newSVpv(use,0);
1128 /* We allow -M'Module qw(Foo Bar)' */
1129 while(isALNUM(*s) || *s==':') ++s;
1131 sv_catpv(Sv, start);
1132 if (*(start-1) == 'm') {
1134 croak("Can't use '%c' after -mname", *s);
1135 sv_catpv( Sv, " ()");
1138 sv_catpvn(Sv, start, s-start);
1139 sv_catpv(Sv, " split(/,/,q{");
1144 if (preambleav == NULL)
1145 preambleav = newAV();
1146 av_push(preambleav, Sv);
1149 croak("No space allowed after -%c", *(s-1));
1177 #if defined(SUBVERSION) && SUBVERSION > 0
1178 printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION);
1180 printf("\nThis is perl, version %s",patchlevel);
1183 #if defined(DEBUGGING) || defined(EMBED) || defined(MULTIPLICITY)
1184 fputs(" with", stdout);
1186 fputs(" DEBUGGING", stdout);
1189 fputs(" EMBED", stdout);
1192 fputs(" MULTIPLICITY", stdout);
1196 #if defined(LOCAL_PATCH_COUNT)
1197 if (LOCAL_PATCH_COUNT > 0)
1199 fputs("\n\tLocally applied patches:\n", stdout);
1200 for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
1201 if (Ilocalpatches[i])
1202 fprintf(stdout, "\t %s\n", Ilocalpatches[i]);
1206 printf("\n\tbuilt under %s",OSNAME);
1209 printf(" at %s %s",__DATE__,__TIME__);
1211 printf(" on %s",__DATE__);
1214 fputs("\n\t+ suidperl security patch", stdout);
1215 fputs("\n\nCopyright 1987-1996, Larry Wall\n",stdout);
1217 fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
1221 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
1222 "Version 5 port Copyright (c) 1994-1995, Andreas Kaiser\n", stdout);
1225 fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout);
1228 Perl may be copied only under the terms of either the Artistic License or the\n\
1229 GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n",stdout);
1240 if (s[1] == '-') /* Additional switches on #! line. */
1253 croak("Can't emulate -%.1s on #! line",s);
1258 /* compliments of Tom Christiansen */
1260 /* unexec() can be found in the Gnu emacs distribution */
1269 sprintf (buf, "%s.perldump", origfilename);
1270 sprintf (tokenbuf, "%s/perl", BIN);
1272 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
1274 fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
1278 # include <lib$routines.h>
1279 lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */
1281 ABORT(); /* for use with undump */
1290 curstash = defstash = newHV();
1291 curstname = newSVpv("main",4);
1292 gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1293 SvREFCNT_dec(GvHV(gv));
1294 GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
1296 HvNAME(defstash) = savepv("main");
1297 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
1299 defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
1300 errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
1302 curstash = defstash;
1303 compiling.cop_stash = defstash;
1304 debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
1305 /* We must init $/ before switches are processed. */
1306 sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1);
1309 #ifdef CAN_PROTOTYPE
1311 open_script(char *scriptname, bool dosearch, SV *sv)
1314 open_script(scriptname,dosearch,sv)
1320 char *xfound = Nullch;
1321 char *xfailed = Nullch;
1325 #if defined(DOSISH) && !defined(OS2) && !defined(atarist)
1326 #define SEARCH_EXTS ".bat", ".cmd", NULL
1329 # define SEARCH_EXTS ".pl", ".com", NULL
1331 /* additional extensions to try in each dir if scriptname not found */
1333 char *ext[] = { SEARCH_EXTS };
1334 int extidx = (strchr(scriptname,'.')) ? -1 : 0; /* has ext already */
1338 if (dosearch && !strpbrk(scriptname,":[</") && (my_getenv("DCL$PATH"))) {
1341 while (my_trnlnm("DCL$PATH",tokenbuf,idx++)) {
1342 strcat(tokenbuf,scriptname);
1344 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
1346 bufend = s + strlen(s);
1349 s = cpytill(tokenbuf,s,bufend,':',&len);
1352 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
1353 tokenbuf[len] = '\0';
1355 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
1356 tokenbuf[len] = '\0';
1362 if (len && tokenbuf[len-1] != '/')
1365 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
1367 if (len && tokenbuf[len-1] != '\\')
1370 (void)strcat(tokenbuf+len,"/");
1371 (void)strcat(tokenbuf+len,scriptname);
1375 len = strlen(tokenbuf);
1376 if (extidx > 0) /* reset after previous loop */
1380 DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
1381 retval = Stat(tokenbuf,&statbuf);
1383 } while ( retval < 0 /* not there */
1384 && extidx>=0 && ext[extidx] /* try an extension? */
1385 && strcpy(tokenbuf+len, ext[extidx++])
1390 if (S_ISREG(statbuf.st_mode)
1391 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
1392 xfound = tokenbuf; /* bingo! */
1396 xfailed = savepv(tokenbuf);
1399 croak("Can't execute %s", xfailed ? xfailed : scriptname );
1402 scriptname = xfound;
1405 if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
1406 char *s = scriptname + 8;
1415 origfilename = savepv(e_tmpname ? "-e" : scriptname);
1416 curcop->cop_filegv = gv_fetchfile(origfilename);
1417 if (strEQ(origfilename,"-"))
1419 if (fdscript >= 0) {
1420 rsfp = fdopen(fdscript,"r");
1421 #if defined(HAS_FCNTL) && defined(F_SETFD)
1422 fcntl(fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
1425 else if (preprocess) {
1426 char *cpp = CPPSTDIN;
1428 if (strEQ(cpp,"cppstdin"))
1429 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
1431 sprintf(tokenbuf, "%s", cpp);
1433 sv_catpv(sv,PRIVLIB_EXP);
1435 (void)sprintf(buf, "\
1436 sed %s -e \"/^[^#]/b\" \
1437 -e \"/^#[ ]*include[ ]/b\" \
1438 -e \"/^#[ ]*define[ ]/b\" \
1439 -e \"/^#[ ]*if[ ]/b\" \
1440 -e \"/^#[ ]*ifdef[ ]/b\" \
1441 -e \"/^#[ ]*ifndef[ ]/b\" \
1442 -e \"/^#[ ]*else/b\" \
1443 -e \"/^#[ ]*elif[ ]/b\" \
1444 -e \"/^#[ ]*undef[ ]/b\" \
1445 -e \"/^#[ ]*endif/b\" \
1448 (doextract ? "-e \"1,/^#/d\n\"" : ""),
1450 (void)sprintf(buf, "\
1451 %s %s -e '/^[^#]/b' \
1452 -e '/^#[ ]*include[ ]/b' \
1453 -e '/^#[ ]*define[ ]/b' \
1454 -e '/^#[ ]*if[ ]/b' \
1455 -e '/^#[ ]*ifdef[ ]/b' \
1456 -e '/^#[ ]*ifndef[ ]/b' \
1457 -e '/^#[ ]*else/b' \
1458 -e '/^#[ ]*elif[ ]/b' \
1459 -e '/^#[ ]*undef[ ]/b' \
1460 -e '/^#[ ]*endif/b' \
1468 (doextract ? "-e '1,/^#/d\n'" : ""),
1470 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
1472 #ifdef IAMSUID /* actually, this is caught earlier */
1473 if (euid != uid && !euid) { /* if running suidperl */
1475 (void)seteuid(uid); /* musn't stay setuid root */
1478 (void)setreuid((Uid_t)-1, uid);
1480 #ifdef HAS_SETRESUID
1481 (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
1487 if (geteuid() != uid)
1488 croak("Can't do seteuid!\n");
1490 #endif /* IAMSUID */
1491 rsfp = my_popen(buf,"r");
1493 else if (!*scriptname) {
1494 taint_not("program input from stdin");
1498 rsfp = fopen(scriptname,"r");
1499 #if defined(HAS_FCNTL) && defined(F_SETFD)
1500 fcntl(fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
1503 if ((FILE*)rsfp == Nullfp) {
1505 #ifndef IAMSUID /* in case script is not readable before setuid */
1506 if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
1507 statbuf.st_mode & (S_ISUID|S_ISGID)) {
1508 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1509 execv(buf, origargv); /* try again */
1510 croak("Can't do setuid\n");
1514 croak("Can't open perl script \"%s\": %s\n",
1515 SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
1520 validate_suid(validarg, scriptname)
1526 /* do we need to emulate setuid on scripts? */
1528 /* This code is for those BSD systems that have setuid #! scripts disabled
1529 * in the kernel because of a security problem. Merely defining DOSUID
1530 * in perl will not fix that problem, but if you have disabled setuid
1531 * scripts in the kernel, this will attempt to emulate setuid and setgid
1532 * on scripts that have those now-otherwise-useless bits set. The setuid
1533 * root version must be called suidperl or sperlN.NNN. If regular perl
1534 * discovers that it has opened a setuid script, it calls suidperl with
1535 * the same argv that it had. If suidperl finds that the script it has
1536 * just opened is NOT setuid root, it sets the effective uid back to the
1537 * uid. We don't just make perl setuid root because that loses the
1538 * effective uid we had before invoking perl, if it was different from the
1541 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
1542 * be defined in suidperl only. suidperl must be setuid root. The
1543 * Configure script will set this up for you if you want it.
1549 if (Fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
1550 croak("Can't stat script \"%s\"",origfilename);
1551 if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) {
1555 #ifndef HAS_SETREUID
1556 /* On this access check to make sure the directories are readable,
1557 * there is actually a small window that the user could use to make
1558 * filename point to an accessible directory. So there is a faint
1559 * chance that someone could execute a setuid script down in a
1560 * non-accessible directory. I don't know what to do about that.
1561 * But I don't think it's too important. The manual lies when
1562 * it says access() is useful in setuid programs.
1564 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
1565 croak("Permission denied");
1567 /* If we can swap euid and uid, then we can determine access rights
1568 * with a simple stat of the file, and then compare device and
1569 * inode to make sure we did stat() on the same file we opened.
1570 * Then we just have to make sure he or she can execute it.
1573 struct stat tmpstatbuf;
1577 setreuid(euid,uid) < 0
1580 setresuid(euid,uid,(Uid_t)-1) < 0
1583 || getuid() != euid || geteuid() != uid)
1584 croak("Can't swap uid and euid"); /* really paranoid */
1585 if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
1586 croak("Permission denied"); /* testing full pathname here */
1587 if (tmpstatbuf.st_dev != statbuf.st_dev ||
1588 tmpstatbuf.st_ino != statbuf.st_ino) {
1590 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
1592 "User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
1593 (Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
1594 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
1595 statbuf.st_dev, statbuf.st_ino,
1596 SvPVX(GvSV(curcop->cop_filegv)),
1597 statbuf.st_uid, statbuf.st_gid);
1598 (void)my_pclose(rsfp);
1600 croak("Permission denied\n");
1604 setreuid(uid,euid) < 0
1606 # if defined(HAS_SETRESUID)
1607 setresuid(uid,euid,(Uid_t)-1) < 0
1610 || getuid() != uid || geteuid() != euid)
1611 croak("Can't reswap uid and euid");
1612 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
1613 croak("Permission denied\n");
1615 #endif /* HAS_SETREUID */
1616 #endif /* IAMSUID */
1618 if (!S_ISREG(statbuf.st_mode))
1619 croak("Permission denied");
1620 if (statbuf.st_mode & S_IWOTH)
1621 croak("Setuid/gid script is writable by world");
1622 doswitches = FALSE; /* -s is insecure in suid */
1624 if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1625 strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */
1626 croak("No #! line");
1629 while (!isSPACE(*s)) s++;
1630 if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
1631 croak("Not a perl script");
1632 while (*s == ' ' || *s == '\t') s++;
1634 * #! arg must be what we saw above. They can invoke it by
1635 * mentioning suidperl explicitly, but they may not add any strange
1636 * arguments beyond what #! says if they do invoke suidperl that way.
1638 len = strlen(validarg);
1639 if (strEQ(validarg," PHOOEY ") ||
1640 strnNE(s,validarg,len) || !isSPACE(s[len]))
1641 croak("Args must match #! line");
1644 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1645 euid == statbuf.st_uid)
1647 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1648 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1649 #endif /* IAMSUID */
1651 if (euid) { /* oops, we're not the setuid root perl */
1654 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
1655 execv(buf, origargv); /* try again */
1657 croak("Can't do setuid\n");
1660 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
1662 (void)setegid(statbuf.st_gid);
1665 (void)setregid((Gid_t)-1,statbuf.st_gid);
1667 #ifdef HAS_SETRESGID
1668 (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
1670 setgid(statbuf.st_gid);
1674 if (getegid() != statbuf.st_gid)
1675 croak("Can't do setegid!\n");
1677 if (statbuf.st_mode & S_ISUID) {
1678 if (statbuf.st_uid != euid)
1680 (void)seteuid(statbuf.st_uid); /* all that for this */
1683 (void)setreuid((Uid_t)-1,statbuf.st_uid);
1685 #ifdef HAS_SETRESUID
1686 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
1688 setuid(statbuf.st_uid);
1692 if (geteuid() != statbuf.st_uid)
1693 croak("Can't do seteuid!\n");
1695 else if (uid) { /* oops, mustn't run as root */
1697 (void)seteuid((Uid_t)uid);
1700 (void)setreuid((Uid_t)-1,(Uid_t)uid);
1702 #ifdef HAS_SETRESUID
1703 (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
1709 if (geteuid() != uid)
1710 croak("Can't do seteuid!\n");
1713 if (!cando(S_IXUSR,TRUE,&statbuf))
1714 croak("Permission denied\n"); /* they can't do this */
1717 else if (preprocess)
1718 croak("-P not allowed for setuid/setgid script\n");
1719 else if (fdscript >= 0)
1720 croak("fd script not allowed in suidperl\n");
1722 croak("Script is not setuid/setgid in suidperl\n");
1724 /* We absolutely must clear out any saved ids here, so we */
1725 /* exec the real perl, substituting fd script for scriptname. */
1726 /* (We pass script name as "subdir" of fd, which perl will grok.) */
1728 for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ;
1729 if (!origargv[which])
1730 croak("Permission denied");
1731 (void)sprintf(buf, "/dev/fd/%d/%.127s", fileno(rsfp), origargv[which]);
1732 origargv[which] = buf;
1734 #if defined(HAS_FCNTL) && defined(F_SETFD)
1735 fcntl(fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */
1738 (void)sprintf(tokenbuf, "%s/perl%s", BIN, patchlevel);
1739 execv(tokenbuf, origargv); /* try again */
1740 croak("Can't do setuid\n");
1741 #endif /* IAMSUID */
1743 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1744 #ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
1745 Fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
1746 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1748 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1751 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
1752 FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1753 #endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1754 /* not set-id, must be wrapped */
1764 /* skip forward in input to the real script? */
1768 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
1769 croak("No Perl script found in input\n");
1770 if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1771 ungetc('\n',rsfp); /* to keep line count right */
1773 if (s = instr(s,"perl -")) {
1776 while (s = moreswitches(s)) ;
1778 if (cddir && chdir(cddir) < 0)
1779 croak("Can't chdir to %s",cddir);
1787 uid = (int)getuid();
1788 euid = (int)geteuid();
1789 gid = (int)getgid();
1790 egid = (int)getegid();
1795 tainting |= (uid && (euid != uid || egid != gid));
1801 curstash = debstash;
1802 dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
1804 DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
1805 DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
1806 DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
1807 DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
1808 sv_setiv(DBsingle, 0);
1809 DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
1810 sv_setiv(DBtrace, 0);
1811 DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
1812 sv_setiv(DBsignal, 0);
1813 curstash = defstash;
1820 mainstack = stack; /* remember in case we switch stacks */
1821 AvREAL_off(stack); /* not a real array */
1822 av_extend(stack,127);
1824 stack_base = AvARRAY(stack);
1825 stack_sp = stack_base;
1826 stack_max = stack_base + 127;
1828 New(54,markstack,64,I32);
1829 markstack_ptr = markstack;
1830 markstack_max = markstack + 64;
1832 New(54,scopestack,32,I32);
1834 scopestack_max = 32;
1836 New(54,savestack,128,ANY);
1838 savestack_max = 128;
1840 New(54,retstack,16,OP*);
1844 cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */
1845 New(50,cxstack,cxstack_max + 1,CONTEXT);
1848 New(50,tmps_stack,128,SV*);
1853 New(51,debname,128,char);
1854 New(52,debdelim,128,char);
1858 static FILE *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
1866 subname = newSVpv("main",4);
1870 init_predump_symbols()
1875 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
1877 stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
1878 GvMULTI_on(stdingv);
1879 IoIFP(GvIOp(stdingv)) = stdin;
1880 tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
1882 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
1884 tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
1886 IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = stdout;
1888 tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
1890 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
1892 othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
1893 GvMULTI_on(othergv);
1894 IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = stderr;
1895 tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
1897 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
1899 statname = NEWSV(66,0); /* last filename we did stat on */
1901 osname = savepv(OSNAME);
1905 init_postdump_symbols(argc,argv,env)
1907 register char **argv;
1908 register char **env;
1914 argc--,argv++; /* skip name of script */
1916 for (; argc > 0 && **argv == '-'; argc--,argv++) {
1919 if (argv[0][1] == '-') {
1923 if (s = strchr(argv[0], '=')) {
1925 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
1928 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
1931 toptarget = NEWSV(0,0);
1932 sv_upgrade(toptarget, SVt_PVFM);
1933 sv_setpvn(toptarget, "", 0);
1934 bodytarget = NEWSV(0,0);
1935 sv_upgrade(bodytarget, SVt_PVFM);
1936 sv_setpvn(bodytarget, "", 0);
1937 formtarget = bodytarget;
1940 if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
1941 sv_setpv(GvSV(tmpgv),origfilename);
1942 magicname("0", "0", 1);
1944 if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV))
1946 if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
1947 sv_setpv(GvSV(tmpgv),origargv[0]);
1948 if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
1950 (void)gv_AVadd(argvgv);
1951 av_clear(GvAVn(argvgv));
1952 for (; argc > 0; argc--,argv++) {
1953 av_push(GvAVn(argvgv),newSVpv(argv[0],0));
1956 if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
1961 #ifndef VMS /* VMS doesn't have environ array */
1962 /* Note that if the supplied env parameter is actually a copy
1963 of the global environ then it may now point to free'd memory
1964 if the environment has been modified since. To avoid this
1965 problem we treat env==NULL as meaning 'use the default'
1969 if (env != environ) {
1970 environ[0] = Nullch;
1971 hv_magic(hv, envgv, 'E');
1973 for (; *env; env++) {
1974 if (!(s = strchr(*env,'=')))
1977 sv = newSVpv(s--,0);
1978 sv_magic(sv, sv, 'e', *env, s - *env);
1979 (void)hv_store(hv, *env, s - *env, sv, 0);
1983 #ifdef DYNAMIC_ENV_FETCH
1984 HvNAME(hv) = savepv(ENV_HV_NAME);
1986 hv_magic(hv, envgv, 'E');
1989 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
1990 sv_setiv(GvSV(tmpgv),(I32)getpid());
1999 s = getenv("PERL5LIB");
2003 incpush(getenv("PERLLIB"));
2007 incpush(APPLLIB_EXP);
2011 incpush(ARCHLIB_EXP);
2014 #define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
2016 incpush(PRIVLIB_EXP);
2019 incpush(SITEARCH_EXP);
2022 incpush(SITELIB_EXP);
2024 #ifdef OLDARCHLIB_EXP /* 5.00[01] compatibility */
2025 incpush(OLDARCHLIB_EXP);
2038 line_t oldline = curcop->cop_line;
2040 Copy(top_env, oldtop, 1, Sigjmp_buf);
2042 while (AvFILL(list) >= 0) {
2043 CV *cv = (CV*)av_shift(list);
2047 switch (Sigsetjmp(top_env,1)) {
2049 SV* atsv = GvSV(errgv);
2051 perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
2052 (void)SvPV(atsv, len);
2054 Copy(oldtop, top_env, 1, Sigjmp_buf);
2055 curcop = &compiling;
2056 curcop->cop_line = oldline;
2057 if (list == beginav)
2058 sv_catpv(atsv, "BEGIN failed--compilation aborted");
2060 sv_catpv(atsv, "END failed--cleanup aborted");
2061 croak("%s", SvPVX(atsv));
2067 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
2073 /* my_exit() was called */
2074 curstash = defstash;
2078 Copy(oldtop, top_env, 1, Sigjmp_buf);
2079 curcop = &compiling;
2080 curcop->cop_line = oldline;
2082 if (list == beginav)
2083 croak("BEGIN failed--compilation aborted");
2085 croak("END failed--cleanup aborted");
2087 my_exit(statusvalue);
2092 fprintf(stderr, "panic: restartop\n");
2096 Copy(oldtop, top_env, 1, Sigjmp_buf);
2097 curcop = &compiling;
2098 curcop->cop_line = oldline;
2099 Siglongjmp(top_env, 3);
2103 Copy(oldtop, top_env, 1, Sigjmp_buf);