home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / Perl5 / perl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-22  |  41.5 KB  |  1,897 lines  |  [TEXT/MPS ]

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