home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / slfinsta.zip / install.c < prev    next >
C/C++ Source or Header  |  2000-03-26  |  46KB  |  1,859 lines

  1. /* $Id: install.c,v 1.1 2000/03/27 04:52:54 ktk Exp $ */
  2.  
  3. /*
  4.  *  install.c (c) 1998,1999 Brian Smith
  5.  *  parts by Daniele Vistalli
  6.  */
  7.  
  8. #define INCL_WIN       /* Window Manager Functions     */
  9. #define INCL_DOS
  10. #define INCL_BASE
  11. #define INCL_RXFUNC
  12. #define INCL_RXMACRO
  13. #define INCL_RXARI
  14. #define INCL_RXSYSEXIT
  15. #define INCL_RXSUBCOM
  16. #define INCL_RXSHV
  17.  
  18. #include <os2.h>
  19. #include <stdio.h>
  20. #include <stddef.h>
  21. #include <stdlib.h>
  22. #include <stdarg.h>
  23. #include <string.h>
  24. #include <fcntl.h>
  25. #include <process.h>
  26. #include <sys/types.h>
  27. #ifndef __EMX__
  28. #include <rexxsaa.h>
  29. #endif
  30. #include "install.h"
  31. #include "instsup.h"
  32. #include "dw.h"
  33.  
  34. #ifndef    OS2_VER
  35. #define OS2_VER    "7.0.0"
  36. #endif
  37.  
  38. #define ENABLE_LOGGING
  39.  
  40. /* My Global variables ;) unusually many due to multiple dialogs */
  41. HAB hab = 0;
  42. HMQ hmq = 0;
  43. HPS hps = 0;
  44. HDC hdc = 0;
  45. HBITMAP hbm = 0;
  46. POINTL bmppoint;
  47. SIZEL sizl;
  48. QMSG qmsg = { 0 };
  49. HWND mainhwnd = 0, logohwnd = 0;
  50. char tempPath[_MAX_PATH];
  51. int installstate = NONE;
  52. int installstage = 0;
  53. int current_file=0, success=0;
  54. unsigned long int acepos=0, aceoffset=0;
  55. int pixels=0;
  56. char confirmstring[1024];
  57. /* I know I am being excessive but... better safe than sorry ;) */
  58. char *configsys[8196];
  59. int configfilecount=-1;
  60. int files = 0, files_deleted=0, packagesize=0, packagesselected[20];
  61. /* Global flags often set by the user */
  62. int driveselected, packagechosen, express = 1, driverstatus = -1, no_update = 0;
  63. int licensechecked = 0, custom = 0, checkforupdate = 1, downloadsite = 0;
  64. int usescitech = 1, usecurrent = 0, checking = 0, checkerror = 0, newerver = 0;
  65. char sddfilename[256] = "",  sddversion[256] = "",  sdddate[256] = "";
  66. char sddurl[4][256] = { "", "", "", "" };
  67.  
  68. /* So these are accessible to REXX */
  69. int drivelist[26];
  70. HWND hwnddir, hwndentry, hwndcombo, hwndper;
  71. FILE *self;
  72. RexxCommands rexxcommands[COMMANDMAX];
  73. char finishedscript[100] = "";
  74.  
  75. /* These get loaded in loadheader */
  76. char *INSTALLER_APPLICATION;
  77. char *INSTALLER_VERSION;
  78. char *INSTALLER_TITLE;
  79. char *INSTALLER_PATH;
  80. char *INSTALLER_FOLDER;
  81. char *INSTALLER_PROGRAM;
  82. char *INSTALLER_SHADOW;
  83. char *INSTALLER_OBJECT;
  84. char *INSTALLER_SETS;
  85. char *INSTALLER_SYSVAR;
  86. char *INSTALLER_SYSLINE;
  87. char *INSTALLER_PACKAGES[20];
  88. char *INSTALLER_CONFIRM_WPS;
  89. char *INSTALLER_CONFIRM_CONFIGSYS;
  90. char *INSTALLER_CONFIRM_OVERWRITE;
  91. int INSTALLER_PACKAGE_COUNT;
  92.  
  93. #define T_BINARY     3
  94.  
  95. int (*ftpget)(char *, char *, char *, char *, char *, char *, char *, int);
  96. int ftpgetfound = 0;
  97.  
  98. /* Config.Sys -- Note the drive letter gets replaced with the boot drive letter
  99.                  It is just a place holder. (For the next 3 entries)             */
  100. char csfile[] = "C:\\CONFIG.SYS";
  101. /* Backup Config.Sys filename */
  102. char bufile[] = "C:\\CONFIG.SDD";
  103. /* Installation Log Database -- Used for uninstallation and aborting */
  104. char instlog[] = "C:\\OS2\\INSTALL\\DBINST.LOG";
  105. #ifdef SDDINST
  106. /* Where SDD will be installed */
  107. char installdir[] = "C:\\";
  108. #else
  109. char installdir[400];
  110. #endif
  111.  
  112. char bootdrive[2] = "C";
  113. char winpath[400] = "C:\\OS2\\MDOS\\WINOS2";
  114. char winjpath[400] = "C:\\OS2\\MDOS\\WINJOS2";
  115. char wintpath[400] = "C:\\OS2\\MDOS\\WINTOS2";
  116. char winhpath[400] = "C:\\OS2\\MDOS\\WINHOS2";
  117. char browsedir[400] = "C:\\";
  118. char installdir2[400] = "";
  119. char empty_string[] = "";
  120. char currentcf[400] = "";
  121.  
  122. #ifdef ENABLE_LOGGING
  123. FILE *logfile;
  124. #endif
  125.  
  126. /* Function prototypes */
  127. int installer_unpack(CHAR * filename, int operation);
  128. void MakeShadow(char Title[], char reference[], char dest[], char id[]);
  129. void MakeProgram(char Title[], char Program[], char Icon[], char dest[], char id[], char setup[]);
  130. void MakeFolder(char Title[], char Icon[], char dest[], char id[], char setup[]);
  131. void MakeObject(char Title[], char oclass[], char dest[], char id[], char setup[]);
  132. void resetglobals(void);
  133. int detect(int argc, char *argv[]);
  134.  
  135. typedef struct _replacements {
  136.     char *replacestring, *replacevar;
  137. } Replacements;
  138.  
  139. /* The variables in this array must be static buffers */
  140. Replacements InstRep[] = {
  141.     { "%INSTALLPATH%",   installdir },
  142.     { "%BOOTDRIVE%",     bootdrive },
  143.     { "%ANYSTRING%",     empty_string },
  144.     { "%WINPATH%",       winpath },
  145.     { "%WINJPATH%",      winjpath },
  146.     { "%WINTPATH%",      wintpath },
  147.     { "%WINHPATH%",      winhpath },
  148.     { "%USERPATH%",      installdir2 },
  149.     { "%VERSION%",       OS2_VER },
  150.     { "%WEB_VER%",       sddversion },
  151.     { "%WEB_DATE%",      sdddate },
  152.     { "%WEB_LOCATION1%", sddurl[0] },
  153.     { "%WEB_LOCATION2%", sddurl[1] },
  154.     { "%WEB_LOCATION3%", sddurl[2] },
  155.     { "%WEB_LOCATION4%", sddurl[3] },
  156.     { "%PRI%",           "SVGA" }
  157. };
  158. int replacemax = 16;
  159.  
  160. typedef struct _cnrentry {
  161.    RECORDCORE   rc;
  162.    HPOINTER hptrIcon;
  163.    char *filename;
  164.    } CnrEntry;
  165.  
  166. /* In str1, str2 gets replaced by str3 */
  167. char *replacestr(char *str1, char *str2, char *str3)
  168. {
  169.     char bigbuffer[4096];
  170.     int z, x=0, len1 = strlen(str1), len2 = strlen(str2), len3 = strlen(str3);
  171.  
  172.     for(z=0;z<len1;z++)
  173.     {
  174.         if(len2 > 0 && strncmp(&str1[z], str2, len2)==0)
  175.         {
  176.             int i;
  177.             for(i=0;i<len3;i++)
  178.             {
  179.                 bigbuffer[x] = str3[i];
  180.                 x++;
  181.             }
  182.             z=z+(len2-1);
  183.         } else {
  184.             bigbuffer[x] = str1[z];
  185.             x++;
  186.         }
  187.     }
  188.     bigbuffer[x] = 0;
  189.     return (char *)strdup(bigbuffer);
  190. }
  191.  
  192. /* This function parses a string and replaces all the text in the
  193.  * Replacement array with the current dynamic text */
  194. char *replaceem(char *orig)
  195. {
  196.     char *tmp1 = NULL, *tmp2 = (char *)strdup(orig);
  197.     int z;
  198.  
  199.     for(z=0;z<replacemax;z++)
  200.     {
  201.         tmp1 = replacestr(tmp2, InstRep[z].replacestring, InstRep[z].replacevar);
  202.         free(tmp2);
  203.         tmp2 = tmp1;
  204.         tmp1 = NULL;
  205.     }
  206.     return tmp2;
  207. }
  208.  
  209. /*
  210.  * Find the offset withing the executable of the ace data for use.
  211.  */
  212. int aceseek_entry(int num)
  213. {
  214.     long headerstart;
  215.     char headerbuf[20], packageconfig[100];
  216.     int z, start = 0, entry = 0, packageoffset=0;
  217.     /* Decode DBSOFT-ACE - small memleak but
  218.      * install should not be running for very long. :) */
  219.     sprintf(headerbuf, "%s%d", decode("EEECFDEPEGFECNEBEDEF"), num);
  220.     if((headerstart = findtext(headerbuf)) < 0)
  221.     {
  222.         mesg("Could not find ACE header in executable.");
  223.         exit(2);
  224.     }
  225.  
  226.     fseek(self, headerstart+strlen(headerbuf), SEEK_SET);
  227.     fread(packageconfig, 1, 100, self);
  228.  
  229.     for(z=0;z<100;z++)
  230.     {
  231.         if(packageconfig[z] == '-' || packageconfig[z] == '~')
  232.         {
  233.             char cur = packageconfig[z];
  234.             packageconfig[z] = 0;
  235.             switch(entry)
  236.             {
  237.             case 0:
  238.                 current_file = 0;
  239.                 files = atoi(&packageconfig[start]);
  240.                 break;
  241.             case 1:
  242.                 packagesize = atoi(&packageconfig[start]);
  243.                 break;
  244.             }
  245.             start = z+1;
  246.             if(cur == '~')
  247.             {
  248.                 packageoffset = z + 1;
  249.                 z = 100;
  250.             }
  251.             entry++;
  252.         }
  253.     }
  254.     aceoffset=headerstart+strlen(headerbuf)+packageoffset;
  255.     fseek(self, aceoffset, SEEK_SET);
  256.     return TRUE;
  257. }
  258.  
  259. /*
  260.  * Reads the embedded .cfg data from the executable and place it in the global
  261.  * INSTALL_* variables for use.
  262.  */
  263. int loadheader(void)
  264. {
  265.     char *buffer;
  266.     long headerstart;
  267.     int z, start=0, entry=0;
  268.  
  269.     buffer = malloc(8096*4);
  270.  
  271.     /* Decode DBSOFT-HEADER */
  272.     if((headerstart = findtext(decode("EEECFDEPEGFECNEIEFEBEEEFFC"))) < 0)
  273.     {
  274.         mesg("Could not find Selfinstaller header in executable.");
  275.         exit(2);
  276.     }
  277.     fseek(self, headerstart+13, SEEK_SET);
  278.  
  279.     fread(buffer, 1, 8096*4, self);
  280.     for(z=0;z<8096*4;z++)
  281.     {
  282.         if(buffer[z] == '-' || buffer[z] == '~')
  283.         {
  284.             char cur = buffer[z];
  285.             buffer[z] = 0;
  286.             switch(entry)
  287.             {
  288.             case 0:
  289.                 INSTALLER_APPLICATION = (char *)strdup(&buffer[start]);
  290.                 break;
  291.             case 1:
  292.                 INSTALLER_VERSION = (char *)strdup(&buffer[start]);
  293.                 break;
  294.             case 2:
  295.                 INSTALLER_TITLE = (char *)strdup(&buffer[start]);
  296.                 break;
  297.             case 3:
  298.                 INSTALLER_PATH = (char *)strdup(&buffer[start]);
  299.                 break;
  300.             case 4:
  301.                 INSTALLER_FOLDER = (char *)strdup(&buffer[start]);
  302.                 break;
  303.             case 5:
  304.                 INSTALLER_PROGRAM = (char *)strdup(&buffer[start]);
  305.                 break;
  306.             case 6:
  307.                 INSTALLER_SHADOW = (char *)strdup(&buffer[start]);
  308.                 break;
  309.             case 7:
  310.                 INSTALLER_OBJECT = (char *)strdup(&buffer[start]);
  311.                 break;
  312.             case 8:
  313.                 INSTALLER_SETS = (char *)strdup(&buffer[start]);
  314.                 break;
  315.             case 9:
  316.                 INSTALLER_SYSVAR = (char *)strdup(&buffer[start]);
  317.                 break;
  318.             case 10:
  319.                 INSTALLER_SYSLINE = (char *)strdup(&buffer[start]);
  320.                 break;
  321.             case 11:
  322.                 INSTALLER_CONFIRM_WPS = (char *)strdup(&buffer[start]);
  323.                 break;
  324.             case 12:
  325.                 INSTALLER_CONFIRM_CONFIGSYS = (char *)strdup(&buffer[start]);
  326.                 break;
  327.             case 13:
  328.                 INSTALLER_CONFIRM_OVERWRITE = (char *)strdup(&buffer[start]);
  329.                 break;
  330.             case 14:
  331.                 INSTALLER_PACKAGE_COUNT = atoi(&buffer[start]);
  332.                 break;
  333.             default:
  334.                 INSTALLER_PACKAGES[entry-15] = malloc((z-start)+1);
  335.                 strcpy(INSTALLER_PACKAGES[entry-15], &buffer[start]);
  336.                 break;
  337.             }
  338.             start = z+1;
  339.             if(cur == '~')
  340.             {
  341.                 free(buffer);
  342.                 return TRUE;
  343.             }
  344.  
  345.             entry++;
  346.         }
  347.     }
  348.     free(buffer);
  349.     return FALSE;
  350. }
  351.  
  352. /*
  353.  * Functions to work on an ace file embedded within the archive in an
  354.  * abstract manner.
  355.  */
  356. int aceread(void *buf, size_t count)
  357. {
  358.     unsigned long curpos = ftell(self);
  359.     size_t readit;
  360.  
  361.     if(count >  (packagesize-(curpos-aceoffset)))
  362.         readit = (packagesize-(curpos-aceoffset));
  363.     else
  364.         readit = count;
  365.  
  366.     return fread(buf, 1, readit, self);
  367. }
  368.  
  369. off_t acelseek(off_t offset, int whence)
  370. {
  371.     switch(whence)
  372.     {
  373.     case SEEK_SET:
  374.         fseek(self, aceoffset+offset, SEEK_SET);
  375.         break;
  376.     case SEEK_CUR:
  377.         fseek(self, offset, SEEK_CUR);
  378.         break;
  379.     }
  380.     return acepos;
  381. }
  382.  
  383. int aceopen(const char *path, int flags)
  384. {
  385.     fseek(self, aceoffset, SEEK_SET);
  386.     return 0;
  387. }
  388.  
  389. int aceclose(int fd)
  390. {
  391.     fseek(self, aceoffset, SEEK_SET);
  392.     return  0;
  393. }
  394.  
  395. /*
  396.  * Read the generated log file and remove any files installed.
  397.  */
  398. void delete_files(void)
  399. {
  400.     char tmpbuf[8196], *fileptr;
  401.     FILE *tmplf;
  402.     int linenum=0, found=-1, z;
  403.  
  404.     files_deleted=1;
  405.  
  406.     if((tmplf=fopen(instlog, "rb"))==NULL)
  407.         return;
  408.  
  409.     while(!feof(tmplf))
  410.     {
  411.         fgets(tmpbuf, 8196, tmplf);
  412.         linenum++;
  413.         if(tmpbuf[0]=='[' && (char *)strstr(tmpbuf, INSTALLER_APPLICATION) != NULL && !feof(tmplf))
  414.         {
  415.             fgets(tmpbuf, 8196, tmplf);
  416.             linenum++;
  417.             if((char *)strstr(tmpbuf, "<Version>") != NULL && (char *)strstr(tmpbuf, INSTALLER_VERSION) != NULL)
  418.                 found=linenum;
  419.         }
  420.     }
  421.     if(found != -1)
  422.     {
  423.         rewind(tmplf);
  424.         for (z=0;z<found;z++)
  425.             fgets(tmpbuf, 8196, tmplf);
  426.         while(!feof(tmplf))
  427.         {
  428.             fgets(tmpbuf, 8196, tmplf);
  429.             if((char *)strstr(tmpbuf, "<FileInst>") != NULL)
  430.             {
  431.                 fileptr = (char *)strchr(tmpbuf, ',')+1;
  432.                 /* Remove trailing CRLFs */
  433.                 if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n')
  434.                     fileptr[strlen(fileptr)-1]=0;
  435.                 if(fileptr[strlen(fileptr)-1] == '\r' || fileptr[strlen(fileptr)-1] == '\n')
  436.                     fileptr[strlen(fileptr)-1]=0;
  437.                 remove(fileptr);
  438.                 current_file--;
  439.                 WinSendMsg(mainhwnd, WM_USER, 0, 0);
  440.             }
  441.             if((char *)strstr(tmpbuf, "<End>") != NULL)
  442.             {
  443.                 fclose(tmplf);
  444.                 return;
  445.             }
  446.         }
  447.     }
  448.     fclose(tmplf);
  449.     return;
  450. }
  451.  
  452. /*
  453.  * Reads a config file into memory for editing with updatesys, updateset, etc.
  454.  */
  455. int readconfigfile(char *filename)
  456. {
  457.     char tmpbuf[8196];
  458.     FILE *tmpcs;
  459.  
  460.     /* Reset this value when restarting */
  461.     configfilecount = -1;
  462.  
  463.     if((tmpcs=fopen(filename, "rb"))==NULL)
  464.     {
  465.         strcpy(currentcf, empty_string);
  466.         return 1;
  467.     }
  468.     else
  469.         strcpy(currentcf, filename);
  470.  
  471.     while(!feof(tmpcs))
  472.     {
  473.         configfilecount++;
  474.         fgets(tmpbuf, 8196, tmpcs);
  475.         configsys[configfilecount] = malloc(strlen(tmpbuf)+1);
  476.         strcpy(configsys[configfilecount], tmpbuf);
  477.         stripcrlf(configsys[configfilecount]);
  478.     }
  479.  
  480.     fclose(tmpcs);
  481.     return 0;
  482. }
  483.  
  484. /*
  485.  * Write the updated config file to disk and backup the original.
  486.  */
  487. int writeconfigfile(char *filename, char *backup)
  488. {
  489.     FILE *tmpcs;
  490.     int i;
  491.  
  492.     if(backup)
  493.     {
  494.         remove(backup);
  495.         DosMove(filename, backup);
  496.     }
  497.     else
  498.         remove(filename);
  499.  
  500.     if((tmpcs=fopen(filename, "wb"))==NULL)
  501.         return 1;
  502.  
  503.     for(i=0;i<configfilecount;i++)
  504.     {
  505.         if(configsys[i])
  506.         {
  507.             fwrite(configsys[i], 1, strlen(configsys[i]), tmpcs);
  508.             /* Add the CRLF that got stripped in the reading stage. */
  509.             fwrite("\r\n", 1, 2, tmpcs);
  510.             free(configsys[i]);
  511.         }
  512.     }
  513.  
  514.     fclose(tmpcs);
  515.     return 0;
  516. }
  517. /*
  518.  * Adds or replaces a SET variable based on the flags (CONFIG.SYS)
  519.  */
  520. void updateset(char *setname, char *newvalue, int flag)
  521. {
  522.     char *cmpbuf1, *cmpbuf2, *tmpptr, *tmpptr2, *nv;
  523.     int i, z, t;
  524.  
  525.     nv=replaceem(newvalue);
  526.  
  527.     cmpbuf1=malloc(strlen(setname)+2);
  528.     strcpy(cmpbuf1, setname);
  529.     strcat(cmpbuf1, "=");
  530.     for(i=0;i<configfilecount;i++)
  531.     {
  532.         if(strlen(cmpbuf1) <= strlen(configsys[i]))
  533.         {
  534.             tmpptr=(char *)strdup(configsys[i]);
  535.             strupr(tmpptr);
  536.             if((tmpptr2=(char*)strstr(tmpptr, "SET "))!=NULL)
  537.             {
  538.                 tmpptr2 += 4;
  539.                 cmpbuf2=malloc(strlen(tmpptr2)+1);
  540.                 /* Remove any spaces from the string */
  541.                 z=0;
  542.                 for (t=0;t<strlen(tmpptr2) && z < strlen(cmpbuf1);t++)
  543.                 {
  544.                     if(tmpptr2[t] != ' ')
  545.                     {
  546.                         cmpbuf2[z]=tmpptr2[t];
  547.                         z++;
  548.                     }
  549.                 }
  550.                 cmpbuf2[z]=0;
  551.                 if(stricmp(cmpbuf1, cmpbuf2) == 0)
  552.                 {
  553.                     /* Ok we found the entry, and if UPDATE_ALWAYS change it to the
  554.                      new entry, otherwise exit */
  555.                     if(flag == UPDATE_ALWAYS)
  556.                     {
  557. #ifdef ENABLE_LOGGING
  558.                         fprintf(logfile, "<CFRemLine>,%s,%s\r\n", currentcf, configsys[i]);
  559. #endif
  560.                         free(configsys[i]);
  561.                         configsys[i] = malloc(strlen(setname)+strlen(nv)+6);
  562.                         strcpy(configsys[i], "SET ");
  563.                         strcat(configsys[i], setname);
  564.                         strcat(configsys[i], "=");
  565.                         strcat(configsys[i], nv);
  566. #ifdef ENABLE_LOGGING
  567.                         fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, configsys[i]);
  568. #endif
  569.                         free(cmpbuf1);free(cmpbuf2);free(tmpptr);
  570.                     }
  571.                     return;
  572.                 }
  573.                 free(cmpbuf2);
  574.             }
  575.             free(tmpptr);
  576.         }
  577.     }
  578.     /* Couldn't find the line so we'll add it */
  579.     configsys[configfilecount]=malloc(strlen(cmpbuf1)+strlen(nv)+6);
  580.     strcpy(configsys[configfilecount], "SET ");
  581.     strcat(configsys[configfilecount], setname);
  582.     strcat(configsys[configfilecount], "=");
  583.     strcat(configsys[configfilecount], nv);
  584. #ifdef ENABLE_LOGGING
  585.     fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, configsys[configfilecount]);
  586. #endif
  587.     configfilecount++;
  588.     free(cmpbuf1);
  589. }     
  590.  
  591. /*
  592.  * Adds an entry to a system variable (CONFIG.SYS)
  593.  */
  594. void updatesys(char *sysname, char *newvalue)
  595. {
  596.     char *cmpbuf1, *cmpbuf2, *tmpptr, *tmpptr2, *capbuf1, *capbuf2, *nv, *brian;
  597.     int i, z, t;
  598.  
  599.     nv=replaceem(newvalue);
  600.  
  601.     cmpbuf1=malloc(strlen(sysname)+2);
  602.     strcpy(cmpbuf1, sysname);
  603.     strcat(cmpbuf1, "=");
  604.     for(i=0;i<configfilecount;i++)
  605.     {
  606.         if(strlen(cmpbuf1) <= strlen(configsys[i]))
  607.         {
  608.             cmpbuf2=malloc(strlen(configsys[i])+1);
  609.             /* Remove any spaces from the string */
  610.             z=0;
  611.             for (t=0;t<strlen(configsys[i]) && z < strlen(cmpbuf1);t++)
  612.             {
  613.                 if(configsys[i][t] != ' ')
  614.                 {
  615.                     cmpbuf2[z]=configsys[i][t];
  616.                     z++;
  617.                 }
  618.             }
  619.             cmpbuf2[z]=0;
  620.             if(stricmp(cmpbuf1, cmpbuf2) == 0)
  621.             {
  622.                 /* Do a case insensitive comparison but preserve the case */
  623.                 tmpptr = &configsys[i][t];
  624.                 capbuf1=malloc(strlen(tmpptr)+1);
  625.                 capbuf2=malloc(strlen(nv)+1);
  626.                 strcpy(capbuf1, tmpptr);
  627.                 strcpy(capbuf2, nv);
  628.                 strupr(capbuf1);
  629.                 strupr(capbuf2);
  630.                 /* Ok, we found the line, and it doesn't have an entry so we'll add it */
  631.                 if((tmpptr2=(char *)strstr(capbuf1, capbuf2)) == NULL)
  632.                 {
  633. #ifdef ENABLE_LOGGING
  634.                     fprintf(logfile, "<CFRemLine>,%s,%s\r\n", currentcf, configsys[i]);
  635. #endif
  636.                     brian = configsys[i];
  637.                     configsys[i] = malloc(strlen(configsys[i])+strlen(nv)+4);
  638.                     strcpy(configsys[i], brian);
  639.                     free(brian);
  640.                     /* Remove any trailing CRLFs */
  641.                     if(configsys[i][strlen(configsys[i])-1]!=';')
  642.                         strcat(configsys[i], ";");
  643.                     strcat(configsys[i], nv);
  644.                     strcat(configsys[i], ";");
  645. #ifdef ENABLE_LOGGING
  646.                     fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, configsys[i]);
  647. #endif
  648.                 }
  649.                 free(cmpbuf1);free(cmpbuf2);free(capbuf1);free(capbuf2);
  650.                 return;
  651.             }
  652.             free(cmpbuf2);
  653.         }
  654.     }
  655.     /* Couldn't find the line so we'll add it */
  656.     configsys[configfilecount]=malloc(strlen(cmpbuf1)+strlen(nv)+3);
  657.     strcpy(configsys[configfilecount], cmpbuf1);
  658.     strcat(configsys[configfilecount], nv);
  659.     strcat(configsys[configfilecount], ";");
  660. #ifdef ENABLE_LOGGING
  661.     fprintf(logfile, "<CFAddLine>,%s,%s", currentcf, configsys[configfilecount]);
  662. #endif
  663.     configfilecount++;
  664.     free(cmpbuf1);
  665.     if(nv)
  666.         free(nv);
  667. }
  668.  
  669. /*
  670.  * Removes a line from a config file.
  671.  */
  672. void removeline(char *text)
  673. {
  674.     int z;
  675.     for(z=0;z<configfilecount;z++)
  676.     {
  677.         if(stricmp(configsys[z], text) == 0)
  678.         {
  679.             int t;
  680.  
  681. #ifdef ENABLE_LOGGING
  682.             fprintf(logfile, "<CFRemLine>,%s,%s\r\n", currentcf, configsys[z]);
  683. #endif
  684.             free(configsys[z]);
  685.             for(t=z;t<(configfilecount-1);t++)
  686.                 configsys[t] = configsys[t+1];
  687.             configfilecount--;
  688.         }
  689.     }
  690. }
  691.  
  692.  
  693. /*
  694.  * The Window peocedure for the confirmation dialog.
  695.  */
  696. MRESULT    EXPENTRY ConfirmDlgProc(HWND hWnd, ULONG msg, MPARAM mp1,    MPARAM mp2)
  697. {
  698.     SWP winpos;
  699.  
  700.     switch (msg)
  701.     {
  702.     case WM_INITDLG:
  703.         WinSetWindowText(hWnd, INSTALLER_TITLE);
  704.         WinEnableWindow(WinWindowFromID(mainhwnd, I_Cancel), FALSE);
  705.         WinSetDlgItemText(hWnd,    I_Confirm, confirmstring);
  706.         WinQueryWindowPos(mainhwnd, &winpos);
  707.         WinSetWindowPos(hWnd, HWND_TOP, winpos.x+30, winpos.y+30, 0, 0, SWP_MOVE | SWP_ZORDER);
  708.         break;
  709.     case WM_COMMAND:
  710.         WinEnableWindow(WinWindowFromID(mainhwnd, I_Cancel), TRUE);
  711.         switch ( SHORT1FROMMP(mp1) )
  712.         {
  713.         case I_Ja:
  714.             WinDismissDlg(hWnd, 0);
  715.             break;
  716.         case I_Alle:
  717.             WinDismissDlg(hWnd, 1);
  718.             break;
  719.         case I_Nein:
  720.             WinDismissDlg(hWnd, 2);
  721.             break;
  722.         case I_Halt:
  723.             success=2;
  724.             installstate=ABORTED;
  725.             WinDismissDlg(hWnd, 3);
  726.             break;
  727.         }
  728.         break;
  729.     default :
  730.         return(WinDefDlgProc(hWnd, msg, mp1, mp2));
  731.     }
  732.     return(0L);
  733. }
  734. /*
  735.  * Display a confirmation dialog with the options: YES NO ALL CANCEL
  736.  * Returns: 0 for YES, 1 for ALL, 2 for NO and 3 for CANCEL
  737.  */
  738. int confirm(char *format, ...) {
  739.     va_list args;
  740.  
  741.     /* if no confirmation, return 1, meaning overwrite all */
  742.     if (stricmp(INSTALLER_CONFIRM_OVERWRITE, "no") == 0)
  743.         return 1;
  744.  
  745.     va_start(args, format);
  746.     vsprintf(confirmstring, format, args);
  747.     va_end(args);
  748.  
  749.     return WinDlgBox(HWND_DESKTOP, HWND_DESKTOP, &ConfirmDlgProc, NULLHANDLE, I_Karte, NULL);
  750. }
  751.  
  752. /*
  753.  * A function to grab a file from an embedded archive and extract it to the TEMP directory.
  754.  */
  755. void grabfile(char *filename)
  756. {
  757.     no_update = 1;
  758.     settempdir();
  759.     remove(filename);
  760.     aceseek_entry(0);
  761.     resetglobals();
  762.     installer_unpack(filename, 2);
  763.     no_update = 0;
  764. }
  765.  
  766. /*
  767.  * This thread runs along side the main thread allowing the user to cancel the process.
  768.  */
  769. void install_thread(void *param)
  770. {
  771.     HAB ihab = 0;
  772.     HMQ ihmq = 0;
  773.     char tmpinstallpath[1024];
  774.     int  k, j, installcount=0, installed=0;
  775.  
  776.     (void)param;
  777.     ihab = WinInitialize(0);
  778.     ihmq = WinCreateMsgQueue(ihab, 0);
  779.  
  780.     installstate = INSTALLING;
  781.  
  782. #ifdef ENABLE_LOGGING
  783.     if((logfile=fopen(instlog, "ab"))==NULL)
  784.     {
  785.         error("Log file \"%s\" open failed! Installation aborted!", instlog);
  786.         exit(1);
  787.     }
  788.  
  789.     fprintf(logfile, "[%s]\r\n<Version>,%s\r\n<Start>\r\n", INSTALLER_APPLICATION, INSTALLER_VERSION);
  790. #endif
  791.  
  792.     /* Create nested subdirectories if necessary. */
  793.     strcpy(tmpinstallpath, installdir);
  794.     for(k=3;k<strlen(installdir);k++)
  795.     {
  796.         if(tmpinstallpath[k] == '\\')
  797.         {
  798.             tmpinstallpath[k] = 0;
  799.             if(DosCreateDir(tmpinstallpath, NULL)==NO_ERROR)
  800. #ifdef ENABLE_LOGGING
  801.                 fprintf(logfile, "<NewDir>,%s\r\n", tmpinstallpath);
  802. #else
  803.                 ;
  804. #endif
  805.             tmpinstallpath[k] = '\\';
  806.         }
  807.     }
  808.  
  809.     if(DosCreateDir(installdir, NULL)==NO_ERROR)
  810. #ifdef ENABLE_LOGGING
  811.         fprintf(logfile, "<NewDir>,%s\r\n", installdir);
  812. #else
  813.         ;
  814. #endif
  815.  
  816.     if(strlen(installdir) > 0 && installdir[0] > 'a'-1 && installdir[0] < 'z'+1)
  817.         installdir[0]=installdir[0] - ('a'-'A');
  818.     if(strlen(installdir)>2 && installdir[1]==':' && installdir[2]=='\\')
  819.         DosSetDefaultDisk((int)(installdir[0]-'A'+1));
  820.  
  821.     DosSetCurrentDir(installdir);
  822.  
  823.     /* Unpack files to destination directory */
  824.     for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  825.     {
  826.         if(packagesselected[j] == TRUE)
  827.             installcount++;
  828.     }
  829.     if(installcount == 0)
  830.     {
  831.         mesg("No packages selected for installation!");
  832.     }
  833.     else
  834.     {
  835.         for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  836.         {
  837.             if(packagesselected[j] == TRUE)
  838.             {
  839.                 char statustext[512];
  840.                 aceseek_entry(j);
  841.                 resetglobals();
  842. #ifdef SDDINST
  843.                 strcpy(statustext, "Press \"Exit Installation\" to Abort.");
  844. #else
  845.                 sprintf(statustext,"Copying Files for %s %d/%d, Press \"Exit Installation\" to Abort.", INSTALLER_PACKAGES[j], installed+1, installcount);
  846. #endif
  847.                 WinSetDlgItemText(mainhwnd,    I_Info3, statustext);
  848.                 /* filename parameter when null is all files */
  849.                 installer_unpack(NULL, 2);
  850.                 installed++;
  851.             }
  852.         }
  853.     }
  854.  
  855.     if(success==1)
  856.     {
  857.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Error unpacking files, Installer may be corrupt!", INSTALLER_TITLE, 0, MB_OK | MB_ERROR | MB_MOVEABLE | MB_SYSTEMMODAL);
  858.     }
  859.  
  860.     if(success==2)
  861.     {
  862.         WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "User aborted installation!", INSTALLER_TITLE, 0, MB_OK | MB_ERROR | MB_MOVEABLE | MB_SYSTEMMODAL);
  863.     }
  864.  
  865.     if(installstate != ABORTED)
  866.         installstate = COMPLETED;
  867.  
  868. #ifdef SDDINST
  869.     DosCreateDir(replaceem("%BOOTDRIVE%:\\OS2\\DRIVERS\\NUCLEUS\\CONFIG\\MODES"), NULL);
  870.     DosCreateDir(replaceem("%BOOTDRIVE%:\\OS2\\DRIVERS\\NUCLEUS\\CONFIG\\OPTIONS"), NULL);
  871.  
  872.     setdrivedir(replaceem("%USERPATH%\\disk"));
  873.     if(usescitech)
  874.     {
  875.             char *t = replaceem("/c %USERPATH%\\disk\\setup.cmd sdd ");
  876.  
  877.             cmdrun(t);
  878.  
  879.             free(t);
  880.     }
  881. #endif
  882.  
  883.     WinSendMsg(mainhwnd, WM_USER+1, NULL, NULL);
  884.  
  885.     WinDestroyMsgQueue(ihmq);
  886.     WinTerminate(ihab);
  887. }
  888. /*
  889.  * Use the information from the .cfg file which is embedded in the EXE to update the
  890.  * CONFIG.SYS settings.
  891.  */
  892. void configsys_update(void)
  893. {
  894.     char *arg1, *arg2, *arg3;
  895.     char temp[5000];
  896.     int z, argn=0;
  897.  
  898.     if(readconfigfile(csfile))
  899.         return;
  900.  
  901.     /* Update Miscellaneous lines */
  902.     if(strlen(INSTALLER_SYSLINE)>0)
  903.     {
  904.         char *tmpptr = &temp[0];
  905.         int len;
  906.  
  907.         strcpy(temp, INSTALLER_SYSLINE);
  908.         temp[4999] = 0;
  909.         len = strlen(temp);
  910.  
  911.         for(z=0;z<len;z++)
  912.         {
  913.             if(temp[z]==',')
  914.             {
  915.                 char *tmpptr2;
  916.  
  917.                 temp[z] = 0;
  918.                 tmpptr2 = replaceem(tmpptr);
  919.                 tmpptr = &temp[z+1];
  920.                 removeline(tmpptr2);
  921.                 configsys[configfilecount] = tmpptr2;
  922. #ifdef ENABLE_LOGGING
  923.                 fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, tmpptr2);
  924. #endif
  925.                 configfilecount++;
  926.             }
  927.         }
  928.         if(tmpptr && *tmpptr)
  929.         {
  930.             char *tmpptr2;
  931.  
  932.             tmpptr2 = replaceem(tmpptr);
  933.             removeline(tmpptr2);
  934.             configsys[configfilecount] = tmpptr2;
  935. #ifdef ENABLE_LOGGING
  936.             fprintf(logfile, "<CFAddLine>,%s,%s\r\n", currentcf, tmpptr2);
  937. #endif
  938.             configfilecount++;
  939.         }
  940.  
  941.     }
  942.     /* Update SET variables */
  943.     if(strlen(INSTALLER_SETS)>0)
  944.     {
  945.         strcpy(temp, INSTALLER_SETS);
  946.         argn=0;
  947.         arg1=&temp[0];
  948.         arg2=arg3=NULL;
  949.         for(z=0;z<strlen(INSTALLER_SETS);z++)
  950.         {
  951.             if(temp[z]==',')
  952.             {
  953.                 argn++;
  954.                 temp[z]=0;
  955.                 switch(argn)
  956.                 {
  957.                 case 1:
  958.                     arg2=&temp[z+1];
  959.                     break;
  960.                 case 2:
  961.                     arg3=&temp[z+1];
  962.                     break;
  963.                 case 3:
  964.                     argn=0;
  965.                     updateset(arg1, arg2, (int)(arg3[0]-'0'));
  966.                     arg1=&temp[z+1];
  967.                     arg2=arg3=NULL;
  968.                     break;
  969.                 }
  970.             }
  971.         }
  972.         if(arg3)
  973.             updateset(arg1, arg2, (int)arg3-'0');
  974.     }
  975.     /* Update system variables */
  976.     if(strlen(INSTALLER_SYSVAR)>0)
  977.     {
  978.         strcpy(temp, INSTALLER_SYSVAR);
  979.         argn=0;
  980.         arg1=&temp[0];
  981.         arg2=NULL;
  982.         for(z=0;z<strlen(INSTALLER_SYSVAR);z++)
  983.         {
  984.             if(temp[z]==',')
  985.             {
  986.                 argn++;
  987.                 temp[z]=0;
  988.                 switch(argn)
  989.                 {
  990.                 case 1:
  991.                     arg2=&temp[z+1];
  992.                     break;
  993.                 case 2:
  994.                     argn=0;
  995.                     updatesys(arg1, arg2);
  996.                     arg1=&temp[z+1];
  997.                     arg2=NULL;
  998.                     break;
  999.                 }
  1000.             }
  1001.         }
  1002.         if(arg2)
  1003.             updatesys(arg1, arg2);
  1004.     }
  1005.  
  1006.     writeconfigfile(csfile, bufile);
  1007. }
  1008.  
  1009. void create_wps_objects(void)
  1010. {
  1011.     char *arg1, *arg2, *arg3, *arg4, *arg5, *arg6;
  1012.     char temp[5000];
  1013.     char zerotext[2] = "";
  1014.     int z, argn, len;
  1015.  
  1016.     /* Create Folder Objects */
  1017.     if(strlen(INSTALLER_FOLDER)>0)
  1018.     {
  1019.         strcpy(temp, replaceem(INSTALLER_FOLDER));
  1020.         argn=0;
  1021.         arg1=&temp[0];
  1022.         arg2=arg3=arg4=arg5=&zerotext[0];
  1023.         len = strlen(temp);
  1024.         for(z=0;z<len;z++)
  1025.         {
  1026.             if(temp[z]==',')
  1027.             {
  1028.                 argn++;
  1029.                 temp[z]=0;
  1030.                 switch(argn)
  1031.                 {
  1032.                 case 1:
  1033.                     arg2=&temp[z+1];
  1034.                     break;
  1035.                 case 2:
  1036.                     arg3=&temp[z+1];
  1037.                     break;
  1038.                 case 3:
  1039.                     arg4=&temp[z+1];
  1040.                     break;
  1041.                 case 4:
  1042.                     arg5=&temp[z+1];
  1043.                     break;
  1044.                 case 5:
  1045.                     argn=0;
  1046.                     MakeFolder(arg1, arg2, arg3, arg4, arg5);
  1047. #ifdef ENABLE_LOGGING
  1048.                     fprintf(logfile, "<WPSFolderAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
  1049. #endif
  1050.                     arg1=&temp[z+1];
  1051.                     arg2=arg3=arg4=arg5=&zerotext[0];
  1052.                     break;
  1053.                 }
  1054.             }
  1055.         }
  1056.         MakeFolder(arg1, arg2, arg3, arg4, arg5);
  1057. #ifdef ENABLE_LOGGING
  1058.         fprintf(logfile, "<WPSFolderAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
  1059. #endif
  1060.     }
  1061.  
  1062.     /* Create Program Objects */
  1063.     if(strlen(INSTALLER_PROGRAM)>0)
  1064.     {
  1065.         strcpy(temp, replaceem(INSTALLER_PROGRAM));
  1066.         argn=0;
  1067.         arg1=&temp[0];
  1068.         arg2=arg3=arg4=arg5=arg6=&zerotext[0];
  1069.         len = strlen(temp);
  1070.         for(z=0;z<len;z++)
  1071.         {
  1072.             if(temp[z]==',')
  1073.             {
  1074.                 argn++;
  1075.                 temp[z]=0;
  1076.                 switch(argn)
  1077.                 {
  1078.                 case 1:
  1079.                     arg2=&temp[z+1];
  1080.                     break;
  1081.                 case 2:
  1082.                     arg3=&temp[z+1];
  1083.                     break;
  1084.                 case 3:
  1085.                     arg4=&temp[z+1];
  1086.                     break;
  1087.                 case 4:
  1088.                     arg5=&temp[z+1];
  1089.                     break;
  1090.                 case 5:
  1091.                     arg6=&temp[z+1];
  1092.                     break;
  1093.                 case 6:
  1094.                     argn=0;
  1095.                     MakeProgram(arg1, arg2, arg3, arg4, arg5, arg6);
  1096. #ifdef ENABLE_LOGGING
  1097.                     fprintf(logfile, "<WPSProgramAdd>,%s,%s,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4,arg5,arg6);
  1098. #endif
  1099.                     arg1=&temp[z+1];
  1100.                     arg2=arg3=arg4=arg5=arg6=&zerotext[0];
  1101.                     break;
  1102.                 }
  1103.             }
  1104.         }
  1105.         MakeProgram(arg1, arg2, arg3, arg4, arg5, arg6);
  1106. #ifdef ENABLE_LOGGING
  1107.         fprintf(logfile, "<WPSProgramAdd>,%s,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5,arg6);
  1108. #endif
  1109.     }
  1110.  
  1111.     /* Create Shadow Objects */
  1112.     if(strlen(INSTALLER_SHADOW)>0)
  1113.     {
  1114.         strcpy(temp, replaceem(INSTALLER_SHADOW));
  1115.         argn=0;
  1116.         arg1=&temp[0];
  1117.         arg2=arg3=arg4=&zerotext[0];
  1118.         len = strlen(temp);
  1119.         for(z=0;z<len;z++)
  1120.         {
  1121.             if(temp[z]==',')
  1122.             {
  1123.                 argn++;
  1124.                 temp[z]=0;
  1125.                 switch(argn)
  1126.                 {
  1127.                 case 1:
  1128.                     arg2=&temp[z+1];
  1129.                     break;
  1130.                 case 2:
  1131.                     arg3=&temp[z+1];
  1132.                     break;
  1133.                 case 3:
  1134.                     arg4=&temp[z+1];
  1135.                     break;
  1136.                 case 4:
  1137.                     argn=0;
  1138.                     MakeShadow(arg1, arg2, arg3, arg4);
  1139. #ifdef ENABLE_LOGGING
  1140.                     fprintf(logfile, "<WPSShadowAdd>,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4);
  1141. #endif
  1142.                     arg1=&temp[z+1];
  1143.                     arg2=arg3=arg4=&zerotext[0];
  1144.                     break;
  1145.                 }
  1146.             }
  1147.         }
  1148.         MakeShadow(arg1, arg2, arg3, arg4);
  1149. #ifdef ENABLE_LOGGING
  1150.         fprintf(logfile, "<WPSShadowAdd>,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4);
  1151. #endif
  1152.     }
  1153.  
  1154.     /* Create Generic Objects */
  1155.     if(strlen(INSTALLER_OBJECT)>0)
  1156.     {
  1157.         strcpy(temp, replaceem(INSTALLER_OBJECT));
  1158.         argn=0;
  1159.         arg1=&temp[0];
  1160.         arg2=arg3=arg4=arg5=&zerotext[0];
  1161.         len = strlen(temp);
  1162.         for(z=0;z<len;z++)
  1163.         {
  1164.             if(temp[z]==',')
  1165.             {
  1166.                 argn++;
  1167.                 temp[z]=0;
  1168.                 switch(argn)
  1169.                 {
  1170.                 case 1:
  1171.                     arg2=&temp[z+1];
  1172.                     break;
  1173.                 case 2:
  1174.                     arg3=&temp[z+1];
  1175.                     break;
  1176.                 case 3:
  1177.                     arg4=&temp[z+1];
  1178.                     break;
  1179.                 case 4:
  1180.                     arg5=&temp[z+1];
  1181.                     break;
  1182.                 case 5:
  1183.                     argn=0;
  1184.                     MakeObject(arg1, arg2, arg3, arg4, arg5);
  1185. #ifdef ENABLE_LOGGING
  1186.                     fprintf(logfile, "<WPSObjectAdd>,%s,%s,%s,%s,%s\r\n", arg1,arg2,arg3,arg4,arg5);
  1187. #endif
  1188.                     arg1=&temp[z+1];
  1189.                     arg2=arg3=arg4=arg5=&zerotext[0];
  1190.                     break;
  1191.                 }
  1192.             }
  1193.         }
  1194.         MakeObject(arg1, arg2, arg3, arg4, arg5);
  1195. #ifdef ENABLE_LOGGING
  1196.         fprintf(logfile, "<WPSObjectAdd>,%s,%s,%s,%s,%s\r\n", arg1, arg2,arg3,arg4,arg5);
  1197. #endif
  1198.     }
  1199. }
  1200.  
  1201. /*
  1202.  * Reads a line from a file and returns it in raw.
  1203.  */
  1204. void getline(FILE *f, char *raw)
  1205. {
  1206.     memset(raw, 0, 256);
  1207.     fgets(raw, 255, f);
  1208.     stripcrlf(raw);
  1209. }
  1210.  
  1211. /*
  1212.  * Removes a character from a buffer by advancing the buffer to the left.
  1213.  */
  1214. void removechar(char *buffer, int thisone, int len)
  1215. {
  1216.     int x;
  1217.  
  1218.     for(x=thisone;x<len;x++)
  1219.         buffer[x] = buffer[x+1];
  1220. }
  1221.  
  1222. /*
  1223.  * Breaks up a line in raw into it's components.
  1224.  */
  1225. void parseline(char *raw, char comment, char delimiter, char quotes, char *entry, char *entrydata, char *entrydata2)
  1226. {
  1227.     char in[256];
  1228.     int z, len, in_quotes = 0, entrynum=0, last = 0;
  1229.  
  1230.     strcpy(entry, empty_string);
  1231.     strcpy(entrydata, empty_string);
  1232.     strcpy(entrydata2, empty_string);
  1233.     strcpy(in, raw);
  1234.  
  1235.     if(in[strlen(in)-1] == '\n')
  1236.         in[strlen(in)-1] = 0;
  1237.  
  1238.     if(in[0] != comment)
  1239.     {
  1240.         len=strlen(in);
  1241.         for(z=0;z<len;z++)
  1242.         {
  1243.             if(!in_quotes && in[z] == delimiter)
  1244.             {
  1245.                 in[z] = 0;
  1246.                 /* Strip any other delimiters */
  1247.                 z++;
  1248.                 while(in[z] == delimiter && z < len)
  1249.                     z++;
  1250.                 if(!entrynum)
  1251.                     strcpy(entry, in);
  1252.                 else
  1253.                 {
  1254.                     strcpy(entrydata, &in[last]);
  1255.                     strcpy(entrydata2, &in[z]);
  1256.                 }
  1257.                 last = z;
  1258.                 if(entrynum)
  1259.                     return;
  1260.                 entrynum++;
  1261.             }
  1262.             if(in[z] == quotes)
  1263.             {
  1264.                 removechar(in, z, len);
  1265.                 z--;
  1266.                 len--;
  1267.                 if(in_quotes)
  1268.                     in_quotes = 0;
  1269.                 else
  1270.                     in_quotes = 1;
  1271.             }
  1272.         }
  1273.         if(!entrynum)
  1274.             strcpy(entry, in);
  1275.         else
  1276.             strcpy(entrydata, &in[last]);
  1277.     }
  1278. }
  1279.  
  1280. /*
  1281.  * Reads a line from the file and splits it up into it's components.
  1282.  */
  1283. void getparseline(FILE *f, char comment, char delimiter, char quotes, char *raw, char *entry, char *entrydata, char *entrydata2)
  1284. {
  1285.     getline(f, raw);
  1286.     parseline(raw, comment, delimiter, quotes, entry, entrydata, entrydata2);
  1287. }
  1288.  
  1289. /*
  1290.  * Window procedure for the package selection dialog when there are multiple
  1291.  * packages included in an archive.
  1292.  */
  1293. MRESULT    EXPENTRY PackageDlgProc(HWND hWnd, ULONG msg, MPARAM mp1,    MPARAM mp2)
  1294. {
  1295.     int j, i, count = 0;
  1296.  
  1297.     switch(msg)
  1298.     {
  1299.     case WM_INITDLG:
  1300.         for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  1301.             WinSendMsg(WinWindowFromID(hWnd, PACKAGES), LM_INSERTITEM, MPFROMSHORT(LIT_END), MPFROMP(INSTALLER_PACKAGES[j]));
  1302.         break;
  1303.         /* Process push button selections */
  1304.     case WM_CLOSE:
  1305.         for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  1306.             packagesselected[j] = FALSE;
  1307.         i = (int)WinSendMsg(WinWindowFromID(hWnd, PACKAGES),
  1308.                             LM_QUERYSELECTION,
  1309.                             MPFROMSHORT(LIT_FIRST),0L);
  1310.         while(i!=LIT_NONE)
  1311.         {
  1312.             packagesselected[i] = TRUE;
  1313.             i = (int)WinSendMsg(WinWindowFromID(hWnd, PACKAGES),
  1314.                                 LM_QUERYSELECTION,
  1315.                                 (MPARAM)i,0L);
  1316.         }
  1317.         for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  1318.         {
  1319.             if(packagesselected[j] == TRUE)
  1320.                 count++;
  1321.         }
  1322.         if(count == 0)
  1323.             packagechosen=FALSE;
  1324.         else
  1325.             packagechosen=TRUE;
  1326.  
  1327.         WinDismissDlg(hWnd, FALSE);
  1328.         break;
  1329.     case WM_COMMAND:
  1330.         switch ( SHORT1FROMMP(mp1) )
  1331.         {
  1332.         case PB_OK:
  1333.             for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  1334.                 packagesselected[j] = FALSE;
  1335.             i = (int)WinSendMsg(WinWindowFromID(hWnd, PACKAGES),
  1336.                                 LM_QUERYSELECTION,
  1337.                                 MPFROMSHORT(LIT_FIRST),0L);
  1338.             while(i!=LIT_NONE)
  1339.             {
  1340.                 packagesselected[i] = TRUE;
  1341.                 i = (int)WinSendMsg(WinWindowFromID(hWnd, PACKAGES),
  1342.                                     LM_QUERYSELECTION,
  1343.                                     (MPARAM)i,0L);
  1344.             }
  1345.             for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  1346.             {
  1347.                 if(packagesselected[j] == TRUE)
  1348.                     count++;
  1349.             }
  1350.             if(count == 0)
  1351.                 packagechosen=FALSE;
  1352.             else
  1353.                 packagechosen=TRUE;
  1354.  
  1355.             WinDismissDlg(hWnd, FALSE);
  1356.             break;
  1357.         case PB_CANCEL:
  1358.             WinDismissDlg(hWnd, FALSE);
  1359.             break;
  1360.         case PB_SELECTALL:
  1361.             for(j=0;j<INSTALLER_PACKAGE_COUNT;j++)
  1362.                 WinSendMsg(WinWindowFromID(hWnd, PACKAGES), LM_SELECTITEM, MPFROMSHORT(j), (MPARAM)TRUE);
  1363.             break;
  1364.         case PB_DESELECTALL:
  1365.             WinSendMsg(WinWindowFromID(hWnd, PACKAGES), LM_SELECTITEM, MPFROMSHORT(LIT_NONE), FALSE);
  1366.             break;
  1367.         }
  1368.         break;
  1369.         /* Pass through unhandled messages */
  1370.     default :
  1371.         return(WinDefDlgProc(hWnd, msg, mp1, mp2));
  1372.     }
  1373. return(0L);
  1374. }
  1375.  
  1376. /*
  1377.  * Configures the container window passed to it for use with populatedir()
  1378.  */
  1379. void setdir(HWND hwnd)
  1380. {
  1381.     PFIELDINFO details, first, left = NULL;
  1382.     FIELDINFOINSERT detin;
  1383.     CNRINFO cnri;
  1384.     int z;
  1385.     ULONG flData[2] = {  CFA_BITMAPORICON | CFA_CENTER | CFA_HORZSEPARATOR | CFA_SEPARATOR,
  1386.     CFA_STRING | CFA_LEFT | CFA_HORZSEPARATOR };
  1387.     ULONG offStruct[2] = {
  1388.         offsetof(CnrEntry, hptrIcon),
  1389.         offsetof(CnrEntry, filename),
  1390.     };
  1391.  
  1392.     first = details = (PFIELDINFO)WinSendMsg(hwnd, CM_ALLOCDETAILFIELDINFO, MPFROMLONG(2), 0L);
  1393.     if(!first)
  1394.     {
  1395.         mesg("Error creating Directory container!");
  1396.         return;
  1397.     }
  1398.     for(z=0;z<2;z++)
  1399.     {
  1400.         if(z==1)
  1401.             left=details;
  1402.         details->cb = sizeof(FIELDINFO);
  1403.         details->flData = flData[z];
  1404.         details->flTitle = CFA_FITITLEREADONLY;
  1405.         switch(z)
  1406.         {
  1407.         case 0:
  1408.             details->pTitleData = "Icon";
  1409.             break;
  1410.         case 1:
  1411.             details->pTitleData = "Name";
  1412.             break;
  1413.         }
  1414.         details->offStruct = offStruct[z];
  1415.         details = details->pNextFieldInfo;
  1416.     }
  1417.  
  1418.     detin.cb = sizeof(FIELDINFOINSERT);
  1419.     detin.fInvalidateFieldInfo = FALSE;
  1420.     detin.pFieldInfoOrder = (PFIELDINFO) CMA_FIRST;
  1421.     detin.cFieldInfoInsert = 2;
  1422.  
  1423.     WinSendMsg(hwnd, CM_INSERTDETAILFIELDINFO, MPFROMP(first), MPFROMP(&detin));
  1424.  
  1425.     cnri.cb = sizeof(CNRINFO);
  1426.     cnri.pFieldInfoLast = left;
  1427.     cnri.xVertSplitbar  = 150;
  1428.     cnri.flWindowAttr = CV_DETAIL | CV_MINI;
  1429.     cnri.slBitmapOrIcon.cx = 15;
  1430.     cnri.slBitmapOrIcon.cy = 15;
  1431.  
  1432.     WinSendMsg(hwnd, CM_SETCNRINFO, MPFROMP(&cnri),  MPFROMLONG(CMA_FLWINDOWATTR | CMA_SLBITMAPORICON /*| CMA_PFIELDINFOLAST | CMA_XVERTSPLITBAR*/));
  1433. }
  1434. /*
  1435.  * Reads the directory list from the directory specified in the global variable
  1436.  * browserdir and populates the container window passed to it.
  1437.  */
  1438. void populatedir(HWND hwnd)
  1439. {
  1440.     FILEFINDBUF3 ffb;
  1441.     APIRET rc;
  1442.     HPOINTER fileicon, foldericon;
  1443.     RECORDINSERT recin;
  1444.     HDIR hdir = HDIR_CREATE;
  1445.     ULONG findcount = 1;
  1446.     CnrEntry *direntry, *first;
  1447.     int count = 0, j;
  1448.     char tmpbuf[201];
  1449.  
  1450.     fileicon = WinLoadPointer(HWND_DESKTOP,NULLHANDLE,FILEICON);
  1451.     foldericon = WinLoadPointer(HWND_DESKTOP,NULLHANDLE,FOLDERICON);
  1452.  
  1453.     strcpy(tmpbuf, browsedir);
  1454.     if(tmpbuf[strlen(tmpbuf)-1] == '\\')
  1455.         strcat(tmpbuf, "*");
  1456.     else
  1457.         strcat(tmpbuf, "\\*");
  1458.  
  1459.     WinSendMsg(hwnd, CM_REMOVERECORD, (MPARAM)0L, MPFROM2SHORT(0, CMA_INVALIDATE | CMA_FREE));
  1460.  
  1461.     if((rc = DosFindFirst(tmpbuf, &hdir, MUST_HAVE_DIRECTORY, &ffb, sizeof(FILEFINDBUF3), &findcount, FIL_STANDARD)) == NO_ERROR)
  1462.     {
  1463.         while(rc != ERROR_NO_MORE_FILES)
  1464.         {
  1465.             if(strcmp(ffb.achName, ".") != 0)
  1466.                 count++;
  1467.             rc = DosFindNext(hdir, &ffb, sizeof(FILEFINDBUF3), &findcount);
  1468.         }
  1469.     }
  1470.     DosFindClose(hdir);
  1471.  
  1472.     for(j=2;j<27;j++)
  1473.     {
  1474.         if(drivefree(j) > 0)
  1475.             count++;
  1476.     }
  1477.     hdir = HDIR_CREATE;
  1478.     findcount = 1;
  1479.  
  1480.     first = direntry = (CnrEntry *)WinSendMsg(hwnd, CM_ALLOCRECORD, MPFROMLONG(sizeof(CnrEntry) - sizeof(RECORDCORE)), MPFROMLONG(count));
  1481.  
  1482.     if(!first)
  1483.     {
  1484.         mesg("Error populating directory");
  1485.         return;
  1486.     }
  1487.  
  1488.     if((rc = DosFindFirst(tmpbuf, &hdir, MUST_HAVE_DIRECTORY, &ffb, sizeof(FILEFINDBUF3), &findcount, FIL_STANDARD)) == NO_ERROR)
  1489.     {
  1490.         while(rc != ERROR_NO_MORE_FILES)
  1491.         {
  1492.             if(strcmp(ffb.achName, ".") != 0)
  1493.             {
  1494.                 direntry->hptrIcon = direntry->rc.hptrIcon = foldericon;
  1495.                 direntry->filename = (char *)strdup(ffb.achName);
  1496.                 direntry->rc.pszIcon = direntry->filename;
  1497.                 direntry->rc.pszName = direntry->filename;
  1498.                 direntry->rc.pszText = direntry->filename;
  1499.  
  1500.                 direntry = (CnrEntry *)direntry->rc.preccNextRecord;
  1501.             }
  1502.  
  1503.             rc = DosFindNext(hdir, &ffb, sizeof(FILEFINDBUF3), &findcount);
  1504.         }
  1505.     }
  1506.  
  1507.     DosFindClose(hdir);
  1508.  
  1509.     for(j=2;j<27;j++)
  1510.     {
  1511.         if(drivefree(j) > 0)
  1512.         {
  1513.             sprintf(tmpbuf, "Drive %c:", ('A'+j)-1);
  1514.             direntry->hptrIcon = direntry->rc.hptrIcon = foldericon;
  1515.             direntry->filename = (char *)strdup(tmpbuf);
  1516.             direntry->rc.pszIcon = direntry->filename;
  1517.             direntry->rc.pszName = direntry->filename;
  1518.             direntry->rc.pszText = direntry->filename;
  1519.  
  1520.             direntry = (CnrEntry *)direntry->rc.preccNextRecord;
  1521.         }
  1522.     }
  1523.  
  1524.     recin.cb = sizeof(RECORDINSERT);
  1525.     recin.pRecordOrder = (PRECORDCORE)CMA_END;
  1526.     recin.pRecordParent = NULL;
  1527.     recin.zOrder = CMA_TOP;
  1528.     recin.fInvalidateRecord = TRUE;
  1529.     recin.cRecordsInsert = count;
  1530.  
  1531.     WinSendMsg(hwnd, CM_INSERTRECORD, MPFROMP(first), MPFROMP(&recin));
  1532.  
  1533.     WinDestroyPointer(foldericon);
  1534.     WinDestroyPointer(fileicon);
  1535. }
  1536.  
  1537. /*
  1538.  * Thread to spawn the readme file.
  1539.  */
  1540. void readme(void *param)
  1541. {
  1542.     HAB zhab;
  1543.     HMQ zhmq;
  1544.     char *filename = (char *)param;
  1545.  
  1546.     zhab = WinInitialize(0);
  1547.     zhmq = WinCreateMsgQueue(zhab, 0);
  1548.  
  1549.     grabfile(filename); 
  1550.     viewfile(filename, zhab);
  1551.     remove(filename);
  1552.  
  1553.     while (WinGetMsg(zhab, &qmsg, (HWND)NULL, 0, 0))
  1554.         WinDispatchMsg(zhab, &qmsg);
  1555.  
  1556.     WinSendMsg(mainhwnd, WM_USER+2, NULL, NULL);
  1557.     WinDestroyMsgQueue(zhmq);
  1558.     WinTerminate(zhab);
  1559. }
  1560.  
  1561. /*
  1562.  * Thread to download the new version and start it up.
  1563.  */
  1564. void getupdate(void *param)
  1565. {
  1566.     if(strnicmp(sddurl[downloadsite], "ftp", 3)==0)
  1567.     {
  1568.         char site[256], *path = empty_string;
  1569.  
  1570.         if(strlen(sddurl[downloadsite]) > 6)
  1571.         {
  1572.             int z, len = strlen(&sddurl[downloadsite][6]);
  1573.             for(z = 6; z < len; z++)
  1574.             {
  1575.                 if(sddurl[downloadsite][z] == '/')
  1576.                 {
  1577.                     strncpy(site, &sddurl[downloadsite][6], z-6);
  1578.                     path = &sddurl[downloadsite][z];
  1579.                     z = len;
  1580.                 }
  1581.  
  1582.             }
  1583.             remove(sddfilename);
  1584.             if(!ftpget("ftp.scitechsoft.com", "anonymous", "install@scitechsoft.com", NULL, sddfilename, path, "w", T_BINARY))
  1585.                 error("Error downloading new version.");
  1586.             else {
  1587.                 spawnlp(P_NOWAIT, sddfilename, sddfilename, NULL);
  1588.                 exit(-1);
  1589.                 }
  1590.         }
  1591.         else
  1592.             error("Unable to determine path to file.");
  1593.     }
  1594. }
  1595.  
  1596. /*
  1597.  * Thread to download the status file and check the version.
  1598.  */
  1599. void checkforupdates(void *param)
  1600. {
  1601.     HAB xhab = 0;
  1602.     HMQ xhmq = 0;
  1603.     char *url = param;
  1604.  
  1605.     xhab = WinInitialize(0);
  1606.     xhmq = WinCreateMsgQueue(xhab, 0);
  1607.  
  1608.     settempdir();
  1609.     if(ftpget(url, "anonymous", "install@dbsoft-consulting.com", NULL, "install.ini", "/install.ini", "w", T_BINARY))
  1610.     {
  1611.         int savestate = installstate;
  1612.         error("Unable to connect to update server.  We cannot tell if you have the current version.");
  1613.         success=0;
  1614.         installstate=savestate;
  1615.     }
  1616.     else
  1617.     {
  1618.         FILE *f;
  1619.  
  1620.         if((f=fopen("install.ini", "r")) != NULL)
  1621.         {
  1622.             char raw[256], entry[256], entrydata[256], entrydata2[256];
  1623.  
  1624.             while(!feof(f))
  1625.             {
  1626.                 getparseline(f, '#', '=', '\"', raw, entry, entrydata, entrydata2);
  1627.                 if(stricmp(entry, "location1") == 0)
  1628.                     strcpy(sddurl[0], entrydata);
  1629.                 if(stricmp(entry, "location2") == 0)
  1630.                     strcpy(sddurl[1], entrydata);
  1631.                 if(stricmp(entry, "location3") == 0)
  1632.                     strcpy(sddurl[2], entrydata);
  1633.                 if(stricmp(entry, "location4") == 0)
  1634.                     strcpy(sddurl[3], entrydata);
  1635.                 if(stricmp(entry, "version") == 0)
  1636.                     strcpy(sddversion, entrydata);
  1637.                 if(stricmp(entry, "filename") == 0)
  1638.                     strcpy(sddfilename, entrydata);
  1639.                 if(stricmp(entry, "date") == 0)
  1640.                     strcpy(sdddate, entrydata);
  1641.             }
  1642.             fclose(f);
  1643.             if(strcmp(OS2_VER, sddversion) != 0)
  1644.             {
  1645.                 installstage++;
  1646.                 newerver = 1;
  1647.                 checking = 0;
  1648.                 checkerror = 0;
  1649.                 WinEnableWindow(WinWindowFromID(mainhwnd, I_Next), TRUE);
  1650.                 WinEnableWindow(WinWindowFromID(mainhwnd, I_Cancel), TRUE);
  1651.                 WinSendMsg(mainhwnd, WM_COMMAND, MPFROMSHORT(I_Next), NULL);
  1652.                 WinDestroyMsgQueue(xhmq);
  1653.                 WinTerminate(xhab);
  1654.                 _endthread();
  1655.             }
  1656.         }
  1657.         else
  1658.         {
  1659.             int savestate = installstate;
  1660.             error("Unable to connect to update server.  We cannot tell if you have the current version.");
  1661.             success=0;
  1662.             installstate=savestate;
  1663.         }
  1664.  
  1665.     }
  1666.  
  1667.     installstage+=3;
  1668.     WinEnableWindow(WinWindowFromID(mainhwnd, I_Next), TRUE);
  1669.     WinEnableWindow(WinWindowFromID(mainhwnd, I_Cancel), TRUE);
  1670.     WinSendMsg(mainhwnd, WM_COMMAND, MPFROMSHORT(I_Next), NULL);
  1671.  
  1672.     WinDestroyMsgQueue(xhmq);
  1673.     WinTerminate(xhab);
  1674.     newerver = 0;
  1675.     checking = 0;
  1676.     checkerror = 1;
  1677. }
  1678.  
  1679. /*
  1680.  * Main Window Procedure.  This code handles all the installers dialogs.
  1681.  */
  1682. MRESULT EXPENTRY DynamicWindowsFilter(HWND hWnd, ULONG msg, MPARAM mp1, MPARAM mp2)
  1683. {
  1684.     ULONG sliderpos = 0;
  1685.  
  1686.     switch ( msg )
  1687.     {
  1688.     /* Process control selections            */
  1689.     case    WM_CONTROL :
  1690.         {
  1691.             switch ( SHORT2FROMMP(mp1) )
  1692.             {
  1693.             case LN_SELECT:
  1694.                 if(SHORT1FROMMP(mp1) == WinQueryWindowUShort(hwndcombo, QWS_ID))
  1695.                 {
  1696.                     char tmpbuf[400];
  1697.                     int i = WinQueryLboxSelectedItem(hwndcombo);
  1698.  
  1699.                     browsedir[0] = ('A'+drivelist[i])-1;
  1700.                     populatedir(hwnddir);
  1701.                     strcpy(tmpbuf, browsedir);
  1702.                     if(tmpbuf[strlen(tmpbuf)-1] != '\\')
  1703.                         strcat(tmpbuf, "\\");
  1704.                     strcat(tmpbuf, &INSTALLER_PATH[3]);
  1705.                     WinSetWindowText(hwndentry, tmpbuf);
  1706.                 }
  1707.                 break;
  1708.             case CN_ENTER:
  1709.                 if(SHORT1FROMMP(mp1) == WinQueryWindowUShort(hwnddir, QWS_ID) && mp2)
  1710.                 {
  1711.                     PRECORDCORE current;
  1712.                     char tmpbuf[400];
  1713.  
  1714.                     current = ((PNOTIFYRECORDENTER)mp2)->pRecord;
  1715.  
  1716.                     if(strlen(current->pszIcon) > 7 && strncmp(current->pszIcon, "Drive ", 6) == 0)
  1717.                     {
  1718.                         sprintf(browsedir, "%c:\\", current->pszIcon[6]);
  1719.                     } else if(strcmp(current->pszIcon, "..") != 0)
  1720.                     {
  1721.                         if(browsedir[strlen(browsedir)-1] != '\\')
  1722.                             strcat(browsedir, "\\");
  1723.                         strcat(browsedir, current->pszIcon);
  1724.                     }
  1725.                     else
  1726.                     {
  1727.                         int i;
  1728.  
  1729.                         for(i=strlen(browsedir);i>0;i--)
  1730.                         {
  1731.                             if(browsedir[i] == '\\')
  1732.                             {
  1733.                                 browsedir[i] = 0;
  1734.                                 if(browsedir[1] == ':' && strlen(installdir2) == 2)
  1735.                                     strcat(browsedir, "\\");
  1736.                                 i=-1;
  1737.                             }
  1738.                         }
  1739.                     }
  1740.                     populatedir(hwnddir);
  1741.                     strcpy(tmpbuf, browsedir);
  1742.                     if(tmpbuf[strlen(tmpbuf)-1] != '\\')
  1743.                         strcat(tmpbuf, "\\");
  1744.                     strcat(tmpbuf, &INSTALLER_PATH[3]);
  1745.                     WinSetWindowText(hwndentry, tmpbuf);
  1746.                 }
  1747.                 break;
  1748.             }
  1749.         }
  1750.         break;
  1751.     case WM_COMMAND:
  1752.         {
  1753.             int b;
  1754.  
  1755.             for(b=0;b<COMMANDMAX;b++)
  1756.             {
  1757.                 if(rexxcommands[b].id &&
  1758.                    rexxcommands[b].id == COMMANDMSG(&msg)->cmd)
  1759.                 {
  1760.                     char tempbuf[50];
  1761.  
  1762.                     strcpy(tempbuf, rexxcommands[b].file);
  1763.                     grabfile(tempbuf);
  1764.                     rexx_run(tempbuf);
  1765.                     remove(tempbuf);
  1766.                     return (MRESULT)-1;
  1767.                 }
  1768.             }
  1769.         }
  1770.         break;
  1771.     case WM_USER:
  1772.         if(!no_update)
  1773.         {
  1774.             if(pixels==0)
  1775.                 pixels = SHORT2FROMMP(WinSendMsg(hwndper, SLM_QUERYSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), 0));
  1776.             if(files!=0)
  1777.                 sliderpos = (int)(((float)(current_file)/(float)files)*pixels);
  1778.             WinSendMsg(hwndper, SLM_SETSLIDERINFO, MPFROM2SHORT(SMA_SLIDERARMPOSITION,SMA_RANGEVALUE), MPFROMLONG(sliderpos-1));
  1779.         }
  1780.         break;
  1781.     case WM_USER+1:
  1782.         if(installstate == COMPLETED)
  1783.         {
  1784.             if(strlen(INSTALLER_PROGRAM) > 0 || strlen(INSTALLER_FOLDER) > 0 || strlen(INSTALLER_SHADOW) >0)
  1785.                 if((stricmp(INSTALLER_CONFIRM_WPS, "no") == 0) || (WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Do you wish to make WPS items on your desktop?", INSTALLER_TITLE, 0, MB_YESNO | MB_INFORMATION | MB_MOVEABLE | MB_SYSTEMMODAL)==MBID_YES))
  1786.                     create_wps_objects();
  1787.             if(strlen(INSTALLER_SETS) > 0 || strlen(INSTALLER_SYSVAR) > 0 || strlen(INSTALLER_SYSLINE) > 0)
  1788.                 if((stricmp(INSTALLER_CONFIRM_CONFIGSYS, "no") == 0) || (WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Do you wish to add the required entries to your CONFIG.SYS?", INSTALLER_TITLE, 0, MB_YESNO | MB_INFORMATION | MB_MOVEABLE | MB_SYSTEMMODAL)==MBID_YES))
  1789.                     configsys_update();
  1790.             grabfile(finishedscript);
  1791.             rexx_run(finishedscript);
  1792.             remove(finishedscript);
  1793.         }
  1794.         else
  1795.         {
  1796. #ifdef ENABLE_LOGGING
  1797.             if(WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, "Do you wish to delete the files that were already copied?", INSTALLER_TITLE, 0, MB_YESNO | MB_INFORMATION | MB_MOVEABLE | MB_SYSTEMMODAL)==MBID_YES)
  1798.             {
  1799.                 fprintf(logfile, "<Removed>\r\n<End>\r\n");
  1800.                 fclose(logfile);
  1801.                 delete_files();
  1802.                 current_file=0;
  1803.                 WinPostMsg(mainhwnd, WM_USER, 0, 0);
  1804.             }
  1805. #endif
  1806.             exit(1);
  1807.         }
  1808.         break;
  1809.     }
  1810.     return (MRESULT)-1;
  1811. }
  1812.  
  1813. /*
  1814.  * Main function
  1815.  */
  1816. int main(int argc, char *argv[])
  1817. {
  1818.     HMODULE hmod;
  1819.  
  1820.     /* Initialization */
  1821.     hab = WinInitialize(0);
  1822.     hmq = WinCreateMsgQueue(hab, 0);
  1823.  
  1824.     if((self = fopen(argv[0], "rb")) == NULL)
  1825.     {
  1826.         mesg("Could not open SFX archive for reading!");
  1827.         exit(1);
  1828.     }
  1829.     if(loadheader() == FALSE)
  1830.     {
  1831.         mesg("Could not load all required variables!");
  1832.         exit(3);
  1833.     }
  1834.     strcpy(installdir, INSTALLER_PATH);
  1835.  
  1836.     getbootdrive();
  1837.  
  1838.     if(DosLoadModule(NULL, 0, "FTPAPI", &hmod) == NO_ERROR)
  1839.     {
  1840.             if(DosQueryProcAddr(hmod, 0, "ftpget", (PFN *)&ftpget) == NO_ERROR)
  1841.                     ftpgetfound = 1;
  1842.             else
  1843.                     ftpgetfound = 0;
  1844.             DosFreeModule(hmod);
  1845.     }
  1846.  
  1847.     dw_init(FALSE);
  1848.     rexx_init();
  1849.  
  1850.     rexx_run("page1.cmd");
  1851.  
  1852.     dw_main(0L, DynamicWindowsFilter);
  1853.     /* Cleanup */
  1854.     rexx_deinit();
  1855.     WinDestroyMsgQueue(hmq);
  1856.     WinTerminate(hab);
  1857.     return 0;
  1858. }
  1859.