1 /**********************************************************************
4 * This program adds a ZIP engine directly to the REXX language. *
6 * UZDropFuncs -- Makes all functions in this package *
8 * UZLoadFuncs -- Makes all functions in this package *
9 * known to REXX so REXX programs may *
11 * UZFileTree -- Searches for files matching a given *
12 * filespec, including files in *
14 * UZUnZip -- Unzip command-line entry point. *
15 * This is functionally equivalent to *
16 * using Unzip as an external program. *
17 * UZUnZipToVar -- Unzip one file to a variable *
18 * UZUnZipToStem -- Unzip files to a variable array *
19 * UZVer -- Returns the Unzip version number *
21 **********************************************************************/
27 #define INCL_DOSMEMMGR
33 #define UNZIP_INTERNAL
35 #include "../version.h"
38 /*********************************************************************/
39 /* Various definitions used by various functions. */
40 /*********************************************************************/
42 RexxFunctionHandler UZDropFuncs
;
43 RexxFunctionHandler UZLoadFuncs
;
44 RexxFunctionHandler UZFileTree
;
45 RexxFunctionHandler UZUnZip
;
46 RexxFunctionHandler UZUnZipToVar
;
47 RexxFunctionHandler UZUnZipToStem
;
48 RexxFunctionHandler UZVer
;
49 RexxFunctionHandler UZAPIVer
;
52 int SetOutputVar(__GPRO__
const char *name
);
53 int SetOutputVarStem(__GPRO__
const char *name
);
54 int SetOutputVarLength(__GPRO
);
55 int WriteToVariable(__GPRO__
const char *name
, char *buffer
, int len
);
56 int PrintToSubVariable(__GPRO__
int idx
, const char *format
,...);
57 int PrintToVariable(__GPRO__
const char *name
, const char *format
,...);
58 int _PrintToVariable(__GPRO__
const char *name
, const char *format
, va_list arg_ptr
);
59 int TextSetNext(__GPRO__
char *format
, int len
, int all
);
61 #define EZRXSTRING(r,p) {(r).strptr=(PCH)p;(r).strlength=(ULONG)strlen((r).strptr);}
64 /*********************************************************************/
66 /* Array of names of the UNZIPAPI functions. */
67 /* This list is used for registration and deregistration. */
68 /*********************************************************************/
70 static PSZ RxFncTable
[] =
82 /*********************************************************************/
83 /* Numeric Error Return Strings */
84 /*********************************************************************/
86 #define NO_UTIL_ERROR "0" /* No error whatsoever */
87 #define ERROR_NOMEM "2" /* Insufficient memory */
89 /*********************************************************************/
90 /* Numeric Return calls */
91 /*********************************************************************/
93 #define INVALID_ROUTINE 40 /* Raise Rexx error */
94 #define VALID_ROUTINE 0 /* Successful completion */
96 /*********************************************************************/
97 /* Some useful macros */
98 /*********************************************************************/
100 #define BUILDRXSTRING(t, s) { \
101 strcpy((t)->strptr,(s));\
102 (t)->strlength = strlen((s)); \
106 /*********************************************************************/
107 /**************** UNZIPAPI Supporting Functions ********************/
108 /**************** UNZIPAPI Supporting Functions ********************/
109 /**************** UNZIPAPI Supporting Functions ********************/
110 /*********************************************************************/
113 int RexxReturn(__GPRO__
int nodefault
, RXSTRING
*retstr
)
115 int ret
= G
.os2
.rexx_error
;
117 G
.os2
.rexx_mes
= "file not found";
118 if (*G
.os2
.rexx_mes
!= '0') {
119 if (retstr
->strlength
> 255) {
120 DosFreeMem(retstr
->strptr
);
121 retstr
->strptr
= NULL
;
123 } else if (nodefault
)
125 BUILDRXSTRING(retstr
, G
.os2
.rexx_mes
);
131 /* Get a variable from REXX, return 0 if OK */
132 int GetVariable(__GPRO__
const char *name
)
134 G
.os2
.request
.shvnext
= NULL
;
135 EZRXSTRING(G
.os2
.request
.shvname
, name
);
136 G
.os2
.request
.shvnamelen
= G
.os2
.request
.shvname
.strlength
;
137 G
.os2
.request
.shvvalue
.strptr
= G
.os2
.buffer
;
138 G
.os2
.request
.shvvalue
.strlength
= IBUF_LEN
;
139 G
.os2
.request
.shvvaluelen
= IBUF_LEN
;
140 G
.os2
.request
.shvcode
= RXSHV_SYFET
;
141 G
.os2
.request
.shvret
= 0;
142 switch (RexxVariablePool(&G
.os2
.request
)) {
144 G
.os2
.rexx_mes
= ERROR_NOMEM
;
148 G
.os2
.request
.shvvaluelen
= 0;
150 *(G
.os2
.buffer
+G
.os2
.request
.shvvaluelen
) = 0;
151 return G
.os2
.request
.shvvaluelen
;
157 /* Get REXX compound variable */
158 /* Stem must exist in G.os2.getvar_buf w/ length in G.os2.getvar_len */
159 int GetVariableIndex(__GPRO__
int index
)
161 sprintf(G
.os2
.getvar_buf
+G
.os2
.getvar_len
,"%d",index
);
162 return GetVariable(__G__ G
.os2
.getvar_buf
);
166 /* Transfer REXX array to standard C string array */
167 /* Returns number of elements */
168 /* User is responsible for calling KillStringArray */
170 int CompoundToStringArray(__GPRO__
char ***pointer
, const char *name
)
176 G
.os2
.getvar_len
= strlen(name
);
177 memcpy(G
.os2
.getvar_buf
,name
,G
.os2
.getvar_len
+1);
178 if (*(G
.os2
.getvar_buf
+G
.os2
.getvar_len
-1) != '.')
179 *(G
.os2
.getvar_buf
+G
.os2
.getvar_len
++) = '.', *(G
.os2
.getvar_buf
+G
.os2
.getvar_len
) = 0;
181 if (GetVariableIndex(__G__
0))
184 total
= atoi(G
.os2
.buffer
);
185 *pointer
= (char **)malloc((total
+1)<<2);
187 for (count
= 1; count
<= total
; count
++) {
188 GetVariableIndex(__G__ count
);
189 trav
[count
-1] = (char *)malloc(strlen(G
.os2
.buffer
)+1);
190 strcpy(trav
[count
-1],G
.os2
.buffer
);
192 trav
[count
-1] = NULL
;
197 /* Kill string array created by CompoundToStringArray */
199 void KillStringArray(char **pointer
)
202 while (*trav
!= NULL
) {
210 /*************************************************************************
211 * Function: UZDropFuncs *
213 * Syntax: call UZDropFuncs *
215 * Return: NO_UTIL_ERROR - Successful. *
216 *************************************************************************/
218 ULONG
UZDropFuncs(CHAR
*name
, ULONG numargs
, RXSTRING args
[],
219 CHAR
*queuename
, RXSTRING
*retstr
)
221 INT entries
; /* Num of entries */
224 if (numargs
!= 0) /* no arguments for this */
225 return INVALID_ROUTINE
; /* raise an error */
227 retstr
->strlength
= 0; /* return a null string result*/
229 entries
= sizeof(RxFncTable
)/sizeof(PSZ
);
231 for (j
= 0; j
< entries
; j
++)
232 RexxDeregisterFunction(RxFncTable
[j
]);
234 return VALID_ROUTINE
; /* no error on call */
238 /*************************************************************************
239 * Function: UZFileTree *
241 * Syntax: call UZFileTree zipfile, stem[, include-filespec] *
242 * [, exclude-filespec][, options] *
244 * Params: zipfile - Name of zip file to search. *
245 * stem - Name of stem var to store results in. *
246 * include - Filespec to search for (may include * and ?). *
247 * exclude - Filespec to exclude (may include * and ?). *
248 * options - Either of the following: *
249 * 'F' - Give file statistics. *
250 * Length Date Time Name *
251 * 'Z' - Give zip statistics, too. *
252 * Length Method Size Ratio Date Time CRC-32 Name*
253 * Default is to return only filenames *
255 * Return: NO_UTIL_ERROR - Successful. *
256 * ERROR_NOMEM - Out of memory. *
257 *************************************************************************/
259 ULONG
UZFileTree(CHAR
*name
, ULONG numargs
, RXSTRING args
[],
260 CHAR
*queuename
, RXSTRING
*retstr
)
262 /* validate arguments */
267 if (numargs
< 2 || numargs
> 5 ||
268 !RXVALIDSTRING(args
[0]) ||
269 !RXVALIDSTRING(args
[1]) ||
270 args
[0].strlength
> 255) {
272 return INVALID_ROUTINE
; /* Invalid call to routine */
274 /* initialize data area */
275 SetOutputVarStem(__G__ args
[1].strptr
);
276 G
.wildzipfn
= args
[0].strptr
;
277 G
.process_all_files
= TRUE
;
280 uO
.zipinfo_mode
= TRUE
;
282 G
.extract_flag
= FALSE
;
285 if (numargs
>= 3 && /* check third option */
286 !RXNULLSTRING(args
[2]) &&
287 args
[2].strlength
> 0) { /* a zero length string isn't */
288 if (!(G
.filespecs
= CompoundToStringArray(__G__
&G
.pfnames
,args
[2].strptr
))) {
290 incname
[0] = args
[2].strptr
;
294 G
.process_all_files
= FALSE
;
297 if (numargs
>= 4 && /* check third option */
298 !RXNULLSTRING(args
[3]) &&
299 args
[3].strlength
> 0) { /* a zero length string isn't */
300 if (!(G
.xfilespecs
= CompoundToStringArray(__G__
&G
.pxnames
,args
[3].strptr
))) {
302 excname
[0] = args
[3].strptr
;
306 G
.process_all_files
= FALSE
;
309 if (numargs
== 5 && /* check third option */
310 !RXNULLSTRING(args
[4]) &&
311 args
[4].strlength
> 0) { /* a zero length string isn't */
312 int first
= *args
[4].strptr
& 0x5f;
315 uO
.vflag
= 2, uO
.lflag
= 0, uO
.zipinfo_mode
= FALSE
;
316 else if (first
== 'F')
317 uO
.vflag
= 1, uO
.lflag
= 0, uO
.zipinfo_mode
= FALSE
;
320 process_zipfiles(__G
);
321 SetOutputVarLength(__G
);
322 if (G
.filespecs
> 0 && G
.pfnames
!= incname
)
323 KillStringArray(G
.pfnames
);
324 if (G
.xfilespecs
> 0 && G
.pxnames
!= excname
)
325 KillStringArray(G
.pxnames
);
326 return RexxReturn(__G__
0,retstr
); /* no error on call */
330 /*************************************************************************
331 * Function: UZUnZipToVar *
333 * Syntax: call UZUnZipToVar zipfile, filespec [, stem] *
335 * Params: zipfile - Name of zip file to search. *
336 * filespec - File to extract *
337 * stem - If you specify a stem variable, the file will be *
338 * extracted to the variable, one line per index *
339 * In this case, 0 will be returned *
341 * Return: Extracted file *
342 * ERROR_NOMEM - Out of memory. *
343 *************************************************************************/
345 ULONG
UZUnZipToVar(CHAR
*name
, ULONG numargs
, RXSTRING args
[],
346 CHAR
*queuename
, RXSTRING
*retstr
)
349 UzpBuffer
*ub
= (UzpBuffer
*)retstr
;
350 /* validate arguments */
351 if (numargs
< 2 || numargs
> 3 ||
352 !RXVALIDSTRING(args
[0]) ||
353 !RXVALIDSTRING(args
[1]) ||
354 args
[0].strlength
== 0 ||
355 args
[1].strlength
== 0) {
357 return INVALID_ROUTINE
; /* Invalid call to routine */
363 if (!RXVALIDSTRING(args
[2]) ||
364 RXNULLSTRING(args
[1]) ||
365 args
[2].strlength
== 0) {
367 return INVALID_ROUTINE
; /* Invalid call to routine */
369 SetOutputVarStem(__G__ args
[2].strptr
);
373 unzipToMemory(__G__ args
[0].strptr
, args
[1].strptr
,
374 G
.redirect_data
==1 ? ub
: NULL
);
375 return RexxReturn(__G__ G
.redirect_data
==1,retstr
);
379 /*************************************************************************
380 * Function: UZUnZipToStem *
382 * Syntax: call UZUnZipToStem zipfile, stem[, include-filespec] *
383 * [, exclude-filespec][, mode] *
385 * Params: zipfile - Name of zip file to search. *
386 * stem - Name of stem var to store files in. *
387 * include - Filespec to search for (may include * and ?). *
388 * exclude - Filespec to exclude (may include * and ?). *
389 * mode - Specifies 'F'lat or 'T'ree mode. Umm, this is *
390 * hard to explain so I'll give an example, too. *
391 * Assuming a file unzip.zip containing: *
398 * os2/dll/unzipapi.c *
400 * -- In flat mode, each file is stored in *
401 * stem.fullname i.e. stem."os2/dll/unzipapi.c" *
402 * A list of files is created in stem.<index> *
404 * Flat mode returns: *
407 * stem.2 = unshrink.c *
408 * stem.3 = extract.c *
409 * stem.4 = os2/makefile.os2 *
410 * stem.5 = os2/os2.c *
411 * stem.6 = os2/dll/dll.def *
412 * stem.7 = os2/dll/unzipapi.c *
414 * And the following contain the contents of the *
415 * various programs: *
419 * stem.os2/makefile.os2 *
421 * stem.os2/dll/dll.def *
422 * stem.os2/dll/unzipapi.c *
424 * -- In tree mode, slashes are converted to periods*
425 * in the pathname thus the above file would have*
426 * been stored in stem.os2.dll.unzipapi.c *
427 * The index would then be stored in stem.OS2. *
430 * NOTE: All path names are converted to uppercase *
432 * Tree mode returns: *
435 * stem.2 = unshrink.c *
436 * stem.3 = extract.c *
440 * stem.OS2.1 = makefile.os2 *
441 * stem.OS2.2 = os2.c *
442 * stem.OS2.3 = DLL/ *
444 * stem.OS2.DLL.0 = 2 *
445 * stem.OS2.DLL.1 = def *
446 * stem.OS2.DLL.2 = unzipapi.c *
448 * And the following contain the contents of the *
449 * various programs: *
453 * stem.OS2.makefile.os2 *
455 * stem.OS2.DLL.dll.def *
456 * stem.OS2.DLL.unzipapi.c *
459 * Return: NO_UTIL_ERROR - Successful. *
460 * ERROR_NOMEM - Out of memory. *
461 *************************************************************************/
463 ULONG
UZUnZipToStem(CHAR
*name
, ULONG numargs
, RXSTRING args
[],
464 CHAR
*queuename
, RXSTRING
*retstr
)
469 /* validate arguments */
470 if (numargs
< 2 || numargs
> 5 ||
471 !RXVALIDSTRING(args
[0]) ||
472 !RXVALIDSTRING(args
[1]) ||
473 args
[0].strlength
> 255) {
475 return INVALID_ROUTINE
; /* Invalid call to routine */
477 /* initialize data area */
478 G
.wildzipfn
= args
[0].strptr
;
479 G
.process_all_files
= TRUE
;
482 G
.extract_flag
= TRUE
;
483 SetOutputVarStem(__G__ args
[1].strptr
);
487 if (numargs
>= 3 && /* check third option */
488 !RXNULLSTRING(args
[2]) &&
489 args
[2].strlength
> 0) { /* a zero length string isn't */
490 if (!(G
.filespecs
= CompoundToStringArray(__G__
&G
.pfnames
,args
[2].strptr
))) {
492 incname
[0] = args
[2].strptr
;
496 G
.process_all_files
= FALSE
;
499 if (numargs
>= 4 && /* check third option */
500 !RXNULLSTRING(args
[3]) &&
501 args
[3].strlength
> 0) { /* a zero length string isn't */
502 if (!(G
.xfilespecs
= CompoundToStringArray(__G__
&G
.pxnames
,args
[3].strptr
))) {
504 excname
[0] = args
[3].strptr
;
508 G
.process_all_files
= FALSE
;
511 if (numargs
== 5 && /* check third option */
512 !RXNULLSTRING(args
[4]) &&
513 (*args
[4].strptr
& 0x5f) == 'T') {
515 G
.os2
.request
.shvnext
= NULL
;
516 EZRXSTRING(G
.os2
.request
.shvname
, args
[4].strptr
);
517 G
.os2
.request
.shvnamelen
= G
.os2
.request
.shvname
.strlength
;
518 G
.os2
.request
.shvcode
= RXSHV_SYDRO
;
519 G
.os2
.request
.shvret
= 0;
520 RexxVariablePool(&G
.os2
.request
);
526 process_zipfiles(__G
);
527 if (G
.filespecs
> 0 && G
.pfnames
!= incname
)
528 KillStringArray(G
.pfnames
);
529 if (G
.xfilespecs
> 0 && G
.pxnames
!= excname
)
530 KillStringArray(G
.pxnames
);
531 if (G
.redirect_data
== 3)
532 SetOutputVarLength(__G
);
533 return RexxReturn(__G__
0,retstr
); /* no error on call */
537 /*************************************************************************
538 * Function: UZLoadFuncs *
540 * Syntax: call UZLoadFuncs [option] *
544 * Return: null string *
545 *************************************************************************/
547 ULONG
UZLoadFuncs(CHAR
*name
, ULONG numargs
, RXSTRING args
[],
548 CHAR
*queuename
, RXSTRING
*retstr
)
550 INT entries
; /* Num of entries */
553 retstr
->strlength
= 0; /* set return value */
554 /* check arguments */
556 return INVALID_ROUTINE
;
558 entries
= sizeof(RxFncTable
)/sizeof(PSZ
);
560 for (j
= 0; j
< entries
; j
++) {
561 RexxRegisterFunctionDll(RxFncTable
[j
],
562 "UNZIP32", RxFncTable
[j
]);
564 return VALID_ROUTINE
;
569 /*************************************************************************
572 * Syntax: call UZVer *
574 * Return: Version of Unzip *
575 *************************************************************************/
577 ULONG
UZVer(CHAR
*name
, ULONG numargs
, RXSTRING args
[],
578 CHAR
*queuename
, RXSTRING
*retstr
)
580 if (numargs
> 1) /* validate arg count */
581 return INVALID_ROUTINE
;
583 if (numargs
== 0 || (*args
[0].strptr
& 0x5f) != 'L')
584 /* strcpy( retstr->strptr, UZ_VERNUM ); "5.13a BETA" */
585 sprintf( retstr
->strptr
, "%d.%d%d%s", UZ_MAJORVER
, UZ_MINORVER
,
586 PATCHLEVEL
, BETALEVEL
);
588 /* strcpy( retstr->strptr, UZ_VERSION ); UZ_VERNUM" of 26 Sep 94" */
589 sprintf( retstr
->strptr
, "%d.%d%d%s of %s", UZ_MAJORVER
, UZ_MINORVER
,
590 PATCHLEVEL
, BETALEVEL
, VERSION_DATE
);
591 retstr
->strlength
= strlen(retstr
->strptr
);
592 return VALID_ROUTINE
;
596 /*************************************************************************
597 * Function: UZUnZip *
599 * Syntax: call UZUnZip *
601 * Return: Unzip return code *
602 *************************************************************************/
604 ULONG
UZUnZip(CHAR
*name
, ULONG numargs
, RXSTRING args
[],
605 CHAR
*queuename
, RXSTRING
*retstr
)
613 if (numargs
< 1 || numargs
> 2 ||
614 args
[0].strlength
> 255) {
616 return INVALID_ROUTINE
; /* Invalid call to routine */
618 /* initialize data area */
620 SetOutputVarStem(__G__ args
[1].strptr
);
622 scan
= args
[0].strptr
;
623 argv
[argc
++] = ""; /* D:\\SOURCECODE\\UNZIP51S\\UNZIP.COM"; */
627 while ( (scan
= strchr(scan
,' ')) != NULL
) {
633 if (*argv
[argc
-1] == 0)
637 /* GRR: should resetMainFlags() be called in here somewhere? */
639 sprintf(retstr
->strptr
, "%d", unzip(__G__ argc
, argv
)); /* a.k.a. MAIN() */
641 SetOutputVarLength(__G
);
642 retstr
->strlength
= strlen(retstr
->strptr
);
643 return RexxReturn(__G__
1,retstr
);
646 int varmessage(__GPRO__ uch
*buf
, ulg size
)
649 memcpy(G
.os2
.buffer
+G
.os2
.putchar_idx
,buf
,size
);
650 G
.os2
.putchar_idx
= TextSetNext(__G__ G
.os2
.buffer
, size
+G
.os2
.putchar_idx
,0);
654 int varputchar(__GPRO__
int c
)
656 G
.os2
.buffer
[G
.os2
.putchar_idx
++] = c
;
658 G
.os2
.buffer
[G
.os2
.putchar_idx
] = 0;
659 if (G
.os2
.output_var
[0])
660 G
.os2
.putchar_idx
= TextSetNext(__G__ G
.os2
.buffer
, G
.os2
.putchar_idx
,0);
662 G
.os2
.buffer
[--G
.os2
.putchar_idx
] = 0;
664 G
.os2
.putchar_idx
= 0;
672 int SetOutputVarStem(__GPRO__
const char *name
)
674 int len
=strlen(name
);
676 G
.os2
.output_idx
= 0;
677 strcpy(G
.os2
.output_var
, name
);
679 strupr(G
.os2
.output_var
); /* uppercase the name */
680 if (*(G
.os2
.output_var
+len
-1) != '.') {
681 *(G
.os2
.output_var
+len
) = '.';
683 *(G
.os2
.output_var
+len
) = 0;
685 WriteToVariable(__G__ G
.os2
.output_var
,"",0);
687 G
.os2
.stem_len
= len
;
688 return G
.os2
.stem_len
;
691 int SetOutputVar(__GPRO__
const char *name
)
693 int len
=strlen(name
);
695 G
.os2
.output_idx
= 0;
696 strcpy(G
.os2
.output_var
, name
);
697 strupr(G
.os2
.output_var
); /* uppercase the name */
698 if (*(name
+len
-1) == '.')
699 G
.os2
.stem_len
= len
;
702 return G
.os2
.stem_len
;
705 int SetOutputVarLength(__GPRO
)
707 if (G
.os2
.stem_len
> 0) {
708 if (G
.os2
.putchar_idx
)
709 TextSetNext(__G__ G
.os2
.buffer
,G
.os2
.putchar_idx
,1);
710 return PrintToSubVariable(__G__
0,"%d",G
.os2
.output_idx
);
715 int PrintToVariable(__GPRO__
const char *name
, const char *format
,...)
720 va_start(arg_ptr
, format
);
721 ret
= _PrintToVariable(__G__ name
, format
, arg_ptr
);
726 int WriteToVariable(__GPRO__
const char *name
, char *buffer
, int len
)
728 G
.os2
.request
.shvnext
= NULL
;
729 EZRXSTRING(G
.os2
.request
.shvname
, name
);
730 G
.os2
.request
.shvnamelen
= G
.os2
.request
.shvname
.strlength
;
731 G
.os2
.request
.shvvalue
.strptr
= buffer
;
732 G
.os2
.request
.shvvalue
.strlength
= len
;
733 G
.os2
.request
.shvvaluelen
= len
;
734 G
.os2
.request
.shvcode
= RXSHV_SET
;
735 G
.os2
.request
.shvret
= 0;
736 switch (RexxVariablePool(&G
.os2
.request
)) {
738 G
.os2
.rexx_error
= INVALID_ROUTINE
;
741 G
.os2
.rexx_mes
= ERROR_NOMEM
;
746 return INVALID_ROUTINE
; /* error on non-zero */
749 int _PrintToVariable(__GPRO__
const char *name
, const char *format
, va_list arg_ptr
)
751 int ret
= vsprintf(G
.os2
.buffer
, format
, arg_ptr
);
752 WriteToVariable(__G__ name
, G
.os2
.buffer
, strlen(G
.os2
.buffer
));
756 int PrintToSubVariable(__GPRO__
int idx
, const char *format
, ...)
761 if (G
.os2
.stem_len
== 0)
762 return INVALID_ROUTINE
; /* error on non-zero */
763 sprintf(G
.os2
.output_var
+G
.os2
.stem_len
,"%d",idx
);
765 va_start(arg_ptr
, format
);
766 ret
= _PrintToVariable(__G__ G
.os2
.output_var
, format
, arg_ptr
);
772 int WriteToNextVariable(__GPRO__
char *buffer
, int len
)
774 if (G
.os2
.stem_len
> 0) {
776 sprintf(G
.os2
.output_var
+G
.os2
.stem_len
,"%d",G
.os2
.output_idx
);
778 return WriteToVariable(__G__ G
.os2
.output_var
, buffer
, len
);
782 int TextSetNext(__GPRO__
char *buffer
, int len
, int all
)
784 char *scan
= buffer
, *next
, *base
=buffer
;
788 while ((next
= strchr(scan
,'\n')) != NULL
&& remaining
> 0) {
789 if (next
> scan
&& *(next
-1) == 0xd)
793 if (WriteToNextVariable(__G__ scan
,strlen(scan
)))
796 remaining
-= (next
-scan
);
801 *(scan
+remaining
) = 0;
802 WriteToNextVariable(__G__ scan
,remaining
);
804 memcpy(buffer
,scan
,remaining
);
811 int finish_REXX_redirect(__GPRO
)
814 int idx
=0, first
=1, offset
;
816 if (!G
.redirect_size
)
818 switch(G
.redirect_data
) {
822 TextSetNext(__G__ G
.redirect_buffer
, G
.redirect_size
, 1);
823 SetOutputVarLength(__G
);
824 DosFreeMem(G
.redirect_buffer
);
825 G
.redirect_buffer
= NULL
;
829 WriteToNextVariable(__G__ G
.filename
,strlen(G
.filename
));
830 sprintf(G
.os2
.output_var
+G
.os2
.stem_len
,G
.filename
);
831 WriteToVariable(__G__ G
.os2
.output_var
, G
.redirect_buffer
, G
.redirect_size
);
832 DosFreeMem(G
.redirect_buffer
);
833 G
.redirect_buffer
= NULL
;
837 if ((scan
= strrchr(G
.filename
,'/')) != NULL
) {
843 scan
= G
.os2
.output_var
+G
.os2
.stem_len
;
844 strcpy(scan
,G
.filename
);
845 while ((scan
= strchr(scan
,'/')) != NULL
)
847 WriteToVariable(__G__ G
.os2
.output_var
, G
.redirect_buffer
, G
.redirect_size
);
848 DosFreeMem(G
.redirect_buffer
);
849 G
.redirect_buffer
= NULL
;
851 strcpy(G
.os2
.getvar_buf
, G
.os2
.output_var
);
853 if ((scan
= strrchr(G
.filename
,'/')) == NULL
)
856 offset
= scan
-G
.filename
+1;
857 if (first
|| !GetVariable(__G__ G
.os2
.output_var
)) {
858 ptr
= G
.os2
.getvar_buf
+offset
+G
.os2
.stem_len
;
861 if (!GetVariable(__G__ G
.os2
.getvar_buf
))
864 idx
= atoi(G
.os2
.buffer
)+1;
865 PrintToVariable(__G__ G
.os2
.getvar_buf
,"%d",idx
);
866 sprintf(ptr
,"%d",idx
);
868 PrintToVariable(__G__ G
.os2
.output_var
,"%d",idx
);
869 idx
= strlen(G
.filename
);
870 *(G
.filename
+idx
) = '/';
871 *(G
.filename
+idx
+1) = 0;
873 WriteToVariable(__G__ G
.os2
.getvar_buf
,G
.filename
+offset
,strlen(G
.filename
+offset
));
877 *(G
.os2
.output_var
+G
.os2
.stem_len
+offset
-1) = 0;