4 ** Copyright (C) 1994,96,97 Bernardo Innocenti
6 ** Compression/Decompression handling functions.
9 #include <exec/memory.h>
10 #include <utility/hooks.h>
13 #include <proto/exec.h>
14 #include <proto/dos.h>
15 #include <proto/powerpacker.h>
16 #include <proto/xpkmaster.h>
17 #include <proto/xmodule.h>
19 #include "XModulePriv.h"
25 #define CTYPE_POWERPACKER 3
28 /* static struct Library *PPBase = NULL; */
29 static struct Library *XpkBase = NULL;
32 XDEF UBYTE LhACommand[64] = "LhA >NIL: e -x0 -q \"%s\"";
33 XDEF UBYTE TmpDir[PATHNAME_MAX] = "T:XModuleTmp";
34 XDEF UBYTE LhAFilter[64] = "~(#?readme#?|#?txt#?|#?display#?|#?fileid#?)";
38 static LONG HOOKCALL XPKProgressFunc (REG(a0,struct Hook *hook), REG(a1,struct XpkProgress *pr))
40 return (DisplayProgress (pr->xp_UCur, pr->xp_ULen));
45 static struct Hook XPKProgressHook =
55 GLOBALCALL BPTR DecompressFile (CONST_STRPTR name, UWORD type)
57 /* This function will try to decompress the given file and store
58 * it in TmpDir. If TmpDir does not exist, it will be created.
59 * The decompressed file is then locked and returned.
60 * A return value of NULL means failure. Call DecompressFileDone()
61 * when you are done with the decompressed file.
64 struct AnchorPath *ap;
68 UBYTE FullName[PATHNAME_MAX];
73 DisplayAction (MSG_DECRUNCHING);
75 /* Find the full path name of the given file */
79 if (lock = Lock (name, ACCESS_READ))
81 if (!NameFromLock (lock, FullName, PATHNAME_MAX))
90 /* Try to lock or create TmpDir */
92 if (!(dir = Lock (TmpDir, ACCESS_READ)))
94 if (dir = CreateDir (TmpDir))
95 if (!(ChangeMode (CHANGE_LOCK, dir, ACCESS_READ)))
104 olddir = CurrentDir (dir);
110 UBYTE buf[64+PATHNAME_MAX];
112 SPrintf (buf, LhACommand, FullName);
113 if (!SystemTagList (buf, NULL))
115 if (ap = AllocMem (sizeof (struct AnchorPath) + PATHNAME_MAX, MEMF_CLEAR))
117 ap->ap_Strlen = PATHNAME_MAX;
119 if (!(err = MatchFirst (LhAFilter, ap)))
121 if (!(ret = Lock (ap->ap_Buf, ACCESS_READ)))
126 FreeMem (ap, sizeof (struct AnchorPath) + PATHNAME_MAX);
128 else err = ERROR_NO_FREE_STORE; /* Fail AllocMem() */
131 else err = IoErr(); /* Fail SystemTagList() */
138 UBYTE dest[PATHNAME_MAX];
139 UBYTE errstring[XPKERRMSGSIZE];
141 if (!(XpkBase = OpenLibrary ("xpkmaster.library", 2L)))
143 CantOpenLib ("xpkmaster.library", 2L);
144 CloseProgressWindow();
148 strcpy (dest, TmpDir);
149 if (AddPart (dest, "XPKTmp", PATHNAME_MAX))
152 XPK_InName, FullName,
154 XPK_GetError, errstring,
155 XPK_ChunkHook, &XPKProgressHook,
156 // XPK_TaskPri, ThisTask->pr_Task.tc_Node.ln_Pri-1,
159 xmDisplayMessage (XMDMF_ERROR | XMDMF_USECATALOG,
160 (APTR)MSG_ERROR_DECOMPRESSING, FilePart (FullName),
163 else ret = Lock (dest, ACCESS_READ);
166 CloseLibrary (XpkBase); XpkBase = NULL;
170 /* case CTYPE_POWERPACKER:
172 if (!(PPBase = OpenLibrary ("powerpacker.library", 0L)))
174 CantOpenLib ("powerpacker.library", 0L);
175 CloseProgressWindow();
179 xmDisplayMessageA (XMDMF_INFORMATION,
180 "PowerPacker compressed files are not supported yet.", NULL);
182 CloseLibrary (PPBase); PPBase = NULL;
191 else err = IoErr(); /* Fail CreateDir() */
198 if (err == ERROR_NO_MORE_ENTRIES)
199 xmDisplayMessage (XMDMF_ERROR | XMDMF_USECATALOG,
200 (APTR)MSG_NOTHING_IN_ARC, name);
202 xmDisplayMessageA (XMDMF_DOSFAULT | XMDMF_USECATALOG,
203 (APTR)MSG_CANT_LOAD_COMPRESSED, NULL);
206 if (!ret) DecompressFileDone();
208 CloseProgressWindow();
215 GLOBALCALL void DecompressFileDone (void)
217 /* This call releases all resources got by DecompressFile(). */
220 struct FileInfoBlock *fib;
222 if (dir = Lock (TmpDir, ACCESS_READ))
224 olddir = CurrentDir (dir);
226 if (fib = AllocDosObject (DOS_FIB, NULL))
228 if (Examine (dir, fib))
230 /* Delete all files in the temp directory */
231 while (ExNext (dir, fib))
232 DeleteFile (fib->fib_FileName);
235 FreeDosObject (DOS_FIB, fib);
247 GLOBALCALL LONG CruncherType (BPTR file)
259 if (Read (file, &id, sizeof (id)) != sizeof (id))
262 if ((id.lha.prefix >> 8) == '-lh')
265 if (id.fileid == 'XPKF' || id.fileid == 'PP20' || id.fileid == 'PX20')