rexxapi.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895
  1. /*
  2. Copyright (c) 1990-2004 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 2000-Apr-09 or later
  4. (the contents of which are also included in unzip.h) for terms of use.
  5. If, for some reason, all these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  7. */
  8. /**********************************************************************
  9. * REXXAPI.C *
  10. * *
  11. * This program adds a ZIP engine directly to the REXX language. *
  12. * The functions are: *
  13. * UZDropFuncs -- Makes all functions in this package *
  14. * unknown to REXX. *
  15. * UZLoadFuncs -- Makes all functions in this package *
  16. * known to REXX so REXX programs may *
  17. * call them. *
  18. * UZFileTree -- Searches for files matching a given *
  19. * filespec, including files in *
  20. * subdirectories. *
  21. * UZUnZip -- Unzip command-line entry point. *
  22. * This is functionally equivalent to *
  23. * using Unzip as an external program. *
  24. * UZUnZipToVar -- Unzip one file to a variable *
  25. * UZUnZipToStem -- Unzip files to a variable array *
  26. * UZVer -- Returns the Unzip version number *
  27. * *
  28. **********************************************************************/
  29. /* Include files */
  30. #ifdef OS2DLL
  31. #define INCL_DOS
  32. #define INCL_DOSMEMMGR
  33. #include <string.h>
  34. #include <stdlib.h>
  35. #include <stdio.h>
  36. #include <stdarg.h>
  37. #define UNZIP_INTERNAL
  38. #include "../unzip.h"
  39. #include "../unzvers.h"
  40. /*********************************************************************/
  41. /* Various definitions used by various functions. */
  42. /*********************************************************************/
  43. RexxFunctionHandler UZDropFuncs;
  44. RexxFunctionHandler UZLoadFuncs;
  45. RexxFunctionHandler UZFileTree;
  46. RexxFunctionHandler UZUnZip;
  47. RexxFunctionHandler UZUnZipToVar;
  48. RexxFunctionHandler UZUnZipToStem;
  49. RexxFunctionHandler UZVer;
  50. RexxFunctionHandler UZAPIVer;
  51. int SetOutputVar(__GPRO__ const char *name);
  52. int SetOutputVarStem(__GPRO__ const char *name);
  53. int SetOutputVarLength(__GPRO);
  54. int WriteToVariable(__GPRO__ const char *name, char *buffer, int len);
  55. int PrintToSubVariable(__GPRO__ int idx, const char *format,...);
  56. int PrintToVariable(__GPRO__ const char *name, const char *format,...);
  57. int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr);
  58. int TextSetNext(__GPRO__ char *format, int len, int all);
  59. #define EZRXSTRING(r,p) {(r).strptr=(PCH)p;(r).strlength=(ULONG)strlen((r).strptr);}
  60. /*********************************************************************/
  61. /* RxFncTable */
  62. /* Array of names of the UNZIPAPI functions. */
  63. /* This list is used for registration and deregistration. */
  64. /*********************************************************************/
  65. static PSZ RxFncTable[] =
  66. {
  67. "UZDropFuncs",
  68. "UZLoadFuncs",
  69. "UZFileSearch",
  70. "UZFileTree",
  71. "UZUnZip",
  72. "UZUnZipToVar",
  73. "UZUnZipToStem",
  74. "UZVer",
  75. };
  76. /*********************************************************************/
  77. /* Numeric Error Return Strings */
  78. /*********************************************************************/
  79. #define NO_UTIL_ERROR "0" /* No error whatsoever */
  80. #define ERROR_NOMEM "2" /* Insufficient memory */
  81. /*********************************************************************/
  82. /* Numeric Return calls */
  83. /*********************************************************************/
  84. #define INVALID_ROUTINE 40 /* Raise Rexx error */
  85. #define VALID_ROUTINE 0 /* Successful completion */
  86. /*********************************************************************/
  87. /* Some useful macros */
  88. /*********************************************************************/
  89. #define BUILDRXSTRING(t, s) { \
  90. strcpy((t)->strptr,(s));\
  91. (t)->strlength = strlen((s)); \
  92. }
  93. /*********************************************************************/
  94. /**************** UNZIPAPI Supporting Functions ********************/
  95. /**************** UNZIPAPI Supporting Functions ********************/
  96. /**************** UNZIPAPI Supporting Functions ********************/
  97. /*********************************************************************/
  98. int RexxReturn(__GPRO__ int nodefault, RXSTRING *retstr)
  99. {
  100. int ret = G.os2.rexx_error;
  101. if (G.filenotfound)
  102. G.os2.rexx_mes = "file not found";
  103. if (*G.os2.rexx_mes != '0') {
  104. if (retstr->strlength > 255) {
  105. DosFreeMem(retstr->strptr);
  106. retstr->strptr = NULL;
  107. }
  108. } else if (nodefault)
  109. goto noBuild;
  110. BUILDRXSTRING(retstr, G.os2.rexx_mes);
  111. noBuild:
  112. DESTROYGLOBALS();
  113. return ret;
  114. }
  115. /* Get a variable from REXX, return 0 if OK */
  116. int GetVariable(__GPRO__ const char *name)
  117. {
  118. G.os2.request.shvnext = NULL;
  119. EZRXSTRING(G.os2.request.shvname, name);
  120. G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
  121. G.os2.request.shvvalue.strptr = G.os2.buffer;
  122. G.os2.request.shvvalue.strlength = IBUF_LEN;
  123. G.os2.request.shvvaluelen = IBUF_LEN;
  124. G.os2.request.shvcode = RXSHV_SYFET;
  125. G.os2.request.shvret = 0;
  126. switch (RexxVariablePool(&G.os2.request)) {
  127. case RXSHV_MEMFL:
  128. G.os2.rexx_mes = ERROR_NOMEM;
  129. break;
  130. case RXSHV_BADN:
  131. case RXSHV_NEWV:
  132. G.os2.request.shvvaluelen = 0;
  133. case RXSHV_OK:
  134. *(G.os2.buffer+G.os2.request.shvvaluelen) = 0;
  135. return G.os2.request.shvvaluelen;
  136. }
  137. return 0;
  138. }
  139. /* Get REXX compound variable */
  140. /* Stem must exist in G.os2.getvar_buf w/ length in G.os2.getvar_len */
  141. int GetVariableIndex(__GPRO__ int index)
  142. {
  143. sprintf(G.os2.getvar_buf+G.os2.getvar_len,"%d",index);
  144. return GetVariable(__G__ G.os2.getvar_buf);
  145. }
  146. /* Transfer REXX array to standard C string array */
  147. /* Returns number of elements */
  148. /* User is responsible for calling KillStringArray */
  149. int CompoundToStringArray(__GPRO__ char ***pointer, const char *name)
  150. {
  151. int count;
  152. int total;
  153. char **trav;
  154. G.os2.getvar_len = strlen(name);
  155. memcpy(G.os2.getvar_buf,name,G.os2.getvar_len+1);
  156. if (*(G.os2.getvar_buf+G.os2.getvar_len-1) != '.')
  157. *(G.os2.getvar_buf+G.os2.getvar_len++) = '.', *(G.os2.getvar_buf+G.os2.getvar_len) = 0;
  158. if (GetVariableIndex(__G__ 0))
  159. return 0;
  160. total = atoi(G.os2.buffer);
  161. *pointer = (char **)malloc((total+1)<<2);
  162. trav = *pointer;
  163. for (count = 1; count <= total; count++) {
  164. GetVariableIndex(__G__ count);
  165. trav[count-1] = (char *)malloc(strlen(G.os2.buffer)+1);
  166. strcpy(trav[count-1],G.os2.buffer);
  167. }
  168. trav[count-1] = NULL;
  169. return total;
  170. }
  171. /* Kill string array created by CompoundToStringArray */
  172. void KillStringArray(char **pointer)
  173. {
  174. char **trav=pointer;
  175. while (*trav != NULL) {
  176. free(*trav);
  177. trav++;
  178. }
  179. free(pointer);
  180. }
  181. /*************************************************************************
  182. * Function: UZDropFuncs *
  183. * *
  184. * Syntax: call UZDropFuncs *
  185. * *
  186. * Return: NO_UTIL_ERROR - Successful. *
  187. *************************************************************************/
  188. ULONG UZDropFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  189. CHAR *queuename, RXSTRING *retstr)
  190. {
  191. INT entries; /* Num of entries */
  192. INT j; /* Counter */
  193. if (numargs != 0) /* no arguments for this */
  194. return INVALID_ROUTINE; /* raise an error */
  195. retstr->strlength = 0; /* return a null string result*/
  196. entries = sizeof(RxFncTable)/sizeof(PSZ);
  197. for (j = 0; j < entries; j++)
  198. RexxDeregisterFunction(RxFncTable[j]);
  199. return VALID_ROUTINE; /* no error on call */
  200. }
  201. /*************************************************************************
  202. * Function: UZFileTree *
  203. * *
  204. * Syntax: call UZFileTree zipfile, stem[, include-filespec] *
  205. * [, exclude-filespec][, options] *
  206. * *
  207. * Params: zipfile - Name of zip file to search. *
  208. * stem - Name of stem var to store results in. *
  209. * include - Filespec to search for (may include * and ?). *
  210. * exclude - Filespec to exclude (may include * and ?). *
  211. * options - Either of the following: *
  212. * 'F' - Give file statistics. *
  213. * Length Date Time Name *
  214. * 'Z' - Give zip statistics, too. *
  215. * Length Method Size Ratio Date Time CRC-32 Name*
  216. * Default is to return only filenames *
  217. * *
  218. * Return: NO_UTIL_ERROR - Successful. *
  219. * ERROR_NOMEM - Out of memory. *
  220. *************************************************************************/
  221. ULONG UZFileTree(CHAR *name, ULONG numargs, RXSTRING args[],
  222. CHAR *queuename, RXSTRING *retstr)
  223. {
  224. /* validate arguments */
  225. char *incname[2];
  226. char *excname[2];
  227. CONSTRUCTGLOBALS();
  228. if (numargs < 2 || numargs > 5 ||
  229. !RXVALIDSTRING(args[0]) ||
  230. !RXVALIDSTRING(args[1]) ||
  231. args[0].strlength > 255) {
  232. DESTROYGLOBALS();
  233. return INVALID_ROUTINE; /* Invalid call to routine */
  234. }
  235. /* initialize data area */
  236. SetOutputVarStem(__G__ args[1].strptr);
  237. G.wildzipfn = args[0].strptr;
  238. G.process_all_files = TRUE;
  239. uO.lflag = 1;
  240. uO.zipinfo_mode = TRUE;
  241. uO.C_flag = 1;
  242. G.extract_flag = FALSE;
  243. uO.qflag = 2;
  244. if (numargs >= 3 && /* check third option */
  245. !RXNULLSTRING(args[2]) &&
  246. args[2].strlength > 0) { /* a zero length string isn't */
  247. if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) {
  248. G.pfnames = incname;
  249. incname[0] = args[2].strptr;
  250. incname[1] = NULL;
  251. G.filespecs = 1;
  252. }
  253. G.process_all_files = FALSE;
  254. }
  255. if (numargs >= 4 && /* check third option */
  256. !RXNULLSTRING(args[3]) &&
  257. args[3].strlength > 0) { /* a zero length string isn't */
  258. if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) {
  259. G.pxnames = excname;
  260. excname[0] = args[3].strptr;
  261. excname[1] = NULL;
  262. G.xfilespecs = 1;
  263. }
  264. G.process_all_files = FALSE;
  265. }
  266. if (numargs == 5 && /* check third option */
  267. !RXNULLSTRING(args[4]) &&
  268. args[4].strlength > 0) { /* a zero length string isn't */
  269. int first = *args[4].strptr & 0x5f;
  270. if (first == 'Z')
  271. uO.vflag = 2, uO.lflag = 0, uO.zipinfo_mode = FALSE;
  272. else if (first == 'F')
  273. uO.vflag = 1, uO.lflag = 0, uO.zipinfo_mode = FALSE;
  274. }
  275. process_zipfiles(__G);
  276. SetOutputVarLength(__G);
  277. if (G.filespecs > 0 && G.pfnames != incname)
  278. KillStringArray(G.pfnames);
  279. if (G.xfilespecs > 0 && G.pxnames != excname)
  280. KillStringArray(G.pxnames);
  281. return RexxReturn(__G__ 0,retstr); /* no error on call */
  282. }
  283. /*************************************************************************
  284. * Function: UZUnZipToVar *
  285. * *
  286. * Syntax: call UZUnZipToVar zipfile, filespec [, stem] *
  287. * *
  288. * Params: zipfile - Name of zip file to search. *
  289. * filespec - File to extract *
  290. * stem - If you specify a stem variable, the file will be *
  291. * extracted to the variable, one line per index *
  292. * In this case, 0 will be returned *
  293. * *
  294. * Return: Extracted file *
  295. * ERROR_NOMEM - Out of memory. *
  296. *************************************************************************/
  297. ULONG UZUnZipToVar(CHAR *name, ULONG numargs, RXSTRING args[],
  298. CHAR *queuename, RXSTRING *retstr)
  299. {
  300. CONSTRUCTGLOBALS();
  301. UzpBuffer *ub = (UzpBuffer *)retstr;
  302. /* validate arguments */
  303. if (numargs < 2 || numargs > 3 ||
  304. !RXVALIDSTRING(args[0]) ||
  305. !RXVALIDSTRING(args[1]) ||
  306. args[0].strlength == 0 ||
  307. args[1].strlength == 0) {
  308. DESTROYGLOBALS();
  309. return INVALID_ROUTINE; /* Invalid call to routine */
  310. }
  311. uO.C_flag = 1;
  312. G.redirect_data=1;
  313. if (numargs == 3) {
  314. if (!RXVALIDSTRING(args[2]) ||
  315. RXNULLSTRING(args[1]) ||
  316. args[2].strlength == 0) {
  317. DESTROYGLOBALS();
  318. return INVALID_ROUTINE; /* Invalid call to routine */
  319. }
  320. SetOutputVarStem(__G__ args[2].strptr);
  321. G.redirect_text = 0;
  322. G.redirect_data++;
  323. }
  324. unzipToMemory(__G__ args[0].strptr, args[1].strptr,
  325. G.redirect_data==1 ? ub : NULL);
  326. return RexxReturn(__G__ G.redirect_data==1,retstr);
  327. }
  328. /*************************************************************************
  329. * Function: UZUnZipToStem *
  330. * *
  331. * Syntax: call UZUnZipToStem zipfile, stem[, include-filespec] *
  332. * [, exclude-filespec][, mode] *
  333. * *
  334. * Params: zipfile - Name of zip file to search. *
  335. * stem - Name of stem var to store files in. *
  336. * include - Filespec to search for (may include * and ?). *
  337. * exclude - Filespec to exclude (may include * and ?). *
  338. * mode - Specifies 'F'lat or 'T'ree mode. Umm, this is *
  339. * hard to explain so I'll give an example, too. *
  340. * Assuming a file unzip.zip containing: *
  341. * unzip.c *
  342. * unshrink.c *
  343. * extract.c *
  344. * os2/makefile.os2 *
  345. * os2/os2.c *
  346. * os2/dll/dll.def *
  347. * os2/dll/unzipapi.c *
  348. * *
  349. * -- In flat mode, each file is stored in *
  350. * stem.fullname i.e. stem."os2/dll/unzipapi.c" *
  351. * A list of files is created in stem.<index> *
  352. * *
  353. * Flat mode returns: *
  354. * stem.0 = 7 *
  355. * stem.1 = unzip.c *
  356. * stem.2 = unshrink.c *
  357. * stem.3 = extract.c *
  358. * stem.4 = os2/makefile.os2 *
  359. * stem.5 = os2/os2.c *
  360. * stem.6 = os2/dll/dll.def *
  361. * stem.7 = os2/dll/unzipapi.c *
  362. * *
  363. * And the following contain the contents of the *
  364. * various programs: *
  365. * stem.unzip.c *
  366. * stem.unshrink.c *
  367. * stem.extract.c *
  368. * stem.os2/makefile.os2 *
  369. * stem.os2/os2.c *
  370. * stem.os2/dll/dll.def *
  371. * stem.os2/dll/unzipapi.c *
  372. * *
  373. * -- In tree mode, slashes are converted to periods*
  374. * in the pathname thus the above file would have*
  375. * been stored in stem.os2.dll.unzipapi.c *
  376. * The index would then be stored in stem.OS2. *
  377. * DLL.<index>. *
  378. * *
  379. * NOTE: All path names are converted to uppercase *
  380. * *
  381. * Tree mode returns: *
  382. * stem.0 = 4 *
  383. * stem.1 = unzip.c *
  384. * stem.2 = unshrink.c *
  385. * stem.3 = extract.c *
  386. * stem.4 = OS2/ *
  387. * *
  388. * stem.OS2.0 = 3 *
  389. * stem.OS2.1 = makefile.os2 *
  390. * stem.OS2.2 = os2.c *
  391. * stem.OS2.3 = DLL/ *
  392. * *
  393. * stem.OS2.DLL.0 = 2 *
  394. * stem.OS2.DLL.1 = def *
  395. * stem.OS2.DLL.2 = unzipapi.c *
  396. * *
  397. * And the following contain the contents of the *
  398. * various programs: *
  399. * stem.unzip.c *
  400. * stem.unshrink.c *
  401. * stem.extract.c *
  402. * stem.OS2.makefile.os2 *
  403. * stem.OS2.os2.c *
  404. * stem.OS2.DLL.dll.def *
  405. * stem.OS2.DLL.unzipapi.c *
  406. * *
  407. * *
  408. * Return: NO_UTIL_ERROR - Successful. *
  409. * ERROR_NOMEM - Out of memory. *
  410. *************************************************************************/
  411. ULONG UZUnZipToStem(CHAR *name, ULONG numargs, RXSTRING args[],
  412. CHAR *queuename, RXSTRING *retstr)
  413. {
  414. char *incname[2];
  415. char *excname[2];
  416. CONSTRUCTGLOBALS();
  417. /* validate arguments */
  418. if (numargs < 2 || numargs > 5 ||
  419. !RXVALIDSTRING(args[0]) ||
  420. !RXVALIDSTRING(args[1]) ||
  421. args[0].strlength > 255) {
  422. DESTROYGLOBALS();
  423. return INVALID_ROUTINE; /* Invalid call to routine */
  424. }
  425. /* initialize data area */
  426. G.wildzipfn = args[0].strptr;
  427. G.process_all_files = TRUE;
  428. uO.C_flag = 1;
  429. G.extract_flag = TRUE;
  430. SetOutputVarStem(__G__ args[1].strptr);
  431. G.redirect_data = 3;
  432. G.redirect_text = 0;
  433. if (numargs >= 3 && /* check third option */
  434. !RXNULLSTRING(args[2]) &&
  435. args[2].strlength > 0) { /* a zero length string isn't */
  436. if (!(G.filespecs = CompoundToStringArray(__G__ &G.pfnames,args[2].strptr))) {
  437. G.pfnames = incname;
  438. incname[0] = args[2].strptr;
  439. incname[1] = NULL;
  440. G.filespecs = 1;
  441. }
  442. G.process_all_files = FALSE;
  443. }
  444. if (numargs >= 4 && /* check third option */
  445. !RXNULLSTRING(args[3]) &&
  446. args[3].strlength > 0) { /* a zero length string isn't */
  447. if (!(G.xfilespecs = CompoundToStringArray(__G__ &G.pxnames,args[3].strptr))) {
  448. G.pxnames = excname;
  449. excname[0] = args[3].strptr;
  450. excname[1] = NULL;
  451. G.xfilespecs = 1;
  452. }
  453. G.process_all_files = FALSE;
  454. }
  455. if (numargs == 5 && /* check third option */
  456. !RXNULLSTRING(args[4]) &&
  457. (*args[4].strptr & 0x5f) == 'T') {
  458. G.redirect_data++;
  459. G.os2.request.shvnext = NULL;
  460. EZRXSTRING(G.os2.request.shvname, args[4].strptr);
  461. G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
  462. G.os2.request.shvcode = RXSHV_SYDRO;
  463. G.os2.request.shvret = 0;
  464. RexxVariablePool(&G.os2.request);
  465. }
  466. uO.qflag = 2;
  467. process_zipfiles(__G);
  468. if (G.filespecs > 0 && G.pfnames != incname)
  469. KillStringArray(G.pfnames);
  470. if (G.xfilespecs > 0 && G.pxnames != excname)
  471. KillStringArray(G.pxnames);
  472. if (G.redirect_data == 3)
  473. SetOutputVarLength(__G);
  474. return RexxReturn(__G__ 0,retstr); /* no error on call */
  475. }
  476. /*************************************************************************
  477. * Function: UZLoadFuncs *
  478. * *
  479. * Syntax: call UZLoadFuncs [option] *
  480. * *
  481. * Params: none *
  482. * *
  483. * Return: null string *
  484. *************************************************************************/
  485. ULONG UZLoadFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  486. CHAR *queuename, RXSTRING *retstr)
  487. {
  488. INT entries; /* Num of entries */
  489. INT j; /* Counter */
  490. retstr->strlength = 0; /* set return value */
  491. /* check arguments */
  492. if (numargs > 0)
  493. return INVALID_ROUTINE;
  494. entries = sizeof(RxFncTable)/sizeof(PSZ);
  495. for (j = 0; j < entries; j++) {
  496. RexxRegisterFunctionDll(RxFncTable[j],
  497. "UNZIP32", RxFncTable[j]);
  498. }
  499. return VALID_ROUTINE;
  500. }
  501. /*************************************************************************
  502. * Function: UZVer *
  503. * *
  504. * Syntax: call UZVer *
  505. * *
  506. * Return: Version of Unzip *
  507. *************************************************************************/
  508. ULONG UZVer(CHAR *name, ULONG numargs, RXSTRING args[],
  509. CHAR *queuename, RXSTRING *retstr)
  510. {
  511. if (numargs > 1) /* validate arg count */
  512. return INVALID_ROUTINE;
  513. if (numargs == 0 || (*args[0].strptr & 0x5f) != 'L')
  514. /* strcpy( retstr->strptr, UZ_VERNUM ); "5.13a BETA" */
  515. sprintf( retstr->strptr, "%d.%d%d%s", UZ_MAJORVER, UZ_MINORVER,
  516. UZ_PATCHLEVEL, UZ_BETALEVEL );
  517. else
  518. /* strcpy( retstr->strptr, UZ_VERSION ); UZ_VERNUM" of 26 Sep 94" */
  519. sprintf( retstr->strptr, "%d.%d%d%s of %s", UZ_MAJORVER, UZ_MINORVER,
  520. UZ_PATCHLEVEL, UZ_BETALEVEL, UZ_VERSION_DATE );
  521. retstr->strlength = strlen(retstr->strptr);
  522. return VALID_ROUTINE;
  523. }
  524. /*************************************************************************
  525. * Function: UZUnZip *
  526. * *
  527. * Syntax: call UZUnZip *
  528. * *
  529. * Return: Unzip return code *
  530. *************************************************************************/
  531. ULONG UZUnZip(CHAR *name, ULONG numargs, RXSTRING args[],
  532. CHAR *queuename, RXSTRING *retstr)
  533. {
  534. char *argv[30];
  535. char *scan;
  536. int argc=0;
  537. int idx;
  538. CONSTRUCTGLOBALS();
  539. if (numargs < 1 || numargs > 2 ||
  540. args[0].strlength > 255) {
  541. DESTROYGLOBALS();
  542. return INVALID_ROUTINE; /* Invalid call to routine */
  543. }
  544. /* initialize data area */
  545. if (numargs == 2)
  546. SetOutputVarStem(__G__ args[1].strptr);
  547. scan = args[0].strptr;
  548. argv[argc++] = ""; /* D:\\SOURCECODE\\UNZIP51S\\UNZIP.COM"; */
  549. while (*scan == ' ')
  550. scan++;
  551. argv[argc++] = scan;
  552. while ( (scan = strchr(scan,' ')) != NULL) {
  553. *scan++ = 0;
  554. while (*scan == ' ')
  555. scan++;
  556. argv[argc++] = scan;
  557. }
  558. if (*argv[argc-1] == 0)
  559. argc--;
  560. argv[argc] = 0;
  561. /* GRR: should resetMainFlags() be called in here somewhere? */
  562. sprintf(retstr->strptr, "%d", unzip(__G__ argc, argv)); /* a.k.a. MAIN() */
  563. if (numargs == 2)
  564. SetOutputVarLength(__G);
  565. retstr->strlength = strlen(retstr->strptr);
  566. return RexxReturn(__G__ 1,retstr);
  567. }
  568. int varmessage(__GPRO__ ZCONST uch *buf, ulg size)
  569. {
  570. if (size > 0)
  571. memcpy(G.os2.buffer+G.os2.putchar_idx,buf,size);
  572. G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, size+G.os2.putchar_idx,0);
  573. return 0;
  574. }
  575. int varputchar(__GPRO__ int c)
  576. {
  577. G.os2.buffer[G.os2.putchar_idx++] = c;
  578. if (c == '\n') {
  579. G.os2.buffer[G.os2.putchar_idx] = 0;
  580. if (G.os2.output_var[0])
  581. G.os2.putchar_idx = TextSetNext(__G__ G.os2.buffer, G.os2.putchar_idx,0);
  582. else {
  583. G.os2.buffer[--G.os2.putchar_idx] = 0;
  584. puts(G.os2.buffer);
  585. G.os2.putchar_idx = 0;
  586. }
  587. }
  588. return 1;
  589. }
  590. int SetOutputVarStem(__GPRO__ const char *name)
  591. {
  592. int len=strlen(name);
  593. G.redirect_text=1;
  594. G.os2.output_idx = 0;
  595. strcpy(G.os2.output_var, name);
  596. if (len) {
  597. strupr(G.os2.output_var); /* uppercase the name */
  598. if (*(G.os2.output_var+len-1) != '.') {
  599. *(G.os2.output_var+len) = '.';
  600. len++;
  601. *(G.os2.output_var+len) = 0;
  602. }
  603. WriteToVariable(__G__ G.os2.output_var,"",0);
  604. }
  605. G.os2.stem_len = len;
  606. return G.os2.stem_len;
  607. }
  608. int SetOutputVar(__GPRO__ const char *name)
  609. {
  610. int len=strlen(name);
  611. G.redirect_text=1;
  612. G.os2.output_idx = 0;
  613. strcpy(G.os2.output_var, name);
  614. strupr(G.os2.output_var); /* uppercase the name */
  615. if (*(name+len-1) == '.')
  616. G.os2.stem_len = len;
  617. else
  618. G.os2.stem_len = 0;
  619. return G.os2.stem_len;
  620. }
  621. int SetOutputVarLength(__GPRO)
  622. {
  623. if (G.os2.stem_len > 0) {
  624. if (G.os2.putchar_idx)
  625. TextSetNext(__G__ G.os2.buffer,G.os2.putchar_idx,1);
  626. return PrintToSubVariable(__G__ 0,"%d",G.os2.output_idx);
  627. }
  628. return 0;
  629. }
  630. int PrintToVariable(__GPRO__ const char *name, const char *format,...)
  631. {
  632. va_list arg_ptr;
  633. int ret;
  634. va_start(arg_ptr, format);
  635. ret = _PrintToVariable(__G__ name, format, arg_ptr);
  636. va_end(arg_ptr);
  637. return ret;
  638. }
  639. int WriteToVariable(__GPRO__ const char *name, char *buffer, int len)
  640. {
  641. G.os2.request.shvnext = NULL;
  642. EZRXSTRING(G.os2.request.shvname, name);
  643. G.os2.request.shvnamelen = G.os2.request.shvname.strlength;
  644. G.os2.request.shvvalue.strptr = buffer;
  645. G.os2.request.shvvalue.strlength = len;
  646. G.os2.request.shvvaluelen = len;
  647. G.os2.request.shvcode = RXSHV_SET;
  648. G.os2.request.shvret = 0;
  649. switch (RexxVariablePool(&G.os2.request)) {
  650. case RXSHV_BADN:
  651. G.os2.rexx_error = INVALID_ROUTINE;
  652. break;
  653. case RXSHV_MEMFL:
  654. G.os2.rexx_mes = ERROR_NOMEM;
  655. break;
  656. case RXSHV_OK:
  657. return 0;
  658. }
  659. return INVALID_ROUTINE; /* error on non-zero */
  660. }
  661. int _PrintToVariable(__GPRO__ const char *name, const char *format, va_list arg_ptr)
  662. {
  663. int ret = vsprintf(G.os2.buffer, format, arg_ptr);
  664. WriteToVariable(__G__ name, G.os2.buffer, strlen(G.os2.buffer));
  665. return ret;
  666. }
  667. int PrintToSubVariable(__GPRO__ int idx, const char *format, ...)
  668. {
  669. va_list arg_ptr;
  670. int ret;
  671. if (G.os2.stem_len == 0)
  672. return INVALID_ROUTINE; /* error on non-zero */
  673. sprintf(G.os2.output_var+G.os2.stem_len,"%d",idx);
  674. va_start(arg_ptr, format);
  675. ret = _PrintToVariable(__G__ G.os2.output_var, format, arg_ptr);
  676. va_end(arg_ptr);
  677. return ret;
  678. }
  679. int WriteToNextVariable(__GPRO__ char *buffer, int len)
  680. {
  681. if (G.os2.stem_len > 0) {
  682. G.os2.output_idx++;
  683. sprintf(G.os2.output_var+G.os2.stem_len,"%d",G.os2.output_idx);
  684. }
  685. return WriteToVariable(__G__ G.os2.output_var, buffer, len);
  686. }
  687. int TextSetNext(__GPRO__ char *buffer, int len, int all)
  688. {
  689. char *scan = buffer, *next, *base=buffer;
  690. int remaining=len;
  691. int ret;
  692. while ((next = strchr(scan,'\n')) != NULL && remaining > 0) {
  693. if (next > scan && *(next-1) == 0xd)
  694. *(next-1) = 0;
  695. else
  696. *next = 0;
  697. if (WriteToNextVariable(__G__ scan,strlen(scan)))
  698. return 0;
  699. next++;
  700. remaining -= (next-scan);
  701. scan = next;
  702. }
  703. if (remaining > 0)
  704. if (all) {
  705. *(scan+remaining) = 0;
  706. WriteToNextVariable(__G__ scan,remaining);
  707. } else {
  708. memcpy(buffer,scan,remaining);
  709. return remaining;
  710. }
  711. return 0;
  712. }
  713. int finish_REXX_redirect(__GPRO)
  714. {
  715. char *scan, *ptr;
  716. int idx=0, first=1, offset;
  717. if (!G.redirect_size)
  718. return 0;
  719. switch(G.redirect_data) {
  720. case 1:
  721. break;
  722. case 2:
  723. TextSetNext(__G__ G.redirect_buffer, G.redirect_size, 1);
  724. SetOutputVarLength(__G);
  725. DosFreeMem(G.redirect_buffer);
  726. G.redirect_buffer = NULL;
  727. G.redirect_size = 0;
  728. break;
  729. case 3:
  730. WriteToNextVariable(__G__ G.filename, strlen(G.filename));
  731. strcpy(G.os2.output_var+G.os2.stem_len, G.filename);
  732. WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size);
  733. DosFreeMem(G.redirect_buffer);
  734. G.redirect_buffer = NULL;
  735. G.redirect_size = 0;
  736. break;
  737. case 4:
  738. if ((scan = strrchr(G.filename,'/')) != NULL) {
  739. idx = *scan;
  740. *scan = 0;
  741. strupr(G.filename);
  742. *scan = idx;
  743. }
  744. scan = G.os2.output_var+G.os2.stem_len;
  745. strcpy(scan,G.filename);
  746. while ((scan = strchr(scan,'/')) != NULL)
  747. *scan = '.';
  748. WriteToVariable(__G__ G.os2.output_var, G.redirect_buffer, G.redirect_size);
  749. DosFreeMem(G.redirect_buffer);
  750. G.redirect_buffer = NULL;
  751. G.redirect_size = 0;
  752. strcpy(G.os2.getvar_buf, G.os2.output_var);
  753. do {
  754. if ((scan = strrchr(G.filename,'/')) == NULL)
  755. offset = 0;
  756. else
  757. offset = scan-G.filename+1;
  758. if (first || !GetVariable(__G__ G.os2.output_var)) {
  759. ptr = G.os2.getvar_buf+offset+G.os2.stem_len;
  760. *ptr = '0';
  761. *(ptr+1) = 0;
  762. if (!GetVariable(__G__ G.os2.getvar_buf))
  763. idx = 1;
  764. else
  765. idx = atoi(G.os2.buffer)+1;
  766. PrintToVariable(__G__ G.os2.getvar_buf,"%d",idx);
  767. sprintf(ptr,"%d",idx);
  768. if (!first) {
  769. PrintToVariable(__G__ G.os2.output_var,"%d",idx);
  770. idx = strlen(G.filename);
  771. *(G.filename+idx) = '/';
  772. *(G.filename+idx+1) = 0;
  773. }
  774. WriteToVariable(__G__ G.os2.getvar_buf,G.filename+offset,strlen(G.filename+offset));
  775. first=0;
  776. }
  777. if (offset) {
  778. *(G.os2.output_var+G.os2.stem_len+offset-1) = 0;
  779. *scan = 0;
  780. }
  781. } while (offset);
  782. break;
  783. }
  784. return 0;
  785. }
  786. #endif /* OS2DLL */