perl 3.0 patch #33 patch #29, continued
[p5sagit/p5-mst-13.2.git] / usersub.c
1 /* $Header: usersub.c,v 3.0.1.1 90/08/09 05:40:45 lwall Locked $
2  *
3  *  This file contains stubs for routines that the user may define to
4  *  set up glue routines for C libraries or to decrypt encrypted scripts
5  *  for execution.
6  *
7  * $Log:        usersub.c,v $
8  * Revision 3.0.1.1  90/08/09  05:40:45  lwall
9  * patch19: Initial revision
10  * 
11  */
12
13 #include "EXTERN.h"
14 #include "perl.h"
15
16 userinit()
17 {
18     return 0;
19 }
20
21 /*
22  * The following is supplied by John MacDonald as a means of decrypting
23  * and executing (presumably proprietary) scripts that have been encrypted
24  * by a (presumably secret) method.  The idea is that you supply your own
25  * routine in place of cryptfilter (which is purposefully a very weak
26  * encryption).  If an encrypted script is detected, a process is forked
27  * off to run the cryptfilter routine as input to perl.
28  */
29
30 #ifdef CRYPTSCRIPT
31
32 #include <signal.h>
33 #ifdef I_VFORK
34 #include <vfork.h>
35 #endif
36
37 #define CRYPT_MAGIC_1   0xfb
38 #define CRYPT_MAGIC_2   0xf1
39
40 cryptfilter( fil )
41 FILE *  fil;
42 {
43     int    ch;
44
45     while( (ch = getc( fil )) != EOF ) {
46         putchar( (ch ^ 0x80) );
47     }
48 }
49
50 #ifndef MSDOS
51 static FILE     *lastpipefile;
52 static int      pipepid;
53
54 #ifdef VOIDSIG
55 #  define       VOID    void
56 #else
57 #  define       VOID    int
58 #endif
59
60 FILE *
61 mypfiopen(fil,func)             /* open a pipe to function call for input */
62 FILE    *fil;
63 VOID    (*func)();
64 {
65     int p[2];
66     STR *str;
67
68     if (pipe(p) < 0) {
69         fclose( fil );
70         fatal("Can't get pipe for decrypt");
71     }
72
73     /* make sure that the child doesn't get anything extra */
74     fflush(stdout);
75     fflush(stderr);
76
77     while ((pipepid = fork()) < 0) {
78         if (errno != EAGAIN) {
79             close(p[0]);
80             close(p[1]);
81             fclose( fil );
82             fatal("Can't fork for decrypt");
83         }
84         sleep(5);
85     }
86     if (pipepid == 0) {
87         close(p[0]);
88         if (p[1] != 1) {
89             dup2(p[1], 1);
90             close(p[1]);
91         }
92         (*func)(fil);
93         fflush(stdout);
94         fflush(stderr);
95         _exit(0);
96     }
97     close(p[1]);
98     fclose(fil);
99     str = afetch(pidstatary,p[0],TRUE);
100     str_numset(str,(double)pipepid);
101     str->str_cur = 0;
102     return fdopen(p[0], "r");
103 }
104
105 cryptswitch()
106 {
107     int ch;
108 #ifdef STDSTDIO
109     /* cheat on stdio if possible */
110     if (rsfp->_cnt > 0 && (*rsfp->_ptr & 0xff) != CRYPT_MAGIC_1)
111         return;
112 #endif
113     ch = getc(rsfp);
114     if (ch == CRYPT_MAGIC_1) {
115         if (getc(rsfp) == CRYPT_MAGIC_2) {
116             rsfp = mypfiopen( rsfp, cryptfilter );
117             preprocess = 1;     /* force call to pclose when done */
118         }
119         else
120             fatal( "bad encryption format" );
121     }
122     else
123         ungetc(ch,rsfp);
124 }
125
126 FILE *
127 cryptopen(cmd)          /* open a (possibly encrypted) program for input */
128 char    *cmd;
129 {
130     FILE        *fil = fopen( cmd, "r" );
131
132     lastpipefile = Nullfp;
133     pipepid = 0;
134
135     if( fil ) {
136         int     ch = getc( fil );
137         int     lines = 0;
138         int     chars = 0;
139
140         /* Search for the magic cookie that starts the encrypted script,
141         ** while still allowing a few lines of unencrypted text to let
142         ** '#!' and the nih hack both continue to work.  (These lines
143         ** will end up being ignored.)
144         */
145         while( ch != CRYPT_MAGIC_1 && ch != EOF && lines < 5 && chars < 300 ) {
146             if( ch == '\n' )
147                 ++lines;
148             ch = getc( fil );
149             ++chars;
150         }
151
152         if( ch == CRYPT_MAGIC_1 ) {
153             if( (ch = getc( fil ) ) == CRYPT_MAGIC_2 ) {
154                 if( perldb ) fatal("can't debug an encrypted script");
155                 /* we found it, decrypt the rest of the file */
156                 fil = mypfiopen( fil, cryptfilter );
157                 return( lastpipefile = fil );
158             } else
159                 /* if its got MAGIC 1 without MAGIC 2, too bad */
160                 fatal( "bad encryption format" );
161         }
162
163         /* this file is not encrypted - rewind and process it normally */
164         rewind( fil );
165     }
166
167     return( fil );
168 }
169
170 VOID
171 cryptclose(fil)
172 FILE    *fil;
173 {
174     if( fil == Nullfp )
175         return;
176
177     if( fil == lastpipefile )
178         mypclose( fil );
179     else
180         fclose( fil );
181 }
182 #endif /* !MSDOS */
183
184 #endif /* CRYPTSCRIPT */