1 |
|
---|
2 | /*
|
---|
3 | * Copyright © 2001 Novell, Inc. All Rights Reserved.
|
---|
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 | * FILENAME : nw5.c
|
---|
12 | * DESCRIPTION : Definitions for the redefined functions for NetWare.
|
---|
13 | * Author : SGP, HYAK
|
---|
14 | * Date : January 2001.
|
---|
15 | *
|
---|
16 | */
|
---|
17 |
|
---|
18 |
|
---|
19 |
|
---|
20 | #include <perl.h> // For dTHX, etc.
|
---|
21 | #include "nwpipe.h"
|
---|
22 |
|
---|
23 |
|
---|
24 | // This was added since the compile failed saying "undefined P_WAIT"
|
---|
25 | // when USE_ITHREADS was commented in the makefile
|
---|
26 | #ifndef P_WAIT
|
---|
27 | #define P_WAIT 0
|
---|
28 | #endif
|
---|
29 |
|
---|
30 | #ifndef P_NOWAIT
|
---|
31 | #define P_NOWAIT 1
|
---|
32 | #endif
|
---|
33 |
|
---|
34 | #define EXECF_EXEC 1
|
---|
35 | #define EXECF_SPAWN 2
|
---|
36 | #define EXECF_SPAWN_NOWAIT 3
|
---|
37 |
|
---|
38 | static BOOL has_shell_metachars(char *ptr);
|
---|
39 |
|
---|
40 | // The array is used to store pointer to the memory allocated to the TempPipeFile structure everytime
|
---|
41 | // a call to the function, nw_Popen. If a simple variable is used, everytime the memory is allocated before
|
---|
42 | // the previously allocated memory is freed, the pointer will get overwritten and the previous memory allocations
|
---|
43 | // are lost! Only the most recent one will get freed when calls are made to nw_Pclose.
|
---|
44 | // By using the array and the iPopenCount to index the array, all memory are freed!
|
---|
45 |
|
---|
46 | // The size of the array indicates the limit on the no of times the nw_Popen function can be called (and
|
---|
47 | // memory allocted) from within a script through backtick operators!
|
---|
48 | // This is arbitrarily set to MAX_PIPE_RECURSION=256 which indicates there can be 256 nested backtick operators possible!
|
---|
49 | PTEMPPIPEFILE ptpf1[MAX_PIPE_RECURSION] = {'\0'};
|
---|
50 | int iPopenCount = 0;
|
---|
51 | FILE* File1[MAX_PIPE_RECURSION] = {'\0'};
|
---|
52 |
|
---|
53 | /**
|
---|
54 | General:
|
---|
55 |
|
---|
56 | In this code, wherever there is a FILE *, the error condition is checked; and only if the FILE * is TRUE,
|
---|
57 | then the corresponding operation is done. Otherwise the error value is returned.
|
---|
58 | This is done because the file operations like "open" in the Perl code returns the FILE *,
|
---|
59 | returning a valid value if the file is found or NULL when the particular file is not found.
|
---|
60 | Now, if the return value is NULL, then an operation say "fgets", "fopen" etc. using this this NULL value
|
---|
61 | for FILE * will abend the server. If the check is made then an operation on a non existing file
|
---|
62 | does not abend the server.
|
---|
63 | **/
|
---|
64 |
|
---|
65 | void
|
---|
66 | nw_abort(void)
|
---|
67 | {
|
---|
68 | abort(); // Terminate the NLM application abnormally.
|
---|
69 | return;
|
---|
70 | }
|
---|
71 |
|
---|
72 | int
|
---|
73 | nw_access(const char *path, int mode)
|
---|
74 | {
|
---|
75 | return access(path, mode);
|
---|
76 | }
|
---|
77 |
|
---|
78 | int
|
---|
79 | nw_chmod(const char *path, int mode)
|
---|
80 | {
|
---|
81 | return chmod(path, mode);
|
---|
82 | }
|
---|
83 |
|
---|
84 | void
|
---|
85 | nw_clearerr(FILE *pf)
|
---|
86 | {
|
---|
87 | if(pf)
|
---|
88 | clearerr(pf);
|
---|
89 | }
|
---|
90 |
|
---|
91 | int
|
---|
92 | nw_close(int fd)
|
---|
93 | {
|
---|
94 | return close(fd);
|
---|
95 | }
|
---|
96 |
|
---|
97 | nw_closedir(DIR *dirp)
|
---|
98 | {
|
---|
99 | return (closedir(dirp));
|
---|
100 | }
|
---|
101 |
|
---|
102 | void
|
---|
103 | nw_setbuf(FILE *pf, char *buf)
|
---|
104 | {
|
---|
105 | if(pf)
|
---|
106 | setbuf(pf, buf);
|
---|
107 | }
|
---|
108 |
|
---|
109 | int
|
---|
110 | nw_setmode(FILE *fp, int mode)
|
---|
111 | {
|
---|
112 | /**
|
---|
113 | // Commented since a few abends were happening in fnFpSetMode
|
---|
114 | int *dummy = 0;
|
---|
115 | return(fnFpSetMode(fp, mode, dummy));
|
---|
116 | **/
|
---|
117 |
|
---|
118 | int handle = -1;
|
---|
119 | errno = 0;
|
---|
120 |
|
---|
121 | handle = fileno(fp);
|
---|
122 | if (errno)
|
---|
123 | {
|
---|
124 | errno = 0;
|
---|
125 | return -1;
|
---|
126 | }
|
---|
127 | return setmode(handle, mode);
|
---|
128 | }
|
---|
129 |
|
---|
130 | int
|
---|
131 | nw_setvbuf(FILE *pf, char *buf, int type, size_t size)
|
---|
132 | {
|
---|
133 | if(pf)
|
---|
134 | return setvbuf(pf, buf, type, size);
|
---|
135 | else
|
---|
136 | return -1;
|
---|
137 | }
|
---|
138 |
|
---|
139 |
|
---|
140 | unsigned int
|
---|
141 | nw_sleep(unsigned int t)
|
---|
142 | {
|
---|
143 | delay(t*1000); // Put the thread to sleep for 't' seconds. Initially 't' is passed in milliseconds.
|
---|
144 | return 0;
|
---|
145 | }
|
---|
146 |
|
---|
147 | int
|
---|
148 | nw_spawnvp(int mode, char *cmdname, char **argv)
|
---|
149 | {
|
---|
150 | // There is no pass-around environment on NetWare so we throw that
|
---|
151 | // argument away for now.
|
---|
152 |
|
---|
153 | // The function "spawnvp" does not work in all situations. Loading
|
---|
154 | // edit.nlm seems to work, for example, but the name of the file
|
---|
155 | // to edit does not appear to get passed correctly. Another problem
|
---|
156 | // is that on Netware, P_WAIT does not really work reliably. It only
|
---|
157 | // works with NLMs built to use CLIB (according to Nile Thayne).
|
---|
158 | // NLMs such as EDIT that are written directly to the system have no
|
---|
159 | // way of running synchronously from another process. The whole
|
---|
160 | // architecture on NetWare seems pretty busted, so we just support it
|
---|
161 | // as best we can.
|
---|
162 | //
|
---|
163 | // The spawnvp function only launches NLMs, it will not execute a command;
|
---|
164 | // the NetWare "system" function is used for that purpose. Unfortunately, "system"
|
---|
165 | // always returns success whether the command is successful or not or even
|
---|
166 | // if the command was not found! To avoid ambiguity--you can have both an
|
---|
167 | // NLM named "perl" and a system command named "perl"--we need to
|
---|
168 | // force perl scripts to carry the word "load" when loading an NLM. This
|
---|
169 | // might be clearer anyway.
|
---|
170 |
|
---|
171 | int ret = 0;
|
---|
172 | int argc = 0;
|
---|
173 |
|
---|
174 |
|
---|
175 | if (stricmp(cmdname, LOAD_COMMAND) == 0)
|
---|
176 | {
|
---|
177 | if (argv[1] != NULL)
|
---|
178 | ret = spawnvp(mode, argv[1], &argv[1]);
|
---|
179 | }
|
---|
180 | else
|
---|
181 | {
|
---|
182 | int i=0;
|
---|
183 | while (argv[i] != '\0')
|
---|
184 | i++;
|
---|
185 | argc = i;
|
---|
186 |
|
---|
187 | fnSystemCommand(argv, argc);
|
---|
188 | }
|
---|
189 |
|
---|
190 | return ret;
|
---|
191 | }
|
---|
192 |
|
---|
193 | int
|
---|
194 | nw_execv(char *cmdname, char **argv)
|
---|
195 | {
|
---|
196 | return spawnvp(P_WAIT, cmdname, (char **)argv);
|
---|
197 | }
|
---|
198 |
|
---|
199 |
|
---|
200 | int
|
---|
201 | nw_execvp(char *cmdname, char **argv)
|
---|
202 | {
|
---|
203 | return nw_spawnvp(P_WAIT, cmdname, (char **)argv);
|
---|
204 | }
|
---|
205 |
|
---|
206 | int
|
---|
207 | nw_stat(const char *path, struct stat *sbuf)
|
---|
208 | {
|
---|
209 | return (stat(path, sbuf));
|
---|
210 | }
|
---|
211 |
|
---|
212 | FILE *
|
---|
213 | nw_stderr(void)
|
---|
214 | {
|
---|
215 | return (stderr);
|
---|
216 | }
|
---|
217 |
|
---|
218 | FILE *
|
---|
219 | nw_stdin(void)
|
---|
220 | {
|
---|
221 | return (stdin);
|
---|
222 | }
|
---|
223 |
|
---|
224 | FILE *
|
---|
225 | nw_stdout()
|
---|
226 | {
|
---|
227 | return (stdout);
|
---|
228 | }
|
---|
229 |
|
---|
230 | long
|
---|
231 | nw_telldir(DIR *dirp)
|
---|
232 | {
|
---|
233 | dTHX;
|
---|
234 | Perl_croak(aTHX_ "The telldir() function is not implemented on NetWare\n");
|
---|
235 | return 0l;
|
---|
236 | }
|
---|
237 |
|
---|
238 | int
|
---|
239 | nw_times(struct tms *timebuf)
|
---|
240 | {
|
---|
241 | clock_t now = clock();
|
---|
242 |
|
---|
243 | timebuf->tms_utime = now;
|
---|
244 | timebuf->tms_stime = 0;
|
---|
245 | timebuf->tms_cutime = 0;
|
---|
246 | timebuf->tms_cstime = 0;
|
---|
247 |
|
---|
248 | return 0;
|
---|
249 | }
|
---|
250 |
|
---|
251 | FILE*
|
---|
252 | nw_tmpfile(void)
|
---|
253 | {
|
---|
254 | return tmpfile();
|
---|
255 | }
|
---|
256 |
|
---|
257 | int
|
---|
258 | nw_uname(struct utsname *name)
|
---|
259 | {
|
---|
260 | return(uname(name));
|
---|
261 | }
|
---|
262 |
|
---|
263 | int
|
---|
264 | nw_ungetc(int c, FILE *pf)
|
---|
265 | {
|
---|
266 | if(pf)
|
---|
267 | return ungetc(c, pf);
|
---|
268 | else
|
---|
269 | return -1;
|
---|
270 | }
|
---|
271 |
|
---|
272 | int
|
---|
273 | nw_unlink(const char *filename)
|
---|
274 | {
|
---|
275 | return(unlink(filename));
|
---|
276 | }
|
---|
277 |
|
---|
278 | int
|
---|
279 | nw_utime(const char *filename, struct utimbuf *times)
|
---|
280 | {
|
---|
281 | return(utime(filename, times));
|
---|
282 | }
|
---|
283 |
|
---|
284 | int
|
---|
285 | nw_vfprintf(FILE *fp, const char *format, va_list args)
|
---|
286 | {
|
---|
287 | if(fp)
|
---|
288 | return (vfprintf(fp, format, args));
|
---|
289 | else
|
---|
290 | return -1;
|
---|
291 | }
|
---|
292 |
|
---|
293 | int
|
---|
294 | nw_wait(int *status)
|
---|
295 | {
|
---|
296 | return 0;
|
---|
297 | }
|
---|
298 |
|
---|
299 | int
|
---|
300 | nw_waitpid(int pid, int *status, int flags)
|
---|
301 | {
|
---|
302 | return 0;
|
---|
303 | }
|
---|
304 |
|
---|
305 | int
|
---|
306 | nw_write(int fd, const void *buf, unsigned int cnt)
|
---|
307 | {
|
---|
308 | return write(fd, buf, cnt);
|
---|
309 | }
|
---|
310 |
|
---|
311 | char *
|
---|
312 | nw_crypt(const char *txt, const char *salt)
|
---|
313 | {
|
---|
314 | dTHX;
|
---|
315 |
|
---|
316 | #ifdef HAVE_DES_FCRYPT
|
---|
317 | dTHR;
|
---|
318 | return des_fcrypt(txt, salt, w32_crypt_buffer);
|
---|
319 | #else
|
---|
320 | Perl_croak(aTHX_ "The crypt() function is not implemented on NetWare\n");
|
---|
321 | return Nullch;
|
---|
322 | #endif
|
---|
323 | }
|
---|
324 |
|
---|
325 | int
|
---|
326 | nw_dup(int fd)
|
---|
327 | {
|
---|
328 | return dup(fd);
|
---|
329 | }
|
---|
330 |
|
---|
331 | int
|
---|
332 | nw_dup2(int fd1,int fd2)
|
---|
333 | {
|
---|
334 | return dup2(fd1,fd2);
|
---|
335 | }
|
---|
336 |
|
---|
337 | void*
|
---|
338 | nw_dynaload(const char* filename)
|
---|
339 | {
|
---|
340 | return NULL;
|
---|
341 | }
|
---|
342 |
|
---|
343 | int
|
---|
344 | nw_fclose(FILE *pf)
|
---|
345 | {
|
---|
346 | if(pf)
|
---|
347 | return (fclose(pf));
|
---|
348 | else
|
---|
349 | return -1;
|
---|
350 | }
|
---|
351 |
|
---|
352 | FILE *
|
---|
353 | nw_fdopen(int handle, const char *mode)
|
---|
354 | {
|
---|
355 | return(fdopen(handle, mode));
|
---|
356 | }
|
---|
357 |
|
---|
358 | int
|
---|
359 | nw_feof(FILE *fp)
|
---|
360 | {
|
---|
361 | if(fp)
|
---|
362 | return (feof(fp));
|
---|
363 | else
|
---|
364 | return -1;
|
---|
365 | }
|
---|
366 |
|
---|
367 | int
|
---|
368 | nw_ferror(FILE *fp)
|
---|
369 | {
|
---|
370 | if(fp)
|
---|
371 | return (ferror(fp));
|
---|
372 | else
|
---|
373 | return -1;
|
---|
374 | }
|
---|
375 |
|
---|
376 |
|
---|
377 | int
|
---|
378 | nw_fflush(FILE *pf)
|
---|
379 | {
|
---|
380 | if(pf)
|
---|
381 | return fflush(pf);
|
---|
382 | else
|
---|
383 | return -1;
|
---|
384 | }
|
---|
385 |
|
---|
386 | int
|
---|
387 | nw_fgetpos(FILE *pf, fpos_t *p)
|
---|
388 | {
|
---|
389 | if(pf)
|
---|
390 | return fgetpos(pf, p);
|
---|
391 | else
|
---|
392 | return -1;
|
---|
393 | }
|
---|
394 |
|
---|
395 | char*
|
---|
396 | nw_fgets(char *s, int n, FILE *pf)
|
---|
397 | {
|
---|
398 | if(pf)
|
---|
399 | return(fgets(s, n, pf));
|
---|
400 | else
|
---|
401 | return NULL;
|
---|
402 | }
|
---|
403 |
|
---|
404 | int
|
---|
405 | nw_fileno(FILE *pf)
|
---|
406 | {
|
---|
407 | if(pf)
|
---|
408 | return fileno(pf);
|
---|
409 | else
|
---|
410 | return -1;
|
---|
411 | }
|
---|
412 |
|
---|
413 | int
|
---|
414 | nw_flock(int fd, int oper)
|
---|
415 | {
|
---|
416 | dTHX;
|
---|
417 | Perl_croak(aTHX_ "The flock() function is not implemented on NetWare\n");
|
---|
418 | return 0;
|
---|
419 | }
|
---|
420 |
|
---|
421 |
|
---|
422 | FILE *
|
---|
423 | nw_fopen(const char *filename, const char *mode)
|
---|
424 | {
|
---|
425 | return (fopen(filename, mode));
|
---|
426 | }
|
---|
427 |
|
---|
428 | int
|
---|
429 | nw_fputc(int c, FILE *pf)
|
---|
430 | {
|
---|
431 | if(pf)
|
---|
432 | return fputc(c,pf);
|
---|
433 | else
|
---|
434 | return -1;
|
---|
435 | }
|
---|
436 |
|
---|
437 | int
|
---|
438 | nw_fputs(const char *s, FILE *pf)
|
---|
439 | {
|
---|
440 | if(pf)
|
---|
441 | return fputs(s, pf);
|
---|
442 | else
|
---|
443 | return -1;
|
---|
444 | }
|
---|
445 |
|
---|
446 | size_t
|
---|
447 | nw_fread(void *buf, size_t size, size_t count, FILE *fp)
|
---|
448 | {
|
---|
449 | if(fp)
|
---|
450 | return fread(buf, size, count, fp);
|
---|
451 | else
|
---|
452 | return -1;
|
---|
453 | }
|
---|
454 |
|
---|
455 | FILE *
|
---|
456 | nw_freopen(const char *path, const char *mode, FILE *stream)
|
---|
457 | {
|
---|
458 | if(stream)
|
---|
459 | return freopen(path, mode, stream);
|
---|
460 | else
|
---|
461 | return NULL;
|
---|
462 | }
|
---|
463 |
|
---|
464 | int
|
---|
465 | nw_fseek(FILE *pf, long offset, int origin)
|
---|
466 | {
|
---|
467 | if(pf)
|
---|
468 | return (fseek(pf, offset, origin));
|
---|
469 | else
|
---|
470 | return -1;
|
---|
471 | }
|
---|
472 |
|
---|
473 | int
|
---|
474 | nw_fsetpos(FILE *pf, const fpos_t *p)
|
---|
475 | {
|
---|
476 | if(pf)
|
---|
477 | return fsetpos(pf, p);
|
---|
478 | else
|
---|
479 | return -1;
|
---|
480 | }
|
---|
481 |
|
---|
482 | long
|
---|
483 | nw_ftell(FILE *pf)
|
---|
484 | {
|
---|
485 | if(pf)
|
---|
486 | return ftell(pf);
|
---|
487 | else
|
---|
488 | return -1;
|
---|
489 | }
|
---|
490 |
|
---|
491 | size_t
|
---|
492 | nw_fwrite(const void *buf, size_t size, size_t count, FILE *fp)
|
---|
493 | {
|
---|
494 | if(fp)
|
---|
495 | return fwrite(buf, size, count, fp);
|
---|
496 | else
|
---|
497 | return -1;
|
---|
498 | }
|
---|
499 |
|
---|
500 | long
|
---|
501 | nw_get_osfhandle(int fd)
|
---|
502 | {
|
---|
503 | return 0l;
|
---|
504 | }
|
---|
505 |
|
---|
506 | int
|
---|
507 | nw_getc(FILE *pf)
|
---|
508 | {
|
---|
509 | if(pf)
|
---|
510 | return getc(pf);
|
---|
511 | else
|
---|
512 | return -1;
|
---|
513 | }
|
---|
514 |
|
---|
515 | int
|
---|
516 | nw_putc(int c, FILE *pf)
|
---|
517 | {
|
---|
518 | if(pf)
|
---|
519 | return putc(c,pf);
|
---|
520 | else
|
---|
521 | return -1;
|
---|
522 | }
|
---|
523 |
|
---|
524 | int
|
---|
525 | nw_fgetc(FILE *pf)
|
---|
526 | {
|
---|
527 | if(pf)
|
---|
528 | return fgetc(pf);
|
---|
529 | else
|
---|
530 | return -1;
|
---|
531 | }
|
---|
532 |
|
---|
533 | int
|
---|
534 | nw_getpid(void)
|
---|
535 | {
|
---|
536 | return GetThreadGroupID();
|
---|
537 | }
|
---|
538 |
|
---|
539 | int
|
---|
540 | nw_kill(int pid, int sig)
|
---|
541 | {
|
---|
542 | return 0;
|
---|
543 | }
|
---|
544 |
|
---|
545 | int
|
---|
546 | nw_link(const char *oldname, const char *newname)
|
---|
547 | {
|
---|
548 | return 0;
|
---|
549 | }
|
---|
550 |
|
---|
551 | long
|
---|
552 | nw_lseek(int fd, long offset, int origin)
|
---|
553 | {
|
---|
554 | return lseek(fd, offset, origin);
|
---|
555 | }
|
---|
556 |
|
---|
557 | int
|
---|
558 | nw_chdir(const char *dir)
|
---|
559 | {
|
---|
560 | return chdir(dir);
|
---|
561 | }
|
---|
562 |
|
---|
563 | int
|
---|
564 | nw_rmdir(const char *dir)
|
---|
565 | {
|
---|
566 | return rmdir(dir);
|
---|
567 | }
|
---|
568 |
|
---|
569 | DIR *
|
---|
570 | nw_opendir(char *filename)
|
---|
571 | {
|
---|
572 | char *buff = NULL;
|
---|
573 | int len = 0;
|
---|
574 | DIR *ret = NULL;
|
---|
575 |
|
---|
576 | len = strlen(filename);
|
---|
577 | buff = malloc(len + 5);
|
---|
578 | if (buff) {
|
---|
579 | strcpy(buff, filename);
|
---|
580 | if (buff[len-1]=='/' || buff[len-1]=='\\') {
|
---|
581 | buff[--len] = 0;
|
---|
582 | }
|
---|
583 | strcpy(buff+len, "/*.*");
|
---|
584 | ret = opendir(buff);
|
---|
585 | free (buff);
|
---|
586 | buff = NULL;
|
---|
587 | return ret;
|
---|
588 | } else {
|
---|
589 | return NULL;
|
---|
590 | }
|
---|
591 | }
|
---|
592 |
|
---|
593 | int
|
---|
594 | nw_open(const char *path, int flag, ...)
|
---|
595 | {
|
---|
596 | va_list ap;
|
---|
597 | int pmode = -1;
|
---|
598 |
|
---|
599 | va_start(ap, flag);
|
---|
600 | pmode = va_arg(ap, int);
|
---|
601 | va_end(ap);
|
---|
602 |
|
---|
603 | if (stricmp(path, "/dev/null")==0)
|
---|
604 | path = "NWNUL";
|
---|
605 |
|
---|
606 | return open(path, flag, pmode);
|
---|
607 | }
|
---|
608 |
|
---|
609 | int
|
---|
610 | nw_open_osfhandle(long handle, int flags)
|
---|
611 | {
|
---|
612 | return 0;
|
---|
613 | }
|
---|
614 |
|
---|
615 | unsigned long
|
---|
616 | nw_os_id(void)
|
---|
617 | {
|
---|
618 | return 0l;
|
---|
619 | }
|
---|
620 |
|
---|
621 | int nw_Pipe(int* a, int* e)
|
---|
622 | {
|
---|
623 | int ret = 0;
|
---|
624 |
|
---|
625 | errno = 0;
|
---|
626 | ret = pipe(a);
|
---|
627 | if(errno)
|
---|
628 | e = &errno;
|
---|
629 |
|
---|
630 | return ret;
|
---|
631 | }
|
---|
632 |
|
---|
633 | FILE* nw_Popen(char* command, char* mode, int* e)
|
---|
634 | {
|
---|
635 | int i = -1;
|
---|
636 |
|
---|
637 | FILE* ret = NULL;
|
---|
638 | PTEMPPIPEFILE ptpf = NULL;
|
---|
639 |
|
---|
640 | // this callback is supposed to call _popen, which spawns an
|
---|
641 | // asynchronous command and opens a pipe to it. The returned
|
---|
642 | // file handle can be read or written to; if read, it represents
|
---|
643 | // stdout of the called process and will return EOF when the
|
---|
644 | // called process finishes. If written to, it represents stdin
|
---|
645 | // of the called process. Naturally _popen is not available on
|
---|
646 | // NetWare so we must do some fancy stuff to simulate it. We will
|
---|
647 | // redirect to and from temp files; this has the side effect
|
---|
648 | // of having to run the process synchronously rather than
|
---|
649 | // asynchronously. This means that you will only be able to do
|
---|
650 | // this with CLIB NLMs built to run on the calling thread.
|
---|
651 |
|
---|
652 | errno = 0;
|
---|
653 |
|
---|
654 | ptpf1[iPopenCount] = (PTEMPPIPEFILE) malloc(sizeof(TEMPPIPEFILE));
|
---|
655 | if (!ptpf1[iPopenCount])
|
---|
656 | return NULL;
|
---|
657 |
|
---|
658 | ptpf = ptpf1[iPopenCount];
|
---|
659 | iPopenCount ++;
|
---|
660 | if(iPopenCount > MAX_PIPE_RECURSION)
|
---|
661 | iPopenCount = MAX_PIPE_RECURSION; // Limit to the max no of pipes to be open recursively.
|
---|
662 |
|
---|
663 | fnTempPipeFile(ptpf);
|
---|
664 | ret = fnPipeFileOpen((PTEMPPIPEFILE) ptpf, (char *) command, (char *) mode);
|
---|
665 | if (ret)
|
---|
666 | File1[iPopenCount-1] = ret; // Store the obtained Pipe file handle.
|
---|
667 | else
|
---|
668 | { // Pipe file not obtained. So free the allocated memory.
|
---|
669 | if(ptpf1[iPopenCount-1])
|
---|
670 | {
|
---|
671 | free(ptpf1[iPopenCount-1]);
|
---|
672 | ptpf1[iPopenCount-1] = NULL;
|
---|
673 | ptpf = NULL;
|
---|
674 | iPopenCount --;
|
---|
675 | }
|
---|
676 | }
|
---|
677 |
|
---|
678 | if (errno)
|
---|
679 | e = &errno;
|
---|
680 |
|
---|
681 | return ret;
|
---|
682 | }
|
---|
683 |
|
---|
684 | int nw_Pclose(FILE* file, int* e)
|
---|
685 | {
|
---|
686 | int i=0, j=0;
|
---|
687 |
|
---|
688 | errno = 0;
|
---|
689 |
|
---|
690 | if(file)
|
---|
691 | {
|
---|
692 | if(iPopenCount > 0)
|
---|
693 | {
|
---|
694 | for (i=0; i<iPopenCount; i++)
|
---|
695 | {
|
---|
696 | if(File1[i] == file)
|
---|
697 | {
|
---|
698 | // Delete the memory allocated corresponding to the file handle passed-in and
|
---|
699 | // also close the file corresponding to the file handle passed-in!
|
---|
700 | if(ptpf1[i])
|
---|
701 | {
|
---|
702 | fnPipeFileClose(ptpf1[i]);
|
---|
703 |
|
---|
704 | free(ptpf1[i]);
|
---|
705 | ptpf1[i] = NULL;
|
---|
706 | }
|
---|
707 |
|
---|
708 | fclose(File1[i]);
|
---|
709 | File1[i] = NULL;
|
---|
710 |
|
---|
711 | break;
|
---|
712 | }
|
---|
713 | }
|
---|
714 |
|
---|
715 | // Rearrange the file pointer array
|
---|
716 | for(j=i; j<(iPopenCount-1); j++)
|
---|
717 | {
|
---|
718 | File1[j] = File1[j+1];
|
---|
719 | ptpf1[j] = ptpf1[j+1];
|
---|
720 | }
|
---|
721 | iPopenCount--;
|
---|
722 | }
|
---|
723 | }
|
---|
724 | else
|
---|
725 | return -1;
|
---|
726 |
|
---|
727 | if (errno)
|
---|
728 | e = &errno;
|
---|
729 |
|
---|
730 | return 0;
|
---|
731 | }
|
---|
732 |
|
---|
733 |
|
---|
734 | int
|
---|
735 | nw_vprintf(const char *format, va_list args)
|
---|
736 | {
|
---|
737 | return (vprintf(format, args));
|
---|
738 | }
|
---|
739 |
|
---|
740 | int
|
---|
741 | nw_printf(const char *format, ...)
|
---|
742 | {
|
---|
743 |
|
---|
744 | va_list marker;
|
---|
745 | va_start(marker, format); /* Initialize variable arguments. */
|
---|
746 |
|
---|
747 | return (vprintf(format, marker));
|
---|
748 | }
|
---|
749 |
|
---|
750 | int
|
---|
751 | nw_read(int fd, void *buf, unsigned int cnt)
|
---|
752 | {
|
---|
753 | return read(fd, buf, cnt);
|
---|
754 | }
|
---|
755 |
|
---|
756 | struct direct *
|
---|
757 | nw_readdir(DIR *dirp)
|
---|
758 | {
|
---|
759 | DIR* ret=NULL;
|
---|
760 |
|
---|
761 | ret = readdir(dirp);
|
---|
762 | if(ret)
|
---|
763 | return((struct direct *)ret);
|
---|
764 | return NULL;
|
---|
765 | }
|
---|
766 |
|
---|
767 | int
|
---|
768 | nw_rename(const char *oname, const char *newname)
|
---|
769 | {
|
---|
770 | return(rename(oname,newname));
|
---|
771 | }
|
---|
772 |
|
---|
773 | void
|
---|
774 | nw_rewinddir(DIR *dirp)
|
---|
775 | {
|
---|
776 | dTHX;
|
---|
777 | Perl_croak(aTHX_ "The rewinddir() function is not implemented on NetWare\n");
|
---|
778 | }
|
---|
779 |
|
---|
780 | void
|
---|
781 | nw_rewind(FILE *pf)
|
---|
782 | {
|
---|
783 | if(pf)
|
---|
784 | rewind(pf);
|
---|
785 | }
|
---|
786 |
|
---|
787 | void
|
---|
788 | nw_seekdir(DIR *dirp, long loc)
|
---|
789 | {
|
---|
790 | dTHX;
|
---|
791 | Perl_croak(aTHX_ "The seekdir() function is not implemented on NetWare\n");
|
---|
792 | }
|
---|
793 |
|
---|
794 | int *
|
---|
795 | nw_errno(void)
|
---|
796 | {
|
---|
797 | return (&errno);
|
---|
798 | }
|
---|
799 |
|
---|
800 | char ***
|
---|
801 | nw_environ(void)
|
---|
802 | {
|
---|
803 | return ((char ***)nw_getenviron());
|
---|
804 | }
|
---|
805 |
|
---|
806 | char *
|
---|
807 | nw_strerror(int e)
|
---|
808 | {
|
---|
809 | return (strerror(e));
|
---|
810 | }
|
---|
811 |
|
---|
812 | int
|
---|
813 | nw_isatty(int fd)
|
---|
814 | {
|
---|
815 | return(isatty(fd));
|
---|
816 | }
|
---|
817 |
|
---|
818 | char *
|
---|
819 | nw_mktemp(char *Template)
|
---|
820 | {
|
---|
821 | return (fnMy_MkTemp(Template));
|
---|
822 | }
|
---|
823 |
|
---|
824 | int
|
---|
825 | nw_chsize(int handle, long size)
|
---|
826 | {
|
---|
827 | return(chsize(handle,size));
|
---|
828 | }
|
---|
829 |
|
---|
830 | #ifdef HAVE_INTERP_INTERN
|
---|
831 | void
|
---|
832 | sys_intern_init(pTHX)
|
---|
833 | {
|
---|
834 |
|
---|
835 | }
|
---|
836 |
|
---|
837 | void
|
---|
838 | sys_intern_clear(pTHX)
|
---|
839 | {
|
---|
840 |
|
---|
841 | }
|
---|
842 |
|
---|
843 | void
|
---|
844 | sys_intern_dup(pTHX_ struct interp_intern *src, struct interp_intern *dst)
|
---|
845 | {
|
---|
846 |
|
---|
847 | }
|
---|
848 | #endif /* HAVE_INTERP_INTERN */
|
---|
849 |
|
---|
850 | void
|
---|
851 | Perl_init_os_extras(void)
|
---|
852 | {
|
---|
853 |
|
---|
854 | }
|
---|
855 |
|
---|
856 | void
|
---|
857 | Perl_nw5_init(int *argcp, char ***argvp)
|
---|
858 | {
|
---|
859 | MALLOC_INIT;
|
---|
860 | }
|
---|
861 |
|
---|
862 | #ifdef USE_ITHREADS
|
---|
863 | PerlInterpreter *
|
---|
864 | perl_clone_host(PerlInterpreter* proto_perl, UV flags)
|
---|
865 | {
|
---|
866 | // Perl Clone is not implemented on NetWare.
|
---|
867 | return NULL;
|
---|
868 | }
|
---|
869 | #endif
|
---|
870 |
|
---|
871 | // Some more functions:
|
---|
872 |
|
---|
873 | char *
|
---|
874 | nw_get_sitelib(const char *pl)
|
---|
875 | {
|
---|
876 | return (NULL);
|
---|
877 | }
|
---|
878 |
|
---|
879 | int
|
---|
880 | execv(char *cmdname, char **argv)
|
---|
881 | {
|
---|
882 | // This feature needs to be implemented.
|
---|
883 | // _asm is commented out since it goes into the internal debugger.
|
---|
884 | // _asm {int 3};
|
---|
885 | return(0);
|
---|
886 | }
|
---|
887 |
|
---|
888 | int
|
---|
889 | execvp(char *cmdname, char **argv)
|
---|
890 | {
|
---|
891 | // This feature needs to be implemented.
|
---|
892 | // _asm is commented out since it goes into the internal debugger.
|
---|
893 | // _asm {int 3};
|
---|
894 | return(0);
|
---|
895 | }
|
---|
896 |
|
---|
897 | int
|
---|
898 | do_aspawn(void *vreally, void **vmark, void **vsp)
|
---|
899 | {
|
---|
900 | // This feature needs to be implemented.
|
---|
901 | // _asm is commented out since it goes into the internal debugger.
|
---|
902 | // _asm {int 3};
|
---|
903 | //// return(0);
|
---|
904 |
|
---|
905 |
|
---|
906 | // This below code is required for system() call.
|
---|
907 | // Otherwise system() does not work on NetWare.
|
---|
908 | // Ananth, 3 Sept 2001
|
---|
909 |
|
---|
910 | dTHX;
|
---|
911 | SV *really = (SV*)vreally;
|
---|
912 | SV **mark = (SV**)vmark;
|
---|
913 | SV **sp = (SV**)vsp;
|
---|
914 | char **argv;
|
---|
915 | char *str;
|
---|
916 | int status;
|
---|
917 | int flag = P_WAIT;
|
---|
918 | int index = 0;
|
---|
919 |
|
---|
920 |
|
---|
921 | if (sp <= mark)
|
---|
922 | return -1;
|
---|
923 |
|
---|
924 | nw_perlshell_items = 0; // No Shell
|
---|
925 | // Newx(argv, (sp - mark) + nw_perlshell_items + 3, char*); // In the old code of 5.6.1
|
---|
926 | Newx(argv, (sp - mark) + nw_perlshell_items + 2, char*);
|
---|
927 |
|
---|
928 | if (SvNIOKp(*(mark+1)) && !SvPOKp(*(mark+1))) {
|
---|
929 | ++mark;
|
---|
930 | flag = SvIVx(*mark);
|
---|
931 | }
|
---|
932 |
|
---|
933 | while (++mark <= sp) {
|
---|
934 | if (*mark && (str = (char *)SvPV_nolen(*mark)))
|
---|
935 | {
|
---|
936 | argv[index] = str;
|
---|
937 | index++;
|
---|
938 | }
|
---|
939 | else
|
---|
940 | {
|
---|
941 | argv[index] = "";
|
---|
942 | // argv[index] = '\0';
|
---|
943 | index++;
|
---|
944 | }
|
---|
945 | }
|
---|
946 | argv[index] = '\0';
|
---|
947 | index++;
|
---|
948 |
|
---|
949 | status = nw_spawnvp(flag,
|
---|
950 | (char*)(really ? SvPV_nolen(really) : argv[0]),
|
---|
951 | (char**)argv);
|
---|
952 |
|
---|
953 | if (flag != P_NOWAIT) {
|
---|
954 | if (status < 0) {
|
---|
955 | // dTHR; // Only in old code of 5.6.1
|
---|
956 | if (ckWARN(WARN_EXEC))
|
---|
957 | Perl_warner(aTHX_ packWARN(WARN_EXEC), "Can't spawn \"%s\": %s", argv[0], strerror(errno));
|
---|
958 | status = 255 * 256;
|
---|
959 | }
|
---|
960 | else
|
---|
961 | status *= 256;
|
---|
962 | PL_statusvalue = status;
|
---|
963 | }
|
---|
964 |
|
---|
965 | Safefree(argv);
|
---|
966 | return (status);
|
---|
967 | }
|
---|
968 |
|
---|
969 | int
|
---|
970 | do_spawn2(char *cmd, int exectype)
|
---|
971 | {
|
---|
972 | // This feature needs to be implemented.
|
---|
973 | // _asm is commented out since it goes into the internal debugger.
|
---|
974 | // _asm {int 3};
|
---|
975 | //// return(0);
|
---|
976 |
|
---|
977 | // Below added to make system() work for NetWare
|
---|
978 |
|
---|
979 | dTHX;
|
---|
980 | char **a;
|
---|
981 | char *s;
|
---|
982 | char **argv;
|
---|
983 | int status = -1;
|
---|
984 | BOOL needToTry = TRUE;
|
---|
985 | char *cmd2;
|
---|
986 |
|
---|
987 | /* Save an extra exec if possible. See if there are shell
|
---|
988 | * metacharacters in it */
|
---|
989 | if (!has_shell_metachars(cmd)) {
|
---|
990 | Newx(argv, strlen(cmd) / 2 + 2, char*);
|
---|
991 | Newx(cmd2, strlen(cmd) + 1, char);
|
---|
992 | strcpy(cmd2, cmd);
|
---|
993 | a = argv;
|
---|
994 | for (s = cmd2; *s;) {
|
---|
995 | while (*s && isSPACE(*s))
|
---|
996 | s++;
|
---|
997 | if (*s)
|
---|
998 | *(a++) = s;
|
---|
999 | while (*s && !isSPACE(*s))
|
---|
1000 | s++;
|
---|
1001 | if (*s)
|
---|
1002 | *s++ = '\0';
|
---|
1003 | }
|
---|
1004 | *a = Nullch;
|
---|
1005 | if (argv[0]) {
|
---|
1006 | switch (exectype) {
|
---|
1007 | case EXECF_SPAWN:
|
---|
1008 | status = nw_spawnvp(P_WAIT, argv[0], (char **)argv);
|
---|
1009 | break;
|
---|
1010 |
|
---|
1011 | case EXECF_SPAWN_NOWAIT:
|
---|
1012 | status = nw_spawnvp(P_NOWAIT, argv[0], (char **)argv);
|
---|
1013 | break;
|
---|
1014 |
|
---|
1015 | case EXECF_EXEC:
|
---|
1016 | status = nw_execvp(argv[0], (char **)argv);
|
---|
1017 | break;
|
---|
1018 | }
|
---|
1019 | if (status != -1 || errno == 0)
|
---|
1020 | needToTry = FALSE;
|
---|
1021 | }
|
---|
1022 | Safefree(argv);
|
---|
1023 | Safefree(cmd2);
|
---|
1024 | }
|
---|
1025 |
|
---|
1026 | if (needToTry) {
|
---|
1027 | char **argv = NULL;
|
---|
1028 | int i = -1;
|
---|
1029 |
|
---|
1030 | Newx(argv, nw_perlshell_items + 2, char*);
|
---|
1031 | while (++i < nw_perlshell_items)
|
---|
1032 | argv[i] = nw_perlshell_vec[i];
|
---|
1033 | argv[i++] = cmd;
|
---|
1034 | argv[i] = Nullch;
|
---|
1035 | switch (exectype) {
|
---|
1036 | case EXECF_SPAWN:
|
---|
1037 | status = nw_spawnvp(P_WAIT, argv[0], (char **)argv);
|
---|
1038 | break;
|
---|
1039 |
|
---|
1040 | case EXECF_SPAWN_NOWAIT:
|
---|
1041 | status = nw_spawnvp(P_NOWAIT, argv[0], (char **)argv);
|
---|
1042 | break;
|
---|
1043 |
|
---|
1044 | case EXECF_EXEC:
|
---|
1045 | status = nw_execvp(argv[0], (char **)argv);
|
---|
1046 | break;
|
---|
1047 | }
|
---|
1048 | cmd = argv[0];
|
---|
1049 | Safefree(argv);
|
---|
1050 | }
|
---|
1051 |
|
---|
1052 | if (exectype != EXECF_SPAWN_NOWAIT) {
|
---|
1053 | if (status < 0) {
|
---|
1054 | dTHR;
|
---|
1055 | if (ckWARN(WARN_EXEC))
|
---|
1056 | Perl_warner(aTHX_ WARN_EXEC, "Can't %s \"%s\": %s",
|
---|
1057 | (exectype == EXECF_EXEC ? "exec" : "spawn"),
|
---|
1058 | cmd, strerror(errno));
|
---|
1059 | status = 255 * 256;
|
---|
1060 | }
|
---|
1061 | else
|
---|
1062 | status *= 256;
|
---|
1063 | PL_statusvalue = status;
|
---|
1064 | }
|
---|
1065 | return (status);
|
---|
1066 | }
|
---|
1067 |
|
---|
1068 | int
|
---|
1069 | do_spawn(char *cmd)
|
---|
1070 | {
|
---|
1071 | return do_spawn2(cmd, EXECF_SPAWN);
|
---|
1072 | }
|
---|
1073 |
|
---|
1074 | // Added to make system() work for NetWare
|
---|
1075 | static BOOL
|
---|
1076 | has_shell_metachars(char *ptr)
|
---|
1077 | {
|
---|
1078 | int inquote = 0;
|
---|
1079 | char quote = '\0';
|
---|
1080 |
|
---|
1081 | /*
|
---|
1082 | * Scan string looking for redirection (< or >) or pipe
|
---|
1083 | * characters (|) that are not in a quoted string.
|
---|
1084 | * Shell variable interpolation (%VAR%) can also happen inside strings.
|
---|
1085 | */
|
---|
1086 | while (*ptr) {
|
---|
1087 | switch(*ptr) {
|
---|
1088 | case '%':
|
---|
1089 | return TRUE;
|
---|
1090 | case '\'':
|
---|
1091 | case '\"':
|
---|
1092 | if (inquote) {
|
---|
1093 | if (quote == *ptr) {
|
---|
1094 | inquote = 0;
|
---|
1095 | quote = '\0';
|
---|
1096 | }
|
---|
1097 | }
|
---|
1098 | else {
|
---|
1099 | quote = *ptr;
|
---|
1100 | inquote++;
|
---|
1101 | }
|
---|
1102 | break;
|
---|
1103 | case '>':
|
---|
1104 | case '<':
|
---|
1105 | case '|':
|
---|
1106 | if (!inquote)
|
---|
1107 | return TRUE;
|
---|
1108 | default:
|
---|
1109 | break;
|
---|
1110 | }
|
---|
1111 | ++ptr;
|
---|
1112 | }
|
---|
1113 | return FALSE;
|
---|
1114 | }
|
---|
1115 |
|
---|
1116 | int
|
---|
1117 | fork(void)
|
---|
1118 | {
|
---|
1119 | return 0;
|
---|
1120 | }
|
---|
1121 |
|
---|
1122 |
|
---|
1123 | // added to remove undefied symbol error in CodeWarrior compilation
|
---|
1124 | int
|
---|
1125 | Perl_Ireentrant_buffer_ptr(aTHX)
|
---|
1126 | {
|
---|
1127 | return 0;
|
---|
1128 | }
|
---|