|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
4: * routines to handle compressed file automatically
5: *
1.1.1.2 root 6: * (c) 1996 Samuel Devulder, Tim Gunn
1.1 root 7: */
8:
9: #include "sysconfig.h"
10: #include "sysdeps.h"
11:
12: #include "config.h"
13: #include "options.h"
14: #include "zfile.h"
15:
16: #ifdef USE_ZFILE
17:
1.1.1.2 root 18: #ifdef AMIGA
19: extern char *amiga_dev_path; /* dev: */
20: extern char *ixemul_dev_path; /* /dev/ */
1.1.1.3 ! root 21: extern int readdevice (const char *, char *);
1.1.1.2 root 22: #endif
23:
1.1 root 24: static struct zfile
25: {
1.1.1.3 ! root 26: struct zfile *next;
! 27: FILE *f;
! 28: char name[L_tmpnam];
1.1 root 29: } *zlist;
30:
31: /*
32: * called on exit()
33: */
34: void zfile_exit(void)
35: {
1.1.1.3 ! root 36: struct zfile *l;
! 37:
! 38: while ((l = zlist)) {
! 39: zlist = l->next;
! 40: fclose(l->f);
! 41: unlink(l->name); /* sam: in case unlink() after fopen() fails */
! 42: free(l);
1.1 root 43: }
44: }
45:
46: /*
47: * fclose() but for a compressed file
48: */
49: int zfile_close(FILE *f)
50: {
1.1.1.3 ! root 51: struct zfile *pl = NULL;
! 52: struct zfile *l = zlist;
! 53: int ret;
! 54:
! 55: while(l && l->f!=f) {
! 56: pl = l;
! 57: l = l->next;
! 58: }
! 59: if (!l)
! 60: return fclose(f);
! 61: ret = fclose(l->f);
! 62:
! 63: if(!pl)
! 64: zlist = l->next;
! 65: else
! 66: pl->next = l->next;
! 67: free(l);
1.1 root 68:
1.1.1.3 ! root 69: return ret;
1.1 root 70: }
71:
72: /*
73: * gzip decompression
74: */
1.1.1.3 ! root 75: static int gunzip (const char *decompress, const char *src, const char *dst)
1.1 root 76: {
1.1.1.3 ! root 77: char cmd[1024];
! 78: if (!dst)
! 79: return 1;
! 80: sprintf (cmd, "%s -c -d %s >%s", decompress, src, dst);
! 81: return !system (cmd);
1.1 root 82: }
83:
84: /*
85: * lha decompression
86: */
1.1.1.3 ! root 87: static int lha (const char *src, const char *dst)
1.1 root 88: {
1.1.1.3 ! root 89: char cmd[1024];
! 90: if (!dst)
! 91: return 1;
1.1.1.2 root 92: #if defined(AMIGA)
1.1.1.3 ! root 93: sprintf (cmd, "lha -q -N p %s >%s", src, dst);
1.1.1.2 root 94: #else
1.1.1.3 ! root 95: sprintf (cmd, "lha pq %s >%s", src, dst);
1.1.1.2 root 96: #endif
1.1.1.3 ! root 97: return !system (cmd);
1.1.1.2 root 98: }
99:
100: /*
101: * (pk)unzip decompression
102: */
103: static int unzip(const char *src, const char *dst)
104: {
1.1.1.3 ! root 105: char cmd[1024];
! 106: if (!dst)
! 107: return 1;
! 108: #if defined AMIGA || defined __unix
! 109: sprintf (cmd, "unzip -p %s '*.adf' >%s", src, dst);
! 110: return !system (cmd);
1.1.1.2 root 111: #endif
1.1 root 112: }
113:
114: /*
115: * decompresses the file (or check if dest is null)
116: */
1.1.1.2 root 117: static int uncompress(const char *name, char *dest)
1.1 root 118: {
1.1.1.3 ! root 119: char *ext = strrchr (name, '.');
1.1 root 120: char nam[1024];
121:
1.1.1.3 ! root 122: if (ext != NULL && access (name, 0) >= 0) {
1.1 root 123: ext++;
1.1.1.3 ! root 124: if (strcasecmp (ext, "z") == 0
! 125: || strcasecmp (ext, "gz") == 0
! 126: || strcasecmp (ext, "adz") == 0
! 127: || strcasecmp (ext, "roz") == 0)
! 128: return gunzip ("gzip", name, dest);
! 129: if (strcasecmp (ext, "bz") == 0)
! 130: return gunzip ("bzip", name, dest);
! 131: if (strcasecmp (ext, "bz2") == 0)
! 132: return gunzip ("bzip2", name, dest);
! 133:
1.1.1.2 root 134: #ifndef __DOS__
1.1.1.3 ! root 135: if (strcasecmp (ext, "lha") == 0
! 136: || strcasecmp (ext, "lzh") == 0)
! 137: return lha (name, dest);
! 138: if (strcasecmp (ext, "zip") == 0)
! 139: return unzip (name, dest);
1.1.1.2 root 140: #endif
1.1 root 141: }
142:
1.1.1.3 ! root 143: if (access (strcat (strcpy (nam, name), ".z"), 0) >= 0
! 144: || access (strcat (strcpy (nam, name), ".Z"), 0) >= 0
! 145: || access (strcat (strcpy (nam, name), ".gz"), 0) >= 0
! 146: || access (strcat (strcpy (nam, name), ".GZ"), 0) >= 0
! 147: || access (strcat (strcpy (nam, name), ".adz"), 0) >= 0
! 148: || access (strcat (strcpy (nam, name), ".roz"), 0) >= 0)
! 149: return gunzip ("gzip", nam, dest);
! 150:
! 151: if (access (strcat (strcpy (nam, name), ".bz"), 0) >= 0
! 152: || access (strcat (strcpy (nam, name), ".BZ"), 0) >= 0)
! 153: return gunzip ("bzip", nam, dest);
! 154:
! 155: if (access (strcat (strcpy (nam, name), ".bz2"), 0) >= 0
! 156: || access (strcat (strcpy (nam, name), ".BZ2"), 0) >= 0)
! 157: return gunzip ("bzip2", nam, dest);
1.1 root 158:
1.1.1.2 root 159: #ifndef __DOS__
1.1.1.3 ! root 160: if (access (strcat (strcpy (nam, name), ".lha"), 0) >= 0
! 161: || access (strcat (strcpy (nam, name), ".LHA"), 0) >= 0
! 162: || access (strcat (strcpy (nam, name), ".lzh"), 0) >= 0
! 163: || access (strcat (strcpy (nam, name), ".LZH"), 0) >= 0)
! 164: return lha (nam, dest);
! 165:
! 166: if (access (strcat (strcpy (nam, name),".zip"),0) >= 0
! 167: || access (strcat (strcpy (nam, name),".ZIP"),0) >= 0)
! 168: return unzip (nam, dest);
1.1.1.2 root 169: #endif
170:
171: #if defined(AMIGA)
1.1.1.3 ! root 172: /* sam: must be before real access to work */
! 173: if (!strnicmp (name, ixemul_dev_path, strlen (ixemul_dev_path)))
! 174: return readdevice (name + strlen (ixemul_dev_path), dest);
! 175: if (!strnicmp (name, amiga_dev_path, strlen (amiga_dev_path)))
! 176: return readdevice (name + strlen (amiga_dev_path), dest);
1.1.1.2 root 177: #endif
178:
1.1 root 179: return 0;
180: }
181:
182: /*
183: * fopen() for a compressed file
184: */
1.1.1.2 root 185: FILE *zfile_open(const char *name, const char *mode)
1.1 root 186: {
187: struct zfile *l;
1.1.1.2 root 188: int fd = 0;
1.1.1.3 ! root 189:
! 190: if(! uncompress (name, NULL))
! 191: return fopen (name, mode);
! 192:
! 193: l = malloc (sizeof *l);
! 194: if (!l)
! 195: return NULL;
1.1 root 196:
197: tmpnam(l->name);
1.1.1.3 ! root 198:
1.1.1.2 root 199: /* On the amiga this would make ixemul loose the break handler */
1.1.1.3 ! root 200: /* ==> fixed in exmul v4.6 */
1.1 root 201: fd = creat(l->name, 0666);
202: if (fd < 0)
203: return NULL;
1.1.1.3 ! root 204:
! 205: if (!uncompress (name, l->name)) {
! 206: free(l);
! 207: close (fd);
! 208: unlink(l->name);
! 209: return NULL;
1.1 root 210: }
211:
1.1.1.3 ! root 212: l->f = uae_fopen_del (l->name, mode);
1.1 root 213:
214: close (fd);
1.1.1.3 ! root 215:
1.1 root 216: if (l->f == NULL) {
217: free(l);
218: return NULL;
219: }
220:
221: l->next = zlist;
222: zlist = l;
223:
224: return l->f;
225: }
226:
227: #else
228:
229: /*
230: * Stubs for machines that this doesn't work on.
231: */
232:
233: void zfile_exit(void)
234: {
235: }
236:
237: int zfile_close(FILE *f)
238: {
239: return fclose(f);
240: }
241:
1.1.1.2 root 242: FILE *zfile_open(const char *name, const char *mode)
1.1 root 243: {
244: return fopen(name, mode);
245: }
246:
247: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.