This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
This is my patch patch.1h for perl5.001.
[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 ';'
79072805 836#else
232e078e
AD
837# if defined(VMS)
838# define PERLLIB_SEP '|'
839# else
748a9306 840# define PERLLIB_SEP ':'
232e078e 841# endif
79072805
LW
842#endif
843
844static void
845incpush(p)
846char *p;
847{
848 char *s;
849
850 if (!p)
851 return;
852
853 /* Break at all separators */
854 while (*p) {
855 /* First, skip any consecutive separators */
856 while ( *p == PERLLIB_SEP ) {
857 /* Uncomment the next line for PATH semantics */
a0d0e21e 858 /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
79072805
LW
859 p++;
860 }
93a17b20 861 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
a0d0e21e 862 av_push(GvAVn(incgv), newSVpv(p, (STRLEN)(s - p)));
79072805
LW
863 p = s + 1;
864 } else {
a0d0e21e 865 av_push(GvAVn(incgv), newSVpv(p, 0));
79072805
LW
866 break;
867 }
868 }
869}
870
871/* This routine handles any switches that can be given during run */
872
873char *
874moreswitches(s)
875char *s;
876{
877 I32 numlen;
878
879 switch (*s) {
880 case '0':
881 nrschar = scan_oct(s, 4, &numlen);
a0d0e21e 882 nrs = savepvn("\n",1);
79072805
LW
883 *nrs = nrschar;
884 if (nrschar > 0377) {
885 nrslen = 0;
886 nrs = "";
887 }
888 else if (!nrschar && numlen >= 2) {
889 nrslen = 2;
890 nrs = "\n\n";
891 nrschar = '\n';
892 }
893 return s + numlen;
2304df62
AD
894 case 'F':
895 minus_F = TRUE;
a0d0e21e 896 splitstr = savepv(s + 1);
2304df62
AD
897 s += strlen(s);
898 return s;
79072805
LW
899 case 'a':
900 minus_a = TRUE;
901 s++;
902 return s;
903 case 'c':
904 minus_c = TRUE;
905 s++;
906 return s;
907 case 'd':
463ee0b2 908 taint_not("-d");
a0d0e21e
LW
909 if (!perldb) {
910 perldb = TRUE;
911 init_debugger();
912 }
79072805
LW
913 s++;
914 return s;
915 case 'D':
916#ifdef DEBUGGING
463ee0b2 917 taint_not("-D");
79072805 918 if (isALPHA(s[1])) {
8990e307 919 static char debopts[] = "psltocPmfrxuLHXD";
79072805
LW
920 char *d;
921
93a17b20 922 for (s++; *s && (d = strchr(debopts,*s)); s++)
79072805
LW
923 debug |= 1 << (d - debopts);
924 }
925 else {
926 debug = atoi(s+1);
927 for (s++; isDIGIT(*s); s++) ;
928 }
8990e307 929 debug |= 0x80000000;
79072805
LW
930#else
931 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
a0d0e21e 932 for (s++; isALNUM(*s); s++) ;
79072805
LW
933#endif
934 /*SUPPRESS 530*/
935 return s;
936 case 'i':
937 if (inplace)
938 Safefree(inplace);
a0d0e21e 939 inplace = savepv(s+1);
79072805
LW
940 /*SUPPRESS 530*/
941 for (s = inplace; *s && !isSPACE(*s); s++) ;
942 *s = '\0';
943 break;
944 case 'I':
463ee0b2 945 taint_not("-I");
79072805 946 if (*++s) {
748a9306
LW
947 char *e;
948 for (e = s; *e && !isSPACE(*e); e++) ;
949 av_push(GvAVn(incgv),newSVpv(s,e-s));
950 if (*e)
951 return e;
79072805
LW
952 }
953 else
463ee0b2 954 croak("No space allowed after -I");
79072805
LW
955 break;
956 case 'l':
957 minus_l = TRUE;
958 s++;
a0d0e21e
LW
959 if (ors)
960 Safefree(ors);
79072805 961 if (isDIGIT(*s)) {
a0d0e21e 962 ors = savepv("\n");
79072805
LW
963 orslen = 1;
964 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
965 s += numlen;
966 }
967 else {
a0d0e21e 968 ors = savepvn(nrs,nrslen);
79072805
LW
969 orslen = nrslen;
970 }
971 return s;
972 case 'n':
973 minus_n = TRUE;
974 s++;
975 return s;
976 case 'p':
977 minus_p = TRUE;
978 s++;
979 return s;
980 case 's':
463ee0b2 981 taint_not("-s");
79072805
LW
982 doswitches = TRUE;
983 s++;
984 return s;
463ee0b2
LW
985 case 'T':
986 tainting = TRUE;
987 s++;
988 return s;
79072805
LW
989 case 'u':
990 do_undump = TRUE;
991 s++;
992 return s;
993 case 'U':
994 unsafe = TRUE;
995 s++;
996 return s;
997 case 'v':
a0d0e21e 998 printf("\nThis is perl, version %s\n\n",patchlevel);
f0b7e567 999 fputs("\tUnofficial patchlevel 1e.\n",stdout);
a0d0e21e 1000 fputs("\nCopyright 1987-1994, Larry Wall\n",stdout);
79072805
LW
1001#ifdef MSDOS
1002 fputs("MS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n",
1003 stdout);
1004#ifdef OS2
1005 fputs("OS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n",
1006 stdout);
1007#endif
1008#endif
1009#ifdef atarist
1010 fputs("atariST series port, ++jrb bammi@cadence.com\n", stdout);
1011#endif
1012 fputs("\n\
1013Perl may be copied only under the terms of either the Artistic License or the\n\
1014GNU General Public License, which may be found in the Perl 5.0 source kit.\n",stdout);
1015#ifdef MSDOS
1016 usage(origargv[0]);
1017#endif
1018 exit(0);
1019 case 'w':
1020 dowarn = TRUE;
1021 s++;
1022 return s;
a0d0e21e 1023 case '*':
79072805
LW
1024 case ' ':
1025 if (s[1] == '-') /* Additional switches on #! line. */
1026 return s+2;
1027 break;
a0d0e21e 1028 case '-':
79072805
LW
1029 case 0:
1030 case '\n':
1031 case '\t':
1032 break;
a0d0e21e
LW
1033 case 'P':
1034 if (preprocess)
1035 return s+1;
1036 /* FALL THROUGH */
79072805 1037 default:
a0d0e21e 1038 croak("Can't emulate -%.1s on #! line",s);
79072805
LW
1039 }
1040 return Nullch;
1041}
1042
1043/* compliments of Tom Christiansen */
1044
1045/* unexec() can be found in the Gnu emacs distribution */
1046
1047void
1048my_unexec()
1049{
1050#ifdef UNEXEC
1051 int status;
1052 extern int etext;
1053
1054 sprintf (buf, "%s.perldump", origfilename);
1055 sprintf (tokenbuf, "%s/perl", BIN);
1056
1057 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
1058 if (status)
1059 fprintf(stderr, "unexec of %s into %s failed!\n", tokenbuf, buf);
a0d0e21e 1060 exit(status);
79072805
LW
1061#else
1062 ABORT(); /* for use with undump */
1063#endif
1064}
1065
1066static void
1067init_main_stash()
1068{
463ee0b2
LW
1069 GV *gv;
1070 curstash = defstash = newHV();
79072805 1071 curstname = newSVpv("main",4);
adbc6bb1
LW
1072 gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1073 SvREFCNT_dec(GvHV(gv));
1074 GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
463ee0b2 1075 SvREADONLY_on(gv);
a0d0e21e 1076 HvNAME(defstash) = savepv("main");
85e6fe83 1077 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
79072805 1078 SvMULTI_on(incgv);
a0d0e21e 1079 defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
8990e307
LW
1080 curstash = defstash;
1081 compiling.cop_stash = defstash;
adbc6bb1 1082 debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
79072805
LW
1083}
1084
a0d0e21e
LW
1085#ifdef CAN_PROTOTYPE
1086static void
1087open_script(char *scriptname, bool dosearch, SV *sv)
1088#else
79072805
LW
1089static void
1090open_script(scriptname,dosearch,sv)
1091char *scriptname;
1092bool dosearch;
1093SV *sv;
a0d0e21e 1094#endif
79072805
LW
1095{
1096 char *xfound = Nullch;
1097 char *xfailed = Nullch;
1098 register char *s;
1099 I32 len;
1100
93a17b20 1101 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
79072805
LW
1102
1103 bufend = s + strlen(s);
1104 while (*s) {
1105#ifndef DOSISH
1106 s = cpytill(tokenbuf,s,bufend,':',&len);
1107#else
1108#ifdef atarist
1109 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
1110 tokenbuf[len] = '\0';
1111#else
1112 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
1113 tokenbuf[len] = '\0';
1114#endif
1115#endif
1116 if (*s)
1117 s++;
1118#ifndef DOSISH
1119 if (len && tokenbuf[len-1] != '/')
1120#else
1121#ifdef atarist
1122 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
1123#else
1124 if (len && tokenbuf[len-1] != '\\')
1125#endif
1126#endif
1127 (void)strcat(tokenbuf+len,"/");
1128 (void)strcat(tokenbuf+len,scriptname);
1129 DEBUG_p(fprintf(stderr,"Looking for %s\n",tokenbuf));
a0d0e21e 1130 if (Stat(tokenbuf,&statbuf) < 0) /* not there? */
79072805
LW
1131 continue;
1132 if (S_ISREG(statbuf.st_mode)
1133 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
1134 xfound = tokenbuf; /* bingo! */
1135 break;
1136 }
1137 if (!xfailed)
a0d0e21e 1138 xfailed = savepv(tokenbuf);
79072805
LW
1139 }
1140 if (!xfound)
463ee0b2 1141 croak("Can't execute %s", xfailed ? xfailed : scriptname );
79072805
LW
1142 if (xfailed)
1143 Safefree(xfailed);
1144 scriptname = xfound;
1145 }
1146
a0d0e21e 1147 origfilename = savepv(e_fp ? "-e" : scriptname);
79072805
LW
1148 curcop->cop_filegv = gv_fetchfile(origfilename);
1149 if (strEQ(origfilename,"-"))
1150 scriptname = "";
1151 if (preprocess) {
1152 char *cpp = CPPSTDIN;
1153
1154 if (strEQ(cpp,"cppstdin"))
1155 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
1156 else
1157 sprintf(tokenbuf, "%s", cpp);
1158 sv_catpv(sv,"-I");
fed7345c 1159 sv_catpv(sv,PRIVLIB_EXP);
79072805
LW
1160#ifdef MSDOS
1161 (void)sprintf(buf, "\
1162sed %s -e \"/^[^#]/b\" \
1163 -e \"/^#[ ]*include[ ]/b\" \
1164 -e \"/^#[ ]*define[ ]/b\" \
1165 -e \"/^#[ ]*if[ ]/b\" \
1166 -e \"/^#[ ]*ifdef[ ]/b\" \
1167 -e \"/^#[ ]*ifndef[ ]/b\" \
1168 -e \"/^#[ ]*else/b\" \
1169 -e \"/^#[ ]*elif[ ]/b\" \
1170 -e \"/^#[ ]*undef[ ]/b\" \
1171 -e \"/^#[ ]*endif/b\" \
1172 -e \"s/^#.*//\" \
1173 %s | %s -C %s %s",
1174 (doextract ? "-e \"1,/^#/d\n\"" : ""),
1175#else
1176 (void)sprintf(buf, "\
1177%s %s -e '/^[^#]/b' \
1178 -e '/^#[ ]*include[ ]/b' \
1179 -e '/^#[ ]*define[ ]/b' \
1180 -e '/^#[ ]*if[ ]/b' \
1181 -e '/^#[ ]*ifdef[ ]/b' \
1182 -e '/^#[ ]*ifndef[ ]/b' \
1183 -e '/^#[ ]*else/b' \
1184 -e '/^#[ ]*elif[ ]/b' \
1185 -e '/^#[ ]*undef[ ]/b' \
1186 -e '/^#[ ]*endif/b' \
1187 -e 's/^[ ]*#.*//' \
1188 %s | %s -C %s %s",
1189#ifdef LOC_SED
1190 LOC_SED,
1191#else
1192 "sed",
1193#endif
1194 (doextract ? "-e '1,/^#/d\n'" : ""),
1195#endif
463ee0b2 1196 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
79072805
LW
1197 doextract = FALSE;
1198#ifdef IAMSUID /* actually, this is caught earlier */
1199 if (euid != uid && !euid) { /* if running suidperl */
1200#ifdef HAS_SETEUID
1201 (void)seteuid(uid); /* musn't stay setuid root */
1202#else
1203#ifdef HAS_SETREUID
85e6fe83
LW
1204 (void)setreuid((Uid_t)-1, uid);
1205#else
1206#ifdef HAS_SETRESUID
1207 (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
79072805
LW
1208#else
1209 setuid(uid);
1210#endif
1211#endif
85e6fe83 1212#endif
79072805 1213 if (geteuid() != uid)
463ee0b2 1214 croak("Can't do seteuid!\n");
79072805
LW
1215 }
1216#endif /* IAMSUID */
1217 rsfp = my_popen(buf,"r");
1218 }
1219 else if (!*scriptname) {
463ee0b2 1220 taint_not("program input from stdin");
79072805
LW
1221 rsfp = stdin;
1222 }
1223 else
1224 rsfp = fopen(scriptname,"r");
45d8adaa 1225 if ((FILE*)rsfp == Nullfp) {
13281fa4 1226#ifdef DOSUID
a687059c 1227#ifndef IAMSUID /* in case script is not readable before setuid */
a0d0e21e 1228 if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
13281fa4 1229 statbuf.st_mode & (S_ISUID|S_ISGID)) {
27e2fb84 1230 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1231 execv(buf, origargv); /* try again */
463ee0b2 1232 croak("Can't do setuid\n");
13281fa4
LW
1233 }
1234#endif
1235#endif
463ee0b2 1236 croak("Can't open perl script \"%s\": %s\n",
2304df62 1237 SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
13281fa4 1238 }
79072805 1239}
8d063cd8 1240
79072805
LW
1241static void
1242validate_suid(validarg)
1243char *validarg;
1244{
13281fa4
LW
1245 /* do we need to emulate setuid on scripts? */
1246
1247 /* This code is for those BSD systems that have setuid #! scripts disabled
1248 * in the kernel because of a security problem. Merely defining DOSUID
1249 * in perl will not fix that problem, but if you have disabled setuid
1250 * scripts in the kernel, this will attempt to emulate setuid and setgid
1251 * on scripts that have those now-otherwise-useless bits set. The setuid
27e2fb84
LW
1252 * root version must be called suidperl or sperlN.NNN. If regular perl
1253 * discovers that it has opened a setuid script, it calls suidperl with
1254 * the same argv that it had. If suidperl finds that the script it has
1255 * just opened is NOT setuid root, it sets the effective uid back to the
1256 * uid. We don't just make perl setuid root because that loses the
1257 * effective uid we had before invoking perl, if it was different from the
1258 * uid.
13281fa4
LW
1259 *
1260 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
1261 * be defined in suidperl only. suidperl must be setuid root. The
1262 * Configure script will set this up for you if you want it.
1263 */
a687059c 1264
13281fa4 1265#ifdef DOSUID
a0d0e21e
LW
1266 char *s;
1267
1268 if (Fstat(fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
463ee0b2 1269 croak("Can't stat script \"%s\"",origfilename);
13281fa4 1270 if (statbuf.st_mode & (S_ISUID|S_ISGID)) {
79072805 1271 I32 len;
13281fa4 1272
a687059c 1273#ifdef IAMSUID
fe14fcc3 1274#ifndef HAS_SETREUID
a687059c
LW
1275 /* On this access check to make sure the directories are readable,
1276 * there is actually a small window that the user could use to make
1277 * filename point to an accessible directory. So there is a faint
1278 * chance that someone could execute a setuid script down in a
1279 * non-accessible directory. I don't know what to do about that.
1280 * But I don't think it's too important. The manual lies when
1281 * it says access() is useful in setuid programs.
1282 */
463ee0b2
LW
1283 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
1284 croak("Permission denied");
a687059c
LW
1285#else
1286 /* If we can swap euid and uid, then we can determine access rights
1287 * with a simple stat of the file, and then compare device and
1288 * inode to make sure we did stat() on the same file we opened.
1289 * Then we just have to make sure he or she can execute it.
1290 */
1291 {
1292 struct stat tmpstatbuf;
1293
85e6fe83
LW
1294 if (
1295#ifdef HAS_SETREUID
1296 setreuid(euid,uid) < 0
a0d0e21e
LW
1297#else
1298# if HAS_SETRESUID
85e6fe83 1299 setresuid(euid,uid,(Uid_t)-1) < 0
a0d0e21e 1300# endif
85e6fe83
LW
1301#endif
1302 || getuid() != euid || geteuid() != uid)
463ee0b2 1303 croak("Can't swap uid and euid"); /* really paranoid */
a0d0e21e 1304 if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
463ee0b2 1305 croak("Permission denied"); /* testing full pathname here */
a687059c
LW
1306 if (tmpstatbuf.st_dev != statbuf.st_dev ||
1307 tmpstatbuf.st_ino != statbuf.st_ino) {
1308 (void)fclose(rsfp);
79072805 1309 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
a687059c
LW
1310 fprintf(rsfp,
1311"User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
1312(Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
1313 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
1314 statbuf.st_dev, statbuf.st_ino,
463ee0b2 1315 SvPVX(GvSV(curcop->cop_filegv)),
20188a90 1316 statbuf.st_uid, statbuf.st_gid);
79072805 1317 (void)my_pclose(rsfp);
a687059c 1318 }
463ee0b2 1319 croak("Permission denied\n");
a687059c 1320 }
85e6fe83
LW
1321 if (
1322#ifdef HAS_SETREUID
1323 setreuid(uid,euid) < 0
a0d0e21e
LW
1324#else
1325# if defined(HAS_SETRESUID)
85e6fe83 1326 setresuid(uid,euid,(Uid_t)-1) < 0
a0d0e21e 1327# endif
85e6fe83
LW
1328#endif
1329 || getuid() != uid || geteuid() != euid)
463ee0b2 1330 croak("Can't reswap uid and euid");
27e2fb84 1331 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
463ee0b2 1332 croak("Permission denied\n");
a687059c 1333 }
fe14fcc3 1334#endif /* HAS_SETREUID */
a687059c
LW
1335#endif /* IAMSUID */
1336
27e2fb84 1337 if (!S_ISREG(statbuf.st_mode))
463ee0b2 1338 croak("Permission denied");
27e2fb84 1339 if (statbuf.st_mode & S_IWOTH)
463ee0b2 1340 croak("Setuid/gid script is writable by world");
13281fa4 1341 doswitches = FALSE; /* -s is insecure in suid */
79072805 1342 curcop->cop_line++;
13281fa4
LW
1343 if (fgets(tokenbuf,sizeof tokenbuf, rsfp) == Nullch ||
1344 strnNE(tokenbuf,"#!",2) ) /* required even on Sys V */
463ee0b2 1345 croak("No #! line");
663a0e37
LW
1346 s = tokenbuf+2;
1347 if (*s == ' ') s++;
45d8adaa 1348 while (!isSPACE(*s)) s++;
27e2fb84 1349 if (strnNE(s-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
463ee0b2 1350 croak("Not a perl script");
a687059c 1351 while (*s == ' ' || *s == '\t') s++;
13281fa4
LW
1352 /*
1353 * #! arg must be what we saw above. They can invoke it by
1354 * mentioning suidperl explicitly, but they may not add any strange
1355 * arguments beyond what #! says if they do invoke suidperl that way.
1356 */
1357 len = strlen(validarg);
1358 if (strEQ(validarg," PHOOEY ") ||
45d8adaa 1359 strnNE(s,validarg,len) || !isSPACE(s[len]))
463ee0b2 1360 croak("Args must match #! line");
a687059c
LW
1361
1362#ifndef IAMSUID
1363 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1364 euid == statbuf.st_uid)
1365 if (!do_undump)
463ee0b2 1366 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
1367FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1368#endif /* IAMSUID */
13281fa4
LW
1369
1370 if (euid) { /* oops, we're not the setuid root perl */
a687059c 1371 (void)fclose(rsfp);
13281fa4 1372#ifndef IAMSUID
27e2fb84 1373 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1374 execv(buf, origargv); /* try again */
13281fa4 1375#endif
463ee0b2 1376 croak("Can't do setuid\n");
13281fa4
LW
1377 }
1378
83025b21 1379 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
fe14fcc3 1380#ifdef HAS_SETEGID
a687059c
LW
1381 (void)setegid(statbuf.st_gid);
1382#else
fe14fcc3 1383#ifdef HAS_SETREGID
85e6fe83
LW
1384 (void)setregid((Gid_t)-1,statbuf.st_gid);
1385#else
1386#ifdef HAS_SETRESGID
1387 (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
a687059c
LW
1388#else
1389 setgid(statbuf.st_gid);
1390#endif
1391#endif
85e6fe83 1392#endif
83025b21 1393 if (getegid() != statbuf.st_gid)
463ee0b2 1394 croak("Can't do setegid!\n");
83025b21 1395 }
a687059c
LW
1396 if (statbuf.st_mode & S_ISUID) {
1397 if (statbuf.st_uid != euid)
fe14fcc3 1398#ifdef HAS_SETEUID
a687059c
LW
1399 (void)seteuid(statbuf.st_uid); /* all that for this */
1400#else
fe14fcc3 1401#ifdef HAS_SETREUID
85e6fe83
LW
1402 (void)setreuid((Uid_t)-1,statbuf.st_uid);
1403#else
1404#ifdef HAS_SETRESUID
1405 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
a687059c
LW
1406#else
1407 setuid(statbuf.st_uid);
1408#endif
1409#endif
85e6fe83 1410#endif
83025b21 1411 if (geteuid() != statbuf.st_uid)
463ee0b2 1412 croak("Can't do seteuid!\n");
a687059c 1413 }
83025b21 1414 else if (uid) { /* oops, mustn't run as root */
fe14fcc3 1415#ifdef HAS_SETEUID
85e6fe83 1416 (void)seteuid((Uid_t)uid);
a687059c 1417#else
fe14fcc3 1418#ifdef HAS_SETREUID
85e6fe83 1419 (void)setreuid((Uid_t)-1,(Uid_t)uid);
a687059c 1420#else
85e6fe83
LW
1421#ifdef HAS_SETRESUID
1422 (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
1423#else
1424 setuid((Uid_t)uid);
1425#endif
a687059c
LW
1426#endif
1427#endif
83025b21 1428 if (geteuid() != uid)
463ee0b2 1429 croak("Can't do seteuid!\n");
83025b21 1430 }
748a9306 1431 init_ids();
27e2fb84 1432 if (!cando(S_IXUSR,TRUE,&statbuf))
463ee0b2 1433 croak("Permission denied\n"); /* they can't do this */
13281fa4
LW
1434 }
1435#ifdef IAMSUID
1436 else if (preprocess)
463ee0b2 1437 croak("-P not allowed for setuid/setgid script\n");
13281fa4 1438 else
463ee0b2 1439 croak("Script is not setuid/setgid in suidperl\n");
13281fa4 1440#endif /* IAMSUID */
a687059c 1441#else /* !DOSUID */
a687059c
LW
1442 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1443#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
a0d0e21e 1444 Fstat(fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
a687059c
LW
1445 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1446 ||
1447 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1448 )
1449 if (!do_undump)
463ee0b2 1450 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c
LW
1451FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1452#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1453 /* not set-id, must be wrapped */
a687059c 1454 }
13281fa4 1455#endif /* DOSUID */
79072805 1456}
13281fa4 1457
79072805
LW
1458static void
1459find_beginning()
1460{
79072805 1461 register char *s;
33b78306
LW
1462
1463 /* skip forward in input to the real script? */
1464
463ee0b2 1465 taint_not("-x");
33b78306 1466 while (doextract) {
79072805 1467 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
463ee0b2 1468 croak("No Perl script found in input\n");
33b78306
LW
1469 if (*s == '#' && s[1] == '!' && instr(s,"perl")) {
1470 ungetc('\n',rsfp); /* to keep line count right */
1471 doextract = FALSE;
1472 if (s = instr(s,"perl -")) {
1473 s += 6;
45d8adaa 1474 /*SUPPRESS 530*/
33b78306
LW
1475 while (s = moreswitches(s)) ;
1476 }
79072805 1477 if (cddir && chdir(cddir) < 0)
463ee0b2 1478 croak("Can't chdir to %s",cddir);
83025b21
LW
1479 }
1480 }
1481}
1482
79072805 1483static void
748a9306 1484init_ids()
352d5a3a 1485{
748a9306
LW
1486 uid = (int)getuid();
1487 euid = (int)geteuid();
1488 gid = (int)getgid();
1489 egid = (int)getegid();
1490#ifdef VMS
1491 uid |= gid << 16;
1492 euid |= egid << 16;
1493#endif
1494 tainting |= (euid != uid || egid != gid);
1495}
79072805 1496
748a9306
LW
1497static void
1498init_debugger()
1499{
79072805 1500 curstash = debstash;
748a9306 1501 dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
79072805 1502 AvREAL_off(dbargs);
a0d0e21e
LW
1503 DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
1504 DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
748a9306
LW
1505 DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
1506 DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
1507 DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
1508 DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
79072805 1509 curstash = defstash;
352d5a3a
LW
1510}
1511
79072805 1512static void
8990e307 1513init_stacks()
79072805
LW
1514{
1515 stack = newAV();
1516 mainstack = stack; /* remember in case we switch stacks */
1517 AvREAL_off(stack); /* not a real array */
a0d0e21e 1518 av_extend(stack,127);
79072805
LW
1519
1520 stack_base = AvARRAY(stack);
1521 stack_sp = stack_base;
8990e307 1522 stack_max = stack_base + 127;
79072805 1523
a0d0e21e 1524 New(54,markstack,64,I32);
79072805
LW
1525 markstack_ptr = markstack;
1526 markstack_max = markstack + 64;
1527
a0d0e21e 1528 New(54,scopestack,32,I32);
79072805
LW
1529 scopestack_ix = 0;
1530 scopestack_max = 32;
1531
1532 New(54,savestack,128,ANY);
1533 savestack_ix = 0;
1534 savestack_max = 128;
1535
1536 New(54,retstack,16,OP*);
1537 retstack_ix = 0;
1538 retstack_max = 16;
8d063cd8 1539
79072805 1540 New(50,cxstack,128,CONTEXT);
8990e307
LW
1541 cxstack_ix = -1;
1542 cxstack_max = 128;
1543
1544 New(50,tmps_stack,128,SV*);
1545 tmps_ix = -1;
1546 tmps_max = 128;
1547
79072805
LW
1548 DEBUG( {
1549 New(51,debname,128,char);
1550 New(52,debdelim,128,char);
1551 } )
378cc40b 1552}
33b78306 1553
a0d0e21e 1554static FILE *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
79072805 1555static void
8990e307
LW
1556init_lexer()
1557{
a0d0e21e 1558 tmpfp = rsfp;
8990e307
LW
1559
1560 lex_start(linestr);
1561 rsfp = tmpfp;
1562 subname = newSVpv("main",4);
1563}
1564
1565static void
79072805 1566init_predump_symbols()
45d8adaa 1567{
93a17b20 1568 GV *tmpgv;
a0d0e21e 1569 GV *othergv;
79072805 1570
85e6fe83 1571 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
79072805 1572
85e6fe83 1573 stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
79072805 1574 SvMULTI_on(stdingv);
a0d0e21e 1575 IoIFP(GvIOp(stdingv)) = stdin;
adbc6bb1 1576 tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
a0d0e21e 1577 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
79072805
LW
1578 SvMULTI_on(tmpgv);
1579
85e6fe83 1580 tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
79072805 1581 SvMULTI_on(tmpgv);
a0d0e21e 1582 IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = stdout;
79072805 1583 defoutgv = tmpgv;
adbc6bb1 1584 tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
a0d0e21e 1585 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
79072805
LW
1586 SvMULTI_on(tmpgv);
1587
a0d0e21e
LW
1588 othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
1589 SvMULTI_on(othergv);
1590 IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = stderr;
adbc6bb1 1591 tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
a0d0e21e 1592 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
79072805 1593 SvMULTI_on(tmpgv);
79072805
LW
1594
1595 statname = NEWSV(66,0); /* last filename we did stat on */
79072805 1596}
33b78306 1597
79072805
LW
1598static void
1599init_postdump_symbols(argc,argv,env)
1600register int argc;
1601register char **argv;
1602register char **env;
33b78306 1603{
79072805
LW
1604 char *s;
1605 SV *sv;
1606 GV* tmpgv;
fe14fcc3 1607
79072805
LW
1608 argc--,argv++; /* skip name of script */
1609 if (doswitches) {
1610 for (; argc > 0 && **argv == '-'; argc--,argv++) {
1611 if (!argv[0][1])
1612 break;
1613 if (argv[0][1] == '-') {
1614 argc--,argv++;
1615 break;
1616 }
93a17b20 1617 if (s = strchr(argv[0], '=')) {
79072805 1618 *s++ = '\0';
85e6fe83 1619 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
79072805
LW
1620 }
1621 else
85e6fe83 1622 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
fe14fcc3 1623 }
79072805
LW
1624 }
1625 toptarget = NEWSV(0,0);
1626 sv_upgrade(toptarget, SVt_PVFM);
1627 sv_setpvn(toptarget, "", 0);
748a9306 1628 bodytarget = NEWSV(0,0);
79072805
LW
1629 sv_upgrade(bodytarget, SVt_PVFM);
1630 sv_setpvn(bodytarget, "", 0);
1631 formtarget = bodytarget;
1632
79072805 1633 tainted = 1;
85e6fe83 1634 if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
79072805
LW
1635 sv_setpv(GvSV(tmpgv),origfilename);
1636 magicname("0", "0", 1);
1637 }
85e6fe83 1638 if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV))
79072805 1639 time(&basetime);
85e6fe83 1640 if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
79072805 1641 sv_setpv(GvSV(tmpgv),origargv[0]);
85e6fe83 1642 if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
79072805
LW
1643 SvMULTI_on(argvgv);
1644 (void)gv_AVadd(argvgv);
1645 av_clear(GvAVn(argvgv));
1646 for (; argc > 0; argc--,argv++) {
a0d0e21e 1647 av_push(GvAVn(argvgv),newSVpv(argv[0],0));
79072805
LW
1648 }
1649 }
85e6fe83 1650 if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
79072805
LW
1651 HV *hv;
1652 SvMULTI_on(envgv);
1653 hv = GvHVn(envgv);
463ee0b2 1654 hv_clear(hv);
a0d0e21e 1655#ifndef VMS /* VMS doesn't have environ array */
8990e307 1656 if (env != environ) {
79072805 1657 environ[0] = Nullch;
8990e307
LW
1658 hv_magic(hv, envgv, 'E');
1659 }
a0d0e21e
LW
1660#endif
1661#ifdef DYNAMIC_ENV_FETCH
1662 HvNAME(hv) = savepv(ENV_HV_NAME);
1663#endif
79072805 1664 for (; *env; env++) {
93a17b20 1665 if (!(s = strchr(*env,'=')))
79072805
LW
1666 continue;
1667 *s++ = '\0';
1668 sv = newSVpv(s--,0);
85e6fe83 1669 sv_magic(sv, sv, 'e', *env, s - *env);
79072805
LW
1670 (void)hv_store(hv, *env, s - *env, sv, 0);
1671 *s = '=';
fe14fcc3 1672 }
f511e57f 1673 hv_magic(hv, envgv, 'E');
79072805 1674 }
79072805 1675 tainted = 0;
85e6fe83 1676 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
79072805
LW
1677 sv_setiv(GvSV(tmpgv),(I32)getpid());
1678
33b78306 1679}
34de22dd 1680
79072805
LW
1681static void
1682init_perllib()
34de22dd 1683{
85e6fe83
LW
1684 char *s;
1685 if (!tainting) {
1686 s = getenv("PERL5LIB");
1687 if (s)
1688 incpush(s);
1689 else
1690 incpush(getenv("PERLLIB"));
1691 }
34de22dd 1692
fed7345c
AD
1693#ifdef ARCHLIB_EXP
1694 incpush(ARCHLIB_EXP);
a0d0e21e 1695#endif
fed7345c
AD
1696#ifndef PRIVLIB_EXP
1697#define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
34de22dd 1698#endif
fed7345c 1699 incpush(PRIVLIB_EXP);
a0d0e21e
LW
1700
1701 av_push(GvAVn(incgv),newSVpv(".",1));
34de22dd 1702}
93a17b20
LW
1703
1704void
1705calllist(list)
1706AV* list;
1707{
93a17b20 1708 jmp_buf oldtop;
a0d0e21e
LW
1709 STRLEN len;
1710 line_t oldline = curcop->cop_line;
93a17b20 1711
93a17b20
LW
1712 Copy(top_env, oldtop, 1, jmp_buf);
1713
8990e307
LW
1714 while (AvFILL(list) >= 0) {
1715 CV *cv = (CV*)av_shift(list);
93a17b20 1716
8990e307 1717 SAVEFREESV(cv);
a0d0e21e 1718
85e6fe83 1719 switch (setjmp(top_env)) {
748a9306
LW
1720 case 0: {
1721 SV* atsv = GvSV(gv_fetchpv("@",TRUE, SVt_PV));
1722 PUSHMARK(stack_sp);
1723 perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
1724 (void)SvPV(atsv, len);
1725 if (len) {
1726 Copy(oldtop, top_env, 1, jmp_buf);
1727 curcop = &compiling;
1728 curcop->cop_line = oldline;
1729 if (list == beginav)
1730 sv_catpv(atsv, "BEGIN failed--compilation aborted");
1731 else
1732 sv_catpv(atsv, "END failed--cleanup aborted");
1733 croak("%s", SvPVX(atsv));
1734 }
a0d0e21e 1735 }
85e6fe83
LW
1736 break;
1737 case 1:
748a9306 1738#ifdef VMS
85e6fe83 1739 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
748a9306
LW
1740#else
1741 statusvalue = 1;
1742#endif
85e6fe83
LW
1743 /* FALL THROUGH */
1744 case 2:
1745 /* my_exit() was called */
1746 curstash = defstash;
1747 if (endav)
1748 calllist(endav);
a0d0e21e
LW
1749 FREETMPS;
1750 Copy(oldtop, top_env, 1, jmp_buf);
1751 curcop = &compiling;
1752 curcop->cop_line = oldline;
85e6fe83
LW
1753 if (statusvalue) {
1754 if (list == beginav)
a0d0e21e 1755 croak("BEGIN failed--compilation aborted");
85e6fe83 1756 else
a0d0e21e 1757 croak("END failed--cleanup aborted");
85e6fe83 1758 }
85e6fe83
LW
1759 my_exit(statusvalue);
1760 /* NOTREACHED */
1761 return;
1762 case 3:
1763 if (!restartop) {
1764 fprintf(stderr, "panic: restartop\n");
a0d0e21e 1765 FREETMPS;
85e6fe83
LW
1766 break;
1767 }
a0d0e21e
LW
1768 Copy(oldtop, top_env, 1, jmp_buf);
1769 curcop = &compiling;
1770 curcop->cop_line = oldline;
1771 longjmp(top_env, 3);
8990e307 1772 }
93a17b20
LW
1773 }
1774
1775 Copy(oldtop, top_env, 1, jmp_buf);
1776}
1777