]> git.saurik.com Git - wxWidgets.git/blob - utils/Install/install.c
added VC++ project file
[wxWidgets.git] / utils / Install / install.c
1 /*
2 * install.c (c) 1998,1999 Brian Smith
3 * parts by Daniele Vistalli
4 */
5
6 #include <stdio.h>
7 #include <stddef.h>
8 #include <stdlib.h>
9 #include <stdarg.h>
10 #include <string.h>
11 #include <fcntl.h>
12 #if defined(__OS2__) || defined(__EMX__) || defined(WINNT) || defined(WIN32)
13 #include <process.h>
14 #endif
15 #include <sys/types.h>
16 #include "install.h"
17 #include "instsup.h"
18
19 #if !defined(__EMX__) && !defined(__OS2__) && !defined(WIN32) && !defined(WINNT)
20 #define stricmp strcasecmp
21 #endif
22
23 /* My Global variables ;) unusually many due to multiple dialogs */
24 char tempPath[MAX_PATH];
25 int installstate = NONE;
26 int installstage = 0;
27 int current_file=0, success=0;
28 unsigned long int acepos=0, aceoffset=0;
29 int pixels=0;
30 char confirmstring[1024];
31 /* I know I am being excessive but... better safe than sorry ;) */
32 char *configsys[8196];
33 int configfilecount=-1;
34 int files = 0, files_deleted=0, packagesize=0, packagesselected[20];
35 /* Global flags often set by the user */
36 int driveselected, packagechosen, express = 1, driverstatus = -1, no_update = 0;
37 int licensechecked = 0, custom = 0, checkforupdate = 1, downloadsite = 0;
38 int usescitech = 1, usecurrent = 0, checking = 0, checkerror = 0, newerver = 0;
39 char sddfilename[256] = "", sddversion[256] = "", sdddate[256] = "";
40 char sddurl[4][256] = { "", "", "", "" };
41
42 /* So these are accessible to REXX */
43 int drivelist[26];
44 FILE *self;
45
46 /* These get loaded in loadheader */
47 char *INSTALLER_APPLICATION;
48 char *INSTALLER_VERSION;
49 char *INSTALLER_TITLE;
50 char *INSTALLER_PATH;
51 char *INSTALLER_FOLDER;
52 char *INSTALLER_PROGRAM;
53 char *INSTALLER_SHADOW;
54 char *INSTALLER_OBJECT;
55 char *INSTALLER_SETS;
56 char *INSTALLER_SYSVAR;
57 char *INSTALLER_SYSLINE;
58 char *INSTALLER_PACKAGES[20];
59 char *INSTALLER_CONFIRM_WPS;
60 char *INSTALLER_CONFIRM_CONFIGSYS;
61 char *INSTALLER_CONFIRM_OVERWRITE;
62 int INSTALLER_PACKAGE_COUNT;
63
64 /* Will have to seperate this stuff to platform specifics... */
65
66 /* Config.Sys -- Note the drive letter gets replaced with the boot drive letter
67 It is just a place holder. (For the next 3 entries) */
68 char csfile[] = "C:\\CONFIG.SYS";
69 /* Backup Config.Sys filename */
70 char bufile[] = "C:\\CONFIG.SDD";
71 /* Installation Log Database -- Used for uninstallation and aborting */
72 #if defined(__OS2__) || defined(__EMX__) || defined(WINNT) || defined(WIN32)
73 char instlog[] = "C:\\DBINST.LOG";
74 #else
75 char instlog[] = "~/dbinst.log";
76 #endif
77 char installdir[400];
78
79 char bootdrive[2] = "C";
80 char winpath[400] = "C:\\OS2\\MDOS\\WINOS2";
81 char winjpath[400] = "C:\\OS2\\MDOS\\WINJOS2";
82 char wintpath[400] = "C:\\OS2\\MDOS\\WINTOS2";
83 char winhpath[400] = "C:\\OS2\\MDOS\\WINHOS2";
84 char browsedir[400] = "C:\\";
85 char installdir2[400] = "";
86 char empty_string[] = "";
87 char currentcf[400] = "";
88
89 #ifdef ENABLE_LOGGING
90 FILE *logfile;
91 #endif
92
93 /* Function prototypes */
94 int installer_unpack(char *filename, int operation);
95 void resetglobals(void);
96
97 typedef struct _replacements {
98 char *replacestring, *replacevar;
99 } Replacements;
100
101 /* The variables in this array must be static buffers */
102 Replacements InstRep[] = {
103 { "%INSTALLPATH%", installdir },
104 { "%BOOTDRIVE%", bootdrive },
105 { "%ANYSTRING%", empty_string },
106 { "%WINPATH%", winpath },
107 { "%WINJPATH%", winjpath },
108 { "%WINTPATH%", wintpath },
109 { "%WINHPATH%", winhpath },
110 { "%USERPATH%", installdir2 },
111 { "%VERSION%", "1.0" }, /* This may be depricated */
112 { "%WEB_VER%", sddversion },
113 { "%WEB_DATE%", sdddate },
114 { "%WEB_LOCATION1%", sddurl[0] },
115 { "%WEB_LOCATION2%", sddurl[1] },
116 { "%WEB_LOCATION3%", sddurl[2] },
117 { "%WEB_LOCATION4%", sddurl[3] },
118 { "%PRI%", "SVGA" }
119 };
120 int replacemax = 16;
121
122 /* In str1, str2 gets replaced by str3 */
123 char *replacestr(char *str1, char *str2, char *str3)
124 {
125 char bigbuffer[4096];
126 int z, x=0, len1 = strlen(str1), len2 = strlen(str2), len3 = strlen(str3);
127
128 for(z=0;z<len1;z++)
129 {
130 if(len2 > 0 && strncmp(&str1[z], str2, len2)==0)
131 {
132 int i;
133 for(i=0;i<len3;i++)
134 {
135 bigbuffer[x] = str3[i];
136 x++;
137 }
138 z=z+(len2-1);
139 } else {
140 bigbuffer[x] = str1[z];
141 x++;
142 }
143 }
144 bigbuffer[x] = 0;
145 return (char *)strdup(bigbuffer);
146 }
147
148 /* This function parses a string and replaces all the text in the
149 * Replacement array with the current dynamic text */
150 char *replaceem(char *orig)
151 {
152 char *tmp1 = NULL, *tmp2 = (char *)strdup(orig);
153 int z;
154
155 for(z=0;z<replacemax;z++)
156 {
157 tmp1 = replacestr(tmp2, InstRep[z].replacestring, InstRep[z].replacevar);
158 free(tmp2);
159 tmp2 = tmp1;
160 tmp1 = NULL;
161 }
162 return tmp2;
163 }
164
165 /*
166 * Find the offset withing the executable of the ace data for use.
167 */
168 int aceseek_entry(int num)
169 {
170 long headerstart;
171 char headerbuf[20], packageconfig[100];
172 int z, start = 0, entry = 0, packageoffset=0;
173 /* Decode DBSOFT-ACE - small memleak but
174 * install should not be running for very long. :) */
175 sprintf(headerbuf, "%s%d", decode("EEECFDEPEGFECNEBEDEF"), num);
176 if((headerstart = findtext(headerbuf)) < 0)
177 {
178 mesg("Could not find ACE header in executable.");
179 exit(2);
180 }
181
182 fseek(self, headerstart+strlen(headerbuf), SEEK_SET);
183 fread(packageconfig, 1, 100, self);
184
185 for(z=0;z<100;z++)
186 {
187 if(packageconfig[z] == '-' || packageconfig[z] == '*')
188 {
189 char cur = packageconfig[z];
190 packageconfig[z] = 0;
191 switch(entry)
192 {
193 case 0:
194 current_file = 0;
195 files = atoi(&packageconfig[start]);
196 break;
197 case 1:
198 packagesize = atoi(&packageconfig[start]);
199 break;
200 }
201 start = z+1;
202 if(cur == '*')
203 {
204 packageoffset = z + 1;
205 z = 100;
206 }
207 entry++;
208 }
209 }
210 aceoffset=headerstart+strlen(headerbuf)+packageoffset;
211 fseek(self, aceoffset, SEEK_SET);
212 return TRUE;
213 }
214
215 /*
216 * Reads the embedded .cfg data from the executable and place it in the global
217 * INSTALL_* variables for use.
218 */
219 int loadheader(void)
220 {
221 char *buffer;
222 long headerstart;
223 int z, start=0, entry=0;
224
225 buffer = malloc(8096*4);
226
227 /* Decode DBSOFT-HEADER */
228 if((headerstart = findtext(decode("EEECFDEPEGFECNEIEFEBEEEFFC"))) < 0)
229 {
230 mesg("Could not find Selfinstaller header in executable.");
231 exit(2);
232 }
233 fseek(self, headerstart+13, SEEK_SET);
234
235 fread(buffer, 1, 8096*4, self);
236 for(z=0;z<8096*4;z++)
237 {
238 if(buffer[z] == '-' || buffer[z] == '*')
239 {
240 char cur = buffer[z];
241 buffer[z] = 0;
242 switch(entry)
243 {
244 case 0:
245 INSTALLER_APPLICATION = (char *)strdup(&buffer[start]);
246 break;
247 case 1:
248 INSTALLER_VERSION = (char *)strdup(&buffer[start]);
249 break;
250 case 2:
251 INSTALLER_TITLE = (char *)strdup(&buffer[start]);
252 break;
253 case 3:
254 INSTALLER_PATH = (char *)strdup(&buffer[start]);
255 break;
256 case 4:
257 INSTALLER_FOLDER = (char *)strdup(&buffer[start]);
258 break;
259 case 5:
260 INSTALLER_PROGRAM = (char *)strdup(&buffer[start]);
261 break;
262 case 6:
263 INSTALLER_SHADOW = (char *)strdup(&buffer[start]);
264 break;
265 case 7:
266 INSTALLER_OBJECT = (char *)strdup(&buffer[start]);
267 break;
268 case 8:
269 INSTALLER_SETS = (char *)strdup(&buffer[start]);
270 break;
271 case 9:
272 INSTALLER_SYSVAR = (char *)strdup(&buffer[start]);
273 break;
274 case 10:
275 INSTALLER_SYSLINE = (char *)strdup(&buffer[start]);
276 break;
277 case 11:
278 INSTALLER_CONFIRM_WPS = (char *)strdup(&buffer[start]);
279 break;
280 case 12:
281 INSTALLER_CONFIRM_CONFIGSYS = (char *)strdup(&buffer[start]);
282 break;
283 case 13:
284 INSTALLER_CONFIRM_OVERWRITE = (char *)strdup(&buffer[start]);
285 break;
286 case 14:
287 INSTALLER_PACKAGE_COUNT = atoi(&buffer[start]);
288 break;
289 default:
290 INSTALLER_PACKAGES[entry-15] = malloc((z-start)+1);
291 strcpy(INSTALLER_PACKAGES[entry-15], &buffer[start]);
292 break;
293 }
294 start = z+1;
295 if(cur == '*')
296 {
297 free(buffer);
298 return TRUE;
299 }
300
301 entry++;
302 }
303 }
304 free(buffer);
305 return FALSE;
306 }
307
308 /*
309 * Functions to work on an ace file embedded within the archive in an
310 * abstract manner.
311 */
312 int aceread(void *buf, size_t count)
313 {
314 unsigned long curpos = ftell(self);
315 size_t readit;
316
317 if(count > (packagesize-(curpos-aceoffset)))
318 readit = (packagesize-(curpos-aceoffset));
319 else
320 readit = count;
321
322 return fread(buf, 1, readit, self);
323 }
324
325 off_t acelseek(off_t offset, int whence)
326 {
327 switch(whence)
328 {
329 case SEEK_SET:
330 fseek(self, aceoffset+offset, SEEK_SET);
331 break;
332 case SEEK_CUR:
333 fseek(self, offset, SEEK_CUR);
334 break;
335 }
336 acepos = ftell(self);
337 return acepos-aceoffset;
338 }
339
340 int aceopen(const char *path, int flags)
341 {
342 fseek(self, aceoffset, SEEK_SET);
343 return 1;
344 }
345
346 int aceclose(int fd)
347 {
348 fseek(self, aceoffset, SEEK_SET);
349 return 0;
350 }
351
352 int acesize(void)
353 {
354 return packagesize;
355 }
356
357 int acetell(int fd)
358 {
359 return ftell(self)-aceoffset;
360 }
361
362 /*
363 * Read the generated log file and remove any files installed.
364 */
365 void delete_files(void)
366 {
367 char tmpbuf[8196], *fileptr;
368 FILE *tmplf;
369 int linenum=0, found=-1, z;
370
371 files_deleted=1;
372
373 if((tmplf=fopen(instlog, "rb"))==NULL)
374 return;
375
376 while(!feof(tmplf))
377 {
378 fgets(tmpbuf, 8196, tmplf);
379 linenum++;
380 if(tmpbuf[0]=='[' && (char *)strstr(tmpbuf, INSTALLER_APPLICATION) != NULL && !feof(tmplf))
381 {
382 fgets(tmpbuf, 8196, tmplf);
383 linenum++;
384 if((char *)strstr(tmpbuf, "<Version>") != NULL && (char *)strstr(tmpbuf, INSTALLER_VERSION) != NULL)
385 found=linenum;
386 }
387 }
388 if(found != -1)
389 {
390 rewind(tmplf);
391 for (z=0;z<found;z++)
392 fgets(tmpbuf, 8196, tmplf);
393 while(!feof(tmplf))
394 {
395 fgets(tmpbuf, 8196, tmplf);
396 if((char *)strstr(tmpbuf, "<FileInst>") != NULL)
397 {
398 fileptr = (char *)strchr(tmpbuf, ',')+1;
399 /* Remove trailing CRLFs */
400 if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n')
401 fileptr[strlen(fileptr)-1]=0;
402 if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n')
403 fileptr[strlen(fileptr)-1]=0;
404 remove(fileptr);
405 current_file--;
406 #if 0
407 sendmessage(0, 1);
408 #endif
409 }
410 if((char *)strstr(tmpbuf, "<End>") != NULL)
411 {
412 fclose(tmplf);
413 return;
414 }
415 }
416 }
417 fclose(tmplf);
418 return;
419 }
420
421 /*
422 * Reads a config file into memory for editing with updatesys, updateset, etc.
423 */
424 int readconfigfile(char *filename)
425 {
426 char tmpbuf[8196];
427 FILE *tmpcs;
428
429 /* Reset this value when restarting */
430 configfilecount = -1;
431
432 if((tmpcs=fopen(filename, "rb"))==NULL)
433 {
434 strcpy(currentcf, empty_string);
435 return 1;
436 }
437 else
438 strcpy(currentcf, filename);
439
440 while(!feof(tmpcs))
441 {
442 configfilecount++;
443 fgets(tmpbuf, 8196, tmpcs);
444 configsys[configfilecount] = malloc(strlen(tmpbuf)+1);
445 strcpy(configsys[configfilecount], tmpbuf);
446 stripcrlf(configsys[configfilecount]);
447 }
448
449 fclose(tmpcs);
450 return 0;
451 }
452
453 /*
454 * Write the updated config file to disk and backup the original.
455 */
456 int writeconfigfile(char *filename, char *backup)
457 {
458 FILE *tmpcs;
459 int i;
460
461 if(backup)
462 {
463 remove(backup);
464 rename(filename, backup);
465 }
466 else
467 remove(filename);
468
469 if((tmpcs=fopen(filename, "wb"))==NULL)
470 return 1;
471
472 for(i=0;i<configfilecount;i++)
473 {
474 if(configsys[i])
475 {
476 fwrite(configsys[i], 1, strlen(configsys[i]), tmpcs);
477 /* Add the CRLF that got stripped in the reading stage. */
478 fwrite("\r\n", 1, 2, tmpcs);
479 free(configsys[i]);
480 }
481 }
482
483 fclose(tmpcs);
484 return 0;
485 }
486 /*
487 * Adds or replaces a SET variable based on the flags (CONFIG.SYS)
488 */
489 void updateset(char *setname, char *newvalue, int flag)
490 {
491 char *cmpbuf1, *cmpbuf2, *tmpptr, *tmpptr2, *nv;
492 int i, z, t;
493
494 nv=replaceem(newvalue);
495
496 cmpbuf1=malloc(strlen(setname)+2);
497 strcpy(cmpbuf1, setname);
498 strcat(cmpbuf1, "=");
499 for(i=0;i<configfilecount;i++)
500 {
501 if(strlen(cmpbuf1) <= strlen(configsys[i]))
502 {
503 tmpptr=(char *)strdup(configsys[i]);
504 #if defined(__EMX__) || defined(__OS2__) || defined(WIN32) || defined(WINNT)
505 strupr(tmpptr);
506 #endif
507 if((tmpptr2=(char*)strstr(tmpptr, "SET "))!=NULL)
508 {
509 tmpptr2 += 4;
510 cmpbuf2=malloc(strlen(tmpptr2)+1);
511 /* Remove any spaces from the string */
512 z=0;
513 for (t=0;t<strlen(tmpptr2) && z < strlen(cmpbuf1);t++)
514 {
515 if(tmpptr2[t] != ' ')
516 {
517 cmpbuf2[z]=tmpptr2[t];
518 z++;
519 }
520 }
521 cmpbuf2[z]=0;
522 if(stricmp(cmpbuf1, cmpbuf2) == 0)
523 {
524 /* Ok we found the entry, and if UPDATE_ALWAYS change it to the
525 new entry, otherwise exit */
526 if(flag == UPDATE_ALWAYS)
527 {
528 #ifdef ENABLE_LOGGING
529 fprintf(logfile, "<CFRemLine>,%s,%s\r\n", currentcf, configsys[i]);
530 #endif
531 free(configsys[i]);
532 configsys[i] = malloc(strlen(setname)+strlen(nv)+6);
533 strcpy(configsys[i], "SET ");
534 strcat(configsys[i], setname);
535 strcat(configsys[i], "=");
536 strcat(configsys[i], nv);
537 #ifdef ENABLE_LOGGING
538 fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, configsys[i]);
539 #endif
540 free(cmpbuf1);free(cmpbuf2);free(tmpptr);
541 }
542 return;
543 }
544 free(cmpbuf2);
545 }
546 free(tmpptr);
547 }
548 }
549 /* Couldn't find the line so we'll add it */
550 configsys[configfilecount]=malloc(strlen(cmpbuf1)+strlen(nv)+6);
551 strcpy(configsys[configfilecount], "SET ");
552 strcat(configsys[configfilecount], setname);
553 strcat(configsys[configfilecount], "=");
554 strcat(configsys[configfilecount], nv);
555 #ifdef ENABLE_LOGGING
556 fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, configsys[configfilecount]);
557 #endif
558 configfilecount++;
559 free(cmpbuf1);
560 }
561
562 /*
563 * Adds an entry to a system variable (CONFIG.SYS)
564 */
565 void updatesys(char *sysname, char *newvalue)
566 {
567 char *cmpbuf1, *cmpbuf2, *tmpptr, *tmpptr2, *capbuf1, *capbuf2, *nv, *brian;
568 int i, z, t;
569
570 nv=replaceem(newvalue);
571
572 cmpbuf1=malloc(strlen(sysname)+2);
573 strcpy(cmpbuf1, sysname);
574 strcat(cmpbuf1, "=");
575 for(i=0;i<configfilecount;i++)
576 {
577 if(strlen(cmpbuf1) <= strlen(configsys[i]))
578 {
579 cmpbuf2=malloc(strlen(configsys[i])+1);
580 /* Remove any spaces from the string */
581 z=0;
582 for (t=0;t<strlen(configsys[i]) && z < strlen(cmpbuf1);t++)
583 {
584 if(configsys[i][t] != ' ')
585 {
586 cmpbuf2[z]=configsys[i][t];
587 z++;
588 }
589 }
590 cmpbuf2[z]=0;
591 if(stricmp(cmpbuf1, cmpbuf2) == 0)
592 {
593 /* Do a case insensitive comparison but preserve the case */
594 tmpptr = &configsys[i][t];
595 capbuf1=malloc(strlen(tmpptr)+1);
596 capbuf2=malloc(strlen(nv)+1);
597 strcpy(capbuf1, tmpptr);
598 strcpy(capbuf2, nv);
599 #if defined(__EMX__) || defined(__OS2__) || defined(WINNT) || defined(WIN32)
600 strupr(capbuf1);
601 strupr(capbuf2);
602 #endif
603 /* Ok, we found the line, and it doesn't have an entry so we'll add it */
604 if((tmpptr2=(char *)strstr(capbuf1, capbuf2)) == NULL)
605 {
606 #ifdef ENABLE_LOGGING
607 fprintf(logfile, "<CFRemLine>,%s,%s\r\n", currentcf, configsys[i]);
608 #endif
609 brian = configsys[i];
610 configsys[i] = malloc(strlen(configsys[i])+strlen(nv)+4);
611 strcpy(configsys[i], brian);
612 free(brian);
613 /* Remove any trailing CRLFs */
614 if(configsys[i][strlen(configsys[i])-1]!=';')
615 strcat(configsys[i], ";");
616 strcat(configsys[i], nv);
617 strcat(configsys[i], ";");
618 #ifdef ENABLE_LOGGING
619 fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, configsys[i]);
620 #endif
621 }
622 free(cmpbuf1);free(cmpbuf2);free(capbuf1);free(capbuf2);
623 return;
624 }
625 free(cmpbuf2);
626 }
627 }
628 /* Couldn't find the line so we'll add it */
629 configsys[configfilecount]=malloc(strlen(cmpbuf1)+strlen(nv)+3);
630 strcpy(configsys[configfilecount], cmpbuf1);
631 strcat(configsys[configfilecount], nv);
632 strcat(configsys[configfilecount], ";");
633 #ifdef ENABLE_LOGGING
634 fprintf(logfile, "<CFAddLine>,%s,%s", currentcf, configsys[configfilecount]);
635 #endif
636 configfilecount++;
637 free(cmpbuf1);
638 if(nv)
639 free(nv);
640 }
641
642 /*
643 * Removes a line from a config file.
644 */
645 void removeline(char *text)
646 {
647 int z;
648 for(z=0;z<configfilecount;z++)
649 {
650 if(stricmp(configsys[z], text) == 0)
651 {
652 int t;
653
654 #ifdef ENABLE_LOGGING
655 fprintf(logfile, "<CFRemLine>,%s,%s\r\n", currentcf, configsys[z]);
656 #endif
657 free(configsys[z]);
658 for(t=z;t<(configfilecount-1);t++)
659 configsys[t] = configsys[t+1];
660 configfilecount--;
661 }
662 }
663 }
664
665
666 /*
667 * The Window peocedure for the confirmation dialog.
668 */
669 #if 0
670 MRESULT EXPENTRY ConfirmDlgProc(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
671 {
672 SWP winpos;
673
674 switch (msg)
675 {
676 case WM_INITDLG:
677 WinSetWindowText(hWnd, INSTALLER_TITLE);
678 WinEnableWindow(WinWindowFromID(mainhwnd, I_Cancel), FALSE);
679 WinSetDlgItemText(hWnd, I_Confirm, confirmstring);
680 WinQueryWindowPos(mainhwnd, &winpos);
681 WinSetWindowPos(hWnd, HWND_TOP, winpos.x+30, winpos.y+30, 0, 0, SWP_MOVE | SWP_ZORDER);
682 break;
683 case WM_COMMAND:
684 WinEnableWindow(WinWindowFromID(mainhwnd, I_Cancel), TRUE);
685 switch ( SHORT1FROMMP(mp1) )
686 {
687 case I_Ja:
688 WinDismissDlg(hWnd, 0);
689 break;
690 case I_Alle:
691 WinDismissDlg(hWnd, 1);
692 break;
693 case I_Nein:
694 WinDismissDlg(hWnd, 2);
695 break;
696 case I_Halt:
697 success=2;
698 installstate=ABORTED;
699 WinDismissDlg(hWnd, 3);
700 break;
701 }
702 break;
703 default :
704 return(WinDefDlgProc(hWnd, msg, mp1, mp2));
705 }
706 return(0L);
707 }
708 #endif
709 /*
710 * Display a confirmation dialog with the options: YES NO ALL CANCEL
711 * Returns: 0 for YES, 1 for ALL, 2 for NO and 3 for CANCEL
712 */
713 int confirm(char *format, ...) {
714 va_list args;
715
716 /* if no confirmation, return 1, meaning overwrite all */
717 if (stricmp(INSTALLER_CONFIRM_OVERWRITE, "no") == 0)
718 return 1;
719
720 va_start(args, format);
721 vsprintf(confirmstring, format, args);
722 va_end(args);
723
724 /* Do something here in wxwindows */
725 return 1;
726 }
727
728 /*
729 * A function to grab a file from an embedded archive and extract it to the TEMP directory.
730 */
731 void grabfile(char *filename)
732 {
733 no_update = 1;
734 settempdir();
735 remove(filename);
736 aceseek_entry(0);
737 resetglobals();
738 installer_unpack(filename, 2);
739 no_update = 0;
740 }
741
742 /*
743 * This thread runs along side the main thread allowing the user to cancel the process.
744 */
745 void install_thread(void *param)
746 {
747 char tmpinstallpath[1024];
748 int k, j, installcount=0, installed=0;
749
750 if(INSTALLER_PACKAGE_COUNT == 2)
751 packagesselected[1] = TRUE;
752
753 installstate = INSTALLING;
754
755 #ifdef ENABLE_LOGGING
756 if((logfile=fopen(instlog, "ab"))==NULL)
757 {
758 error("Log file \"%s\" open failed! Installation aborted!", instlog);
759 exit(1);
760 }
761
762 fprintf(logfile, "[%s]\r\n<Version>,%s\r\n<Start>\r\n", INSTALLER_APPLICATION, INSTALLER_VERSION);
763 #endif
764
765 /* Create nested subdirectories if necessary. */
766 strcpy(tmpinstallpath, installdir);
767 for(k=3;k<strlen(installdir);k++)
768 {
769 if(tmpinstallpath[k] == '\\')
770 {
771 tmpinstallpath[k] = 0;
772 #if defined(__EMX__) || defined(__CYGWIN__) || defined(UNIX)
773 if (!mkdir(tmpinstallpath, 0))
774 #else
775 if (!mkdir(tmpinstallpath))
776 #endif
777 #ifdef ENABLE_LOGGING
778 fprintf(logfile, "<NewDir>,%s\r\n", tmpinstallpath);
779 #else
780 ;
781 #endif
782 tmpinstallpath[k] = '\\';
783 }
784 }
785
786 #if defined(__EMX__) || defined(__CYGWIN__) || defined(UNIX)
787 if (!mkdir(installdir, 0))
788 #else
789 if (!mkdir(installdir))
790 #endif
791 #ifdef ENABLE_LOGGING
792 fprintf(logfile, "<NewDir>,%s\r\n", installdir);
793 #else
794 ;
795 #endif
796
797 /*if(strlen(installdir) > 0 && installdir[0] > 'a'-1 && installdir[0] < 'z'+1)
798 installdir[0]=installdir[0] - ('a'-'A');
799 if(strlen(installdir)>2 && installdir[1]==':' && installdir[2]=='\\')
800 DosSetDefaultDisk((int)(installdir[0]-'A'+1));*/
801
802 setdrivedir(installdir);
803
804 /* Unpack files to destination directory */
805 for(j=1;j<INSTALLER_PACKAGE_COUNT;j++)
806 {
807 if(packagesselected[j] == TRUE)
808 installcount++;
809 }
810 if(installcount == 0)
811 {
812 mesg("No packages selected for installation!");
813 }
814 else
815 {
816 for(j=1;j<INSTALLER_PACKAGE_COUNT;j++)
817 {
818 if(packagesselected[j] == TRUE)
819 {
820 #if 0
821 char statustext[512];
822 #endif
823 aceseek_entry(j);
824 resetglobals();
825 #if 0
826 sprintf(statustext,"Copying Files for %s %d/%d, Press \"Exit Installation\" to Abort.", INSTALLER_PACKAGES[j], installed+1, installcount);
827 WinSetDlgItemText(mainhwnd, I_Info3, statustext);
828 #endif
829 /* filename parameter when null is all files */
830 installer_unpack(NULL, 2);
831 installed++;
832 }
833 }
834 }
835
836 if(success==1)
837 {
838 error("Error unpacking files, Installer may be corrupt!");
839 }
840
841 if(success==2)
842 {
843 error("User aborted installation!");
844 }
845
846 if(installstate != ABORTED)
847 installstate = COMPLETED;
848
849 #if 0
850 sendmessage(0, 2);
851 #endif
852 }
853
854 /*
855 * Use the information from the .cfg file which is embedded in the EXE to update the
856 * CONFIG.SYS settings.
857 */
858 void configsys_update(void)
859 {
860 char *arg1, *arg2, *arg3;
861 char temp[5000];
862 int z, argn=0;
863
864 if(readconfigfile(csfile))
865 return;
866
867 /* Update Miscellaneous lines */
868 if(strlen(INSTALLER_SYSLINE)>0)
869 {
870 char *tmpptr = &temp[0];
871 int len;
872
873 strcpy(temp, INSTALLER_SYSLINE);
874 temp[4999] = 0;
875 len = strlen(temp);
876
877 for(z=0;z<len;z++)
878 {
879 if(temp[z]==',')
880 {
881 char *tmpptr2;
882
883 temp[z] = 0;
884 tmpptr2 = replaceem(tmpptr);
885 tmpptr = &temp[z+1];
886 removeline(tmpptr2);
887 configsys[configfilecount] = tmpptr2;
888 #ifdef ENABLE_LOGGING
889 fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, tmpptr2);
890 #endif
891 configfilecount++;
892 }
893 }
894 if(tmpptr && *tmpptr)
895 {
896 char *tmpptr2;
897
898 tmpptr2 = replaceem(tmpptr);
899 removeline(tmpptr2);
900 configsys[configfilecount] = tmpptr2;
901 #ifdef ENABLE_LOGGING
902 fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, tmpptr2);
903 #endif
904 configfilecount++;
905 }
906
907 }
908 /* Update SET variables */
909 if(strlen(INSTALLER_SETS)>0)
910 {
911 strcpy(temp, INSTALLER_SETS);
912 argn=0;
913 arg1=&temp[0];
914 arg2=arg3=NULL;
915 for(z=0;z<strlen(INSTALLER_SETS);z++)
916 {
917 if(temp[z]==',')
918 {
919 argn++;
920 temp[z]=0;
921 switch(argn)
922 {
923 case 1:
924 arg2=&temp[z+1];
925 break;
926 case 2:
927 arg3=&temp[z+1];
928 break;
929 case 3:
930 argn=0;
931 updateset(arg1, arg2, (int)(arg3[0]-'0'));
932 arg1=&temp[z+1];
933 arg2=arg3=NULL;
934 break;
935 }
936 }
937 }
938 if(arg3)
939 updateset(arg1, arg2, (int)arg3-'0');
940 }
941 /* Update system variables */
942 if(strlen(INSTALLER_SYSVAR)>0)
943 {
944 strcpy(temp, INSTALLER_SYSVAR);
945 argn=0;
946 arg1=&temp[0];
947 arg2=NULL;
948 for(z=0;z<strlen(INSTALLER_SYSVAR);z++)
949 {
950 if(temp[z]==',')
951 {
952 argn++;
953 temp[z]=0;
954 switch(argn)
955 {
956 case 1:
957 arg2=&temp[z+1];
958 break;
959 case 2:
960 argn=0;
961 updatesys(arg1, arg2);
962 arg1=&temp[z+1];
963 arg2=NULL;
964 break;
965 }
966 }
967 }
968 if(arg2)
969 updatesys(arg1, arg2);
970 }
971
972 writeconfigfile(csfile, bufile);
973 }
974
975 /*
976 * Reads a line from a file and returns it in raw.
977 */
978 void getline(FILE *f, char *raw)
979 {
980 memset(raw, 0, 256);
981 fgets(raw, 255, f);
982 stripcrlf(raw);
983 }
984
985 /*
986 * Removes a character from a buffer by advancing the buffer to the left.
987 */
988 void removechar(char *buffer, int thisone, int len)
989 {
990 int x;
991
992 for(x=thisone;x<len;x++)
993 buffer[x] = buffer[x+1];
994 }
995
996 /*
997 * Breaks up a line in raw into it's components.
998 */
999 void parseline(char *raw, char comment, char delimiter, char quotes, char *entry, char *entrydata, char *entrydata2)
1000 {
1001 char in[256];
1002 int z, len, in_quotes = 0, entrynum=0, last = 0;
1003
1004 strcpy(entry, empty_string);
1005 strcpy(entrydata, empty_string);
1006 strcpy(entrydata2, empty_string);
1007 strcpy(in, raw);
1008
1009 if(in[strlen(in)-1] == '\n')
1010 in[strlen(in)-1] = 0;
1011
1012 if(in[0] != comment)
1013 {
1014 len=strlen(in);
1015 for(z=0;z<len;z++)
1016 {
1017 if(!in_quotes && in[z] == delimiter)
1018 {
1019 in[z] = 0;
1020 /* Strip any other delimiters */
1021 z++;
1022 while(in[z] == delimiter && z < len)
1023 z++;
1024 if(!entrynum)
1025 strcpy(entry, in);
1026 else
1027 {
1028 strcpy(entrydata, &in[last]);
1029 strcpy(entrydata2, &in[z]);
1030 }
1031 last = z;
1032 if(entrynum)
1033 return;
1034 entrynum++;
1035 }
1036 if(in[z] == quotes)
1037 {
1038 removechar(in, z, len);
1039 z--;
1040 len--;
1041 if(in_quotes)
1042 in_quotes = 0;
1043 else
1044 in_quotes = 1;
1045 }
1046 }
1047 if(!entrynum)
1048 strcpy(entry, in);
1049 else
1050 strcpy(entrydata, &in[last]);
1051 }
1052 }
1053
1054 /*
1055 * Reads a line from the file and splits it up into it's components.
1056 */
1057 int getparseline(FILE *f, char comment, char delimiter, char quotes, char *raw, char *entry, char *entrydata, char *entrydata2)
1058 {
1059 getline(f, raw);
1060 parseline(raw, comment, delimiter, quotes, entry, entrydata, entrydata2);
1061 return strlen(raw);
1062 }
1063
1064
1065 void install_init(char *installername)
1066 {
1067 if((self = fopen(installername, "rb")) == NULL)
1068 {
1069 mesg("Could not open SFX archive for reading!");
1070 exit(1);
1071 }
1072 if(loadheader() == FALSE)
1073 {
1074 mesg("Could not load all required variables!");
1075 exit(3);
1076 }
1077
1078 strcpy(installdir, INSTALLER_PATH);
1079 }
1080
1081