Fix regex matching of chars with high bit set
[p5sagit/p5-mst-13.2.git] / perl.c
CommitLineData
a0d0e21e 1/* perl.c
2 *
1a30305b 3 * Copyright (c) 1987-1996 Larry Wall
a687059c 4 *
352d5a3a 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 8 */
9
a0d0e21e 10/*
11 * "A ship then new they built for him/of mithril and of elven glass" --Bilbo
12 */
45d8adaa 13
378cc40b 14#include "EXTERN.h"
15#include "perl.h"
a687059c 16#include "patchlevel.h"
378cc40b 17
df5cef82 18/* XXX If this causes problems, set i_unistd=undef in the hint file. */
a0d0e21e 19#ifdef I_UNISTD
20#include <unistd.h>
21#endif
a0d0e21e 22
4633a7c4 23dEXT char rcsid[] = "perl.c\nPatch level: ###\n";
463ee0b2 24
a687059c 25#ifdef IAMSUID
26#ifndef DOSUID
27#define DOSUID
28#endif
29#endif
378cc40b 30
a687059c 31#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
32#ifdef DOSUID
33#undef DOSUID
34#endif
35#endif
8d063cd8 36
a0d0e21e 37static void find_beginning _((void));
bbce6d69 38static void forbid_setid _((char *));
a0d0e21e 39static void incpush _((char *));
748a9306 40static void init_ids _((void));
a0d0e21e 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));
6e72f9df 48static void nuke_stacks _((void));
a0d0e21e 49static void open_script _((char *, bool, SV *));
ab821d7f 50static void usage _((char *));
96436eeb 51static void validate_suid _((char *, char*));
52
53static int fdscript = -1;
79072805 54
93a17b20 55PerlInterpreter *
79072805 56perl_alloc()
57{
93a17b20 58 PerlInterpreter *sv_interp;
79072805 59
8990e307 60 curinterp = 0;
93a17b20 61 New(53, sv_interp, 1, PerlInterpreter);
79072805 62 return sv_interp;
63}
64
65void
66perl_construct( sv_interp )
93a17b20 67register PerlInterpreter *sv_interp;
79072805 68{
69 if (!(curinterp = sv_interp))
70 return;
71
8990e307 72#ifdef MULTIPLICITY
93a17b20 73 Zero(sv_interp, 1, PerlInterpreter);
8990e307 74#endif
79072805 75
76 /* Init the real globals? */
77 if (!linestr) {
78 linestr = NEWSV(65,80);
ed6116ce 79 sv_upgrade(linestr,SVt_PVIV);
79072805 80
6e72f9df 81 if (!SvREADONLY(&sv_undef)) {
82 SvREADONLY_on(&sv_undef);
79072805 83
6e72f9df 84 sv_setpv(&sv_no,No);
85 SvNV(&sv_no);
86 SvREADONLY_on(&sv_no);
79072805 87
6e72f9df 88 sv_setpv(&sv_yes,Yes);
89 SvNV(&sv_yes);
90 SvREADONLY_on(&sv_yes);
91 }
79072805 92
c07a80fd 93 nrs = newSVpv("\n", 1);
94 rs = SvREFCNT_inc(nrs);
95
79072805 96#ifdef MSDOS
97 /*
98 * There is no way we can refer to them from Perl so close them to save
99 * space. The other alternative would be to provide STDAUX and STDPRN
100 * filehandles.
101 */
102 (void)fclose(stdaux);
103 (void)fclose(stdprn);
104#endif
105 }
106
8990e307 107#ifdef MULTIPLICITY
79072805 108 chopset = " \n-";
463ee0b2 109 copline = NOLINE;
79072805 110 curcop = &compiling;
1a30305b 111 dbargs = 0;
79072805 112 dlmax = 128;
113 laststatval = -1;
114 laststype = OP_STAT;
115 maxscream = -1;
116 maxsysfd = MAXSYSFD;
79072805 117 rsfp = Nullfp;
463ee0b2 118 statname = Nullsv;
79072805 119 tmps_floor = -1;
79072805 120#endif
121
748a9306 122 init_ids();
a5f75d66 123
bbce6d69 124 NUMERIC_STANDARD();
a5f75d66 125#if defined(SUBVERSION) && SUBVERSION > 0
e2666263 126 sprintf(patchlevel, "%7.5f", (double) 5
127 + ((double) PATCHLEVEL / (double) 1000)
128 + ((double) SUBVERSION / (double) 100000));
a5f75d66 129#else
e2666263 130 sprintf(patchlevel, "%5.3f", (double) 5 +
131 ((double) PATCHLEVEL / (double) 1000));
a5f75d66 132#endif
79072805 133
ab821d7f 134#if defined(LOCAL_PATCH_COUNT)
6e72f9df 135 localpatches = local_patches; /* For possible -v */
ab821d7f 136#endif
137
760ac839 138 PerlIO_init(); /* Hook to IO system */
139
79072805 140 fdpid = newAV(); /* for remembering popen pids by fd */
463ee0b2 141 pidstatus = newHV();/* for remembering status of dead pids */
8990e307 142
143 init_stacks();
144 ENTER;
79072805 145}
146
147void
748a9306 148perl_destruct(sv_interp)
93a17b20 149register PerlInterpreter *sv_interp;
79072805 150{
748a9306 151 int destruct_level; /* 0=none, 1=full, 2=full with checks */
8990e307 152 I32 last_sv_count;
a0d0e21e 153 HV *hv;
8990e307 154
79072805 155 if (!(curinterp = sv_interp))
156 return;
748a9306 157
158 destruct_level = perl_destruct_level;
4633a7c4 159#ifdef DEBUGGING
160 {
161 char *s;
162 if (s = getenv("PERL_DESTRUCT_LEVEL"))
163 destruct_level = atoi(s);
164 }
165#endif
166
8990e307 167 LEAVE;
a0d0e21e 168 FREETMPS;
169
6e72f9df 170 /* We must account for everything. First the syntax tree. */
171 if (main_root) {
172 curpad = AvARRAY(comppad);
173 op_free(main_root);
174 main_root = 0;
a0d0e21e 175 }
176 if (sv_objcount) {
177 /*
178 * Try to destruct global references. We do this first so that the
179 * destructors and destructees still exist. Some sv's might remain.
180 * Non-referenced objects are on their own.
181 */
182
183 dirty = TRUE;
184 sv_clean_objs();
8990e307 185 }
186
a0d0e21e 187 if (destruct_level == 0){
8990e307 188
a0d0e21e 189 DEBUG_P(debprofdump());
190
191 /* The exit() function will do everything that needs doing. */
192 return;
193 }
5dd60ef7 194
195 /* unhook hooks which may now point to, or use, broken code */
196 if (warnhook && SvREFCNT(warnhook))
197 SvREFCNT_dec(warnhook);
198 if (diehook && SvREFCNT(diehook))
199 SvREFCNT_dec(diehook);
200 if (parsehook && SvREFCNT(parsehook))
201 SvREFCNT_dec(parsehook);
a0d0e21e 202
203 /* Prepare to destruct main symbol table. */
204 hv = defstash;
85e6fe83 205 defstash = 0;
a0d0e21e 206 SvREFCNT_dec(hv);
207
208 FREETMPS;
209 if (destruct_level >= 2) {
210 if (scopestack_ix != 0)
211 warn("Unbalanced scopes: %d more ENTERs than LEAVEs\n", scopestack_ix);
212 if (savestack_ix != 0)
213 warn("Unbalanced saves: %d more saves than restores\n", savestack_ix);
214 if (tmps_floor != -1)
215 warn("Unbalanced tmps: %d more allocs than frees\n", tmps_floor + 1);
216 if (cxstack_ix != -1)
217 warn("Unbalanced context: %d more PUSHes than POPs\n", cxstack_ix + 1);
218 }
8990e307 219
220 /* Now absolutely destruct everything, somehow or other, loops or no. */
8990e307 221 last_sv_count = 0;
6e72f9df 222 SvFLAGS(strtab) |= SVTYPEMASK; /* don't clean out strtab now */
8990e307 223 while (sv_count != 0 && sv_count != last_sv_count) {
224 last_sv_count = sv_count;
225 sv_clean_all();
226 }
6e72f9df 227 SvFLAGS(strtab) &= ~SVTYPEMASK;
228 SvFLAGS(strtab) |= SVt_PVHV;
229
230 /* Destruct the global string table. */
231 {
232 /* Yell and reset the HeVAL() slots that are still holding refcounts,
233 * so that sv_free() won't fail on them.
234 */
235 I32 riter;
236 I32 max;
237 HE *hent;
238 HE **array;
239
240 riter = 0;
241 max = HvMAX(strtab);
242 array = HvARRAY(strtab);
243 hent = array[0];
244 for (;;) {
245 if (hent) {
246 warn("Unbalanced string table refcount: (%d) for \"%s\"",
247 HeVAL(hent) - Nullsv, HeKEY(hent));
248 HeVAL(hent) = Nullsv;
249 hent = HeNEXT(hent);
250 }
251 if (!hent) {
252 if (++riter > max)
253 break;
254 hent = array[riter];
255 }
256 }
257 }
258 SvREFCNT_dec(strtab);
259
8990e307 260 if (sv_count != 0)
261 warn("Scalars leaked: %d\n", sv_count);
6e72f9df 262
4633a7c4 263 sv_free_arenas();
a0d0e21e 264
6e72f9df 265 linestr = NULL; /* No SVs have survived, need to clean out */
266 if (origfilename)
267 Safefree(origfilename);
268 nuke_stacks();
269 hints = 0; /* Reset hints. Should hints be per-interpreter ? */
270
a0d0e21e 271 DEBUG_P(debprofdump());
79072805 272}
273
274void
275perl_free(sv_interp)
93a17b20 276PerlInterpreter *sv_interp;
79072805 277{
278 if (!(curinterp = sv_interp))
279 return;
280 Safefree(sv_interp);
281}
ecfc5424 282#if !defined(STANDARD_C) && !defined(HAS_GETENV_PROTOTYPE)
a0d0e21e 283char *getenv _((char *)); /* Usually in <stdlib.h> */
284#endif
79072805 285
286int
a0d0e21e 287perl_parse(sv_interp, xsinit, argc, argv, env)
93a17b20 288PerlInterpreter *sv_interp;
a0d0e21e 289void (*xsinit)_((void));
290int argc;
291char **argv;
79072805 292char **env;
8d063cd8 293{
79072805 294 register SV *sv;
8d063cd8 295 register char *s;
1a30305b 296 char *scriptname = NULL;
a0d0e21e 297 VOL bool dosearch = FALSE;
13281fa4 298 char *validarg = "";
748a9306 299 AV* comppadlist;
8d063cd8 300
a687059c 301#ifdef SETUID_SCRIPTS_ARE_SECURE_NOW
302#ifdef IAMSUID
303#undef IAMSUID
463ee0b2 304 croak("suidperl is no longer needed since the kernel can now execute\n\
a687059c 305setuid perl scripts securely.\n");
306#endif
307#endif
308
79072805 309 if (!(curinterp = sv_interp))
310 return 255;
311
6e72f9df 312#if defined(NeXT) && defined(__DYNAMIC__)
313 _dyld_lookup_and_bind
314 ("__environ", (unsigned long *) &environ_pointer, NULL);
315#endif /* environ */
316
ac58e20f 317 origargv = argv;
318 origargc = argc;
a0d0e21e 319#ifndef VMS /* VMS doesn't have environ array */
fe14fcc3 320 origenviron = environ;
a0d0e21e 321#endif
ab821d7f 322 e_tmpname = Nullch;
a0d0e21e 323
324 if (do_undump) {
325
326 /* Come here if running an undumped a.out. */
327
328 origfilename = savepv(argv[0]);
329 do_undump = FALSE;
330 cxstack_ix = -1; /* start label stack again */
748a9306 331 init_ids();
a0d0e21e 332 init_postdump_symbols(argc,argv,env);
333 return 0;
334 }
335
336 if (main_root)
337 op_free(main_root);
338 main_root = 0;
79072805 339
a5f75d66 340 switch (Sigsetjmp(top_env,1)) {
79072805 341 case 1:
748a9306 342#ifdef VMS
79072805 343 statusvalue = 255;
748a9306 344#else
345 statusvalue = 1;
346#endif
79072805 347 case 2:
8990e307 348 curstash = defstash;
349 if (endav)
350 calllist(endav);
79072805 351 return(statusvalue); /* my_exit() was called */
352 case 3:
760ac839 353 PerlIO_printf(PerlIO_stderr(), "panic: top_env\n");
8990e307 354 return 1;
79072805 355 }
356
79072805 357 sv_setpvn(linestr,"",0);
358 sv = newSVpv("",0); /* first used for -I flags */
8990e307 359 SAVEFREESV(sv);
79072805 360 init_main_stash();
33b78306 361 for (argc--,argv++; argc > 0; argc--,argv++) {
8d063cd8 362 if (argv[0][0] != '-' || !argv[0][1])
363 break;
13281fa4 364#ifdef DOSUID
365 if (*validarg)
366 validarg = " PHOOEY ";
367 else
368 validarg = argv[0];
369#endif
370 s = argv[0]+1;
8d063cd8 371 reswitch:
13281fa4 372 switch (*s) {
27e2fb84 373 case '0':
2304df62 374 case 'F':
378cc40b 375 case 'a':
33b78306 376 case 'c':
a687059c 377 case 'd':
8d063cd8 378 case 'D':
4633a7c4 379 case 'h':
33b78306 380 case 'i':
fe14fcc3 381 case 'l':
1a30305b 382 case 'M':
383 case 'm':
33b78306 384 case 'n':
385 case 'p':
79072805 386 case 's':
463ee0b2 387 case 'T':
33b78306 388 case 'u':
389 case 'U':
390 case 'v':
391 case 'w':
392 if (s = moreswitches(s))
393 goto reswitch;
8d063cd8 394 break;
33b78306 395
8d063cd8 396 case 'e':
a687059c 397 if (euid != uid || egid != gid)
463ee0b2 398 croak("No -e allowed in setuid scripts");
8d063cd8 399 if (!e_fp) {
a0d0e21e 400 e_tmpname = savepv(TMPPATH);
a687059c 401 (void)mktemp(e_tmpname);
83025b21 402 if (!*e_tmpname)
463ee0b2 403 croak("Can't mktemp()");
760ac839 404 e_fp = PerlIO_open(e_tmpname,"w");
33b78306 405 if (!e_fp)
463ee0b2 406 croak("Cannot open temporary file");
8d063cd8 407 }
552a7a9b 408 if (*++s)
409 PerlIO_puts(e_fp,s);
410 else if (argv[1]) {
760ac839 411 PerlIO_puts(e_fp,argv[1]);
33b78306 412 argc--,argv++;
413 }
552a7a9b 414 else
415 croak("No code specified for -e");
760ac839 416 (void)PerlIO_putc(e_fp,'\n');
8d063cd8 417 break;
418 case 'I':
bbce6d69 419 forbid_setid("-I");
79072805 420 sv_catpv(sv,"-");
421 sv_catpv(sv,s);
422 sv_catpv(sv," ");
a687059c 423 if (*++s) {
a0d0e21e 424 av_push(GvAVn(incgv),newSVpv(s,0));
378cc40b 425 }
33b78306 426 else if (argv[1]) {
a0d0e21e 427 av_push(GvAVn(incgv),newSVpv(argv[1],0));
79072805 428 sv_catpv(sv,argv[1]);
8d063cd8 429 argc--,argv++;
79072805 430 sv_catpv(sv," ");
8d063cd8 431 }
432 break;
8d063cd8 433 case 'P':
bbce6d69 434 forbid_setid("-P");
8d063cd8 435 preprocess = TRUE;
13281fa4 436 s++;
8d063cd8 437 goto reswitch;
378cc40b 438 case 'S':
bbce6d69 439 forbid_setid("-S");
378cc40b 440 dosearch = TRUE;
13281fa4 441 s++;
378cc40b 442 goto reswitch;
1a30305b 443 case 'V':
444 if (!preambleav)
445 preambleav = newAV();
446 av_push(preambleav, newSVpv("use Config qw(myconfig config_vars)",0));
447 if (*++s != ':') {
6e72f9df 448 Sv = newSVpv("print myconfig();",0);
449#ifdef VMS
450 sv_catpv(Sv,"print \"\\nCharacteristics of this PERLSHR image: \\n\",");
451#else
452 sv_catpv(Sv,"print \"\\nCharacteristics of this binary (from libperl): \\n\",");
453#endif
454#if defined(DEBUGGING) || defined(NOEMBED) || defined(MULTIPLICITY)
455 strcpy(buf,"\" Compile-time options:");
456# ifdef DEBUGGING
457 strcat(buf," DEBUGGING");
458# endif
459# ifdef NOEMBED
460 strcat(buf," NOEMBED");
461# endif
462# ifdef MULTIPLICITY
463 strcat(buf," MULTIPLICITY");
464# endif
465 strcat(buf,"\\n\",");
466 sv_catpv(Sv,buf);
467#endif
468#if defined(LOCAL_PATCH_COUNT)
469 if (LOCAL_PATCH_COUNT > 0)
470 { int i;
471 sv_catpv(Sv,"print \" Locally applied patches:\\n\",");
472 for (i = 1; i <= LOCAL_PATCH_COUNT; i++) {
473 if (localpatches[i]) {
474 sprintf(buf,"\" \\t%s\\n\",",localpatches[i]);
475 sv_catpv(Sv,buf);
476 }
477 }
478 }
479#endif
480 sprintf(buf,"\" Built under %s\\n\",",OSNAME);
481 sv_catpv(Sv,buf);
482#ifdef __DATE__
483# ifdef __TIME__
484 sprintf(buf,"\" Compiled at %s %s\\n\"",__DATE__,__TIME__);
485# else
486 sprintf(buf,"\" Compiled on %s\\n\"",__DATE__);
487# endif
488 sv_catpv(Sv,buf);
489#endif
490 sv_catpv(Sv,"; $\"=\"\\n \"; print \" \\@INC:\\n @INC\\n\"");
1a30305b 491 }
492 else {
493 Sv = newSVpv("config_vars(qw(",0);
494 sv_catpv(Sv, ++s);
495 sv_catpv(Sv, "))");
496 s += strlen(s);
497 }
498 av_push(preambleav, Sv);
c07a80fd 499 scriptname = BIT_BUCKET; /* don't look for script or read stdin */
1a30305b 500 goto reswitch;
33b78306 501 case 'x':
502 doextract = TRUE;
13281fa4 503 s++;
33b78306 504 if (*s)
a0d0e21e 505 cddir = savepv(s);
33b78306 506 break;
8d063cd8 507 case '-':
508 argc--,argv++;
509 goto switch_end;
510 case 0:
511 break;
512 default:
463ee0b2 513 croak("Unrecognized switch: -%s",s);
8d063cd8 514 }
515 }
516 switch_end:
1a30305b 517 if (!scriptname)
518 scriptname = argv[0];
8d063cd8 519 if (e_fp) {
760ac839 520 if (PerlIO_flush(e_fp) || PerlIO_error(e_fp) || PerlIO_close(e_fp))
2304df62 521 croak("Can't write to temp file for -e: %s", Strerror(errno));
ab821d7f 522 e_fp = Nullfp;
8d063cd8 523 argc++,argv--;
45d8adaa 524 scriptname = e_tmpname;
8d063cd8 525 }
79072805 526 else if (scriptname == Nullch) {
527#ifdef MSDOS
760ac839 528 if ( isatty(PerlIO_fileno(PerlIO_stdin())) )
55497cff 529 moreswitches("h");
fe14fcc3 530#endif
79072805 531 scriptname = "-";
532 }
fe14fcc3 533
79072805 534 init_perllib();
8d063cd8 535
79072805 536 open_script(scriptname,dosearch,sv);
8d063cd8 537
96436eeb 538 validate_suid(validarg, scriptname);
378cc40b 539
79072805 540 if (doextract)
541 find_beginning();
542
748a9306 543 compcv = (CV*)NEWSV(1104,0);
544 sv_upgrade((SV *)compcv, SVt_PVCV);
545
6e72f9df 546 comppad = newAV();
79072805 547 av_push(comppad, Nullsv);
548 curpad = AvARRAY(comppad);
6e72f9df 549 comppad_name = newAV();
8990e307 550 comppad_name_fill = 0;
551 min_intro_pending = 0;
79072805 552 padix = 0;
553
748a9306 554 comppadlist = newAV();
555 AvREAL_off(comppadlist);
8e07c86e 556 av_store(comppadlist, 0, (SV*)comppad_name);
557 av_store(comppadlist, 1, (SV*)comppad);
748a9306 558 CvPADLIST(compcv) = comppadlist;
559
6e72f9df 560 boot_core_UNIVERSAL();
a0d0e21e 561 if (xsinit)
562 (*xsinit)(); /* in case linked C routines want magical variables */
748a9306 563#ifdef VMS
564 init_os_extras();
565#endif
93a17b20 566
93a17b20 567 init_predump_symbols();
8990e307 568 if (!do_undump)
569 init_postdump_symbols(argc,argv,env);
93a17b20 570
79072805 571 init_lexer();
572
573 /* now parse the script */
574
575 error_count = 0;
576 if (yyparse() || error_count) {
577 if (minus_c)
463ee0b2 578 croak("%s had compilation errors.\n", origfilename);
79072805 579 else {
463ee0b2 580 croak("Execution of %s aborted due to compilation errors.\n",
79072805 581 origfilename);
378cc40b 582 }
79072805 583 }
584 curcop->cop_line = 0;
585 curstash = defstash;
586 preprocess = FALSE;
ab821d7f 587 if (e_tmpname) {
79072805 588 (void)UNLINK(e_tmpname);
ab821d7f 589 Safefree(e_tmpname);
590 e_tmpname = Nullch;
378cc40b 591 }
a687059c 592
93a17b20 593 /* now that script is parsed, we can modify record separator */
c07a80fd 594 SvREFCNT_dec(rs);
595 rs = SvREFCNT_inc(nrs);
596 sv_setsv(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), rs);
45d8adaa 597
79072805 598 if (do_undump)
599 my_unexec();
600
8990e307 601 if (dowarn)
602 gv_check(defstash);
603
a0d0e21e 604 LEAVE;
605 FREETMPS;
c07a80fd 606
607#ifdef DEBUGGING_MSTATS
608 if ((s=getenv("PERL_DEBUG_MSTATS")) && atoi(s) >= 2)
609 dump_mstats("after compilation:");
610#endif
611
a0d0e21e 612 ENTER;
613 restartop = 0;
79072805 614 return 0;
615}
616
617int
618perl_run(sv_interp)
93a17b20 619PerlInterpreter *sv_interp;
79072805 620{
621 if (!(curinterp = sv_interp))
622 return 255;
a5f75d66 623 switch (Sigsetjmp(top_env,1)) {
79072805 624 case 1:
625 cxstack_ix = -1; /* start context stack again */
626 break;
627 case 2:
628 curstash = defstash;
93a17b20 629 if (endav)
630 calllist(endav);
a0d0e21e 631 FREETMPS;
c07a80fd 632#ifdef DEBUGGING_MSTATS
633 if (getenv("PERL_DEBUG_MSTATS"))
634 dump_mstats("after execution: ");
635#endif
93a17b20 636 return(statusvalue); /* my_exit() was called */
79072805 637 case 3:
638 if (!restartop) {
760ac839 639 PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
a0d0e21e 640 FREETMPS;
8990e307 641 return 1;
83025b21 642 }
6e72f9df 643 if (curstack != mainstack) {
79072805 644 dSP;
6e72f9df 645 SWITCHSTACK(curstack, mainstack);
79072805 646 }
647 break;
8d063cd8 648 }
79072805 649
760ac839 650 DEBUG_r(PerlIO_printf(PerlIO_stderr(), "%s $` $& $' support.\n",
6e72f9df 651 sawampersand ? "Enabling" : "Omitting"));
652
79072805 653 if (!restartop) {
654 DEBUG_x(dump_all());
760ac839 655 DEBUG(PerlIO_printf(Perl_debug_log, "\nEXECUTING...\n\n"));
79072805 656
657 if (minus_c) {
760ac839 658 PerlIO_printf(PerlIO_stderr(), "%s syntax OK\n", origfilename);
79072805 659 my_exit(0);
660 }
a0d0e21e 661 if (perldb && DBsingle)
662 sv_setiv(DBsingle, 1);
45d8adaa 663 }
79072805 664
665 /* do it */
666
667 if (restartop) {
668 op = restartop;
669 restartop = 0;
ab821d7f 670 runops();
79072805 671 }
672 else if (main_start) {
673 op = main_start;
ab821d7f 674 runops();
79072805 675 }
79072805 676
677 my_exit(0);
a0d0e21e 678 return 0;
79072805 679}
680
681void
682my_exit(status)
748a9306 683U32 status;
79072805 684{
a0d0e21e 685 register CONTEXT *cx;
686 I32 gimme;
687 SV **newsp;
688
748a9306 689 statusvalue = FIXSTATUS(status);
a0d0e21e 690 if (cxstack_ix >= 0) {
691 if (cxstack_ix > 0)
692 dounwind(0);
693 POPBLOCK(cx,curpm);
694 LEAVE;
695 }
a5f75d66 696 Siglongjmp(top_env, 2);
79072805 697}
698
a0d0e21e 699SV*
700perl_get_sv(name, create)
701char* name;
702I32 create;
703{
704 GV* gv = gv_fetchpv(name, create, SVt_PV);
705 if (gv)
706 return GvSV(gv);
707 return Nullsv;
708}
709
710AV*
711perl_get_av(name, create)
712char* name;
713I32 create;
714{
715 GV* gv = gv_fetchpv(name, create, SVt_PVAV);
716 if (create)
717 return GvAVn(gv);
718 if (gv)
719 return GvAV(gv);
720 return Nullav;
721}
722
723HV*
724perl_get_hv(name, create)
725char* name;
726I32 create;
727{
728 GV* gv = gv_fetchpv(name, create, SVt_PVHV);
729 if (create)
730 return GvHVn(gv);
731 if (gv)
732 return GvHV(gv);
733 return Nullhv;
734}
735
736CV*
737perl_get_cv(name, create)
738char* name;
739I32 create;
740{
741 GV* gv = gv_fetchpv(name, create, SVt_PVCV);
742 if (create && !GvCV(gv))
743 return newSUB(start_subparse(),
744 newSVOP(OP_CONST, 0, newSVpv(name,0)),
4633a7c4 745 Nullop,
a0d0e21e 746 Nullop);
747 if (gv)
748 return GvCV(gv);
749 return Nullcv;
750}
751
79072805 752/* Be sure to refetch the stack pointer after calling these routines. */
753
a0d0e21e 754I32
755perl_call_argv(subname, flags, argv)
8990e307 756char *subname;
a0d0e21e 757I32 flags; /* See G_* flags in cop.h */
758register char **argv; /* null terminated arg list */
8990e307 759{
a0d0e21e 760 dSP;
8990e307 761
a0d0e21e 762 PUSHMARK(sp);
763 if (argv) {
8990e307 764 while (*argv) {
a0d0e21e 765 XPUSHs(sv_2mortal(newSVpv(*argv,0)));
8990e307 766 argv++;
767 }
a0d0e21e 768 PUTBACK;
8990e307 769 }
a0d0e21e 770 return perl_call_pv(subname, flags);
8990e307 771}
772
a0d0e21e 773I32
774perl_call_pv(subname, flags)
775char *subname; /* name of the subroutine */
776I32 flags; /* See G_* flags in cop.h */
777{
778 return perl_call_sv((SV*)perl_get_cv(subname, TRUE), flags);
779}
780
781I32
782perl_call_method(methname, flags)
783char *methname; /* name of the subroutine */
784I32 flags; /* See G_* flags in cop.h */
785{
786 dSP;
787 OP myop;
788 if (!op)
789 op = &myop;
790 XPUSHs(sv_2mortal(newSVpv(methname,0)));
791 PUTBACK;
792 pp_method();
793 return perl_call_sv(*stack_sp--, flags);
794}
795
796/* May be called with any of a CV, a GV, or an SV containing the name. */
797I32
798perl_call_sv(sv, flags)
799SV* sv;
800I32 flags; /* See G_* flags in cop.h */
801{
802 LOGOP myop; /* fake syntax tree node */
803 SV** sp = stack_sp;
804 I32 oldmark = TOPMARK;
805 I32 retval;
a5f75d66 806 Sigjmp_buf oldtop;
a0d0e21e 807 I32 oldscope;
6e72f9df 808 static CV *DBcv;
a0d0e21e 809
810 if (flags & G_DISCARD) {
811 ENTER;
812 SAVETMPS;
813 }
814
815 SAVESPTR(op);
816 op = (OP*)&myop;
817 Zero(op, 1, LOGOP);
818 EXTEND(stack_sp, 1);
819 *++stack_sp = sv;
820 oldscope = scopestack_ix;
821
822 if (!(flags & G_NOARGS))
823 myop.op_flags = OPf_STACKED;
824 myop.op_next = Nullop;
825 myop.op_flags |= OPf_KNOW;
826 if (flags & G_ARRAY)
827 myop.op_flags |= OPf_LIST;
828
6e72f9df 829 if (perldb && curstash != debstash
830 && (DBcv || (DBcv = GvCV(DBsub)))) /* to handle first BEGIN of -d */
831 op->op_private |= OPpENTERSUB_DB;
832
a0d0e21e 833 if (flags & G_EVAL) {
a5f75d66 834 Copy(top_env, oldtop, 1, Sigjmp_buf);
a0d0e21e 835
836 cLOGOP->op_other = op;
837 markstack_ptr--;
4633a7c4 838 /* we're trying to emulate pp_entertry() here */
839 {
840 register CONTEXT *cx;
841 I32 gimme = GIMME;
842
843 ENTER;
844 SAVETMPS;
845
846 push_return(op->op_next);
847 PUSHBLOCK(cx, CXt_EVAL, stack_sp);
848 PUSHEVAL(cx, 0, 0);
849 eval_root = op; /* Only needed so that goto works right. */
850
851 in_eval = 1;
852 if (flags & G_KEEPERR)
853 in_eval |= 4;
854 else
855 sv_setpv(GvSV(errgv),"");
856 }
a0d0e21e 857 markstack_ptr++;
858
859 restart:
a5f75d66 860 switch (Sigsetjmp(top_env,1)) {
a0d0e21e 861 case 0:
862 break;
863 case 1:
748a9306 864#ifdef VMS
a0d0e21e 865 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
748a9306 866#else
867 statusvalue = 1;
868#endif
a0d0e21e 869 /* FALL THROUGH */
870 case 2:
871 /* my_exit() was called */
872 curstash = defstash;
873 FREETMPS;
a5f75d66 874 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 875 if (statusvalue)
876 croak("Callback called exit");
877 my_exit(statusvalue);
878 /* NOTREACHED */
879 case 3:
880 if (restartop) {
881 op = restartop;
882 restartop = 0;
883 goto restart;
884 }
885 stack_sp = stack_base + oldmark;
886 if (flags & G_ARRAY)
887 retval = 0;
888 else {
889 retval = 1;
890 *++stack_sp = &sv_undef;
891 }
892 goto cleanup;
893 }
894 }
895
896 if (op == (OP*)&myop)
897 op = pp_entersub();
898 if (op)
ab821d7f 899 runops();
a0d0e21e 900 retval = stack_sp - (stack_base + oldmark);
4633a7c4 901 if ((flags & G_EVAL) && !(flags & G_KEEPERR))
902 sv_setpv(GvSV(errgv),"");
a0d0e21e 903
904 cleanup:
905 if (flags & G_EVAL) {
906 if (scopestack_ix > oldscope) {
a0a2876f 907 SV **newsp;
908 PMOP *newpm;
909 I32 gimme;
910 register CONTEXT *cx;
911 I32 optype;
912
913 POPBLOCK(cx,newpm);
914 POPEVAL(cx);
915 pop_return();
916 curpm = newpm;
917 LEAVE;
a0d0e21e 918 }
a5f75d66 919 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 920 }
921 if (flags & G_DISCARD) {
922 stack_sp = stack_base + oldmark;
923 retval = 0;
924 FREETMPS;
925 LEAVE;
926 }
927 return retval;
928}
929
6e72f9df 930/* Eval a string. The G_EVAL flag is always assumed. */
8990e307 931
a0d0e21e 932I32
4633a7c4 933perl_eval_sv(sv, flags)
8990e307 934SV* sv;
4633a7c4 935I32 flags; /* See G_* flags in cop.h */
a0d0e21e 936{
937 UNOP myop; /* fake syntax tree node */
4633a7c4 938 SV** sp = stack_sp;
939 I32 oldmark = sp - stack_base;
940 I32 retval;
a5f75d66 941 Sigjmp_buf oldtop;
4633a7c4 942 I32 oldscope;
79072805 943
4633a7c4 944 if (flags & G_DISCARD) {
945 ENTER;
946 SAVETMPS;
947 }
948
79072805 949 SAVESPTR(op);
79072805 950 op = (OP*)&myop;
a0d0e21e 951 Zero(op, 1, UNOP);
4633a7c4 952 EXTEND(stack_sp, 1);
953 *++stack_sp = sv;
954 oldscope = scopestack_ix;
79072805 955
4633a7c4 956 if (!(flags & G_NOARGS))
957 myop.op_flags = OPf_STACKED;
79072805 958 myop.op_next = Nullop;
6e72f9df 959 myop.op_type = OP_ENTEREVAL;
4633a7c4 960 myop.op_flags |= OPf_KNOW;
6e72f9df 961 if (flags & G_KEEPERR)
962 myop.op_flags |= OPf_SPECIAL;
4633a7c4 963 if (flags & G_ARRAY)
6e72f9df 964 myop.op_flags |= OPf_LIST;
79072805 965
a5f75d66 966 Copy(top_env, oldtop, 1, Sigjmp_buf);
4633a7c4 967
968restart:
a5f75d66 969 switch (Sigsetjmp(top_env,1)) {
4633a7c4 970 case 0:
971 break;
972 case 1:
973#ifdef VMS
974 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
975#else
976 statusvalue = 1;
977#endif
978 /* FALL THROUGH */
979 case 2:
980 /* my_exit() was called */
981 curstash = defstash;
982 FREETMPS;
a5f75d66 983 Copy(oldtop, top_env, 1, Sigjmp_buf);
4633a7c4 984 if (statusvalue)
985 croak("Callback called exit");
986 my_exit(statusvalue);
987 /* NOTREACHED */
988 case 3:
989 if (restartop) {
990 op = restartop;
991 restartop = 0;
992 goto restart;
993 }
994 stack_sp = stack_base + oldmark;
995 if (flags & G_ARRAY)
996 retval = 0;
997 else {
998 retval = 1;
999 *++stack_sp = &sv_undef;
1000 }
1001 goto cleanup;
1002 }
1003
1004 if (op == (OP*)&myop)
1005 op = pp_entereval();
1006 if (op)
ab821d7f 1007 runops();
4633a7c4 1008 retval = stack_sp - (stack_base + oldmark);
6e72f9df 1009 if (!(flags & G_KEEPERR))
4633a7c4 1010 sv_setpv(GvSV(errgv),"");
1011
1012 cleanup:
a5f75d66 1013 Copy(oldtop, top_env, 1, Sigjmp_buf);
4633a7c4 1014 if (flags & G_DISCARD) {
1015 stack_sp = stack_base + oldmark;
1016 retval = 0;
1017 FREETMPS;
1018 LEAVE;
1019 }
1020 return retval;
1021}
1022
1023/* Require a module. */
1024
1025void
1026perl_require_pv(pv)
1027char* pv;
1028{
1029 SV* sv = sv_newmortal();
1030 sv_setpv(sv, "require '");
1031 sv_catpv(sv, pv);
1032 sv_catpv(sv, "'");
1033 perl_eval_sv(sv, G_DISCARD);
79072805 1034}
1035
79072805 1036void
79072805 1037magicname(sym,name,namlen)
1038char *sym;
1039char *name;
1040I32 namlen;
1041{
1042 register GV *gv;
1043
85e6fe83 1044 if (gv = gv_fetchpv(sym,TRUE, SVt_PV))
79072805 1045 sv_magic(GvSV(gv), (SV*)gv, 0, name, namlen);
1046}
1047
748a9306 1048#if defined(DOSISH)
1049# define PERLLIB_SEP ';'
79072805 1050#else
232e078e 1051# if defined(VMS)
1052# define PERLLIB_SEP '|'
1053# else
748a9306 1054# define PERLLIB_SEP ':'
232e078e 1055# endif
79072805 1056#endif
760ac839 1057#ifndef PERLLIB_MANGLE
1058# define PERLLIB_MANGLE(s,n) (s)
1059#endif
79072805 1060
1061static void
1062incpush(p)
1063char *p;
1064{
1065 char *s;
1066
1067 if (!p)
1068 return;
1069
1070 /* Break at all separators */
1071 while (*p) {
1072 /* First, skip any consecutive separators */
1073 while ( *p == PERLLIB_SEP ) {
1074 /* Uncomment the next line for PATH semantics */
a0d0e21e 1075 /* av_push(GvAVn(incgv), newSVpv(".", 1)); */
79072805 1076 p++;
1077 }
93a17b20 1078 if ( (s = strchr(p, PERLLIB_SEP)) != Nullch ) {
760ac839 1079 av_push(GvAVn(incgv), newSVpv(PERLLIB_MANGLE(p, (STRLEN)(s - p)),
1080 (STRLEN)(s - p)));
79072805 1081 p = s + 1;
1082 } else {
760ac839 1083 av_push(GvAVn(incgv), newSVpv(PERLLIB_MANGLE(p, 0), 0));
79072805 1084 break;
1085 }
1086 }
1087}
1088
ab821d7f 1089static void
1a30305b 1090usage(name) /* XXX move this out into a module ? */
4633a7c4 1091char *name;
1092{
ab821d7f 1093 /* This message really ought to be max 23 lines.
1094 * Removed -h because the user already knows that opton. Others? */
1095 printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name);
4633a7c4 1096 printf("\n -0[octal] specify record separator (\\0, if no argument)");
ab821d7f 1097 printf("\n -a autosplit mode with -n or -p (splits $_ into @F)");
4633a7c4 1098 printf("\n -c check syntax only (runs BEGIN and END blocks)");
1a30305b 1099 printf("\n -d[:debugger] run scripts under debugger");
4633a7c4 1100 printf("\n -D[number/list] set debugging flags (argument is a bit mask or flags)");
ab821d7f 1101 printf("\n -e 'command' one line of script. Several -e's allowed. Omit [programfile].");
1102 printf("\n -F/pattern/ split() pattern for autosplit (-a). The //'s are optional.");
4633a7c4 1103 printf("\n -i[extension] edit <> files in place (make backup if extension supplied)");
ab821d7f 1104 printf("\n -Idirectory specify @INC/#include directory (may be used more then once)");
4633a7c4 1105 printf("\n -l[octal] enable line ending processing, specifies line teminator");
ab821d7f 1106 printf("\n -[mM][-]module.. executes `use/no module...' before executing your script.");
4633a7c4 1107 printf("\n -n assume 'while (<>) { ... }' loop arround your script");
1108 printf("\n -p assume loop like -n but print line also like sed");
1109 printf("\n -P run script through C preprocessor before compilation");
4633a7c4 1110 printf("\n -s enable some switch parsing for switches after script name");
1111 printf("\n -S look for the script using PATH environment variable");
1112 printf("\n -T turn on tainting checks");
1113 printf("\n -u dump core after parsing script");
1114 printf("\n -U allow unsafe operations");
1115 printf("\n -v print version number and patchlevel of perl");
1a30305b 1116 printf("\n -V[:variable] print perl configuration information");
ab821d7f 1117 printf("\n -w TURN WARNINGS ON FOR COMPILATION OF YOUR SCRIPT.");
4633a7c4 1118 printf("\n -x[directory] strip off text before #!perl line and perhaps cd to directory\n");
1119}
1120
79072805 1121/* This routine handles any switches that can be given during run */
1122
1123char *
1124moreswitches(s)
1125char *s;
1126{
1127 I32 numlen;
c07a80fd 1128 U32 rschar;
79072805 1129
1130 switch (*s) {
1131 case '0':
c07a80fd 1132 rschar = scan_oct(s, 4, &numlen);
1133 SvREFCNT_dec(nrs);
1134 if (rschar & ~((U8)~0))
1135 nrs = &sv_undef;
1136 else if (!rschar && numlen >= 2)
1137 nrs = newSVpv("", 0);
1138 else {
1139 char ch = rschar;
1140 nrs = newSVpv(&ch, 1);
79072805 1141 }
1142 return s + numlen;
2304df62 1143 case 'F':
1144 minus_F = TRUE;
a0d0e21e 1145 splitstr = savepv(s + 1);
2304df62 1146 s += strlen(s);
1147 return s;
79072805 1148 case 'a':
1149 minus_a = TRUE;
1150 s++;
1151 return s;
1152 case 'c':
1153 minus_c = TRUE;
1154 s++;
1155 return s;
1156 case 'd':
bbce6d69 1157 forbid_setid("-d");
4633a7c4 1158 s++;
c07a80fd 1159 if (*s == ':' || *s == '=') {
4633a7c4 1160 sprintf(buf, "use Devel::%s;", ++s);
1161 s += strlen(s);
1162 my_setenv("PERL5DB",buf);
1163 }
a0d0e21e 1164 if (!perldb) {
1165 perldb = TRUE;
1166 init_debugger();
1167 }
79072805 1168 return s;
1169 case 'D':
1170#ifdef DEBUGGING
bbce6d69 1171 forbid_setid("-D");
79072805 1172 if (isALPHA(s[1])) {
8990e307 1173 static char debopts[] = "psltocPmfrxuLHXD";
79072805 1174 char *d;
1175
93a17b20 1176 for (s++; *s && (d = strchr(debopts,*s)); s++)
79072805 1177 debug |= 1 << (d - debopts);
1178 }
1179 else {
1180 debug = atoi(s+1);
1181 for (s++; isDIGIT(*s); s++) ;
1182 }
8990e307 1183 debug |= 0x80000000;
79072805 1184#else
1185 warn("Recompile perl with -DDEBUGGING to use -D switch\n");
a0d0e21e 1186 for (s++; isALNUM(*s); s++) ;
79072805 1187#endif
1188 /*SUPPRESS 530*/
1189 return s;
4633a7c4 1190 case 'h':
1191 usage(origargv[0]);
1192 exit(0);
79072805 1193 case 'i':
1194 if (inplace)
1195 Safefree(inplace);
a0d0e21e 1196 inplace = savepv(s+1);
79072805 1197 /*SUPPRESS 530*/
1198 for (s = inplace; *s && !isSPACE(*s); s++) ;
1199 *s = '\0';
1200 break;
1201 case 'I':
bbce6d69 1202 forbid_setid("-I");
79072805 1203 if (*++s) {
748a9306 1204 char *e;
1205 for (e = s; *e && !isSPACE(*e); e++) ;
1206 av_push(GvAVn(incgv),newSVpv(s,e-s));
1207 if (*e)
1208 return e;
79072805 1209 }
1210 else
463ee0b2 1211 croak("No space allowed after -I");
79072805 1212 break;
1213 case 'l':
1214 minus_l = TRUE;
1215 s++;
a0d0e21e 1216 if (ors)
1217 Safefree(ors);
79072805 1218 if (isDIGIT(*s)) {
a0d0e21e 1219 ors = savepv("\n");
79072805 1220 orslen = 1;
1221 *ors = scan_oct(s, 3 + (*s == '0'), &numlen);
1222 s += numlen;
1223 }
1224 else {
c07a80fd 1225 if (RsPARA(nrs)) {
6e72f9df 1226 ors = "\n\n";
c07a80fd 1227 orslen = 2;
1228 }
1229 else
1230 ors = SvPV(nrs, orslen);
6e72f9df 1231 ors = savepvn(ors, orslen);
79072805 1232 }
1233 return s;
1a30305b 1234 case 'M':
bbce6d69 1235 forbid_setid("-M"); /* XXX ? */
1a30305b 1236 /* FALL THROUGH */
1237 case 'm':
bbce6d69 1238 forbid_setid("-m"); /* XXX ? */
1a30305b 1239 if (*++s) {
a5f75d66 1240 char *start;
1241 char *use = "use ";
1242 /* -M-foo == 'no foo' */
1243 if (*s == '-') { use = "no "; ++s; }
1244 Sv = newSVpv(use,0);
1245 start = s;
1a30305b 1246 /* We allow -M'Module qw(Foo Bar)' */
c07a80fd 1247 while(isALNUM(*s) || *s==':') ++s;
1248 if (*s != '=') {
1249 sv_catpv(Sv, start);
1250 if (*(start-1) == 'm') {
1251 if (*s != '\0')
1252 croak("Can't use '%c' after -mname", *s);
1253 sv_catpv( Sv, " ()");
1254 }
1255 } else {
1256 sv_catpvn(Sv, start, s-start);
a5f75d66 1257 sv_catpv(Sv, " split(/,/,q{");
c07a80fd 1258 sv_catpv(Sv, ++s);
a5f75d66 1259 sv_catpv(Sv, "})");
c07a80fd 1260 }
1a30305b 1261 s += strlen(s);
c07a80fd 1262 if (preambleav == NULL)
1263 preambleav = newAV();
1264 av_push(preambleav, Sv);
1a30305b 1265 }
1266 else
1267 croak("No space allowed after -%c", *(s-1));
1268 return s;
79072805 1269 case 'n':
1270 minus_n = TRUE;
1271 s++;
1272 return s;
1273 case 'p':
1274 minus_p = TRUE;
1275 s++;
1276 return s;
1277 case 's':
bbce6d69 1278 forbid_setid("-s");
79072805 1279 doswitches = TRUE;
1280 s++;
1281 return s;
463ee0b2 1282 case 'T':
1283 tainting = TRUE;
1284 s++;
1285 return s;
79072805 1286 case 'u':
1287 do_undump = TRUE;
1288 s++;
1289 return s;
1290 case 'U':
1291 unsafe = TRUE;
1292 s++;
1293 return s;
1294 case 'v':
a5f75d66 1295#if defined(SUBVERSION) && SUBVERSION > 0
1296 printf("\nThis is perl, version 5.%03d_%02d", PATCHLEVEL, SUBVERSION);
1297#else
1298 printf("\nThis is perl, version %s",patchlevel);
1299#endif
1a30305b 1300
760ac839 1301 printf("\n\nCopyright 1987-1996, Larry Wall\n");
1302 printf("\n\t+ suidperl security patch");
79072805 1303#ifdef MSDOS
55497cff 1304 printf("\n\nMS-DOS port Copyright (c) 1989, 1990, Diomidis Spinellis\n");
1305#endif
1306#ifdef DJGPP
1307 printf("djgpp v2 port (jpl5003c) by Hirofumi Watanabe, 1996\n");
4633a7c4 1308#endif
79072805 1309#ifdef OS2
5dd60ef7 1310 printf("\n\nOS/2 port Copyright (c) 1990, 1991, Raymond Chen, Kai Uwe Rommel\n"
760ac839 1311 "Version 5 port Copyright (c) 1994-1996, Andreas Kaiser, Ilya Zakharevich\n");
79072805 1312#endif
79072805 1313#ifdef atarist
760ac839 1314 printf("atariST series port, ++jrb bammi@cadence.com\n");
79072805 1315#endif
760ac839 1316 printf("\n\
79072805 1317Perl may be copied only under the terms of either the Artistic License or the\n\
760ac839 1318GNU General Public License, which may be found in the Perl 5.0 source kit.\n\n");
79072805 1319 exit(0);
1320 case 'w':
1321 dowarn = TRUE;
1322 s++;
1323 return s;
a0d0e21e 1324 case '*':
79072805 1325 case ' ':
1326 if (s[1] == '-') /* Additional switches on #! line. */
1327 return s+2;
1328 break;
a0d0e21e 1329 case '-':
79072805 1330 case 0:
1331 case '\n':
1332 case '\t':
1333 break;
a0d0e21e 1334 case 'P':
1335 if (preprocess)
1336 return s+1;
1337 /* FALL THROUGH */
79072805 1338 default:
a0d0e21e 1339 croak("Can't emulate -%.1s on #! line",s);
79072805 1340 }
1341 return Nullch;
1342}
1343
1344/* compliments of Tom Christiansen */
1345
1346/* unexec() can be found in the Gnu emacs distribution */
1347
1348void
1349my_unexec()
1350{
1351#ifdef UNEXEC
1352 int status;
1353 extern int etext;
1354
1355 sprintf (buf, "%s.perldump", origfilename);
1356 sprintf (tokenbuf, "%s/perl", BIN);
1357
1358 status = unexec(buf, tokenbuf, &etext, sbrk(0), 0);
1359 if (status)
760ac839 1360 PerlIO_printf(PerlIO_stderr(), "unexec of %s into %s failed!\n", tokenbuf, buf);
a0d0e21e 1361 exit(status);
79072805 1362#else
a5f75d66 1363# ifdef VMS
1364# include <lib$routines.h>
1365 lib$signal(SS$_DEBUG); /* ssdef.h #included from vmsish.h */
1366#else
79072805 1367 ABORT(); /* for use with undump */
1368#endif
a5f75d66 1369#endif
79072805 1370}
1371
1372static void
1373init_main_stash()
1374{
463ee0b2 1375 GV *gv;
6e72f9df 1376
1377 /* Note that strtab is a rather special HV. Assumptions are made
1378 about not iterating on it, and not adding tie magic to it.
1379 It is properly deallocated in perl_destruct() */
1380 strtab = newHV();
1381 HvSHAREKEYS_off(strtab); /* mandatory */
1382 Newz(506,((XPVHV*)SvANY(strtab))->xhv_array,
1383 sizeof(HE*) * (((XPVHV*)SvANY(strtab))->xhv_max + 1), char);
1384
463ee0b2 1385 curstash = defstash = newHV();
79072805 1386 curstname = newSVpv("main",4);
adbc6bb1 1387 gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
1388 SvREFCNT_dec(GvHV(gv));
1389 GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
463ee0b2 1390 SvREADONLY_on(gv);
a0d0e21e 1391 HvNAME(defstash) = savepv("main");
85e6fe83 1392 incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
a5f75d66 1393 GvMULTI_on(incgv);
a0d0e21e 1394 defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
4633a7c4 1395 errgv = gv_HVadd(gv_fetchpv("@", TRUE, SVt_PV));
a5f75d66 1396 GvMULTI_on(errgv);
552a7a9b 1397 sv_setpvn(GvSV(errgv), "", 0);
8990e307 1398 curstash = defstash;
1399 compiling.cop_stash = defstash;
adbc6bb1 1400 debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
4633a7c4 1401 /* We must init $/ before switches are processed. */
1402 sv_setpvn(GvSV(gv_fetchpv("/", TRUE, SVt_PV)), "\n", 1);
79072805 1403}
1404
a0d0e21e 1405#ifdef CAN_PROTOTYPE
1406static void
1407open_script(char *scriptname, bool dosearch, SV *sv)
1408#else
79072805 1409static void
1410open_script(scriptname,dosearch,sv)
1411char *scriptname;
1412bool dosearch;
1413SV *sv;
a0d0e21e 1414#endif
79072805 1415{
1416 char *xfound = Nullch;
1417 char *xfailed = Nullch;
1418 register char *s;
1419 I32 len;
a38d6535 1420 int retval;
1421#if defined(DOSISH) && !defined(OS2) && !defined(atarist)
1422#define SEARCH_EXTS ".bat", ".cmd", NULL
1423#endif
ab821d7f 1424#ifdef VMS
1425# define SEARCH_EXTS ".pl", ".com", NULL
1426#endif
a38d6535 1427 /* additional extensions to try in each dir if scriptname not found */
1428#ifdef SEARCH_EXTS
1429 char *ext[] = { SEARCH_EXTS };
1430 int extidx = (strchr(scriptname,'.')) ? -1 : 0; /* has ext already */
1431#endif
79072805 1432
c07a80fd 1433#ifdef VMS
6e72f9df 1434 if (dosearch) {
1435 int hasdir, idx = 0, deftypes = 1;
1436
1437 hasdir = (strpbrk(scriptname,":[</") != Nullch) ;
1438 /* The first time through, just add SEARCH_EXTS to whatever we
1439 * already have, so we can check for default file types. */
1440 while (deftypes || (!hasdir && my_trnlnm("DCL$PATH",tokenbuf,idx++)) ) {
1441 if (deftypes) { deftypes = 0; *tokenbuf = '\0'; }
c07a80fd 1442 strcat(tokenbuf,scriptname);
1443#else /* !VMS */
93a17b20 1444 if (dosearch && !strchr(scriptname, '/') && (s = getenv("PATH"))) {
79072805 1445
1446 bufend = s + strlen(s);
1447 while (*s) {
1448#ifndef DOSISH
1449 s = cpytill(tokenbuf,s,bufend,':',&len);
1450#else
1451#ifdef atarist
1452 for (len = 0; *s && *s != ',' && *s != ';'; tokenbuf[len++] = *s++);
1453 tokenbuf[len] = '\0';
1454#else
1455 for (len = 0; *s && *s != ';'; tokenbuf[len++] = *s++);
1456 tokenbuf[len] = '\0';
1457#endif
1458#endif
1459 if (*s)
1460 s++;
1461#ifndef DOSISH
1462 if (len && tokenbuf[len-1] != '/')
1463#else
1464#ifdef atarist
1465 if (len && ((tokenbuf[len-1] != '\\') && (tokenbuf[len-1] != '/')))
1466#else
1467 if (len && tokenbuf[len-1] != '\\')
1468#endif
1469#endif
1470 (void)strcat(tokenbuf+len,"/");
1471 (void)strcat(tokenbuf+len,scriptname);
c07a80fd 1472#endif /* !VMS */
a38d6535 1473
1474#ifdef SEARCH_EXTS
1475 len = strlen(tokenbuf);
1476 if (extidx > 0) /* reset after previous loop */
1477 extidx = 0;
1478 do {
1479#endif
760ac839 1480 DEBUG_p(PerlIO_printf(Perl_debug_log, "Looking for %s\n",tokenbuf));
a38d6535 1481 retval = Stat(tokenbuf,&statbuf);
1482#ifdef SEARCH_EXTS
1483 } while ( retval < 0 /* not there */
1484 && extidx>=0 && ext[extidx] /* try an extension? */
1485 && strcpy(tokenbuf+len, ext[extidx++])
1486 );
1487#endif
1488 if (retval < 0)
79072805 1489 continue;
1490 if (S_ISREG(statbuf.st_mode)
1491 && cando(S_IRUSR,TRUE,&statbuf) && cando(S_IXUSR,TRUE,&statbuf)) {
1492 xfound = tokenbuf; /* bingo! */
1493 break;
1494 }
1495 if (!xfailed)
a0d0e21e 1496 xfailed = savepv(tokenbuf);
79072805 1497 }
1498 if (!xfound)
463ee0b2 1499 croak("Can't execute %s", xfailed ? xfailed : scriptname );
79072805 1500 if (xfailed)
1501 Safefree(xfailed);
1502 scriptname = xfound;
1503 }
1504
96436eeb 1505 if (strnEQ(scriptname, "/dev/fd/", 8) && isDIGIT(scriptname[8]) ) {
1506 char *s = scriptname + 8;
1507 fdscript = atoi(s);
1508 while (isDIGIT(*s))
1509 s++;
1510 if (*s)
1511 scriptname = s + 1;
1512 }
1513 else
1514 fdscript = -1;
ab821d7f 1515 origfilename = savepv(e_tmpname ? "-e" : scriptname);
79072805 1516 curcop->cop_filegv = gv_fetchfile(origfilename);
1517 if (strEQ(origfilename,"-"))
1518 scriptname = "";
96436eeb 1519 if (fdscript >= 0) {
760ac839 1520 rsfp = PerlIO_fdopen(fdscript,"r");
96436eeb 1521#if defined(HAS_FCNTL) && defined(F_SETFD)
760ac839 1522 fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
96436eeb 1523#endif
1524 }
1525 else if (preprocess) {
79072805 1526 char *cpp = CPPSTDIN;
1527
1528 if (strEQ(cpp,"cppstdin"))
1529 sprintf(tokenbuf, "%s/%s", SCRIPTDIR, cpp);
1530 else
1531 sprintf(tokenbuf, "%s", cpp);
1532 sv_catpv(sv,"-I");
fed7345c 1533 sv_catpv(sv,PRIVLIB_EXP);
79072805 1534#ifdef MSDOS
1535 (void)sprintf(buf, "\
1536sed %s -e \"/^[^#]/b\" \
1537 -e \"/^#[ ]*include[ ]/b\" \
1538 -e \"/^#[ ]*define[ ]/b\" \
1539 -e \"/^#[ ]*if[ ]/b\" \
1540 -e \"/^#[ ]*ifdef[ ]/b\" \
1541 -e \"/^#[ ]*ifndef[ ]/b\" \
1542 -e \"/^#[ ]*else/b\" \
1543 -e \"/^#[ ]*elif[ ]/b\" \
1544 -e \"/^#[ ]*undef[ ]/b\" \
1545 -e \"/^#[ ]*endif/b\" \
1546 -e \"s/^#.*//\" \
1547 %s | %s -C %s %s",
1548 (doextract ? "-e \"1,/^#/d\n\"" : ""),
1549#else
1550 (void)sprintf(buf, "\
1551%s %s -e '/^[^#]/b' \
1552 -e '/^#[ ]*include[ ]/b' \
1553 -e '/^#[ ]*define[ ]/b' \
1554 -e '/^#[ ]*if[ ]/b' \
1555 -e '/^#[ ]*ifdef[ ]/b' \
1556 -e '/^#[ ]*ifndef[ ]/b' \
1557 -e '/^#[ ]*else/b' \
1558 -e '/^#[ ]*elif[ ]/b' \
1559 -e '/^#[ ]*undef[ ]/b' \
1560 -e '/^#[ ]*endif/b' \
1561 -e 's/^[ ]*#.*//' \
1562 %s | %s -C %s %s",
1563#ifdef LOC_SED
1564 LOC_SED,
1565#else
1566 "sed",
1567#endif
1568 (doextract ? "-e '1,/^#/d\n'" : ""),
1569#endif
463ee0b2 1570 scriptname, tokenbuf, SvPV(sv, na), CPPMINUS);
79072805 1571 doextract = FALSE;
1572#ifdef IAMSUID /* actually, this is caught earlier */
1573 if (euid != uid && !euid) { /* if running suidperl */
1574#ifdef HAS_SETEUID
1575 (void)seteuid(uid); /* musn't stay setuid root */
1576#else
1577#ifdef HAS_SETREUID
85e6fe83 1578 (void)setreuid((Uid_t)-1, uid);
1579#else
1580#ifdef HAS_SETRESUID
1581 (void)setresuid((Uid_t)-1, uid, (Uid_t)-1);
79072805 1582#else
1583 setuid(uid);
1584#endif
1585#endif
85e6fe83 1586#endif
79072805 1587 if (geteuid() != uid)
463ee0b2 1588 croak("Can't do seteuid!\n");
79072805 1589 }
1590#endif /* IAMSUID */
1591 rsfp = my_popen(buf,"r");
1592 }
1593 else if (!*scriptname) {
bbce6d69 1594 forbid_setid("program input from stdin");
760ac839 1595 rsfp = PerlIO_stdin();
79072805 1596 }
96436eeb 1597 else {
760ac839 1598 rsfp = PerlIO_open(scriptname,"r");
96436eeb 1599#if defined(HAS_FCNTL) && defined(F_SETFD)
760ac839 1600 fcntl(PerlIO_fileno(rsfp),F_SETFD,1); /* ensure close-on-exec */
96436eeb 1601#endif
1602 }
5dd60ef7 1603 if (e_tmpname) {
1604 e_fp = rsfp;
1605 }
760ac839 1606 if ((PerlIO*)rsfp == Nullfp) {
13281fa4 1607#ifdef DOSUID
a687059c 1608#ifndef IAMSUID /* in case script is not readable before setuid */
a0d0e21e 1609 if (euid && Stat(SvPVX(GvSV(curcop->cop_filegv)),&statbuf) >= 0 &&
13281fa4 1610 statbuf.st_mode & (S_ISUID|S_ISGID)) {
27e2fb84 1611 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1612 execv(buf, origargv); /* try again */
463ee0b2 1613 croak("Can't do setuid\n");
13281fa4 1614 }
1615#endif
1616#endif
463ee0b2 1617 croak("Can't open perl script \"%s\": %s\n",
2304df62 1618 SvPVX(GvSV(curcop->cop_filegv)), Strerror(errno));
13281fa4 1619 }
79072805 1620}
8d063cd8 1621
79072805 1622static void
96436eeb 1623validate_suid(validarg, scriptname)
79072805 1624char *validarg;
96436eeb 1625char *scriptname;
79072805 1626{
96436eeb 1627 int which;
1628
13281fa4 1629 /* do we need to emulate setuid on scripts? */
1630
1631 /* This code is for those BSD systems that have setuid #! scripts disabled
1632 * in the kernel because of a security problem. Merely defining DOSUID
1633 * in perl will not fix that problem, but if you have disabled setuid
1634 * scripts in the kernel, this will attempt to emulate setuid and setgid
1635 * on scripts that have those now-otherwise-useless bits set. The setuid
27e2fb84 1636 * root version must be called suidperl or sperlN.NNN. If regular perl
1637 * discovers that it has opened a setuid script, it calls suidperl with
1638 * the same argv that it had. If suidperl finds that the script it has
1639 * just opened is NOT setuid root, it sets the effective uid back to the
1640 * uid. We don't just make perl setuid root because that loses the
1641 * effective uid we had before invoking perl, if it was different from the
1642 * uid.
13281fa4 1643 *
1644 * DOSUID must be defined in both perl and suidperl, and IAMSUID must
1645 * be defined in suidperl only. suidperl must be setuid root. The
1646 * Configure script will set this up for you if you want it.
1647 */
a687059c 1648
13281fa4 1649#ifdef DOSUID
6e72f9df 1650 char *s, *s2;
a0d0e21e 1651
760ac839 1652 if (Fstat(PerlIO_fileno(rsfp),&statbuf) < 0) /* normal stat is insecure */
463ee0b2 1653 croak("Can't stat script \"%s\"",origfilename);
96436eeb 1654 if (fdscript < 0 && statbuf.st_mode & (S_ISUID|S_ISGID)) {
79072805 1655 I32 len;
13281fa4 1656
a687059c 1657#ifdef IAMSUID
fe14fcc3 1658#ifndef HAS_SETREUID
a687059c 1659 /* On this access check to make sure the directories are readable,
1660 * there is actually a small window that the user could use to make
1661 * filename point to an accessible directory. So there is a faint
1662 * chance that someone could execute a setuid script down in a
1663 * non-accessible directory. I don't know what to do about that.
1664 * But I don't think it's too important. The manual lies when
1665 * it says access() is useful in setuid programs.
1666 */
463ee0b2 1667 if (access(SvPVX(GvSV(curcop->cop_filegv)),1)) /*double check*/
1668 croak("Permission denied");
a687059c 1669#else
1670 /* If we can swap euid and uid, then we can determine access rights
1671 * with a simple stat of the file, and then compare device and
1672 * inode to make sure we did stat() on the same file we opened.
1673 * Then we just have to make sure he or she can execute it.
1674 */
1675 {
1676 struct stat tmpstatbuf;
1677
85e6fe83 1678 if (
1679#ifdef HAS_SETREUID
1680 setreuid(euid,uid) < 0
a0d0e21e 1681#else
1682# if HAS_SETRESUID
85e6fe83 1683 setresuid(euid,uid,(Uid_t)-1) < 0
a0d0e21e 1684# endif
85e6fe83 1685#endif
1686 || getuid() != euid || geteuid() != uid)
463ee0b2 1687 croak("Can't swap uid and euid"); /* really paranoid */
a0d0e21e 1688 if (Stat(SvPVX(GvSV(curcop->cop_filegv)),&tmpstatbuf) < 0)
463ee0b2 1689 croak("Permission denied"); /* testing full pathname here */
a687059c 1690 if (tmpstatbuf.st_dev != statbuf.st_dev ||
1691 tmpstatbuf.st_ino != statbuf.st_ino) {
760ac839 1692 (void)PerlIO_close(rsfp);
79072805 1693 if (rsfp = my_popen("/bin/mail root","w")) { /* heh, heh */
760ac839 1694 PerlIO_printf(rsfp,
a687059c 1695"User %d tried to run dev %d ino %d in place of dev %d ino %d!\n\
1696(Filename of set-id script was %s, uid %d gid %d.)\n\nSincerely,\nperl\n",
1697 uid,tmpstatbuf.st_dev, tmpstatbuf.st_ino,
1698 statbuf.st_dev, statbuf.st_ino,
463ee0b2 1699 SvPVX(GvSV(curcop->cop_filegv)),
20188a90 1700 statbuf.st_uid, statbuf.st_gid);
79072805 1701 (void)my_pclose(rsfp);
a687059c 1702 }
463ee0b2 1703 croak("Permission denied\n");
a687059c 1704 }
85e6fe83 1705 if (
1706#ifdef HAS_SETREUID
1707 setreuid(uid,euid) < 0
a0d0e21e 1708#else
1709# if defined(HAS_SETRESUID)
85e6fe83 1710 setresuid(uid,euid,(Uid_t)-1) < 0
a0d0e21e 1711# endif
85e6fe83 1712#endif
1713 || getuid() != uid || geteuid() != euid)
463ee0b2 1714 croak("Can't reswap uid and euid");
27e2fb84 1715 if (!cando(S_IXUSR,FALSE,&statbuf)) /* can real uid exec? */
463ee0b2 1716 croak("Permission denied\n");
a687059c 1717 }
fe14fcc3 1718#endif /* HAS_SETREUID */
a687059c 1719#endif /* IAMSUID */
1720
27e2fb84 1721 if (!S_ISREG(statbuf.st_mode))
463ee0b2 1722 croak("Permission denied");
27e2fb84 1723 if (statbuf.st_mode & S_IWOTH)
463ee0b2 1724 croak("Setuid/gid script is writable by world");
13281fa4 1725 doswitches = FALSE; /* -s is insecure in suid */
79072805 1726 curcop->cop_line++;
760ac839 1727 if (sv_gets(linestr, rsfp, 0) == Nullch ||
1728 strnNE(SvPV(linestr,na),"#!",2) ) /* required even on Sys V */
463ee0b2 1729 croak("No #! line");
760ac839 1730 s = SvPV(linestr,na)+2;
663a0e37 1731 if (*s == ' ') s++;
45d8adaa 1732 while (!isSPACE(*s)) s++;
760ac839 1733 for (s2 = s; (s2 > SvPV(linestr,na)+2 &&
6e72f9df 1734 (isDIGIT(s2[-1]) || strchr("._-", s2[-1]))); s2--) ;
1735 if (strnNE(s2-4,"perl",4) && strnNE(s-9,"perl",4)) /* sanity check */
463ee0b2 1736 croak("Not a perl script");
a687059c 1737 while (*s == ' ' || *s == '\t') s++;
13281fa4 1738 /*
1739 * #! arg must be what we saw above. They can invoke it by
1740 * mentioning suidperl explicitly, but they may not add any strange
1741 * arguments beyond what #! says if they do invoke suidperl that way.
1742 */
1743 len = strlen(validarg);
1744 if (strEQ(validarg," PHOOEY ") ||
45d8adaa 1745 strnNE(s,validarg,len) || !isSPACE(s[len]))
463ee0b2 1746 croak("Args must match #! line");
a687059c 1747
1748#ifndef IAMSUID
1749 if (euid != uid && (statbuf.st_mode & S_ISUID) &&
1750 euid == statbuf.st_uid)
1751 if (!do_undump)
463ee0b2 1752 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c 1753FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1754#endif /* IAMSUID */
13281fa4 1755
1756 if (euid) { /* oops, we're not the setuid root perl */
760ac839 1757 (void)PerlIO_close(rsfp);
13281fa4 1758#ifndef IAMSUID
27e2fb84 1759 (void)sprintf(buf, "%s/sperl%s", BIN, patchlevel);
a687059c 1760 execv(buf, origargv); /* try again */
13281fa4 1761#endif
463ee0b2 1762 croak("Can't do setuid\n");
13281fa4 1763 }
1764
83025b21 1765 if (statbuf.st_mode & S_ISGID && statbuf.st_gid != egid) {
fe14fcc3 1766#ifdef HAS_SETEGID
a687059c 1767 (void)setegid(statbuf.st_gid);
1768#else
fe14fcc3 1769#ifdef HAS_SETREGID
85e6fe83 1770 (void)setregid((Gid_t)-1,statbuf.st_gid);
1771#else
1772#ifdef HAS_SETRESGID
1773 (void)setresgid((Gid_t)-1,statbuf.st_gid,(Gid_t)-1);
a687059c 1774#else
1775 setgid(statbuf.st_gid);
1776#endif
1777#endif
85e6fe83 1778#endif
83025b21 1779 if (getegid() != statbuf.st_gid)
463ee0b2 1780 croak("Can't do setegid!\n");
83025b21 1781 }
a687059c 1782 if (statbuf.st_mode & S_ISUID) {
1783 if (statbuf.st_uid != euid)
fe14fcc3 1784#ifdef HAS_SETEUID
a687059c 1785 (void)seteuid(statbuf.st_uid); /* all that for this */
1786#else
fe14fcc3 1787#ifdef HAS_SETREUID
85e6fe83 1788 (void)setreuid((Uid_t)-1,statbuf.st_uid);
1789#else
1790#ifdef HAS_SETRESUID
1791 (void)setresuid((Uid_t)-1,statbuf.st_uid,(Uid_t)-1);
a687059c 1792#else
1793 setuid(statbuf.st_uid);
1794#endif
1795#endif
85e6fe83 1796#endif
83025b21 1797 if (geteuid() != statbuf.st_uid)
463ee0b2 1798 croak("Can't do seteuid!\n");
a687059c 1799 }
83025b21 1800 else if (uid) { /* oops, mustn't run as root */
fe14fcc3 1801#ifdef HAS_SETEUID
85e6fe83 1802 (void)seteuid((Uid_t)uid);
a687059c 1803#else
fe14fcc3 1804#ifdef HAS_SETREUID
85e6fe83 1805 (void)setreuid((Uid_t)-1,(Uid_t)uid);
a687059c 1806#else
85e6fe83 1807#ifdef HAS_SETRESUID
1808 (void)setresuid((Uid_t)-1,(Uid_t)uid,(Uid_t)-1);
1809#else
1810 setuid((Uid_t)uid);
1811#endif
a687059c 1812#endif
1813#endif
83025b21 1814 if (geteuid() != uid)
463ee0b2 1815 croak("Can't do seteuid!\n");
83025b21 1816 }
748a9306 1817 init_ids();
27e2fb84 1818 if (!cando(S_IXUSR,TRUE,&statbuf))
463ee0b2 1819 croak("Permission denied\n"); /* they can't do this */
13281fa4 1820 }
1821#ifdef IAMSUID
1822 else if (preprocess)
463ee0b2 1823 croak("-P not allowed for setuid/setgid script\n");
96436eeb 1824 else if (fdscript >= 0)
1825 croak("fd script not allowed in suidperl\n");
13281fa4 1826 else
463ee0b2 1827 croak("Script is not setuid/setgid in suidperl\n");
96436eeb 1828
1829 /* We absolutely must clear out any saved ids here, so we */
1830 /* exec the real perl, substituting fd script for scriptname. */
1831 /* (We pass script name as "subdir" of fd, which perl will grok.) */
760ac839 1832 PerlIO_rewind(rsfp);
1833 lseek(PerlIO_fileno(rsfp),(Off_t)0,0); /* just in case rewind didn't */
96436eeb 1834 for (which = 1; origargv[which] && origargv[which] != scriptname; which++) ;
1835 if (!origargv[which])
1836 croak("Permission denied");
760ac839 1837 (void)sprintf(buf, "/dev/fd/%d/%.127s", PerlIO_fileno(rsfp), origargv[which]);
96436eeb 1838 origargv[which] = buf;
1839
1840#if defined(HAS_FCNTL) && defined(F_SETFD)
760ac839 1841 fcntl(PerlIO_fileno(rsfp),F_SETFD,0); /* ensure no close-on-exec */
96436eeb 1842#endif
1843
1844 (void)sprintf(tokenbuf, "%s/perl%s", BIN, patchlevel);
1845 execv(tokenbuf, origargv); /* try again */
1846 croak("Can't do setuid\n");
13281fa4 1847#endif /* IAMSUID */
a687059c 1848#else /* !DOSUID */
a687059c 1849 if (euid != uid || egid != gid) { /* (suidperl doesn't exist, in fact) */
1850#ifndef SETUID_SCRIPTS_ARE_SECURE_NOW
760ac839 1851 Fstat(PerlIO_fileno(rsfp),&statbuf); /* may be either wrapped or real suid */
a687059c 1852 if ((euid != uid && euid == statbuf.st_uid && statbuf.st_mode & S_ISUID)
1853 ||
1854 (egid != gid && egid == statbuf.st_gid && statbuf.st_mode & S_ISGID)
1855 )
1856 if (!do_undump)
463ee0b2 1857 croak("YOU HAVEN'T DISABLED SET-ID SCRIPTS IN THE KERNEL YET!\n\
a687059c 1858FIX YOUR KERNEL, PUT A C WRAPPER AROUND THIS SCRIPT, OR USE -u AND UNDUMP!\n");
1859#endif /* SETUID_SCRIPTS_ARE_SECURE_NOW */
1860 /* not set-id, must be wrapped */
a687059c 1861 }
13281fa4 1862#endif /* DOSUID */
79072805 1863}
13281fa4 1864
79072805 1865static void
1866find_beginning()
1867{
6e72f9df 1868 register char *s, *s2;
33b78306 1869
1870 /* skip forward in input to the real script? */
1871
bbce6d69 1872 forbid_setid("-x");
33b78306 1873 while (doextract) {
79072805 1874 if ((s = sv_gets(linestr, rsfp, 0)) == Nullch)
463ee0b2 1875 croak("No Perl script found in input\n");
6e72f9df 1876 if (*s == '#' && s[1] == '!' && (s = instr(s,"perl"))) {
760ac839 1877 PerlIO_ungetc(rsfp, '\n'); /* to keep line count right */
33b78306 1878 doextract = FALSE;
6e72f9df 1879 while (*s && !(isSPACE (*s) || *s == '#')) s++;
1880 s2 = s;
1881 while (*s == ' ' || *s == '\t') s++;
1882 if (*s++ == '-') {
1883 while (isDIGIT(s2[-1]) || strchr("-._", s2[-1])) s2--;
1884 if (strnEQ(s2-4,"perl",4))
1885 /*SUPPRESS 530*/
1886 while (s = moreswitches(s)) ;
33b78306 1887 }
79072805 1888 if (cddir && chdir(cddir) < 0)
463ee0b2 1889 croak("Can't chdir to %s",cddir);
83025b21 1890 }
1891 }
1892}
1893
79072805 1894static void
748a9306 1895init_ids()
352d5a3a 1896{
748a9306 1897 uid = (int)getuid();
1898 euid = (int)geteuid();
1899 gid = (int)getgid();
1900 egid = (int)getegid();
1901#ifdef VMS
1902 uid |= gid << 16;
1903 euid |= egid << 16;
1904#endif
4633a7c4 1905 tainting |= (uid && (euid != uid || egid != gid));
748a9306 1906}
79072805 1907
748a9306 1908static void
bbce6d69 1909forbid_setid(s)
1910char *s;
1911{
1912 if (euid != uid)
1913 croak("No %s allowed while running setuid", s);
1914 if (egid != gid)
1915 croak("No %s allowed while running setgid", s);
1916}
1917
1918static void
748a9306 1919init_debugger()
1920{
79072805 1921 curstash = debstash;
748a9306 1922 dbargs = GvAV(gv_AVadd((gv_fetchpv("args", GV_ADDMULTI, SVt_PVAV))));
79072805 1923 AvREAL_off(dbargs);
a0d0e21e 1924 DBgv = gv_fetchpv("DB", GV_ADDMULTI, SVt_PVGV);
1925 DBline = gv_fetchpv("dbline", GV_ADDMULTI, SVt_PVAV);
748a9306 1926 DBsub = gv_HVadd(gv_fetchpv("sub", GV_ADDMULTI, SVt_PVHV));
1927 DBsingle = GvSV((gv_fetchpv("single", GV_ADDMULTI, SVt_PV)));
c07a80fd 1928 sv_setiv(DBsingle, 0);
748a9306 1929 DBtrace = GvSV((gv_fetchpv("trace", GV_ADDMULTI, SVt_PV)));
c07a80fd 1930 sv_setiv(DBtrace, 0);
748a9306 1931 DBsignal = GvSV((gv_fetchpv("signal", GV_ADDMULTI, SVt_PV)));
c07a80fd 1932 sv_setiv(DBsignal, 0);
79072805 1933 curstash = defstash;
352d5a3a 1934}
1935
79072805 1936static void
8990e307 1937init_stacks()
79072805 1938{
6e72f9df 1939 curstack = newAV();
1940 mainstack = curstack; /* remember in case we switch stacks */
1941 AvREAL_off(curstack); /* not a real array */
1942 av_extend(curstack,127);
79072805 1943
6e72f9df 1944 stack_base = AvARRAY(curstack);
79072805 1945 stack_sp = stack_base;
8990e307 1946 stack_max = stack_base + 127;
79072805 1947
6e72f9df 1948 /* Shouldn't these stacks be per-interpreter? */
1949 if (markstack) {
1950 markstack_ptr = markstack;
1951 } else {
1952 New(54,markstack,64,I32);
1953 markstack_ptr = markstack;
1954 markstack_max = markstack + 64;
1955 }
79072805 1956
6e72f9df 1957 if (scopestack) {
1958 scopestack_ix = 0;
1959 } else {
1960 New(54,scopestack,32,I32);
1961 scopestack_ix = 0;
1962 scopestack_max = 32;
1963 }
79072805 1964
6e72f9df 1965 if (savestack) {
1966 savestack_ix = 0;
1967 } else {
1968 New(54,savestack,128,ANY);
1969 savestack_ix = 0;
1970 savestack_max = 128;
1971 }
79072805 1972
6e72f9df 1973 if (retstack) {
1974 retstack_ix = 0;
1975 } else {
1976 New(54,retstack,16,OP*);
1977 retstack_ix = 0;
1978 retstack_max = 16;
1979 }
8d063cd8 1980
a5f75d66 1981 cxstack_max = 8192 / sizeof(CONTEXT) - 2; /* Use most of 8K. */
1982 New(50,cxstack,cxstack_max + 1,CONTEXT);
8990e307 1983 cxstack_ix = -1;
8990e307 1984
1985 New(50,tmps_stack,128,SV*);
1986 tmps_ix = -1;
1987 tmps_max = 128;
1988
79072805 1989 DEBUG( {
1990 New(51,debname,128,char);
1991 New(52,debdelim,128,char);
1992 } )
378cc40b 1993}
33b78306 1994
6e72f9df 1995static void
1996nuke_stacks()
1997{
1998 Safefree(cxstack);
1999 Safefree(tmps_stack);
2000}
2001
760ac839 2002static PerlIO *tmpfp; /* moved outside init_lexer() because of UNICOS bug */
79072805 2003static void
8990e307 2004init_lexer()
2005{
a0d0e21e 2006 tmpfp = rsfp;
8990e307 2007
2008 lex_start(linestr);
2009 rsfp = tmpfp;
2010 subname = newSVpv("main",4);
2011}
2012
2013static void
79072805 2014init_predump_symbols()
45d8adaa 2015{
93a17b20 2016 GV *tmpgv;
a0d0e21e 2017 GV *othergv;
79072805 2018
85e6fe83 2019 sv_setpvn(GvSV(gv_fetchpv("\"", TRUE, SVt_PV)), " ", 1);
79072805 2020
85e6fe83 2021 stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
a5f75d66 2022 GvMULTI_on(stdingv);
760ac839 2023 IoIFP(GvIOp(stdingv)) = PerlIO_stdin();
adbc6bb1 2024 tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
a5f75d66 2025 GvMULTI_on(tmpgv);
a0d0e21e 2026 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
79072805 2027
85e6fe83 2028 tmpgv = gv_fetchpv("STDOUT",TRUE, SVt_PVIO);
a5f75d66 2029 GvMULTI_on(tmpgv);
760ac839 2030 IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = PerlIO_stdout();
4633a7c4 2031 setdefout(tmpgv);
adbc6bb1 2032 tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
a5f75d66 2033 GvMULTI_on(tmpgv);
a0d0e21e 2034 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
79072805 2035
a0d0e21e 2036 othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
a5f75d66 2037 GvMULTI_on(othergv);
760ac839 2038 IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = PerlIO_stderr();
adbc6bb1 2039 tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
a5f75d66 2040 GvMULTI_on(tmpgv);
a0d0e21e 2041 GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
79072805 2042
2043 statname = NEWSV(66,0); /* last filename we did stat on */
ab821d7f 2044
6e72f9df 2045 if (!osname)
2046 osname = savepv(OSNAME);
79072805 2047}
33b78306 2048
79072805 2049static void
2050init_postdump_symbols(argc,argv,env)
2051register int argc;
2052register char **argv;
2053register char **env;
33b78306 2054{
79072805 2055 char *s;
2056 SV *sv;
2057 GV* tmpgv;
fe14fcc3 2058
79072805 2059 argc--,argv++; /* skip name of script */
2060 if (doswitches) {
2061 for (; argc > 0 && **argv == '-'; argc--,argv++) {
2062 if (!argv[0][1])
2063 break;
2064 if (argv[0][1] == '-') {
2065 argc--,argv++;
2066 break;
2067 }
93a17b20 2068 if (s = strchr(argv[0], '=')) {
79072805 2069 *s++ = '\0';
85e6fe83 2070 sv_setpv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),s);
79072805 2071 }
2072 else
85e6fe83 2073 sv_setiv(GvSV(gv_fetchpv(argv[0]+1,TRUE, SVt_PV)),1);
fe14fcc3 2074 }
79072805 2075 }
2076 toptarget = NEWSV(0,0);
2077 sv_upgrade(toptarget, SVt_PVFM);
2078 sv_setpvn(toptarget, "", 0);
748a9306 2079 bodytarget = NEWSV(0,0);
79072805 2080 sv_upgrade(bodytarget, SVt_PVFM);
2081 sv_setpvn(bodytarget, "", 0);
2082 formtarget = bodytarget;
2083
bbce6d69 2084 TAINT;
85e6fe83 2085 if (tmpgv = gv_fetchpv("0",TRUE, SVt_PV)) {
79072805 2086 sv_setpv(GvSV(tmpgv),origfilename);
2087 magicname("0", "0", 1);
2088 }
85e6fe83 2089 if (tmpgv = gv_fetchpv("\024",TRUE, SVt_PV))
79072805 2090 time(&basetime);
85e6fe83 2091 if (tmpgv = gv_fetchpv("\030",TRUE, SVt_PV))
79072805 2092 sv_setpv(GvSV(tmpgv),origargv[0]);
85e6fe83 2093 if (argvgv = gv_fetchpv("ARGV",TRUE, SVt_PVAV)) {
a5f75d66 2094 GvMULTI_on(argvgv);
79072805 2095 (void)gv_AVadd(argvgv);
2096 av_clear(GvAVn(argvgv));
2097 for (; argc > 0; argc--,argv++) {
a0d0e21e 2098 av_push(GvAVn(argvgv),newSVpv(argv[0],0));
79072805 2099 }
2100 }
85e6fe83 2101 if (envgv = gv_fetchpv("ENV",TRUE, SVt_PVHV)) {
79072805 2102 HV *hv;
a5f75d66 2103 GvMULTI_on(envgv);
79072805 2104 hv = GvHVn(envgv);
463ee0b2 2105 hv_clear(hv);
a0d0e21e 2106#ifndef VMS /* VMS doesn't have environ array */
4633a7c4 2107 /* Note that if the supplied env parameter is actually a copy
2108 of the global environ then it may now point to free'd memory
2109 if the environment has been modified since. To avoid this
2110 problem we treat env==NULL as meaning 'use the default'
2111 */
2112 if (!env)
2113 env = environ;
8990e307 2114 if (env != environ) {
79072805 2115 environ[0] = Nullch;
8990e307 2116 hv_magic(hv, envgv, 'E');
2117 }
79072805 2118 for (; *env; env++) {
93a17b20 2119 if (!(s = strchr(*env,'=')))
79072805 2120 continue;
2121 *s++ = '\0';
2122 sv = newSVpv(s--,0);
85e6fe83 2123 sv_magic(sv, sv, 'e', *env, s - *env);
79072805 2124 (void)hv_store(hv, *env, s - *env, sv, 0);
2125 *s = '=';
fe14fcc3 2126 }
4550b24a 2127#endif
2128#ifdef DYNAMIC_ENV_FETCH
2129 HvNAME(hv) = savepv(ENV_HV_NAME);
2130#endif
f511e57f 2131 hv_magic(hv, envgv, 'E');
79072805 2132 }
bbce6d69 2133 TAINT_NOT;
85e6fe83 2134 if (tmpgv = gv_fetchpv("$",TRUE, SVt_PV))
79072805 2135 sv_setiv(GvSV(tmpgv),(I32)getpid());
33b78306 2136}
34de22dd 2137
79072805 2138static void
2139init_perllib()
34de22dd 2140{
85e6fe83 2141 char *s;
2142 if (!tainting) {
552a7a9b 2143#ifndef VMS
85e6fe83 2144 s = getenv("PERL5LIB");
2145 if (s)
2146 incpush(s);
2147 else
2148 incpush(getenv("PERLLIB"));
552a7a9b 2149#else /* VMS */
2150 /* Treat PERL5?LIB as a possible search list logical name -- the
2151 * "natural" VMS idiom for a Unix path string. We allow each
2152 * element to be a set of |-separated directories for compatibility.
2153 */
2154 char buf[256];
2155 int idx = 0;
2156 if (my_trnlnm("PERL5LIB",buf,0))
2157 do { incpush(buf); } while (my_trnlnm("PERL5LIB",buf,++idx));
2158 else
2159 while (my_trnlnm("PERLLIB",buf,idx++)) incpush(buf);
2160#endif /* VMS */
85e6fe83 2161 }
34de22dd 2162
df5cef82 2163/* Use the ~-expanded versions of APPLIB (undocumented),
2164 ARCHLIB PRIVLIB SITEARCH SITELIB and OLDARCHLIB
2165*/
4633a7c4 2166#ifdef APPLLIB_EXP
2167 incpush(APPLLIB_EXP);
16d20bd9 2168#endif
4633a7c4 2169
fed7345c 2170#ifdef ARCHLIB_EXP
2171 incpush(ARCHLIB_EXP);
a0d0e21e 2172#endif
fed7345c 2173#ifndef PRIVLIB_EXP
2174#define PRIVLIB_EXP "/usr/local/lib/perl5:/usr/local/lib/perl"
34de22dd 2175#endif
fed7345c 2176 incpush(PRIVLIB_EXP);
4633a7c4 2177
2178#ifdef SITEARCH_EXP
2179 incpush(SITEARCH_EXP);
2180#endif
2181#ifdef SITELIB_EXP
2182 incpush(SITELIB_EXP);
2183#endif
2184#ifdef OLDARCHLIB_EXP /* 5.00[01] compatibility */
2185 incpush(OLDARCHLIB_EXP);
2186#endif
a0d0e21e 2187
4633a7c4 2188 if (!tainting)
2189 incpush(".");
34de22dd 2190}
93a17b20 2191
2192void
2193calllist(list)
2194AV* list;
2195{
a5f75d66 2196 Sigjmp_buf oldtop;
a0d0e21e 2197 STRLEN len;
2198 line_t oldline = curcop->cop_line;
93a17b20 2199
a5f75d66 2200 Copy(top_env, oldtop, 1, Sigjmp_buf);
93a17b20 2201
8990e307 2202 while (AvFILL(list) >= 0) {
2203 CV *cv = (CV*)av_shift(list);
93a17b20 2204
8990e307 2205 SAVEFREESV(cv);
a0d0e21e 2206
a5f75d66 2207 switch (Sigsetjmp(top_env,1)) {
748a9306 2208 case 0: {
4633a7c4 2209 SV* atsv = GvSV(errgv);
748a9306 2210 PUSHMARK(stack_sp);
2211 perl_call_sv((SV*)cv, G_EVAL|G_DISCARD);
2212 (void)SvPV(atsv, len);
2213 if (len) {
a5f75d66 2214 Copy(oldtop, top_env, 1, Sigjmp_buf);
748a9306 2215 curcop = &compiling;
2216 curcop->cop_line = oldline;
2217 if (list == beginav)
2218 sv_catpv(atsv, "BEGIN failed--compilation aborted");
2219 else
2220 sv_catpv(atsv, "END failed--cleanup aborted");
2221 croak("%s", SvPVX(atsv));
2222 }
a0d0e21e 2223 }
85e6fe83 2224 break;
2225 case 1:
748a9306 2226#ifdef VMS
85e6fe83 2227 statusvalue = 255; /* XXX I don't think we use 1 anymore. */
748a9306 2228#else
2229 statusvalue = 1;
2230#endif
85e6fe83 2231 /* FALL THROUGH */
2232 case 2:
2233 /* my_exit() was called */
2234 curstash = defstash;
2235 if (endav)
2236 calllist(endav);
a0d0e21e 2237 FREETMPS;
a5f75d66 2238 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 2239 curcop = &compiling;
2240 curcop->cop_line = oldline;
85e6fe83 2241 if (statusvalue) {
2242 if (list == beginav)
a0d0e21e 2243 croak("BEGIN failed--compilation aborted");
85e6fe83 2244 else
a0d0e21e 2245 croak("END failed--cleanup aborted");
85e6fe83 2246 }
85e6fe83 2247 my_exit(statusvalue);
2248 /* NOTREACHED */
2249 return;
2250 case 3:
2251 if (!restartop) {
760ac839 2252 PerlIO_printf(PerlIO_stderr(), "panic: restartop\n");
a0d0e21e 2253 FREETMPS;
85e6fe83 2254 break;
2255 }
a5f75d66 2256 Copy(oldtop, top_env, 1, Sigjmp_buf);
a0d0e21e 2257 curcop = &compiling;
2258 curcop->cop_line = oldline;
a5f75d66 2259 Siglongjmp(top_env, 3);
8990e307 2260 }
93a17b20 2261 }
2262
a5f75d66 2263 Copy(oldtop, top_env, 1, Sigjmp_buf);
93a17b20 2264}
2265