|
|
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/ */
! 21: extern int readdevice(const char *, char *);
! 22: #endif
! 23:
! 24: #ifdef __BEOS__
! 25: #undef access
! 26: // This is just a temporary hack.
! 27: // (Will be obsolete in future versions of the BeOS) [ So I hope -- Bernd ]
! 28:
! 29: static int access(const char *name, int mode)
! 30: {
! 31: struct stat statbuf;
! 32:
! 33: if (-1 == stat(name, &statbuf))
! 34: return(-1);
! 35: else{
! 36: if (!mode)
! 37: return 0;
! 38: if ((mode & R_OK) && (statbuf.st_mode & S_IRUSR))
! 39: return 0;
! 40: if ((mode & W_OK) && (statbuf.st_mode & S_IWUSR))
! 41: return 0;
! 42: return -1;
! 43: }
! 44: }
! 45: #endif
! 46:
! 47:
1.1 root 48: static struct zfile
49: {
50: struct zfile *next;
51: FILE *f;
52: char name[L_tmpnam];
53: } *zlist;
54:
55: /*
56: * called on exit()
57: */
58: void zfile_exit(void)
59: {
60: struct zfile *l;
61:
62: while((l = zlist))
63: {
64: zlist = l->next;
65: fclose(l->f);
66: free(l);
67: }
68: }
69:
70: /*
71: * fclose() but for a compressed file
72: */
73: int zfile_close(FILE *f)
74: {
75: struct zfile *pl = NULL,
76: *l = zlist;
77: int ret;
78:
79: while(l && l->f!=f) {pl = l;l=l->next;}
80: if(!l) return fclose(f);
81: ret = fclose(l->f);
82:
83: if(!pl) zlist = l->next;
84: else pl->next = l->next;
85: free(l);
86:
87: return ret;
88: }
89:
90: /*
91: * gzip decompression
92: */
1.1.1.2 ! root 93: static int gunzip(const char *src, const char *dst)
1.1 root 94: {
95: char cmd[1024];
96: if(!dst) return 1;
97: sprintf(cmd,"gzip -d -c %s >%s",src,dst);
98: return !system(cmd);
99: }
100:
101: /*
102: * lha decompression
103: */
1.1.1.2 ! root 104: static int lha(const char *src, const char *dst)
1.1 root 105: {
106: char cmd[1024];
107: if(!dst) return 1;
1.1.1.2 ! root 108: #if defined(AMIGA)
1.1 root 109: sprintf(cmd,"lha -q -N p %s >%s",src,dst);
1.1.1.2 ! root 110: #else
! 111: sprintf(cmd,"lha pq %s >%s",src,dst);
! 112: #endif
! 113: return !system(cmd);
! 114: }
! 115:
! 116: /*
! 117: * (pk)unzip decompression
! 118: */
! 119: static int unzip(const char *src, const char *dst)
! 120: {
! 121: char cmd[1024];
! 122: if(!dst) return 1;
! 123: #if defined(AMIGA)
! 124: sprintf(cmd,"unzip -p %s '*.adf' >%s",src,dst);
1.1 root 125: return !system(cmd);
1.1.1.2 ! root 126: #else
! 127: return gunzip(src,dst); /* I don't know for unix */
! 128: #endif
1.1 root 129: }
130:
131: /*
132: * decompresses the file (or check if dest is null)
133: */
1.1.1.2 ! root 134: static int uncompress(const char *name, char *dest)
1.1 root 135: {
136: char *ext = strrchr(name, '.');
137: char nam[1024];
138:
139: if (ext != NULL && access(name,0) >= 0) {
140: ext++;
1.1.1.2 ! root 141: if(!strcasecmp(ext,"z") ||
! 142: !strcasecmp(ext,"gz") ||
! 143: !strcasecmp(ext,"adz") ||
! 144: !strcasecmp(ext,"roz") ||
1.1 root 145: 0) return gunzip(name,dest);
1.1.1.2 ! root 146: #ifndef __DOS__
! 147: if(!strcasecmp(ext,"lha") ||
! 148: !strcasecmp(ext,"lzh") ||
1.1 root 149: 0) return lha(name,dest);
1.1.1.2 ! root 150: if(!strcasecmp(ext,"zip") ||
! 151: 0) return unzip(name,dest);
! 152: #endif
1.1 root 153: }
154:
155: if(access(strcat(strcpy(nam,name),".z"),0)>=0 ||
156: access(strcat(strcpy(nam,name),".Z"),0)>=0 ||
157: access(strcat(strcpy(nam,name),".gz"),0)>=0 ||
158: access(strcat(strcpy(nam,name),".GZ"),0)>=0 ||
1.1.1.2 ! root 159: access(strcat(strcpy(nam,name),".adz"),0)>=0 ||
! 160: access(strcat(strcpy(nam,name),".roz"),0)>=0 ||
1.1 root 161: 0) return gunzip(nam,dest);
162:
1.1.1.2 ! root 163: #ifndef __DOS__
1.1 root 164: if(access(strcat(strcpy(nam,name),".lha"),0)>=0 ||
165: access(strcat(strcpy(nam,name),".LHA"),0)>=0 ||
166: access(strcat(strcpy(nam,name),".lzh"),0)>=0 ||
167: access(strcat(strcpy(nam,name),".LZH"),0)>=0 ||
168: 0) return lha(nam,dest);
169:
1.1.1.2 ! root 170: if(access(strcat(strcpy(nam,name),".zip"),0)>=0 ||
! 171: access(strcat(strcpy(nam,name),".ZIP"),0)>=0 ||
! 172: 0) return unzip(nam,dest);
! 173: #endif
! 174:
! 175: #if defined(AMIGA)
! 176: if(!strnicmp(nam,ixemul_dev_path,strlen(ixemul_dev_path)))
! 177: return readdevice(name+strlen(ixemul_dev_path),dest);
! 178: if(!strnicmp(nam,amiga_dev_path,strlen(amiga_dev_path)))
! 179: return readdevice(name+strlen(amiga_dev_path),dest);
! 180: #endif
! 181:
1.1 root 182: return 0;
183: }
184:
185: /*
186: * fopen() for a compressed file
187: */
1.1.1.2 ! root 188: FILE *zfile_open(const char *name, const char *mode)
1.1 root 189: {
190: struct zfile *l;
1.1.1.2 ! root 191: int fd = 0;
1.1 root 192:
193: if(!uncompress(name,NULL)) return fopen(name,mode);
194:
195: if(!(l = malloc(sizeof(*l)))) return NULL;
196:
197: tmpnam(l->name);
1.1.1.2 ! root 198: #if !defined(AMIGA)
! 199: /* On the amiga this would make ixemul loose the break handler */
1.1 root 200: fd = creat(l->name, 0666);
201: if (fd < 0)
202: return NULL;
1.1.1.2 ! root 203: #endif
1.1 root 204:
205: if(!uncompress(name,l->name))
206: {
207: free(l); close (fd); unlink(l->name); return NULL;
208: }
209:
210: l->f=fopen(l->name,mode);
211:
212: /* Deleting the file now will cause the space for it to be freed
213: * as soon as we fclose() it. This saves bookkeeping work.
214: */
1.1.1.2 ! root 215: #ifndef __DOS__
1.1 root 216: unlink (l->name);
1.1.1.2 ! root 217: #endif
1.1 root 218:
1.1.1.2 ! root 219: #if !defined(AMIGA)
1.1 root 220: close (fd);
1.1.1.2 ! root 221: #endif
1.1 root 222:
223: if (l->f == NULL) {
224: free(l);
225: return NULL;
226: }
227:
228: l->next = zlist;
229: zlist = l;
230:
231: return l->f;
232: }
233:
234: #else
235:
236: /*
237: * Stubs for machines that this doesn't work on.
238: */
239:
240: void zfile_exit(void)
241: {
242: }
243:
244: int zfile_close(FILE *f)
245: {
246: return fclose(f);
247: }
248:
1.1.1.2 ! root 249: FILE *zfile_open(const char *name, const char *mode)
1.1 root 250: {
251: return fopen(name, mode);
252: }
253:
254: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.