This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Okay, here's your official unofficial closure leak patch
[perl5.git] / perl.c
CommitLineData
a0d0e21e
LW
1/* perl.c
2 *
3 * Copyright (c) 1987-1994 Larry Wall
a687059c 4 *
352d5a3a
LW
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.
a687059c 7 *
8d063cd8
LW
8 */
9
a0d0e21e
LW
10/*
11 * "A ship then new they built for him/of mithril and of elven glass" --Bilbo
12 */
45d8adaa 13
378cc40b
LW
14#include "EXTERN.h"
15#include "perl.h"
a687059c 16#include "patchlevel.h"
378cc40b 17
a0d0e21e
LW
18/* Omit -- it causes too much grief on mixed systems.
19#ifdef I_UNISTD
20#include <unistd.h>
21#endif
22*/
23
24char rcsid[] = "perl.c\nPatch level: ###\n";
463ee0b2 25
a687059c
LW
26#ifdef IAMSUID
27#ifndef DOSUID
28#define DOSUID
29#endif
30#endif
378cc40b 31
a687059c
LW
32#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
33#ifdef DOSUID
34#undef DOSUID
35#endif
36#endif
8d063cd8 37
a0d0e21e
LW
38static void find_beginning _((void));
39static void incpush _((char *));
748a9306 40static void init_ids _((void));
a0d0e21e
LW
41static void init_debugger _((void));
42static void init_lexer _((void));
43static void init_main_stash _((void));
44static void init_perllib _((void));
45static void init_postdump_symbols _((int, char **, char **));
46static void init_predump_symbols _((void));
47static void init_stacks _((void));
48static void open_script _((char *, bool, SV *));
49static void validate_suid _((char *));
79072805 50
93a17b20 51PerlInterpreter *
79072805
LW
52perl_alloc()
53{
93a17b20 54 PerlInterpreter *sv_interp;
79072805 55
8990e307 56 curinterp = 0;
93a17b20 57 New(53, sv_interp, 1, PerlInterpreter);
79072805
LW
58 return sv_interp;
59}
60
61void
62perl_construct( sv_interp )
93a17b20 63register PerlInterpreter *sv_interp;
79072805
LW
64{
65 if (!(curinterp = sv_interp))
66 return;
67
8990e307 68#ifdef MULTIPLICITY
93a17b20 69 Zero(sv_interp, 1, PerlInterpreter);
8990e307 70#endif
79072805
LW
71
72 /* Init the real globals? */
73 if (!linestr) {
74 linestr = NEWSV(65,80);
ed6116ce 75 sv_upgrade(linestr,SVt_PVIV);
79072805
LW
76
77 SvREADONLY_on(&sv_undef);
78
79 sv_setpv(&sv_no,No);
463ee0b2 80 SvNV(&sv_no);
79072805
LW
81 SvREADONLY_on(&sv_no);
82
83 sv_setpv(&sv_yes,Yes);
463ee0b2 84 SvNV(&sv_yes);
79072805
LW
85 SvREADONLY_on(&sv_yes);
86
87#ifdef MSDOS
88 /*
89 * There is no way we can refer to them from Perl so close them to save
90 * space. The other alternative would be to provide STDAUX and STDPRN
91 * filehandles.
92 */
93 (void)fclose(stdaux);
94 (void)fclose(stdprn);
95#endif
96 }
97
8990e307 98#ifdef MULTIPLICITY
79072805 99 chopset = " \n-";
463ee0b2 100 copline = NOLINE;
79072805 101 curcop = &compiling;
79072805
LW
102 dlmax = 128;
103 laststatval = -1;
104 laststype = OP_STAT;
105 maxscream = -1;
106 maxsysfd = MAXSYSFD;
107 nrs = "\n";
108 nrschar = '\n';
109 nrslen = 1;
110 rs = "\n";
111 rschar = '\n';
112 rsfp = Nullfp;
113 rslen = 1;
463ee0b2 114 statname = Nullsv;
79072805 115 tmps_floor = -1;
79072805
LW
116#endif
117
748a9306 118 init_ids();
a0d0e21e 119 sprintf(patchlevel, "%5.3f", 5.0 + (PATCHLEVEL / 1000.0));
79072805
LW
120
121 fdpid = newAV(); /* for remembering popen pids by fd */
463ee0b2 122 pidstatus = newHV();/* for remembering status of dead pids */
8990e307
LW
123
124 init_stacks();
125 ENTER;
79072805
LW
126}
127
128void
748a9306 129perl_destruct(sv_interp)
93a17b20 130register PerlInterpreter *sv_interp;
79072805 131{
748a9306 132 int destruct_level; /* 0=none, 1=full, 2=full with checks */
8990e307 133 I32 last_sv_count;
a0d0e21e 134 HV *hv;
8990e307 135
79072805
LW
136 if (!(curinterp = sv_interp))
137 return;
748a9306
LW
138
139 destruct_level = perl_destruct_level;
8990e307 140 LEAVE;
a0d0e21e
LW
141 FREETMPS;
142
143 if (sv_objcount) {
144 /* We must account for everything. First the syntax tree. */
145 if (main_root) {
146 curpad = AvARRAY(comppad);
147 op_free(main_root);
148 main_root = 0;
149 }
150 }
151 if (sv_objcount) {
152 /*
153 * Try to destruct global references. We do this first so that the
154 * destructors and destructees still exist. Some sv's might remain.
155 * Non-referenced objects are on their own.
156 */
157
158 dirty = TRUE;
159 sv_clean_objs();
8990e307
LW
160 }
161
a0d0e21e 162 if (destruct_level == 0){
8990e307 163
a0d0e21e
LW
164 DEBUG_P(debprofdump());
165
166 /* The exit() function will do everything that needs doing. */
167 return;
168 }
169
170 /* Prepare to destruct main symbol table. */
171 hv = defstash;
85e6fe83 172 defstash = 0;
a0d0e21e
LW
173 SvREFCNT_dec(hv);
174
175 FREETMPS;
176 if (destruct_level >= 2) {
177 if (scopestack_ix != 0)
178 warn("Unbalanced scopes: %d more ENTERs than LEAVEs\n", scopestack_ix);
179 if (savestack_ix != 0)
180 warn("Unbalanced saves: %d more saves than restores\n", savestack_ix);
181 if (tmps_floor != -1)
182 warn("Unbalanced tmps: %d more allocs than frees\n", tmps_floor + 1);
183 if (cxstack_ix != -1)
184 warn("Unbalanced context: %d more PUSHes than POPs\n", cxstack_ix + 1);
185 }
8990e307
LW
186
187 /* Now absolutely destruct everything, somehow or other, loops or no. */
8990e307
LW
188 last_sv_count = 0;
189 while (sv_count != 0 && sv_count != last_sv_count) {
190 last_sv_count = sv_count;
191 sv_clean_all();
192 }
193 if (sv_count != 0)
194 warn("Scalars leaked: %d\n", sv_count);
a0d0e21e
LW
195
196 DEBUG_P(debprofdump());
79072805
LW
197}
198
199void
200perl_free(sv_interp)
93a17b20 201PerlInterpreter *sv_interp;
79072805
LW
202{
203 if (!(curinterp = sv_interp))
204 return;
205 Safefree(sv_interp);
206}
ecfc5424 207#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
a0d0e21e
LW
208char *getenv _((char *)); /* Usually in <stdlib.h> */
209#endif
79072805
LW
210
211int
a0d0e21e 212perl_parse(sv_interp, xsinit, argc, argv, env)
93a17b20 213PerlInterpreter *sv_interp;
a0d0e21e
LW
214void (*xsinit)_((void));
215int argc;
216char **argv;
79072805 217char **env;
8d063cd8 218{
79072805 219 register SV *sv;
8d063cd8 220 register char *s;
45d8adaa 221 char *scriptname;
a0d0e21e 222 VOL bool dosearch = FALSE;
13281fa4 223 char *validarg = "";
748a9306 224 AV* comppadlist;
8d063cd8 225
a687059c
LW
226#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
227#ifdef IAMSUID
228#undef IAMSUID
463ee0b2 229 croak("suidperl is no longer needed since the kernel can now execute\n\
a687059c
LW
230setuid perl scripts securely.\n");
231#endif
232#endif
233
79072805
LW
234 if (!(curinterp = sv_interp))
235 return 255;
236
ac58e20f
LW
237 origargv = argv;
238 origargc = argc;
a0d0e21e 239#ifndef VMS /* VMS doesn't have environ array */
fe14fcc3 240 origenviron = environ;
a0d0e21e
LW
241#endif
242
243 if (do_undump) {
244
245 /* Come here if running an undumped a.out. */
246
247 origfilename = savepv(argv[0]);
248 do_undump = FALSE;
249 cxstack_ix = -1; /* start label stack again */
748a9306 250 init_ids();
a0d0e21e
LW
251 init_postdump_symbols(argc,argv,env);
252 return 0;
253 }
254
255 if (main_root)
256 op_free(main_root);
257 main_root = 0;
79072805
LW
258
259 switch (setjmp(top_env)) {
260 case 1:
748a9306 261#ifdef VMS
79072805 262 statusvalue = 255;
748a9306
LW
263#else
264 statusvalue = 1;
265#endif
79072805 266 case 2:
8990e307
LW
267 curstash = defstash;
268 if (endav)
269 calllist(endav);
79072805
LW
270 return(statusvalue); /* my_exit() was called */
271 case 3:
272 fprintf(stderr, "panic: top_env\n");
8990e307 273 return 1;
79072805
LW
274 }
275
79072805
LW
276 sv_setpvn(linestr,"",0);
277 sv = newSVpv("",0); /* first used for -I flags */
8990e307 278 SAVEFREESV(sv);
79072805 279 init_main_stash();
33b78306 280 for (argc--,argv++; argc > 0; argc--,argv++) {
8d063cd8
LW
281 if (argv[0][0] != '-' || !argv[0][1])
282 break;
13281fa4
LW
283#ifdef DOSUID
284 if (*validarg)
285 validarg = " PHOOEY ";
286 else
287 validarg = argv[0];
288#endif
289 s = argv[0]+1;
8d063cd8 290 reswitch:
13281fa4 291 switch (*s) {
27e2fb84 292 case '0':
2304df62 293 case 'F':
378cc40b 294 case 'a':
33b78306 295 case 'c':
a687059c 296 case 'd':
8d063cd8 297 case 'D':
33b78306 298 case 'i':
fe14fcc3 299 case 'l':
33b78306
LW
300 case 'n':
301 case 'p':
79072805 302 case 's':
463ee0b2 303 case 'T':
33b78306
LW
304 case 'u':
305 case 'U':
306 case 'v':
307 case 'w':
308 if (s = moreswitches(s))
309 goto reswitch;
8d063cd8 310 break;
33b78306 311
8d063cd8 312 case 'e':
a687059c 313 if (euid != uid || egid != gid)
463ee0b2 314 croak("No -e allowed in setuid scripts");
8d063cd8 315 if (!e_fp) {
a0d0e21e 316 e_tmpname = savepv(TMPPATH);
a687059c 317 (void)mktemp(e_tmpname);
83025b21 318 if (!*e_tmpname)
463ee0b2 319 croak("Can't mktemp()");
8d063cd8 320 e_fp = fopen(e_tmpname,"w");
33b78306 321 if (!e_fp)
463ee0b2 322 croak("Cannot open temporary file");
8d063cd8 323 }
33b78306 324 if (argv[1]) {
8d063cd8 325 fputs(argv[1],e_fp);
33b78306
LW
326 argc--,argv++;
327 }
a687059c 328 (void)putc('\n', e_fp);
8d063cd8
LW
329 break;
330 case 'I':
463ee0b2 331 taint_not("-I");
79072805
LW
332 sv_catpv(sv,"-");
333 sv_catpv(sv,s);
334 sv_catpv(sv," ");
a687059c 335 if (*++s) {
a0d0e21e 336 av_push(GvAVn(incgv),newSVpv(s,0));
378cc40b 337 }
33b78306 338 else if (argv[1]) {
a0d0e21e 339 av_push(GvAVn(incgv),newSVpv(argv[1],0));
79072805 340 sv_catpv(sv,argv[1]);
8d063cd8 341 argc--,argv++;
79072805 342 sv_catpv(sv," ");
8d063cd8
LW
343 }
344 break;
8d063cd8 345 case 'P':
463ee0b2 346 taint_not("-P");
8d063cd8 347 preprocess = TRUE;
13281fa4 348 s++;
8d063cd8 349 goto reswitch;
378cc40b 350 case 'S':
463ee0b2 351 taint_not("-S");
378cc40b 352 dosearch = TRUE;
13281fa4 353 s++;
378cc40b 354 goto reswitch;
33b78306
LW
355 case 'x':
356 doextract = TRUE;
13281fa4 357 s++;
33b78306 358 if (*s)
a0d0e21e 359 cddir = savepv(s);
33b78306 360 break;
8d063cd8
LW
361 case '-':
362 argc--,argv++;
363 goto switch_end;
364 case 0:
365 break;
366 default:
463ee0b2 367 croak("Unrecognized switch: -%s",s);
8d063cd8
LW
368 }
369 }
370 switch_end:
45d8adaa 371 scriptname = argv[0];
8d063cd8 372 if (e_fp) {
83025b21 373 if (fflush(e_fp) || ferror(e_fp) || fclose(e_fp))
2304df62 374 croak("Can't write to temp file for -e: %s", Strerror(errno));
8d063cd8 375 argc++,argv--;
45d8adaa 376 scriptname = e_tmpname;
8d063cd8 377 }
79072805
LW
378 else if (scriptname == Nullch) {
379#ifdef MSDOS
380 if ( isatty(fileno(stdin)) )
381 moreswitches("v");
fe14fcc3 382#endif
79072805
LW
383 scriptname = "-";
384 }
fe14fcc3 385
79072805 386 init_perllib();
8d063cd8 387
79072805 388 open_script(scriptname,dosearch,sv);
8d063cd8 389
79072805 390 validate_suid(validarg);
378cc40b 391
79072805
LW
392 if (doextract)
393 find_beginning();
394
748a9306
LW
395 compcv = (CV*)NEWSV(1104,0);
396 sv_upgrade((SV *)compcv, SVt_PVCV);
397
79072805
LW
398 pad = newAV();
399 comppad = pad;
400 av_push(comppad, Nullsv);
401 curpad = AvARRAY(comppad);
93a17b20 402 padname = newAV();
8990e307
LW
403 comppad_name = padname;
404 comppad_name_fill = 0;
405 min_intro_pending = 0;
79072805
LW
406 padix = 0;
407
748a9306
LW
408 comppadlist = newAV();
409 AvREAL_off(comppadlist);
410 av_store(comppadlist, 0, SvREFCNT_inc((SV*)comppad_name));
411 av_store(comppadlist, 1, SvREFCNT_inc((SV*)comppad));
412 CvPADLIST(compcv) = comppadlist;
413
a0d0e21e
LW
414 if (xsinit)
415 (*xsinit)(); /* in case linked C routines want magical variables */
748a9306
LW
416#ifdef VMS
417 init_os_extras();
418#endif
93a17b20 419
93a17b20 420 init_predump_symbols();
8990e307
LW
421 if (!do_undump)
422 init_postdump_symbols(argc,argv,env);
93a17b20 423
79072805
LW
424 init_lexer();
425
426 /* now parse the script */
427
428 error_count = 0;
429 if (yyparse() || error_count) {
430 if (minus_c)
463ee0b2 431 croak("%s had compilation errors.\n", origfilename);
79072805 432 else {
463ee0b2 433 croak("Execution of %s aborted due to compilation errors.\n",
79072805 434 origfilename);
378cc40b 435 }
79072805
LW
436 }
437 curcop->cop_line = 0;
438 curstash = defstash;
439 preprocess = FALSE;
440 if (e_fp) {
441 e_fp = Nullfp;
442 (void)UNLINK(e_tmpname);
378cc40b 443 }
a687059c 444
93a17b20 445 /* now that script is parsed, we can modify record separator */
a687059c 446
93a17b20
LW
447 rs = nrs;
448 rslen = nrslen;
449 rschar = nrschar;
450 rspara = (nrslen == 2);
85e6fe83 451 sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs, rslen);
45d8adaa 452
79072805
LW
453 if (do_undump)
454 my_unexec();
455
8990e307
LW
456 if (dowarn)
457 gv_check(defstash);
458
a0d0e21e
LW
459 LEAVE;
460 FREETMPS;
461 ENTER;
462 restartop = 0;
79072805
LW
463 return 0;
464}
465
466int
467perl_run(sv_interp)
93a17b20 468PerlInterpreter *sv_interp;
79072805
LW
469{
470 if (!(curinterp = sv_interp))
471 return 255;
472 switch (setjmp(top_env)) {
473 case 1:
474 cxstack_ix = -1; /* start context stack again */
475 break;
476 case 2:
477 curstash = defstash;
93a17b20
LW
478 if (endav)
479 calllist(endav);
a0d0e21e 480 FREETMPS;
93a17b20 481 return(statusvalue); /* my_exit() was called */
79072805
LW
482 case 3:
483 if (!restartop) {
484 fprintf(stderr, "panic: restartop\n");
a0d0e21e 485 FREETMPS;
8990e307 486 return 1;
83025b21 487 }
79072805
LW
488 if (stack != mainstack) {
489 dSP;
490 SWITCHSTACK(stack, mainstack);
491 }
492 break;
8d063cd8 493 }
79072805
LW
494
495 if (!restartop) {
496 DEBUG_x(dump_all());
497 DEBUG(fprintf(stderr,"\nEXECUTING...\n\n"));
498
499 if (minus_c) {
500 fprintf(stderr,"%s syntax OK\n", origfilename);
501 my_exit(0);
502 }
a0d0e21e
LW
503 if (perldb && DBsingle)
504 sv_setiv(DBsingle, 1);
45d8adaa 505 }
79072805
LW
506
507 /* do it */
508
509 if (restartop) {
510 op = restartop;
511 restartop = 0;
512 run();
513 }
514 else if (main_start) {
515 op = main_start;
516 run();
517 }
79072805
LW
518
519 my_exit(0);
a0d0e21e 520 return 0;
79072805
LW
521}
522
523void
524my_exit(status)
748a9306 525U32 status;
79072805 526{
a0d0e21e
LW
527 register CONTEXT *cx;
528 I32 gimme;
529 SV **newsp;
530
748a9306 531 statusvalue = FIXSTATUS(status);
a0d0e21e
LW
532 if (cxstack_ix >= 0) {
533 if (cxstack_ix > 0)
534 dounwind(0);
535 POPBLOCK(cx,curpm);
536 LEAVE;
537 }
79072805
LW
538 longjmp(top_env, 2);
539}
540
a0d0e21e
LW
541SV*
542perl_get_sv(name, create)
543char* name;
544I32 create;
545{
546 GV* gv = gv_fetchpv(name, create, SVt_PV);
547 if (gv)
548 return GvSV(gv);
549 return Nullsv;
550}
551
552AV*
553perl_get_av(name, create)
554char* name;
555I32 create;
556{
557 GV* gv = gv_fetchpv(name, create, SVt_PVAV);
558 if (create)
559 return GvAVn(gv);
560 if (gv)
561 return GvAV(gv);
562 return Nullav;
563}
564
565HV*
566perl_get_hv(name, create)
567char* name;
568I32 create;
569{
570 GV* gv = gv_fetchpv(name, create, SVt_PVHV);
571 if (create)
572 return GvHVn(gv);
573 if (gv)
574 return GvHV(gv);
575 return Nullhv;
576}
577
578CV*
579perl_get_cv(name, create)
580char* name;
581I32 create;
582{
583 GV* gv = gv_fetchpv(name, create, SVt_PVCV);
584 if (create && !GvCV(gv))
585 return newSUB(start_subparse(),
586 newSVOP(OP_CONST, 0, newSVpv(name,0)),
587 Nullop);
588 if (gv)
589 return GvCV(gv);
590 return Nullcv;
591}
592
79072805
LW
593/* Be sure to refetch the stack pointer after calling these routines. */
594
a0d0e21e
LW
595I32
596perl_call_argv(subname, flags, argv)
8990e307 597char *subname;
a0d0e21e
LW
598I32 flags; /* See G_* flags in cop.h */
599register char **argv; /* null terminated arg list */
8990e307 600{
a0d0e21e 601 dSP;
8990e307 602
a0d0e21e
LW
603 PUSHMARK(sp);
604 if (argv) {
8990e307 605 while (*argv) {
a0d0e21e 606 XPUSHs(sv_2mortal(newSVpv(*argv,0)));
8990e307
LW
607 argv++;
608 }
a0d0e21e 609 PUTBACK;
8990e307 610 }
a0d0e21e 611 return perl_call_pv(subname, flags);
8990e307
LW
612}
613
a0d0e21e
LW
614I32
615perl_call_pv(subname, flags)
616char *subname; /* name of the subroutine */
617I32 flags; /* See G_* flags in cop.h */
618{
619 return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags);
620}
621
622I32
623perl_call_method(methname, flags)
624char *methname; /* name of the subroutine */
625I32 flags; /* See G_* flags in cop.h */
626{
627 dSP;
628 OP myop;
629 if (!op)
630 op = &myop;
631 XPUSHs(sv_2mortal(newSVpv(methname,0)));
632 PUTBACK;
633 pp_method();
634 return perl_call_sv(*stack_sp--, flags);
635}
636
637/* May be called with any of a CV, a GV, or an SV containing the name. */
638I32
639perl_call_sv(sv, flags)
640SV* sv;
641I32 flags; /* See G_* flags in cop.h */
642{
643 LOGOP myop; /* fake syntax tree node */
644 SV** sp = stack_sp;
645 I32 oldmark = TOPMARK;
646 I32 retval;
647 jmp_buf oldtop;
648 I32 oldscope;
649
650 if (flags & G_DISCARD) {
651 ENTER;
652 SAVETMPS;
653 }
654
655 SAVESPTR(op);
656 op = (OP*)&myop;
657 Zero(op, 1, LOGOP);
658 EXTEND(stack_sp, 1);
659 *++stack_sp = sv;
660 oldscope = scopestack_ix;
661
662 if (!(flags & G_NOARGS))
663 myop.op_flags = OPf_STACKED;
664 myop.op_next = Nullop;
665 myop.op_flags |= OPf_KNOW;
666 if (flags & G_ARRAY)
667 myop.op_flags |= OPf_LIST;
668
669 if (flags & G_EVAL) {
670 Copy(top_env, oldtop, 1, jmp_buf);
671
672 cLOGOP->op_other = op;
673 markstack_ptr--;
674 pp_entertry();
675 markstack_ptr++;
676
677 restart:
678 switch (setjmp(top_env)) {
679 case 0:
680 break;
681 case 1:
748a9306 682#ifdef VMS
a0d0e21e 683 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
748a9306
LW
684#else
685 statusvalue = 1;
686#endif
a0d0e21e
LW
687 /* FALL THROUGH */
688 case 2:
689 /* my_exit() was called */
690 curstash = defstash;
691 FREETMPS;
692 Copy(oldtop, top_env, 1, jmp_buf);
693 if (statusvalue)
694 croak("Callback called exit");
695 my_exit(statusvalue);
696 /* NOTREACHED */
697 case 3:
698 if (restartop) {
699 op = restartop;
700 restartop = 0;
701 goto restart;
702 }
703 stack_sp = stack_base + oldmark;
704 if (flags & G_ARRAY)
705 retval = 0;
706 else {
707 retval = 1;
708 *++stack_sp = &sv_undef;
709 }
710 goto cleanup;
711 }
712 }
713
714 if (op == (OP*)&myop)
715 op = pp_entersub();
716 if (op)
717 run();
718 retval = stack_sp - (stack_base + oldmark);
719 if (flags & G_EVAL)
720 sv_setpv(GvSV(gv_fetchpv("@",TRUE, SVt_PV)),"");
721
722 cleanup:
723 if (flags & G_EVAL) {
724 if (scopestack_ix > oldscope) {
a0a2876f
LW
725 SV **newsp;
726 PMOP *newpm;
727 I32 gimme;
728 register CONTEXT *cx;
729 I32 optype;
730
731 POPBLOCK(cx,newpm);
732 POPEVAL(cx);
733 pop_return();
734 curpm = newpm;
735 LEAVE;
a0d0e21e
LW
736 }
737 Copy(oldtop, top_env, 1, jmp_buf);
738 }
739 if (flags & G_DISCARD) {
740 stack_sp = stack_base + oldmark;
741 retval = 0;
742 FREETMPS;
743 LEAVE;
744 }
745 return retval;
746}
747
748/* Older forms, here grandfathered. */
749
750#ifdef DEPRECATED
751I32
752perl_callargv(subname, spix, gimme, argv)
753char *subname;
754register I32 spix; /* current stack pointer index */
755I32 gimme; /* See G_* flags in cop.h */
756register char **argv; /* null terminated arg list, NULL for no arglist */
757{
758 stack_sp = stack_base + spix;
759 return spix + perl_call_argv(subname, gimme, argv);
760}
761
762I32
763perl_callpv(subname, spix, gimme, hasargs, numargs)
79072805 764char *subname;
a0d0e21e
LW
765I32 spix; /* stack pointer index after args are pushed */
766I32 gimme; /* See G_* flags in cop.h */
8990e307
LW
767I32 hasargs; /* whether to create a @_ array for routine */
768I32 numargs; /* how many args are pushed on the stack */
769{
a0d0e21e
LW
770 stack_sp = stack_base + spix;
771 PUSHMARK(stack_sp - numargs);
772 return spix - numargs + perl_call_sv((SV*)perl_get_cv(subname, TRUE),
773 gimme, hasargs, numargs);
8990e307
LW
774}
775
a0d0e21e
LW
776I32
777perl_callsv(sv, spix, gimme, hasargs, numargs)
8990e307 778SV* sv;
a0d0e21e
LW
779I32 spix; /* stack pointer index after args are pushed */
780I32 gimme; /* See G_* flags in cop.h */
79072805
LW
781I32 hasargs; /* whether to create a @_ array for routine */
782I32 numargs; /* how many args are pushed on the stack */
783{
a0d0e21e
LW
784 stack_sp = stack_base + spix;
785 PUSHMARK(stack_sp - numargs);
786 return spix - numargs + perl_call_sv(sv, gimme, hasargs, numargs);
787}
788#endif
789
790/* Require a module. */
791
792void
793perl_requirepv(pv)
794char* pv;
795{
796 UNOP myop; /* fake syntax tree node */
797 SV* sv;
798 dSP;
79072805
LW
799
800 ENTER;
463ee0b2 801 SAVETMPS;
79072805 802 SAVESPTR(op);
a0d0e21e
LW
803 sv = sv_newmortal();
804 sv_setpv(sv, pv);
79072805 805 op = (OP*)&myop;
a0d0e21e
LW
806 Zero(op, 1, UNOP);
807 XPUSHs(sv);
79072805 808
a0d0e21e 809 myop.op_type = OP_REQUIRE;
79072805 810 myop.op_next = Nullop;
a0d0e21e
LW
811 myop.op_private = 1;
812 myop.op_flags = OPf_KNOW;
79072805 813
a0d0e21e
LW
814 PUTBACK;
815 if (op = pp_require())
463ee0b2 816 run();
a0d0e21e
LW
817 stack_sp--;
818 FREETMPS;
79072805 819 LEAVE;
79072805
LW
820}
821
79072805 822void
79072805
LW
823magicname(sym,name,namlen)
824char *sym;
825char *name;
826I32 namlen;
827{
828 register GV *gv;
829
85e6fe83 830 if (gv = gv_fetchpv(sym,TRUE, SVt_PV))
79072805
LW
831 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
832}
833
748a9306
LW
834#if defined(DOSISH)
835# define PERLLIB_SEP ';'
836#elif defined(VMS)
837# define PERLLIB_SEP '|'
79072805 838#else
748a9306 839# define PERLLIB_SEP ':'
79072805
LW
840#endif
841
842static void
843incpush(p)
844char *p;
845{
846 char *s;
847
848 if (!p)
849 return;
850
851 /* Break at all separators */
852 while (*p) {
853 /* First, skip any consecutive separators */
854 while ( *p == PERLLIB_SEP ) {
855 /* Uncomment the next line for PATH semantics */
a0d0e21e 856 /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
79072805
LW
857 p++;
858 }
93a17b20 859 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
a0d0e21e 860 av_push(GvAVn(incgv), newSVpv(p, (STRLEN)(s - p)));
79072805
LW
861 p = s + 1;
862 } else {
a0d0e21e 863 av_push(GvAVn(incgv), newSVpv(p, 0));
79072805
LW
864 break;
865 }
866 }
867}
868
869/* This routine handles any switches that can be given during run */
870
871char *
872moreswitches(s)
873char *s;
874{
875 I32 numlen;
876
877 switch (*s) {
878 case '0':
879 nrschar = scan_oct(s, 4, &numlen);
a0d0e21e 880 nrs = savepvn("\n",1);
79072805
LW
881 *nrs = nrschar;
882 if (nrschar > 0377) {
883 nrslen = 0;
884 nrs = "";
885 }
886 else if (!nrschar && numlen >= 2) {
887 nrslen = 2;
888 nrs = "\n\n";
889 nrschar = '\n';
890 }
891 return s + numlen;
2304df62
AD
892 case 'F':
893 minus_F = TRUE;
a0d0e21e 894 splitstr = savepv(s + 1);
2304df62
AD
895 s += strlen(s);
896 return s;
79072805
LW
897 case 'a':
898 minus_a = TRUE;
899 s++;
900 return s;
901 case 'c':
902 minus_c = TRUE;
903 s++;
904 return s;
905 case 'd':
463ee0b2 906 taint_not("-d");
a0d0e21e
LW
907 if (!perldb) {
908 perldb = TRUE;
909 init_debugger();
910 }
79072805
LW
911 s++;
912 return s;
913 case 'D':
914#ifdef DEBUGGING
463ee0b2 915 taint_not("-D");
79072805 916 if (isALPHA(s[1])) {
8990e307 917 static char debopts[] = "psltocPmfrxuLHXD";
79072805
LW
918 char *d;
919
93a17b20 920 for (s++; *s && (d = strchr(debopts,*s)); s++)
79072805
LW
921 debug |= 1 << (d - debopts);
922 }
923 else {
924 debug = atoi(s+1);
925 for (s++; isDIGIT(*s); s++) ;
926 }
8990e307 927 debug |= 0x80000000;
79072805
LW
928#else
929 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
a0d0e21e 930 for (s++; isALNUM(*s); s++) ;
79072805
LW
931#endif
932 /*SUPPRESS 530*/
933 return s;
934 case 'i':
935 if (inplace)
936 Safefree(inplace);
a0d0e21e 937 inplace = savepv(s+1);
79072805
LW
938 /*SUPPRESS 530*/
939 for (s = inplace; *s && !isSPACE(*s); s++) ;
940 *s = '\0';
941 break;
942 case 'I':
463ee0b2 943 taint_not("-I");
79072805 944 if (*++s) {
748a9306
LW
945 char *e;
946 for (e = s; *e && !isSPACE(*e); e++) ;
947 av_push(GvAVn(incgv),newSVpv(s,e-s));
948 if (*e)
949 return e;
79072805
LW
950 }
951 else
463ee0b2 952 croak("No space allowed after -I");
79072805
LW
953 break;
954 case 'l':
955 minus_l = TRUE;
956 s++;
a0d0e21e
LW
957 if (ors)
958 Safefree(ors);
79072805 959 if (isDIGIT(*s)) {
a0d0e21e 960 ors = savepv("\n");
79072805
LW
961 orslen = 1;
962 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
963 s += numlen;
964 }
965 else {
a0d0e21e 966 ors = savepvn(nrs,nrslen);
79072805
LW
967 orslen = nrslen;
968 }
969 return s;
970 case 'n':
971 minus_n = TRUE;
972 s++;
973 return s;
974 case 'p':
975 minus_p = TRUE;
976 s++;
977 return s;
978 case 's':
463ee0b2 979 taint_not("-s");
79072805
LW
980 doswitches = TRUE;
981 s++;
982 return s;
463ee0b2
LW
983 case 'T':
984 tainting = TRUE;
985 s++;
986 return s;
79072805
LW
987 case 'u':
988 do_undump = TRUE;
989 s++;
990 return s;
991 case 'U':
992 unsafe = TRUE;
993 s++;
994 return s;
995 case 'v':
a0d0e21e
LW
996 printf("\nThis is perl, version %s\n\n",patchlevel);
997 fputs("\nCopyright 1987-1994, Larry Wall\n",stdout);
79072805
LW
998#ifdef MSDOS
999 fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
1000 stdout);
1001#ifdef OS2
1002 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n",
1003 stdout);
1004#endif
1005#endif
1006#ifdef atarist
1007 fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout);
1008#endif
1009 fputs("\n\
1010Perl may be copied only under the terms of either the Artistic License or the\n\
1011GNU General Public License, which may be found in the Perl 5.0 source kit.\n",stdout);
1012#ifdef MSDOS
1013 usage(origargv[0]);
1014#endif
1015 exit(0);
1016 case 'w':
1017 dowarn = TRUE;
1018 s++;
1019 return s;
a0d0e21e 1020 case '*':
79072805
LW
1021 case ' ':
1022 if (s[1] == '-') /* Additional switches on #! line. */
1023 return s+2;
1024 break;
a0d0e21e 1025 case '-':
79072805
LW
1026 case 0:
1027 case '\n':
1028 case '\t':
1029 break;
a0d0e21e
LW
1030 case 'P':
1031 if (preprocess)
1032 return s+1;
1033 /* FALL THROUGH */
79072805 1034 default:
a0d0e21e 1035 croak("Can't emulate -%.1s on #! line",s);
79072805
LW
1036 }
1037 return Nullch;
1038}
1039
1040/* compliments of Tom Christiansen */
1041
1042/* unexec() can be found in the Gnu emacs distribution */
1043
1044void
1045my_unexec()
1046{
1047#ifdef UNEXEC
1048 int status;
1049 extern int etext;
1050
1051 sprintf (buf, "%s.perldump", origfilename);
1052 sprintf (tokenbuf, "%s/perl", BIN);
1053
1054 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
1055 if (status)
1056 fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
a0d0e21e 1057 exit(status);
79072805
LW
1058#else
1059 ABORT(); /* for use with undump */
1060#endif
1061}
1062
1063static void
1064init_main_stash()
1065{
463ee0b2
LW
1066 GV *gv;
1067 curstash = defstash = newHV();
79072805 1068 curstname = newSVpv("main",4);
adbc6bb1
LW
1069 gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1070 SvREFCNT_dec(GvHV(gv));
1071 GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
463ee0b2 1072 SvREADONLY_on(gv);
a0d0e21e 1073 HvNAME(defstash) = savepv("main");
85e6fe83 1074 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
79072805 1075 SvMULTI_on(incgv);
a0d0e21e 1076 defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
8990e307
LW
1077 curstash = defstash;
1078 compiling.cop_stash = defstash;
adbc6bb1 1079 debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
79072805
LW
1080}
1081
a0d0e21e
LW
1082#ifdef CAN_PROTOTYPE
1083static void
1084open_script(char *scriptname, bool dosearch, SV *sv)
1085#else
79072805
LW
1086static void
1087open_script(scriptname,dosearch,sv)
1088char *scriptname;
1089bool dosearch;
1090SV *sv;
a0d0e21e 1091#endif
79072805
LW
1092{
1093 char *xfound = Nullch;
1094 char *xfailed = Nullch;
1095 register char *s;
1096 I32 len;
1097
93a17b20 1098 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
79072805
LW
1099
1100 bufend = s + strlen(s);
1101 while (*s) {
1102#ifndef DOSISH
1103 s = cpytill(tokenbuf,s,bufend,':',&len);
1104#else
1105#ifdef atarist
1106 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
1107 tokenbuf[len] = '\0';
1108#else
1109 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
1110 tokenbuf[len] = '\0';
1111#endif
1112#endif
1113 if (*s)
1114 s++;
1115#ifndef DOSISH
1116 if (len && tokenbuf[len-1] != '/')
1117#else
1118#ifdef atarist
1119 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
1120#else
1121 if (len && tokenbuf[len-1] != '\\')
1122#endif
1123#endif
1124 (void)strcat(tokenbuf+len,"/");
1125 (void)strcat(tokenbuf+len,scriptname);
1126 DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
a0d0e21e 1127 if (Stat(tokenbuf,&statbuf) < 0) /* not there? */
79072805
LW
1128 continue;
1129 if (S_ISREG(statbuf.st_mode)
1130 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
1131 xfound = tokenbuf; /* bingo! */
1132 break;
1133 }
1134 if (!xfailed)
a0d0e21e 1135 xfailed = savepv(tokenbuf);
79072805
LW
1136 }
1137 if (!xfound)
463ee0b2 1138 croak("Can't execute %s", xfailed ? xfailed : scriptname );
79072805
LW
1139 if (xfailed)
1140 Safefree(xfailed);
1141 scriptname = xfound;
1142 }
1143
a0d0e21e 1144 origfilename = savepv(e_fp ? "-e" : scriptname);
79072805
LW
1145 curcop->cop_filegv = gv_fetchfile(origfilename);
1146 if (strEQ(origfilename,"-"))
1147 scriptname = "";
1148 if (preprocess) {
1149 char *cpp = CPPSTDIN;
1150
1151 if (strEQ(cpp,"cppstdin"))
1152 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
1153 else
1154 sprintf(tokenbuf, "%s", cpp);
1155 sv_catpv(sv,"-I");
fed7345c 1156 sv_catpv(sv,PRIVLIB_EXP);
79072805
LW
1157#ifdef MSDOS
1158 (void)sprintf(buf, "\
1159sed %s -e \"/^[^#]/b\" \
1160 -e \"/^#[ ]*include[ ]/b\" \
1161 -e \"/^#[ ]*define[ ]/b\" \
1162 -e \"/^#[ ]*if[ ]/b\" \
1163 -e \"/^#[ ]*ifdef[ ]/b\" \
1164 -e \"/^#[ ]*ifndef[ ]/b\" \
1165 -e \"/^#[ ]*else/b\" \
1166 -e \"/^#[ ]*elif[ ]/b\" \
1167 -e \"/^#[ ]*undef[ ]/b\" \
1168 -e \"/^#[ ]*endif/b\" \
1169 -e \"s/^#.*//\" \
1170 %s | %s -C %s %s",
1171 (doextract ? "-e \"1,/^#/d\n\"" : ""),
1172#else
1173 (void)sprintf(buf, "\
1174%s %s -e '/^[^#]/b' \
1175 -e '/^#[ ]*include[ ]/b' \
1176 -e '/^#[ ]*define[ ]/b' \
1177 -e '/^#[ ]*if[ ]/b' \
1178 -e '/^#[ ]*ifdef[ ]/b' \
1179 -e '/^#[ ]*ifndef[ ]/b' \
1180 -e '/^#[ ]*else/b' \
1181 -e '/^#[ ]*elif[ ]/b' \
1182 -e '/^#[ ]*undef[ ]/b' \
1183 -e '/^#[ ]*endif/b' \
1184 -e 's/^[ ]*#.*//' \
1185 %s | %s -C %s %s",
1186#ifdef LOC_SED
1187 LOC_SED,
1188#else
1189 "sed",
1190#endif
1191 (doextract ? "-e '1,/^#/d\n'" : ""),
1192#endif
463ee0b2 1193 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
79072805
LW
1194 doextract = FALSE;
1195#ifdef IAMSUID /* actually, this is caught earlier */
1196 if (euid != uid && !euid) { /* if running suidperl */
1197#ifdef HAS_SETEUID
1198 (void)seteuid(uid); /* musn't stay setuid root */
1199#else
1200#ifdef HAS_SETREUID
85e6fe83
LW
1201 (void)setreuid((Uid_t)-1, uid);
1202#else
1203#ifdef HAS_SETRESUID
1204 (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
79072805
LW
1205#else
1206 setuid(uid);
1207#endif
1208#endif
85e6fe83 1209#endif
79072805 1210 if (geteuid() != uid)
463ee0b2 1211 croak("Can't do seteuid!\n");
79072805
LW
1212 }
1213#endif /* IAMSUID */
1214 rsfp = my_popen(buf,"r");
1215 }
1216 else if (!*scriptname) {
463ee0b2 1217 taint_not("program input from stdin");
79072805
LW
1218 rsfp = stdin;
1219 }
1220 else
1221 rsfp = fopen(scriptname,"r");
45d8adaa 1222 if ((FILE*)rsfp == Nullfp) {
13281fa4 1223#ifdef DOSUID
a687059c 1224#ifndef IAMSUID /* in case script is not readable before setuid */
a0d0e21e 1225 if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
13281fa4 1226 statbuf.st_mode & (S_ISUID|S_ISGID)) {
27e2fb84 1227 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1228 execv(buf, origargv); /* try again */
463ee0b2 1229 croak("Can't do setuid\n");
13281fa4
LW
1230 }
1231#endif
1232#endif
463ee0b2 1233 croak("Can't open perl script \"%s\": %s\n",
2304df62 1234 SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
13281fa4 1235 }
79072805 1236}
8d063cd8 1237
79072805
LW
1238static void
1239validate_suid(validarg)
1240char *validarg;
1241{
13281fa4
LW
1242 /* do we need to emulate setuid on scripts? */
1243
1244 /* This code is for those BSD systems that have setuid #! scripts disabled
1245 * in the kernel because of a security problem. Merely defining DOSUID
1246 * in perl will not fix that problem, but if you have disabled setuid
1247 * scripts in the kernel, this will attempt to emulate setuid and setgid
1248 * on scripts that have those now-otherwise-useless bits set. The setuid
27e2fb84
LW
1249 * root version must be called suidperl or sperlN.NNN. If regular perl
1250 * discovers that it has opened a setuid script, it calls suidperl with
1251 * the same argv that it had. If suidperl finds that the script it has
1252 * just opened is NOT setuid root, it sets the effective uid back to the
1253 * uid. We don't just make perl setuid root because that loses the
1254 * effective uid we had before invoking perl, if it was different from the
1255 * uid.
13281fa4
LW
1256 *
1257 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
1258 * be defined in suidperl only. suidperl must be setuid root. The
1259 * Configure script will set this up for you if you want it.
1260 */
a687059c 1261
13281fa4 1262#ifdef DOSUID
a0d0e21e
LW
1263 char *s;
1264
1265 if (Fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
463ee0b2 1266 croak("Can't stat script \"%s\"",origfilename);
13281fa4 1267 if (statbuf.st_mode & (S_ISUID|S_ISGID)) {
79072805 1268 I32 len;
13281fa4 1269
a687059c 1270#ifdef IAMSUID
fe14fcc3 1271#ifndef HAS_SETREUID
a687059c
LW
1272 /* On this access check to make sure the directories are readable,
1273 * there is actually a small window that the user could use to make
1274 * filename point to an accessible directory. So there is a faint
1275 * chance that someone could execute a setuid script down in a
1276 * non-accessible directory. I don't know what to do about that.
1277 * But I don't think it's too important. The manual lies when
1278 * it says access() is useful in setuid programs.
1279 */
463ee0b2
LW
1280 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
1281 croak("Permission denied");
a687059c
LW
1282#else
1283 /* If we can swap euid and uid, then we can determine access rights
1284 * with a simple stat of the file, and then compare device and
1285 * inode to make sure we did stat() on the same file we opened.
1286 * Then we just have to make sure he or she can execute it.
1287 */
1288 {
1289 struct stat tmpstatbuf;
1290
85e6fe83
LW
1291 if (
1292#ifdef HAS_SETREUID
1293 setreuid(euid,uid) < 0
a0d0e21e
LW
1294#else
1295# if HAS_SETRESUID
85e6fe83 1296 setresuid(euid,uid,(Uid_t)-1) < 0
a0d0e21e 1297# endif
85e6fe83
LW
1298#endif
1299 || getuid() != euid || geteuid() != uid)
463ee0b2 1300 croak("Can't swap uid and euid"); /* really paranoid */
a0d0e21e 1301 if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
463ee0b2 1302 croak("Permission denied"); /* testing full pathname here */
a687059c
LW
1303 if (tmpstatbuf.st_dev != statbuf.st_dev ||
1304 tmpstatbuf.st_ino != statbuf.st_ino) {
1305 (void)fclose(rsfp);
79072805 1306 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
a687059c
LW
1307 fprintf(rsfp,
1308"User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
1309(Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
1310 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
1311 statbuf.st_dev, statbuf.st_ino,
463ee0b2 1312 SvPVX(GvSV(curcop->cop_filegv)),
20188a90 1313 statbuf.st_uid, statbuf.st_gid);
79072805 1314 (void)my_pclose(rsfp);
a687059c 1315 }
463ee0b2 1316 croak("Permission denied\n");
a687059c 1317 }
85e6fe83
LW
1318 if (
1319#ifdef HAS_SETREUID
1320 setreuid(uid,euid) < 0
a0d0e21e
LW
1321#else
1322# if defined(HAS_SETRESUID)
85e6fe83 1323 setresuid(uid,euid,(Uid_t)-1) < 0
a0d0e21e 1324# endif
85e6fe83
LW
1325#endif
1326 || getuid() != uid || geteuid() != euid)
463ee0b2 1327 croak("Can't reswap uid and euid");
27e2fb84 1328 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
463ee0b2 1329 croak("Permission denied\n");
a687059c 1330 }
fe14fcc3 1331#endif /* HAS_SETREUID */
a687059c
LW
1332#endif /* IAMSUID */
1333
27e2fb84 1334 if (!S_ISREG(statbuf.st_mode))
463ee0b2 1335 croak("Permission denied");
27e2fb84 1336 if (statbuf.st_mode & S_IWOTH)
463ee0b2 1337 croak("Setuid/gid script is writable by world");
13281fa4 1338 doswitches = FALSE; /* -s is insecure in suid */
79072805 1339 curcop->cop_line++;
13281fa4
LW
1340 if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1341 strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */
463ee0b2 1342 croak("No #! line");
663a0e37
LW
1343 s = tokenbuf+2;
1344 if (*s == ' ') s++;
45d8adaa 1345 while (!isSPACE(*s)) s++;
27e2fb84 1346 if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
463ee0b2 1347 croak("Not a perl script");
a687059c 1348 while (*s == ' ' || *s == '\t') s++;
13281fa4
LW
1349 /*
1350 * #! arg must be what we saw above. They can invoke it by
1351 * mentioning suidperl explicitly, but they may not add any strange
1352 * arguments beyond what #! says if they do invoke suidperl that way.
1353 */
1354 len = strlen(validarg);
1355 if (strEQ(validarg," PHOOEY ") ||
45d8adaa 1356 strnNE(s,validarg,len) || !isSPACE(s[len]))
463ee0b2 1357 croak("Args must match #! line");
a687059c
LW
1358
1359#ifndef IAMSUID
1360 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1361 euid == statbuf.st_uid)
1362 if (!do_undump)
463ee0b2 1363 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
1364FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1365#endif /* IAMSUID */
13281fa4
LW
1366
1367 if (euid) { /* oops, we're not the setuid root perl */
a687059c 1368 (void)fclose(rsfp);
13281fa4 1369#ifndef IAMSUID
27e2fb84 1370 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1371 execv(buf, origargv); /* try again */
13281fa4 1372#endif
463ee0b2 1373 croak("Can't do setuid\n");
13281fa4
LW
1374 }
1375
83025b21 1376 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
fe14fcc3 1377#ifdef HAS_SETEGID
a687059c
LW
1378 (void)setegid(statbuf.st_gid);
1379#else
fe14fcc3 1380#ifdef HAS_SETREGID
85e6fe83
LW
1381 (void)setregid((Gid_t)-1,statbuf.st_gid);
1382#else
1383#ifdef HAS_SETRESGID
1384 (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
a687059c
LW
1385#else
1386 setgid(statbuf.st_gid);
1387#endif
1388#endif
85e6fe83 1389#endif
83025b21 1390 if (getegid() != statbuf.st_gid)
463ee0b2 1391 croak("Can't do setegid!\n");
83025b21 1392 }
a687059c
LW
1393 if (statbuf.st_mode & S_ISUID) {
1394 if (statbuf.st_uid != euid)
fe14fcc3 1395#ifdef HAS_SETEUID
a687059c
LW
1396 (void)seteuid(statbuf.st_uid); /* all that for this */
1397#else
fe14fcc3 1398#ifdef HAS_SETREUID
85e6fe83
LW
1399 (void)setreuid((Uid_t)-1,statbuf.st_uid);
1400#else
1401#ifdef HAS_SETRESUID
1402 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
a687059c
LW
1403#else
1404 setuid(statbuf.st_uid);
1405#endif
1406#endif
85e6fe83 1407#endif
83025b21 1408 if (geteuid() != statbuf.st_uid)
463ee0b2 1409 croak("Can't do seteuid!\n");
a687059c 1410 }
83025b21 1411 else if (uid) { /* oops, mustn't run as root */
fe14fcc3 1412#ifdef HAS_SETEUID
85e6fe83 1413 (void)seteuid((Uid_t)uid);
a687059c 1414#else
fe14fcc3 1415#ifdef HAS_SETREUID
85e6fe83 1416 (void)setreuid((Uid_t)-1,(Uid_t)uid);
a687059c 1417#else
85e6fe83
LW
1418#ifdef HAS_SETRESUID
1419 (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
1420#else
1421 setuid((Uid_t)uid);
1422#endif
a687059c
LW
1423#endif
1424#endif
83025b21 1425 if (geteuid() != uid)
463ee0b2 1426 croak("Can't do seteuid!\n");
83025b21 1427 }
748a9306 1428 init_ids();
27e2fb84 1429 if (!cando(S_IXUSR,TRUE,&statbuf))
463ee0b2 1430 croak("Permission denied\n"); /* they can't do this */
13281fa4
LW
1431 }
1432#ifdef IAMSUID
1433 else if (preprocess)
463ee0b2 1434 croak("-P not allowed for setuid/setgid script\n");
13281fa4 1435 else
463ee0b2 1436 croak("Script is not setuid/setgid in suidperl\n");
13281fa4 1437#endif /* IAMSUID */
a687059c 1438#else /* !DOSUID */
a687059c
LW
1439 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1440#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
a0d0e21e 1441 Fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
a687059c
LW
1442 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1443 ||
1444 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1445 )
1446 if (!do_undump)
463ee0b2 1447 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
1448FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1449#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1450 /* not set-id, must be wrapped */
a687059c 1451 }
13281fa4 1452#endif /* DOSUID */
79072805 1453}
13281fa4 1454
79072805
LW
1455static void
1456find_beginning()
1457{
79072805 1458 register char *s;
33b78306
LW
1459
1460 /* skip forward in input to the real script? */
1461
463ee0b2 1462 taint_not("-x");
33b78306 1463 while (doextract) {
79072805 1464 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
463ee0b2 1465 croak("No Perl script found in input\n");
33b78306
LW
1466 if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1467 ungetc('\n',rsfp); /* to keep line count right */
1468 doextract = FALSE;
1469 if (s = instr(s,"perl -")) {
1470 s += 6;
45d8adaa 1471 /*SUPPRESS 530*/
33b78306
LW
1472 while (s = moreswitches(s)) ;
1473 }
79072805 1474 if (cddir && chdir(cddir) < 0)
463ee0b2 1475 croak("Can't chdir to %s",cddir);
83025b21
LW
1476 }
1477 }
1478}
1479
79072805 1480static void
748a9306 1481init_ids()
352d5a3a 1482{
748a9306
LW
1483 uid = (int)getuid();
1484 euid = (int)geteuid();
1485 gid = (int)getgid();
1486 egid = (int)getegid();
1487#ifdef VMS
1488 uid |= gid << 16;
1489 euid |= egid << 16;
1490#endif
1491 tainting |= (euid != uid || egid != gid);
1492}
79072805 1493
748a9306
LW
1494static void
1495init_debugger()
1496{
79072805 1497 curstash = debstash;
748a9306 1498 dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
79072805 1499 AvREAL_off(dbargs);
a0d0e21e
LW
1500 DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
1501 DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
748a9306
LW
1502 DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
1503 DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
1504 DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
1505 DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
79072805 1506 curstash = defstash;
352d5a3a
LW
1507}
1508
79072805 1509static void
8990e307 1510init_stacks()
79072805
LW
1511{
1512 stack = newAV();
1513 mainstack = stack; /* remember in case we switch stacks */
1514 AvREAL_off(stack); /* not a real array */
a0d0e21e 1515 av_extend(stack,127);
79072805
LW
1516
1517 stack_base = AvARRAY(stack);
1518 stack_sp = stack_base;
8990e307 1519 stack_max = stack_base + 127;
79072805 1520
a0d0e21e 1521 New(54,markstack,64,I32);
79072805
LW
1522 markstack_ptr = markstack;
1523 markstack_max = markstack + 64;
1524
a0d0e21e 1525 New(54,scopestack,32,I32);
79072805
LW
1526 scopestack_ix = 0;
1527 scopestack_max = 32;
1528
1529 New(54,savestack,128,ANY);
1530 savestack_ix = 0;
1531 savestack_max = 128;
1532
1533 New(54,retstack,16,OP*);
1534 retstack_ix = 0;
1535 retstack_max = 16;
8d063cd8 1536
79072805 1537 New(50,cxstack,128,CONTEXT);
8990e307
LW
1538 cxstack_ix = -1;
1539 cxstack_max = 128;
1540
1541 New(50,tmps_stack,128,SV*);
1542 tmps_ix = -1;
1543 tmps_max = 128;
1544
79072805
LW
1545 DEBUG( {
1546 New(51,debname,128,char);
1547 New(52,debdelim,128,char);
1548 } )
378cc40b 1549}
33b78306 1550
a0d0e21e 1551static FILE *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
79072805 1552static void
8990e307
LW
1553init_lexer()
1554{
a0d0e21e 1555 tmpfp = rsfp;
8990e307
LW
1556
1557 lex_start(linestr);
1558 rsfp = tmpfp;
1559 subname = newSVpv("main",4);
1560}
1561
1562static void
79072805 1563init_predump_symbols()
45d8adaa 1564{
93a17b20 1565 GV *tmpgv;
a0d0e21e 1566 GV *othergv;
79072805 1567
85e6fe83 1568 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
79072805 1569
85e6fe83 1570 stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
79072805 1571 SvMULTI_on(stdingv);
a0d0e21e 1572 IoIFP(GvIOp(stdingv)) = stdin;
adbc6bb1 1573 tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
a0d0e21e 1574 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
79072805
LW
1575 SvMULTI_on(tmpgv);
1576
85e6fe83 1577 tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
79072805 1578 SvMULTI_on(tmpgv);
a0d0e21e 1579 IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = stdout;
79072805 1580 defoutgv = tmpgv;
adbc6bb1 1581 tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
a0d0e21e 1582 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
79072805
LW
1583 SvMULTI_on(tmpgv);
1584
a0d0e21e
LW
1585 othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
1586 SvMULTI_on(othergv);
1587 IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = stderr;
adbc6bb1 1588 tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
a0d0e21e 1589 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
79072805 1590 SvMULTI_on(tmpgv);
79072805
LW
1591
1592 statname = NEWSV(66,0); /* last filename we did stat on */
79072805 1593}
33b78306 1594
79072805
LW
1595static void
1596init_postdump_symbols(argc,argv,env)
1597register int argc;
1598register char **argv;
1599register char **env;
33b78306 1600{
79072805
LW
1601 char *s;
1602 SV *sv;
1603 GV* tmpgv;
fe14fcc3 1604
79072805
LW
1605 argc--,argv++; /* skip name of script */
1606 if (doswitches) {
1607 for (; argc > 0 && **argv == '-'; argc--,argv++) {
1608 if (!argv[0][1])
1609 break;
1610 if (argv[0][1] == '-') {
1611 argc--,argv++;
1612 break;
1613 }
93a17b20 1614 if (s = strchr(argv[0], '=')) {
79072805 1615 *s++ = '\0';
85e6fe83 1616 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
79072805
LW
1617 }
1618 else
85e6fe83 1619 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
fe14fcc3 1620 }
79072805
LW
1621 }
1622 toptarget = NEWSV(0,0);
1623 sv_upgrade(toptarget, SVt_PVFM);
1624 sv_setpvn(toptarget, "", 0);
748a9306 1625 bodytarget = NEWSV(0,0);
79072805
LW
1626 sv_upgrade(bodytarget, SVt_PVFM);
1627 sv_setpvn(bodytarget, "", 0);
1628 formtarget = bodytarget;
1629
79072805 1630 tainted = 1;
85e6fe83 1631 if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
79072805
LW
1632 sv_setpv(GvSV(tmpgv),origfilename);
1633 magicname("0", "0", 1);
1634 }
85e6fe83 1635 if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV))
79072805 1636 time(&basetime);
85e6fe83 1637 if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
79072805 1638 sv_setpv(GvSV(tmpgv),origargv[0]);
85e6fe83 1639 if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
79072805
LW
1640 SvMULTI_on(argvgv);
1641 (void)gv_AVadd(argvgv);
1642 av_clear(GvAVn(argvgv));
1643 for (; argc > 0; argc--,argv++) {
a0d0e21e 1644 av_push(GvAVn(argvgv),newSVpv(argv[0],0));
79072805
LW
1645 }
1646 }
85e6fe83 1647 if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
79072805
LW
1648 HV *hv;
1649 SvMULTI_on(envgv);
1650 hv = GvHVn(envgv);
463ee0b2 1651 hv_clear(hv);
a0d0e21e 1652#ifndef VMS /* VMS doesn't have environ array */
8990e307 1653 if (env != environ) {
79072805 1654 environ[0] = Nullch;
8990e307
LW
1655 hv_magic(hv, envgv, 'E');
1656 }
a0d0e21e
LW
1657#endif
1658#ifdef DYNAMIC_ENV_FETCH
1659 HvNAME(hv) = savepv(ENV_HV_NAME);
1660#endif
79072805 1661 for (; *env; env++) {
93a17b20 1662 if (!(s = strchr(*env,'=')))
79072805
LW
1663 continue;
1664 *s++ = '\0';
1665 sv = newSVpv(s--,0);
85e6fe83 1666 sv_magic(sv, sv, 'e', *env, s - *env);
79072805
LW
1667 (void)hv_store(hv, *env, s - *env, sv, 0);
1668 *s = '=';
fe14fcc3 1669 }
f511e57f 1670 hv_magic(hv, envgv, 'E');
79072805 1671 }
79072805 1672 tainted = 0;
85e6fe83 1673 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
79072805
LW
1674 sv_setiv(GvSV(tmpgv),(I32)getpid());
1675
33b78306 1676}
34de22dd 1677
79072805
LW
1678static void
1679init_perllib()
34de22dd 1680{
85e6fe83
LW
1681 char *s;
1682 if (!tainting) {
1683 s = getenv("PERL5LIB");
1684 if (s)
1685 incpush(s);
1686 else
1687 incpush(getenv("PERLLIB"));
1688 }
34de22dd 1689
fed7345c
AD
1690#ifdef ARCHLIB_EXP
1691 incpush(ARCHLIB_EXP);
a0d0e21e 1692#endif
fed7345c
AD
1693#ifndef PRIVLIB_EXP
1694#define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
34de22dd 1695#endif
fed7345c 1696 incpush(PRIVLIB_EXP);
a0d0e21e
LW
1697
1698 av_push(GvAVn(incgv),newSVpv(".",1));
34de22dd 1699}
93a17b20
LW
1700
1701void
1702calllist(list)
1703AV* list;
1704{
93a17b20 1705 jmp_buf oldtop;
a0d0e21e
LW
1706 STRLEN len;
1707 line_t oldline = curcop->cop_line;
93a17b20 1708
93a17b20
LW
1709 Copy(top_env, oldtop, 1, jmp_buf);
1710
8990e307
LW
1711 while (AvFILL(list) >= 0) {
1712 CV *cv = (CV*)av_shift(list);
93a17b20 1713
8990e307 1714 SAVEFREESV(cv);
a0d0e21e 1715
85e6fe83 1716 switch (setjmp(top_env)) {
748a9306
LW
1717 case 0: {
1718 SV* atsv = GvSV(gv_fetchpv("@",TRUE, SVt_PV));
1719 PUSHMARK(stack_sp);
1720 perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
1721 (void)SvPV(atsv, len);
1722 if (len) {
1723 Copy(oldtop, top_env, 1, jmp_buf);
1724 curcop = &compiling;
1725 curcop->cop_line = oldline;
1726 if (list == beginav)
1727 sv_catpv(atsv, "BEGIN failed--compilation aborted");
1728 else
1729 sv_catpv(atsv, "END failed--cleanup aborted");
1730 croak("%s", SvPVX(atsv));
1731 }
a0d0e21e 1732 }
85e6fe83
LW
1733 break;
1734 case 1:
748a9306 1735#ifdef VMS
85e6fe83 1736 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
748a9306
LW
1737#else
1738 statusvalue = 1;
1739#endif
85e6fe83
LW
1740 /* FALL THROUGH */
1741 case 2:
1742 /* my_exit() was called */
1743 curstash = defstash;
1744 if (endav)
1745 calllist(endav);
a0d0e21e
LW
1746 FREETMPS;
1747 Copy(oldtop, top_env, 1, jmp_buf);
1748 curcop = &compiling;
1749 curcop->cop_line = oldline;
85e6fe83
LW
1750 if (statusvalue) {
1751 if (list == beginav)
a0d0e21e 1752 croak("BEGIN failed--compilation aborted");
85e6fe83 1753 else
a0d0e21e 1754 croak("END failed--cleanup aborted");
85e6fe83 1755 }
85e6fe83
LW
1756 my_exit(statusvalue);
1757 /* NOTREACHED */
1758 return;
1759 case 3:
1760 if (!restartop) {
1761 fprintf(stderr, "panic: restartop\n");
a0d0e21e 1762 FREETMPS;
85e6fe83
LW
1763 break;
1764 }
a0d0e21e
LW
1765 Copy(oldtop, top_env, 1, jmp_buf);
1766 curcop = &compiling;
1767 curcop->cop_line = oldline;
1768 longjmp(top_env, 3);
8990e307 1769 }
93a17b20
LW
1770 }
1771
1772 Copy(oldtop, top_env, 1, jmp_buf);
1773}
1774