Commit | Line | Data |
---|---|---|
fe14fcc3 | 1 | /* $Header: usersub.c,v 4.0 91/03/20 01:55:56 lwall Locked $ |
62b28dd9 LW |
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 $ | |
fe14fcc3 LW |
8 | * Revision 4.0 91/03/20 01:55:56 lwall |
9 | * 4.0 baseline. | |
62b28dd9 LW |
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); | |
20188a90 LW |
99 | str = afetch(fdpid,p[0],TRUE); |
100 | str->str_u.str_useful = pipepid; | |
62b28dd9 LW |
101 | return fdopen(p[0], "r"); |
102 | } | |
103 | ||
104 | cryptswitch() | |
105 | { | |
106 | int ch; | |
107 | #ifdef STDSTDIO | |
108 | /* cheat on stdio if possible */ | |
109 | if (rsfp->_cnt > 0 && (*rsfp->_ptr & 0xff) != CRYPT_MAGIC_1) | |
110 | return; | |
111 | #endif | |
112 | ch = getc(rsfp); | |
113 | if (ch == CRYPT_MAGIC_1) { | |
114 | if (getc(rsfp) == CRYPT_MAGIC_2) { | |
115 | rsfp = mypfiopen( rsfp, cryptfilter ); | |
116 | preprocess = 1; /* force call to pclose when done */ | |
117 | } | |
118 | else | |
119 | fatal( "bad encryption format" ); | |
120 | } | |
121 | else | |
122 | ungetc(ch,rsfp); | |
123 | } | |
124 | ||
125 | FILE * | |
126 | cryptopen(cmd) /* open a (possibly encrypted) program for input */ | |
127 | char *cmd; | |
128 | { | |
129 | FILE *fil = fopen( cmd, "r" ); | |
130 | ||
131 | lastpipefile = Nullfp; | |
132 | pipepid = 0; | |
133 | ||
134 | if( fil ) { | |
135 | int ch = getc( fil ); | |
136 | int lines = 0; | |
137 | int chars = 0; | |
138 | ||
139 | /* Search for the magic cookie that starts the encrypted script, | |
140 | ** while still allowing a few lines of unencrypted text to let | |
141 | ** '#!' and the nih hack both continue to work. (These lines | |
142 | ** will end up being ignored.) | |
143 | */ | |
144 | while( ch != CRYPT_MAGIC_1 && ch != EOF && lines < 5 && chars < 300 ) { | |
145 | if( ch == '\n' ) | |
146 | ++lines; | |
147 | ch = getc( fil ); | |
148 | ++chars; | |
149 | } | |
150 | ||
151 | if( ch == CRYPT_MAGIC_1 ) { | |
152 | if( (ch = getc( fil ) ) == CRYPT_MAGIC_2 ) { | |
153 | if( perldb ) fatal("can't debug an encrypted script"); | |
154 | /* we found it, decrypt the rest of the file */ | |
155 | fil = mypfiopen( fil, cryptfilter ); | |
156 | return( lastpipefile = fil ); | |
157 | } else | |
158 | /* if its got MAGIC 1 without MAGIC 2, too bad */ | |
159 | fatal( "bad encryption format" ); | |
160 | } | |
161 | ||
162 | /* this file is not encrypted - rewind and process it normally */ | |
163 | rewind( fil ); | |
164 | } | |
165 | ||
166 | return( fil ); | |
167 | } | |
168 | ||
169 | VOID | |
170 | cryptclose(fil) | |
171 | FILE *fil; | |
172 | { | |
173 | if( fil == Nullfp ) | |
174 | return; | |
175 | ||
176 | if( fil == lastpipefile ) | |
177 | mypclose( fil ); | |
178 | else | |
179 | fclose( fil ); | |
180 | } | |
181 | #endif /* !MSDOS */ | |
182 | ||
183 | #endif /* CRYPTSCRIPT */ |