]>
Commit | Line | Data |
---|---|---|
f6bcfd97 BP |
1 | /********************************************************************** |
2 | * REXXAPI.C * | |
3 | * * | |
4 | * This program adds a ZIP engine directly to the REXX language. * | |
5 | * The functions are: * | |
6 | * UZDropFuncs -- Makes all functions in this package * | |
7 | * unknown to REXX. * | |
8 | * UZLoadFuncs -- Makes all functions in this package * | |
9 | * known to REXX so REXX programs may * | |
10 | * call them. * | |
11 | * UZFileTree -- Searches for files matching a given * | |
12 | * filespec, including files in * | |
13 | * subdirectories. * | |
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 * | |
20 | * * | |
21 | **********************************************************************/ | |
22 | /* Include files */ | |
23 | ||
24 | #ifdef OS2DLL | |
25 | ||
26 | #define INCL_DOS | |
27 | #define INCL_DOSMEMMGR | |
28 | #include <string.h> | |
29 | #include <stdlib.h> | |
30 | #include <stdio.h> | |
31 | #include <stdarg.h> | |
32 | ||
33 | #define UNZIP_INTERNAL | |
34 | #include "../unzip.h" | |
35 | #include "../version.h" | |
36 | ||
37 | ||
38 | /*********************************************************************/ | |
39 | /* Various definitions used by various functions. */ | |
40 | /*********************************************************************/ | |
41 | ||
42 | RexxFunctionHandler UZDropFuncs; | |
43 | RexxFunctionHandler UZLoadFuncs; | |
44 | RexxFunctionHandler UZFileTree; | |
45 | RexxFunctionHandler UZUnZip; | |
46 | RexxFunctionHandler UZUnZipToVar; | |
47 | RexxFunctionHandler UZUnZipToStem; | |
48 | RexxFunctionHandler UZVer; | |
49 | RexxFunctionHandler UZAPIVer; | |
50 | ||
51 | ||
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); | |
60 | ||
61 | #define EZRXSTRING(r,p) {(r).strptr=(PCH)p;(r).strlength=(ULONG)strlen((r).strptr);} | |
62 | ||
63 | ||
64 | /*********************************************************************/ | |
65 | /* RxFncTable */ | |
66 | /* Array of names of the UNZIPAPI functions. */ | |
67 | /* This list is used for registration and deregistration. */ | |
68 | /*********************************************************************/ | |
69 | ||
70 | static PSZ RxFncTable[] = | |
71 | { | |
72 | "UZDropFuncs", | |
73 | "UZLoadFuncs", | |
74 | "UZFileSearch", | |
75 | "UZFileTree", | |
76 | "UZUnZip", | |
77 | "UZUnZipToVar", | |
78 | "UZUnZipToStem", | |
79 | "UZVer", | |
80 | }; | |
81 | ||
82 | /*********************************************************************/ | |
83 | /* Numeric Error Return Strings */ | |
84 | /*********************************************************************/ | |
85 | ||
86 | #define NO_UTIL_ERROR "0" /* No error whatsoever */ | |
87 | #define ERROR_NOMEM "2" /* Insufficient memory */ | |
88 | ||
89 | /*********************************************************************/ | |
90 | /* Numeric Return calls */ | |
91 | /*********************************************************************/ | |
92 | ||
93 | #define INVALID_ROUTINE 40 /* Raise Rexx error */ | |
94 | #define VALID_ROUTINE 0 /* Successful completion */ | |
95 | ||
96 | /*********************************************************************/ | |
97 | /* Some useful macros */ | |
98 | /*********************************************************************/ | |
99 | ||
100 | #define BUILDRXSTRING(t, s) { \ | |
101 | strcpy((t)->strptr,(s));\ | |
102 | (t)->strlength = strlen((s)); \ | |
103 | } | |
104 | ||
105 | ||
106 | /*********************************************************************/ | |
107 | /**************** UNZIPAPI Supporting Functions ********************/ | |
108 | /**************** UNZIPAPI Supporting Functions ********************/ | |
109 | /**************** UNZIPAPI Supporting Functions ********************/ | |
110 | /*********************************************************************/ | |
111 | ||
112 | ||
113 | int RexxReturn(__GPRO__ int nodefault, RXSTRING *retstr) | |
114 | { | |
115 | int ret = G.os2.rexx_error; | |
116 | if (G.filenotfound) | |
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; | |
122 | } | |
123 | } else if (nodefault) | |
124 | goto noBuild; | |
125 | BUILDRXSTRING(retstr, G.os2.rexx_mes); | |
126 | noBuild: | |
127 | DESTROYGLOBALS(); | |
128 | return ret; | |
129 | } | |
130 | ||
131 | /* Get a variable from REXX, return 0 if OK */ | |
132 | int GetVariable(__GPRO__ const char *name) | |
133 | { | |
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)) { | |
143 | case RXSHV_MEMFL: | |
144 | G.os2.rexx_mes = ERROR_NOMEM; | |
145 | break; | |
146 | case RXSHV_BADN: | |
147 | case RXSHV_NEWV: | |
148 | G.os2.request.shvvaluelen = 0; | |
149 | case RXSHV_OK: | |
150 | *(G.os2.buffer+G.os2.request.shvvaluelen) = 0; | |
151 | return G.os2.request.shvvaluelen; | |
152 | } | |
153 | return 0; | |
154 | } | |
155 | ||
156 | ||
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) | |
160 | { | |
161 | sprintf(G.os2.getvar_buf+G.os2.getvar_len,"%d",index); | |
162 | return GetVariable(__G__ G.os2.getvar_buf); | |
163 | } | |
164 | ||
165 | ||
166 | /* Transfer REXX array to standard C string array */ | |
167 | /* Returns number of elements */ | |
168 | /* User is responsible for calling KillStringArray */ | |
169 | ||
170 | int CompoundToStringArray(__GPRO__ char ***pointer, const char *name) | |
171 | { | |
172 | int count; | |
173 | int total; | |
174 | char **trav; | |
175 | ||
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; | |
180 | ||
181 | if (GetVariableIndex(__G__ 0)) | |
182 | return 0; | |
183 | ||
184 | total = atoi(G.os2.buffer); | |
185 | *pointer = (char **)malloc((total+1)<<2); | |
186 | trav = *pointer; | |
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); | |
191 | } | |
192 | trav[count-1] = NULL; | |
193 | return total; | |
194 | } | |
195 | ||
196 | ||
197 | /* Kill string array created by CompoundToStringArray */ | |
198 | ||
199 | void KillStringArray(char **pointer) | |
200 | { | |
201 | char **trav=pointer; | |
202 | while (*trav != NULL) { | |
203 | free(*trav); | |
204 | trav++; | |
205 | } | |
206 | free(pointer); | |
207 | } | |
208 | ||
209 | ||
210 | /************************************************************************* | |
211 | * Function: UZDropFuncs * | |
212 | * * | |
213 | * Syntax: call UZDropFuncs * | |
214 | * * | |
215 | * Return: NO_UTIL_ERROR - Successful. * | |
216 | *************************************************************************/ | |
217 | ||
218 | ULONG UZDropFuncs(CHAR *name, ULONG numargs, RXSTRING args[], | |
219 | CHAR *queuename, RXSTRING *retstr) | |
220 | { | |
221 | INT entries; /* Num of entries */ | |
222 | INT j; /* Counter */ | |
223 | ||
224 | if (numargs != 0) /* no arguments for this */ | |
225 | return INVALID_ROUTINE; /* raise an error */ | |
226 | ||
227 | retstr->strlength = 0; /* return a null string result*/ | |
228 | ||
229 | entries = sizeof(RxFncTable)/sizeof(PSZ); | |
230 | ||
231 | for (j = 0; j < entries; j++) | |
232 | RexxDeregisterFunction(RxFncTable[j]); | |
233 | ||
234 | return VALID_ROUTINE; /* no error on call */ | |
235 | } | |
236 | ||
237 | ||
238 | /************************************************************************* | |
239 | * Function: UZFileTree * | |
240 | * * | |
241 | * Syntax: call UZFileTree zipfile, stem[, include-filespec] * | |
242 | * [, exclude-filespec][, options] * | |
243 | * * | |
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 * | |
254 | * * | |
255 | * Return: NO_UTIL_ERROR - Successful. * | |
256 | * ERROR_NOMEM - Out of memory. * | |
257 | *************************************************************************/ | |
258 | ||
259 | ULONG UZFileTree(CHAR *name, ULONG numargs, RXSTRING args[], | |
260 | CHAR *queuename, RXSTRING *retstr) | |
261 | { | |
262 | /* validate arguments */ | |
263 | char *incname[2]; | |
264 | char *excname[2]; | |
265 | CONSTRUCTGLOBALS(); | |
266 | ||
267 | if (numargs < 2 || numargs > 5 || | |
268 | !RXVALIDSTRING(args[0]) || | |
269 | !RXVALIDSTRING(args[1]) || | |
270 | args[0].strlength > 255) { | |
271 | DESTROYGLOBALS(); | |
272 | return INVALID_ROUTINE; /* Invalid call to routine */ | |
273 | } | |
274 | /* initialize data area */ | |
275 | SetOutputVarStem(__G__ args[1].strptr); | |
276 | G.wildzipfn = args[0].strptr; | |
277 | G.process_all_files = TRUE; | |
278 | ||
279 | uO.lflag = 1; | |
280 | uO.zipinfo_mode = TRUE; | |
281 | uO.C_flag = 1; | |
282 | G.extract_flag = FALSE; | |
283 | uO.qflag = 2; | |
284 | ||
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))) { | |
289 | G.pfnames = incname; | |
290 | incname[0] = args[2].strptr; | |
291 | incname[1] = NULL; | |
292 | G.filespecs = 1; | |
293 | } | |
294 | G.process_all_files = FALSE; | |
295 | } | |
296 | ||
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))) { | |
301 | G.pxnames = excname; | |
302 | excname[0] = args[3].strptr; | |
303 | excname[1] = NULL; | |
304 | G.xfilespecs = 1; | |
305 | } | |
306 | G.process_all_files = FALSE; | |
307 | } | |
308 | ||
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; | |
313 | ||
314 | if (first == 'Z') | |
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; | |
318 | } | |
319 | ||
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 */ | |
327 | } | |
328 | ||
329 | ||
330 | /************************************************************************* | |
331 | * Function: UZUnZipToVar * | |
332 | * * | |
333 | * Syntax: call UZUnZipToVar zipfile, filespec [, stem] * | |
334 | * * | |
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 * | |
340 | * * | |
341 | * Return: Extracted file * | |
342 | * ERROR_NOMEM - Out of memory. * | |
343 | *************************************************************************/ | |
344 | ||
345 | ULONG UZUnZipToVar(CHAR *name, ULONG numargs, RXSTRING args[], | |
346 | CHAR *queuename, RXSTRING *retstr) | |
347 | { | |
348 | CONSTRUCTGLOBALS(); | |
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) { | |
356 | DESTROYGLOBALS(); | |
357 | return INVALID_ROUTINE; /* Invalid call to routine */ | |
358 | } | |
359 | ||
360 | uO.C_flag = 1; | |
361 | G.redirect_data=1; | |
362 | if (numargs == 3) { | |
363 | if (!RXVALIDSTRING(args[2]) || | |
364 | RXNULLSTRING(args[1]) || | |
365 | args[2].strlength == 0) { | |
366 | DESTROYGLOBALS(); | |
367 | return INVALID_ROUTINE; /* Invalid call to routine */ | |
368 | } | |
369 | SetOutputVarStem(__G__ args[2].strptr); | |
370 | G.redirect_text = 0; | |
371 | G.redirect_data++; | |
372 | } | |
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); | |
376 | } | |
377 | ||
378 | ||
379 | /************************************************************************* | |
380 | * Function: UZUnZipToStem * | |
381 | * * | |
382 | * Syntax: call UZUnZipToStem zipfile, stem[, include-filespec] * | |
383 | * [, exclude-filespec][, mode] * | |
384 | * * | |
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: * | |
392 | * unzip.c * | |
393 | * unshrink.c * | |
394 | * extract.c * | |
395 | * os2/makefile.os2 * | |
396 | * os2/os2.c * | |
397 | * os2/dll/dll.def * | |
398 | * os2/dll/unzipapi.c * | |
399 | * * | |
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> * | |
403 | * * | |
404 | * Flat mode returns: * | |
405 | * stem.0 = 7 * | |
406 | * stem.1 = unzip.c * | |
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 * | |
413 | * * | |
414 | * And the following contain the contents of the * | |
415 | * various programs: * | |
416 | * stem.unzip.c * | |
417 | * stem.unshrink.c * | |
418 | * stem.extract.c * | |
419 | * stem.os2/makefile.os2 * | |
420 | * stem.os2/os2.c * | |
421 | * stem.os2/dll/dll.def * | |
422 | * stem.os2/dll/unzipapi.c * | |
423 | * * | |
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. * | |
428 | * DLL.<index>. * | |
429 | * * | |
430 | * NOTE: All path names are converted to uppercase * | |
431 | * * | |
432 | * Tree mode returns: * | |
433 | * stem.0 = 4 * | |
434 | * stem.1 = unzip.c * | |
435 | * stem.2 = unshrink.c * | |
436 | * stem.3 = extract.c * | |
437 | * stem.4 = OS2/ * | |
438 | * * | |
439 | * stem.OS2.0 = 3 * | |
440 | * stem.OS2.1 = makefile.os2 * | |
441 | * stem.OS2.2 = os2.c * | |
442 | * stem.OS2.3 = DLL/ * | |
443 | * * | |
444 | * stem.OS2.DLL.0 = 2 * | |
445 | * stem.OS2.DLL.1 = def * | |
446 | * stem.OS2.DLL.2 = unzipapi.c * | |
447 | * * | |
448 | * And the following contain the contents of the * | |
449 | * various programs: * | |
450 | * stem.unzip.c * | |
451 | * stem.unshrink.c * | |
452 | * stem.extract.c * | |
453 | * stem.OS2.makefile.os2 * | |
454 | * stem.OS2.os2.c * | |
455 | * stem.OS2.DLL.dll.def * | |
456 | * stem.OS2.DLL.unzipapi.c * | |
457 | * * | |
458 | * * | |
459 | * Return: NO_UTIL_ERROR - Successful. * | |
460 | * ERROR_NOMEM - Out of memory. * | |
461 | *************************************************************************/ | |
462 | ||
463 | ULONG UZUnZipToStem(CHAR *name, ULONG numargs, RXSTRING args[], | |
464 | CHAR *queuename, RXSTRING *retstr) | |
465 | { | |
466 | char *incname[2]; | |
467 | char *excname[2]; | |
468 | CONSTRUCTGLOBALS(); | |
469 | /* validate arguments */ | |
470 | if (numargs < 2 || numargs > 5 || | |
471 | !RXVALIDSTRING(args[0]) || | |
472 | !RXVALIDSTRING(args[1]) || | |
473 | args[0].strlength > 255) { | |
474 | DESTROYGLOBALS(); | |
475 | return INVALID_ROUTINE; /* Invalid call to routine */ | |
476 | } | |
477 | /* initialize data area */ | |
478 | G.wildzipfn = args[0].strptr; | |
479 | G.process_all_files = TRUE; | |
480 | ||
481 | uO.C_flag = 1; | |
482 | G.extract_flag = TRUE; | |
483 | SetOutputVarStem(__G__ args[1].strptr); | |
484 | G.redirect_data = 3; | |
485 | G.redirect_text = 0; | |
486 | ||
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))) { | |
491 | G.pfnames = incname; | |
492 | incname[0] = args[2].strptr; | |
493 | incname[1] = NULL; | |
494 | G.filespecs = 1; | |
495 | } | |
496 | G.process_all_files = FALSE; | |
497 | } | |
498 | ||
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))) { | |
503 | G.pxnames = excname; | |
504 | excname[0] = args[3].strptr; | |
505 | excname[1] = NULL; | |
506 | G.xfilespecs = 1; | |
507 | } | |
508 | G.process_all_files = FALSE; | |
509 | } | |
510 | ||
511 | if (numargs == 5 && /* check third option */ | |
512 | !RXNULLSTRING(args[4]) && | |
513 | (*args[4].strptr & 0x5f) == 'T') { | |
514 | G.redirect_data++; | |
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); | |
521 | } | |
522 | ||
523 | ||
524 | uO.qflag = 2; | |
525 | ||
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 */ | |
534 | } | |
535 | ||
536 | ||
537 | /************************************************************************* | |
538 | * Function: UZLoadFuncs * | |
539 | * * | |
540 | * Syntax: call UZLoadFuncs [option] * | |
541 | * * | |
542 | * Params: none * | |
543 | * * | |
544 | * Return: null string * | |
545 | *************************************************************************/ | |
546 | ||
547 | ULONG UZLoadFuncs(CHAR *name, ULONG numargs, RXSTRING args[], | |
548 | CHAR *queuename, RXSTRING *retstr) | |
549 | { | |
550 | INT entries; /* Num of entries */ | |
551 | INT j; /* Counter */ | |
552 | ||
553 | retstr->strlength = 0; /* set return value */ | |
554 | /* check arguments */ | |
555 | if (numargs > 0) | |
556 | return INVALID_ROUTINE; | |
557 | ||
558 | entries = sizeof(RxFncTable)/sizeof(PSZ); | |
559 | ||
560 | for (j = 0; j < entries; j++) { | |
561 | RexxRegisterFunctionDll(RxFncTable[j], | |
562 | "UNZIP32", RxFncTable[j]); | |
563 | } | |
564 | return VALID_ROUTINE; | |
565 | } | |
566 | ||
567 | ||
568 | ||
569 | /************************************************************************* | |
570 | * Function: UZVer * | |
571 | * * | |
572 | * Syntax: call UZVer * | |
573 | * * | |
574 | * Return: Version of Unzip * | |
575 | *************************************************************************/ | |
576 | ||
577 | ULONG UZVer(CHAR *name, ULONG numargs, RXSTRING args[], | |
578 | CHAR *queuename, RXSTRING *retstr) | |
579 | { | |
580 | if (numargs > 1) /* validate arg count */ | |
581 | return INVALID_ROUTINE; | |
582 | ||
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 ); | |
587 | else | |
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; | |
593 | } | |
594 | ||
595 | ||
596 | /************************************************************************* | |
597 | * Function: UZUnZip * | |
598 | * * | |
599 | * Syntax: call UZUnZip * | |
600 | * * | |
601 | * Return: Unzip return code * | |
602 | *************************************************************************/ | |
603 | ||
604 | ULONG UZUnZip(CHAR *name, ULONG numargs, RXSTRING args[], | |
605 | CHAR *queuename, RXSTRING *retstr) | |
606 | { | |
607 | char *argv[30]; | |
608 | char *scan; | |
609 | int argc=0; | |
610 | int idx; | |
611 | CONSTRUCTGLOBALS(); | |
612 | ||
613 | if (numargs < 1 || numargs > 2 || | |
614 | args[0].strlength > 255) { | |
615 | DESTROYGLOBALS(); | |
616 | return INVALID_ROUTINE; /* Invalid call to routine */ | |
617 | } | |
618 | /* initialize data area */ | |
619 | if (numargs == 2) | |
620 | SetOutputVarStem(__G__ args[1].strptr); | |
621 | ||
622 | scan = args[0].strptr; | |
623 | argv[argc++] = ""; /* D:\\SOURCECODE\\UNZIP51S\\UNZIP.COM"; */ | |
624 | while (*scan == ' ') | |
625 | scan++; | |
626 | argv[argc++] = scan; | |
627 | while ( (scan = strchr(scan,' ')) != NULL) { | |
628 | *scan++ = 0; | |
629 | while (*scan == ' ') | |
630 | scan++; | |
631 | argv[argc++] = scan; | |
632 | } | |
633 | if (*argv[argc-1] == 0) | |
634 | argc--; | |
635 | argv[argc] = 0; | |
636 | ||
637 | /* GRR: should resetMainFlags() be called in here somewhere? */ | |
638 | ||
639 | sprintf(retstr->strptr, "%d", unzip(__G__ argc, argv)); /* a.k.a. MAIN() */ | |
640 | if (numargs == 2) | |
641 | SetOutputVarLength(__G); | |
642 | retstr->strlength = strlen(retstr->strptr); | |
643 | return RexxReturn(__G__ 1,retstr); | |
644 | } | |
645 | ||
646 | int varmessage(__GPRO__ uch *buf, ulg size) | |
647 | { | |
648 | if (size > 0) | |
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); | |
651 | return 0; | |
652 | } | |
653 | ||
654 | int varputchar(__GPRO__ int c) | |
655 | { | |
656 | G.os2.buffer[G.os2.putchar_idx++] = c; | |
657 | if (c == '\n') { | |
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); | |
661 | else { | |
662 | G.os2.buffer[--G.os2.putchar_idx] = 0; | |
663 | puts(G.os2.buffer); | |
664 | G.os2.putchar_idx = 0; | |
665 | } | |
666 | } | |
667 | return 1; | |
668 | } | |
669 | ||
670 | ||
671 | ||
672 | int SetOutputVarStem(__GPRO__ const char *name) | |
673 | { | |
674 | int len=strlen(name); | |
675 | G.redirect_text=1; | |
676 | G.os2.output_idx = 0; | |
677 | strcpy(G.os2.output_var, name); | |
678 | if (len) { | |
679 | strupr(G.os2.output_var); /* uppercase the name */ | |
680 | if (*(G.os2.output_var+len-1) != '.') { | |
681 | *(G.os2.output_var+len) = '.'; | |
682 | len++; | |
683 | *(G.os2.output_var+len) = 0; | |
684 | } | |
685 | WriteToVariable(__G__ G.os2.output_var,"",0); | |
686 | } | |
687 | G.os2.stem_len = len; | |
688 | return G.os2.stem_len; | |
689 | } | |
690 | ||
691 | int SetOutputVar(__GPRO__ const char *name) | |
692 | { | |
693 | int len=strlen(name); | |
694 | G.redirect_text=1; | |
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; | |
700 | else | |
701 | G.os2.stem_len = 0; | |
702 | return G.os2.stem_len; | |
703 | } | |
704 | ||
705 | int SetOutputVarLength(__GPRO) | |
706 | { | |
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); | |
711 | } | |
712 | return 0; | |
713 | } | |
714 | ||
715 | int PrintToVariable(__GPRO__ const char *name, const char *format,...) | |
716 | { | |
717 | va_list arg_ptr; | |
718 | int ret; | |
719 | ||
720 | va_start(arg_ptr, format); | |
721 | ret = _PrintToVariable(__G__ name, format, arg_ptr); | |
722 | va_end(arg_ptr); | |
723 | return ret; | |
724 | } | |
725 | ||
726 | int WriteToVariable(__GPRO__ const char *name, char *buffer, int len) | |
727 | { | |
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)) { | |
737 | case RXSHV_BADN: | |
738 | G.os2.rexx_error = INVALID_ROUTINE; | |
739 | break; | |
740 | case RXSHV_MEMFL: | |
741 | G.os2.rexx_mes = ERROR_NOMEM; | |
742 | break; | |
743 | case RXSHV_OK: | |
744 | return 0; | |
745 | } | |
746 | return INVALID_ROUTINE; /* error on non-zero */ | |
747 | } | |
748 | ||
749 | int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr) | |
750 | { | |
751 | int ret = vsprintf(G.os2.buffer, format, arg_ptr); | |
752 | WriteToVariable(__G__ name, G.os2.buffer, strlen(G.os2.buffer)); | |
753 | return ret; | |
754 | } | |
755 | ||
756 | int PrintToSubVariable(__GPRO__ int idx, const char *format, ...) | |
757 | { | |
758 | va_list arg_ptr; | |
759 | int ret; | |
760 | ||
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); | |
764 | ||
765 | va_start(arg_ptr, format); | |
766 | ret = _PrintToVariable(__G__ G.os2.output_var, format, arg_ptr); | |
767 | va_end(arg_ptr); | |
768 | return ret; | |
769 | } | |
770 | ||
771 | ||
772 | int WriteToNextVariable(__GPRO__ char *buffer, int len) | |
773 | { | |
774 | if (G.os2.stem_len > 0) { | |
775 | G.os2.output_idx++; | |
776 | sprintf(G.os2.output_var+G.os2.stem_len,"%d",G.os2.output_idx); | |
777 | } | |
778 | return WriteToVariable(__G__ G.os2.output_var, buffer, len); | |
779 | } | |
780 | ||
781 | ||
782 | int TextSetNext(__GPRO__ char *buffer, int len, int all) | |
783 | { | |
784 | char *scan = buffer, *next, *base=buffer; | |
785 | int remaining=len; | |
786 | int ret; | |
787 | ||
788 | while ((next = strchr(scan,'\n')) != NULL && remaining > 0) { | |
789 | if (next > scan && *(next-1) == 0xd) | |
790 | *(next-1) = 0; | |
791 | else | |
792 | *next = 0; | |
793 | if (WriteToNextVariable(__G__ scan,strlen(scan))) | |
794 | return 0; | |
795 | next++; | |
796 | remaining -= (next-scan); | |
797 | scan = next; | |
798 | } | |
799 | if (remaining > 0) | |
800 | if (all) { | |
801 | *(scan+remaining) = 0; | |
802 | WriteToNextVariable(__G__ scan,remaining); | |
803 | } else { | |
804 | memcpy(buffer,scan,remaining); | |
805 | return remaining; | |
806 | } | |
807 | ||
808 | return 0; | |
809 | } | |
810 | ||
811 | int finish_REXX_redirect(__GPRO) | |
812 | { | |
813 | char *scan, *ptr; | |
814 | int idx=0, first=1, offset; | |
815 | ||
816 | if (!G.redirect_size) | |
817 | return 0; | |
818 | switch(G.redirect_data) { | |
819 | case 1: | |
820 | break; | |
821 | case 2: | |
822 | TextSetNext(__G__ G.redirect_buffer, G.redirect_size, 1); | |
823 | SetOutputVarLength(__G); | |
824 | DosFreeMem(G.redirect_buffer); | |
825 | G.redirect_buffer = NULL; | |
826 | G.redirect_size = 0; | |
827 | break; | |
828 | case 3: | |
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; | |
834 | G.redirect_size = 0; | |
835 | break; | |
836 | case 4: | |
837 | if ((scan = strrchr(G.filename,'/')) != NULL) { | |
838 | idx = *scan; | |
839 | *scan = 0; | |
840 | strupr(G.filename); | |
841 | *scan = idx; | |
842 | } | |
843 | scan = G.os2.output_var+G.os2.stem_len; | |
844 | strcpy(scan,G.filename); | |
845 | while ((scan = strchr(scan,'/')) != NULL) | |
846 | *scan = '.'; | |
847 | WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size); | |
848 | DosFreeMem(G.redirect_buffer); | |
849 | G.redirect_buffer = NULL; | |
850 | G.redirect_size = 0; | |
851 | strcpy(G.os2.getvar_buf, G.os2.output_var); | |
852 | do { | |
853 | if ((scan = strrchr(G.filename,'/')) == NULL) | |
854 | offset = 0; | |
855 | else | |
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; | |
859 | *ptr = '0'; | |
860 | *(ptr+1) = 0; | |
861 | if (!GetVariable(__G__ G.os2.getvar_buf)) | |
862 | idx = 1; | |
863 | else | |
864 | idx = atoi(G.os2.buffer)+1; | |
865 | PrintToVariable(__G__ G.os2.getvar_buf,"%d",idx); | |
866 | sprintf(ptr,"%d",idx); | |
867 | if (!first) { | |
868 | PrintToVariable(__G__ G.os2.output_var,"%d",idx); | |
869 | idx = strlen(G.filename); | |
870 | *(G.filename+idx) = '/'; | |
871 | *(G.filename+idx+1) = 0; | |
872 | } | |
873 | WriteToVariable(__G__ G.os2.getvar_buf,G.filename+offset,strlen(G.filename+offset)); | |
874 | first=0; | |
875 | } | |
876 | if (offset) { | |
877 | *(G.os2.output_var+G.os2.stem_len+offset-1) = 0; | |
878 | *scan = 0; | |
879 | } | |
880 | } while (offset); | |
881 | break; | |
882 | } | |
883 | return 0; | |
884 | } | |
885 | ||
886 | #endif /* OS2DLL */ |