Line 19... |
Line 19... |
19 |
#include "showinst.h" /* pkg_loadflist() */
|
19 |
#include "showinst.h" /* pkg_loadflist() */
|
20 |
#include "pkginst.h" /* include self for control */
|
20 |
#include "pkginst.h" /* include self for control */
|
21 |
#include "version.h"
|
21 |
#include "version.h"
|
22 |
|
22 |
|
23 |
|
23 |
|
24 |
/* return 1 if fname looks like a link filename, 0 otherwise */
|
- |
|
25 |
static int islinkfile(const char *fname) {
|
- |
|
26 |
char *link1 = "LINKS\\";
|
- |
|
27 |
char *link2 = "links\\";
|
- |
|
28 |
int x;
|
- |
|
29 |
for (x = 0; ; x++) {
|
- |
|
30 |
if (link1[x] == 0) return(1);
|
- |
|
31 |
if ((fname[x] != link1[x]) && (fname[x] != link2[x])) return(0);
|
- |
|
32 |
}
|
- |
|
33 |
}
|
- |
|
34 |
|
- |
|
35 |
|
- |
|
36 |
/* validate a filename (8+3, no weird characters, etc). returns 0 on success,
|
24 |
/* validate a filename (8+3, no weird characters, etc). returns 0 on success,
|
37 |
* nonzero otherwise. */
|
25 |
* nonzero otherwise. */
|
38 |
static int validfilename(const char *fname) {
|
26 |
static int validfilename(const char *fname) {
|
39 |
int i, i2;
|
27 |
int i, i2;
|
40 |
char *validchars = "!#$%&'()-@^_`{}~";
|
28 |
char *validchars = "!#$%&'()-@^_`{}~";
|
Line 76... |
Line 64... |
76 |
/* all checks passed */
|
64 |
/* all checks passed */
|
77 |
return(0);
|
65 |
return(0);
|
78 |
}
|
66 |
}
|
79 |
|
67 |
|
80 |
|
68 |
|
81 |
/* processes a link file - that is, reads the target inside, and overwrite
|
- |
|
82 |
* the file with new content */
|
- |
|
83 |
static void processlinkfile(const char *linkfile, const char *dosdir, const struct customdirs *dirlist, char *buff) {
|
- |
|
84 |
char origtarget[512];
|
- |
|
85 |
int x;
|
- |
|
86 |
char *shortfile;
|
- |
|
87 |
unsigned char comstub[] = { /* machine code of a COM stub launcher */
|
- |
|
88 |
0xBC,0x00,0x00,0xBB,0x00,0x10,0xB4,0x4A,0xCD,0x21,0xBB,0x2A,0x01,0x8C,0x5F,0x04,
|
- |
|
89 |
0x8C,0x5F,0x08,0x8C,0x5F,0x0C,0xB8,0x00,0x4B,0xBA,0x38,0x01,0xCD,0x21,0xB0,0x7F,
|
- |
|
90 |
0x72,0x04,0xB4,0x4D,0xCD,0x21,0xB4,0x4C,0xCD,0x21,0x00,0x00,0x80,0x00,0x00,0x00,
|
- |
|
91 |
0x5C,0x00,0x00,0x00,0x6C,0x00,0x00,0x00}; /* read comlink.asm for details */
|
- |
|
92 |
const unsigned stack_paras = 12;
|
- |
|
93 |
unsigned alloc_paras, alloc_bytes;
|
- |
|
94 |
FILE *fd;
|
- |
|
95 |
/* open the link file and read the original target */
|
- |
|
96 |
fd = fopen(linkfile, "r");
|
- |
|
97 |
if (fd == NULL) {
|
- |
|
98 |
kitten_printf(3, 21, "Error: Failed to open link file '%s' for read access.", linkfile);
|
- |
|
99 |
puts("");
|
- |
|
100 |
return;
|
- |
|
101 |
}
|
- |
|
102 |
x = fread(origtarget, 1, sizeof(origtarget) - 1, fd);
|
- |
|
103 |
origtarget[x] = 0;
|
- |
|
104 |
fclose(fd);
|
- |
|
105 |
/* validate the original target (ltrim to first \r or \n) */
|
- |
|
106 |
for (x = 0; origtarget[x] != 0; x++) {
|
- |
|
107 |
if ((origtarget[x] == '\r') || (origtarget[x] == '\n')) {
|
- |
|
108 |
origtarget[x] = 0;
|
- |
|
109 |
break;
|
- |
|
110 |
}
|
- |
|
111 |
}
|
- |
|
112 |
/* translate the original target to a local path */
|
- |
|
113 |
shortfile = computelocalpath(origtarget, buff, dosdir, dirlist);
|
- |
|
114 |
/* compute the amount of memory the stub should leave for itself:
|
- |
|
115 |
- 16 paragraphs needed for the PSP
|
- |
|
116 |
- sizeof(comstub) bytes needed for code and data
|
- |
|
117 |
- strlen(shortfile) + 1 for the command line
|
- |
|
118 |
- stack_paras paragraphs for the stack */
|
- |
|
119 |
alloc_paras = 16 + (sizeof(comstub) + strlen(shortfile) + 16) / 16 + stack_paras;
|
- |
|
120 |
alloc_bytes = 16 * alloc_paras;
|
- |
|
121 |
comstub[1] = alloc_bytes & 0xff;
|
- |
|
122 |
comstub[2] = alloc_bytes >> 8;
|
- |
|
123 |
comstub[4] = alloc_paras & 0xff;
|
- |
|
124 |
comstub[5] = alloc_paras >> 8;
|
- |
|
125 |
/* write new content into the link file */
|
- |
|
126 |
fd = fopen(linkfile, "wb");
|
- |
|
127 |
if (fd == NULL) {
|
- |
|
128 |
kitten_printf(3, 22, "Error: Failed to open link file '%s' for write access.", linkfile);
|
- |
|
129 |
puts("");
|
- |
|
130 |
return;
|
- |
|
131 |
}
|
- |
|
132 |
fwrite(comstub, 1, sizeof(comstub), fd);
|
- |
|
133 |
fprintf(fd, "%s%s%c", buff, shortfile, 0);
|
- |
|
134 |
fclose(fd);
|
- |
|
135 |
}
|
- |
|
136 |
|
- |
|
137 |
|
- |
|
138 |
/* returns 0 if pkgname is not installed, non-zero otherwise */
|
69 |
/* returns 0 if pkgname is not installed, non-zero otherwise */
|
139 |
int is_package_installed(const char *pkgname, const char *dosdir) {
|
70 |
int is_package_installed(const char *pkgname, const char *dosdir) {
|
140 |
char fname[512];
|
71 |
char fname[512];
|
141 |
sprintf(fname, "%s\\packages\\%s.lst", dosdir, pkgname);
|
72 |
sprintf(fname, "%s\\packages\\%s.lst", dosdir, pkgname);
|
142 |
return(fileexists(fname)); /* file exists -> package is installed */
|
73 |
return(fileexists(fname)); /* file exists -> package is installed */
|
Line 155... |
Line 86... |
155 |
|
86 |
|
156 |
|
87 |
|
157 |
/* find a filename in a flist linked list, and returns a pointer to it */
|
88 |
/* find a filename in a flist linked list, and returns a pointer to it */
|
158 |
static struct flist_t *findfileinlist(struct flist_t *flist, const char *fname) {
|
89 |
static struct flist_t *findfileinlist(struct flist_t *flist, const char *fname) {
|
159 |
while (flist != NULL) {
|
90 |
while (flist != NULL) {
|
160 |
if (strcmp(flist->fname, fname) == 0) return(flist);
|
91 |
if (strcasecmp(flist->fname, fname) == 0) return(flist);
|
161 |
flist = flist->next;
|
92 |
flist = flist->next;
|
162 |
}
|
93 |
}
|
163 |
return(NULL);
|
94 |
return(NULL);
|
164 |
}
|
95 |
}
|
165 |
|
96 |
|
Line 196... |
Line 127... |
196 |
}
|
127 |
}
|
197 |
/* if updating, load the list of files belonging to the current package */
|
128 |
/* if updating, load the list of files belonging to the current package */
|
198 |
if ((flags & PKGINST_UPDATE) != 0) {
|
129 |
if ((flags & PKGINST_UPDATE) != 0) {
|
199 |
flist = pkg_loadflist(pkgname, dosdir);
|
130 |
flist = pkg_loadflist(pkgname, dosdir);
|
200 |
}
|
131 |
}
|
201 |
/* Verify that there's no collision with existing local files, look for the appinfo presence, get rid of sources if required, and rename BAT links into COM files */
|
132 |
/* Verify that there's no collision with existing local files, look for the appinfo presence */
|
202 |
appinfopresence = 0;
|
133 |
appinfopresence = 0;
|
203 |
prevzipnode = NULL;
|
134 |
prevzipnode = NULL;
|
204 |
for (curzipnode = ziplinkedlist; curzipnode != NULL;) {
|
135 |
for (curzipnode = ziplinkedlist; curzipnode != NULL;) {
|
205 |
/* change all slashes to backslashes, and switch into all-lowercase */
|
136 |
/* change all slashes to backslashes, and switch into all-lowercase */
|
206 |
slash2backslash(curzipnode->filename);
|
137 |
slash2backslash(curzipnode->filename);
|
207 |
strtolower(curzipnode->filename);
|
138 |
strtolower(curzipnode->filename);
|
208 |
/* remove 'directory' ZIP entries to avoid false alerts about directory already existing */
|
139 |
/* remove 'directory' ZIP entries to avoid false alerts about directory already existing */
|
209 |
if ((curzipnode->flags & ZIP_FLAG_ISADIR) != 0) {
|
140 |
if ((curzipnode->flags & ZIP_FLAG_ISADIR) != 0) {
|
210 |
curzipnode->filename[0] = 0; /* mark it "empty", will be removed in a short moment */
|
141 |
curzipnode->filename[0] = 0; /* mark it "empty", will be removed in a short moment */
|
211 |
}
|
142 |
}
|
212 |
/* is it a "link file"? */
|
143 |
/* is it a "link file"? skip it - link files are no longer supported */
|
213 |
if (fdnpkg_strcasestr(curzipnode->filename, "links\\") == curzipnode->filename) {
|
144 |
if (fdnpkg_strcasestr(curzipnode->filename, "links\\") == curzipnode->filename) {
|
214 |
/* skip links, if that's what the user wants */
|
- |
|
215 |
if ((flags & PKGINST_SKIPLINKS) != 0) {
|
- |
|
216 |
curzipnode->filename[0] = 0; /* in fact, we just mark the file as 'empty' on the filename.. see later below */
|
145 |
curzipnode->filename[0] = 0; /* in fact, I just mark the file as 'empty' on the filename - see later below */
|
217 |
} else {
|
- |
|
218 |
/* if it's a *.BAT link, then rename it to *.COM */
|
- |
|
219 |
char *ext = getfext(curzipnode->filename);
|
- |
|
220 |
if (strcasecmp(ext, "bat") == 0) sprintf(ext, "com");
|
- |
|
221 |
}
|
- |
|
222 |
}
|
146 |
}
|
223 |
|
147 |
|
224 |
if (curzipnode->filename[0] == 0) { /* ignore empty filenames (maybe it was empty originally, or has been emptied because it's a dropped source or link) */
|
148 |
if (curzipnode->filename[0] == 0) { /* ignore empty filenames (maybe it was empty originally, or has been emptied because it's a dropped source or link) */
|
225 |
if (prevzipnode == NULL) { /* take the item out of the list */
|
149 |
if (prevzipnode == NULL) { /* take the item out of the list */
|
226 |
ziplinkedlist = curzipnode->nextfile;
|
150 |
ziplinkedlist = curzipnode->nextfile;
|
Line 347... |
Line 271... |
347 |
filesextractedfailure += 1;
|
271 |
filesextractedfailure += 1;
|
348 |
} else {
|
272 |
} else {
|
349 |
printf(" %s -> %s\n", curzipnode->filename, buff);
|
273 |
printf(" %s -> %s\n", curzipnode->filename, buff);
|
350 |
filesextractedsuccess += 1;
|
274 |
filesextractedsuccess += 1;
|
351 |
}
|
275 |
}
|
352 |
/* if it's a LINK file, recompute a new content */
|
- |
|
353 |
if (islinkfile(curzipnode->filename) != 0) {
|
- |
|
354 |
processlinkfile(fulldestfilename, dosdir, dirlist, buff);
|
- |
|
355 |
}
|
- |
|
356 |
}
|
276 |
}
|
357 |
fclose(lstfd);
|
277 |
fclose(lstfd);
|
358 |
|
278 |
|
359 |
/* free the ziplist and close file descriptor */
|
279 |
/* free the ziplist and close file descriptor */
|
360 |
zip_freelist(&ziplinkedlist);
|
280 |
zip_freelist(&ziplinkedlist);
|