1 /*
2   Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
3 
4   See the accompanying file LICENSE, version 2000-Apr-09 or later
5   (the contents of which are also included in unzip.h) for terms of use.
6   If, for some reason, these files are missing, the Info-ZIP license
7   also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
8 */
9 #include <qdos.h>
10 #include <limits.h>
11 #include <string.h>
12 
13 struct
14 {
15     short flag1;
16     short flag2;
17     long offset;            // The offset from &ds to unzipsfx exe
18     long sfxlen;            // size of unzipsfx program
19     long sfxdsiz;           // data size of unzipsfx program
20     long sfxnam;            // Name offset from start of sfxprog
21     long ziplen;            // size of zip file
22 } ds = {0x4afb, 0x4afb, 0};
23 
24 
25 typedef struct {short len; char chrs[1];} __QP_t;
26 
27 #define __QA(l) struct {short len; char chrs[(l)+1];}
28 
29 #define T1 \
30    "\nThis is a self-extracting zip archive. In order to process the\n" \
31    "archive you will be asked to give the name of a temporary directory\n" \
32    "which must have at least as much free space as this SFX file.\n\n" \
33    "You will also be asked for the name of the directory to which the\n" \
34    "files are extracted. This directory _MUST_ exist. If you do not give\n" \
35    "an output directory, the current default is used.\n\n\n" \
36    "Device/directory for temporary files: "
37 #define T2 "Device/directory to extract to      : "
38 
39 #define T1LEN (sizeof(T1)-1)
40 #define T2LEN (sizeof(T2)-1)
41 
xgetcwd(__QP_t * s)42 static void xgetcwd (__QP_t *s)
43 {
44     extern char *_sys_var;
45     static __QP_t **q;
46 
47     if (q = (__QP_t ** q) (_sys_var + 0xAC + 4))
48     {
49         memcpy (s->chrs, (*q)->chrs, (*q)->len);
50         s->len = (*q)->len;
51         *(s->chrs+s->len) = 0;
52     }
53 }
54 
checkdir(__QP_t * dir)55 int checkdir(__QP_t *dir)
56 {
57     qdirect_t s;
58     int r,ch;
59 
60     if(dir->len > 1)
61     {
62         if(*(dir->chrs + dir->len-2) == '_')
63         {
64             *(dir->chrs + dir->len-1) = 0;
65             dir->len--;
66         }
67         else
68         {
69             *(dir->chrs + dir->len-1) = '_';
70         }
71     }
72     else
73     {
74         xgetcwd(dir);
75     }
76 
77     r = ERR_NF;
78 
79     if((ch = io_open(dir->chrs, 4)) > 0)
80     {
81         if((r = fs_headr(ch, -1, &s, sizeof(s))) > 0)
82         {
83             r = (s.d_type == 0xff) ? 0 : ERR_NF;
84         }
85         io_close(ch);
86     }
87     return r;
88 }
89 
makesfx(__QP_t * tmp)90 int makesfx(__QP_t *tmp)
91 {
92     char *p = (char *)&ds;
93     char *q;
94     char txt[PATH_MAX];
95     int fd,r = 0;
96     qdirect_t qd;
97 
98     memcpy(txt, tmp->chrs, tmp->len);
99     memcpy(txt+tmp->len, "SFX_EXE", 8);
100 
101     q = p + ds.offset;
102     if((fd = io_open(txt, NEW_OVER)) > 0)
103     {
104         memcpy(txt+tmp->len+4, "DAT", 4);
105         memcpy(q+ds.sfxnam, txt, tmp->len+8);
106         fs_save(fd, q, ds.sfxlen);
107         qd.d_length = ds.sfxlen;
108         qd.d_datalen = ds.sfxdsiz;
109         qd.d_type = 1;
110         fs_heads(fd, -1, &qd, sizeof(qd));
111         io_close(fd);
112         if((fd = io_open(txt, NEW_OVER)) > 0)
113         {
114             q += ds.sfxlen;
115             fs_save(fd, q, ds.ziplen);
116             io_close(fd);
117         }
118         else r = fd;
119     }
120     else r = fd;
121     return r;
122 }
123 
124 #define T3 "\n\nTo extract the files, run the command \"LRUN "
125 #define T4 "Press any key to exit "
126 #define T3LEN (sizeof(T3)-1)
127 #define T4LEN (sizeof(T4)-1)
128 
unpackit(__QP_t * tmpdir,__QP_t * outdir,char * basfil,int con)129 int unpackit ( __QP_t *tmpdir, __QP_t *outdir, char *basfil, int con)
130 {
131     int ch, r = 0;
132     char c;
133 
134     memcpy(basfil, tmpdir->chrs,tmpdir->len);
135     memcpy(basfil+tmpdir->len,"SFX_BAS", 8);
136 
137     if((ch = io_open(basfil, NEW_OVER)) > 0)
138     {
139         char *p,txt[80];
140         int l;
141 
142         p = txt;
143         *p++ = 'E';
144         *p++ = 'W';
145         *p++ = ' ';
146         memcpy(p, tmpdir->chrs, tmpdir->len);
147         p += tmpdir->len;
148         memcpy(p, "SFX_EXE;'-d ", 12);
149         p += 12;
150         memcpy(p, outdir->chrs, outdir->len);
151         p += outdir->len;
152         *p++ = '\'';
153         *p++ = '\n';
154         io_sstrg(ch, -1, txt, (int)(p-txt));
155 
156         memcpy(txt, "delete ", 7);
157         p = txt + 7;
158         memcpy(p, tmpdir->chrs, tmpdir->len);
159         p += tmpdir->len;
160         memcpy(p, "SFX_EXE\n", 8);
161         p += 4;
162         l = (int)(p+4-txt);
163         io_sstrg(ch, -1, txt, l);
164         memcpy(p, "DAT\n", 4);
165         io_sstrg(ch, -1, txt, l);
166         memcpy(p, "BAS\n", 4);
167         io_sstrg(ch, -1, txt, l);
168         io_close(ch);
169         makesfx((__QP_t *)tmpdir);
170     }
171     else r = ch;
172 
173     if(r == 0)
174     {
175         char t3[80];
176         char *p;
177         p = t3;
178         memcpy(p, T3, T3LEN);
179         p += T3LEN;
180         memcpy (p, basfil, tmpdir->len+7);
181         p += tmpdir->len+7;
182         *p++ = '"';
183         *p++ = '\n';
184         io_sstrg(con, -1, t3, (int)(p-t3));
185     }
186     io_sstrg(con, -1, T4, T4LEN);
187     io_fbyte(con, (5*60*50), &c);
188     return r;
189 }
190 
main(void)191 int main(void)
192 {
193     int con;
194     int r,n;
195     __QA(PATH_MAX) tmpdir;
196     __QA(PATH_MAX) outdir;
197     char basfil[PATH_MAX];
198 
199     con = io_open("con_480x160a16x38", 0);
200     sd_bordr(con, -1, 7, 2);
201     sd_clear(con, -1);
202     sd_cure (con, -1);
203 
204     io_sstrg(con, -1, T1, T1LEN);
205     if((tmpdir.len = io_fline(con, -1, tmpdir.chrs, PATH_MAX-1)) > 1)
206     {
207         if((r = checkdir((__QP_t *)&tmpdir)) == 0)
208         {
209             io_sstrg(con, -1, T2, T2LEN);
210             if((outdir.len = io_fline(con, -1, outdir.chrs, PATH_MAX-1)) > 0)
211             {
212                 if((r = checkdir((__QP_t *)&outdir)) == 0)
213                 {
214                     r = unpackit ((__QP_t *)&tmpdir, (__QP_t *)&outdir,
215                                     basfil, con);
216                 }
217             }
218         }
219     }
220     sd_bordr(con, -1, 0, 0);
221     sd_clear(con, -1);
222     io_close(con);
223     return r;
224 }
225