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