www.pudn.com > CENVID.rar > INSTALL.CMM


/************************************************************************* 
 ***                            Install.cmm                            *** 
 *** This is the installation program to set up CEnvi unregistered     *** 
 *** shareware on your computer.  Before running this program, CEnvi   *** 
 *** must be copied to a hard disk directory.  This Install.cmm        *** 
 *** program is identical for DOS, OS/2, and Windows version of CEnvi  *** 
 *** and this program is itself an example for how to use CEnvi        *** 
 *************************************************************************/ 
 
 
main(argc,argv) 
{ 
   // There should be no input args.  If there are then the user needs help. 
   ScreenClear(); 
   if ( argc != 1 ) 
      GiveInstructionsAndExit(); 
 
   // Get the current directory.  The GetInstallDirectory() function assures 
   // that it is not a floppy. 
   InstallDirectory = GetInstallDirectory(argv[0]); 
 
   if defined( _DOS_ ) 
      DosOrOS2Install(InstallDirectory,"C:\\AUTOEXEC.BAT","C:\\AUTOEXEC.BAK"); 
   else if defined( _OS2_) 
      DosOrOS2Install(InstallDirectory,"C:\\CONFIG.SYS","C:\\CONFIG.BAK"); 
   else { 
      assert( defined(_WINDOWS_) ); 
      WindowsInstall(InstallDirectory); 
      printf("\nPress any key to exit..."); 
      getch(); 
   } 
   return(EXIT_SUCCESS); 
} 
 
 
GiveInstructionsAndExit()  // Show some info about using this program 
{                          // and then exit this program. Do not return. 
   printf("Install.cmm - CEnvi installation procedure.  Execute with no parameters\n"); 
   printf("              from the directory that contains CEnvi.exe and also contains\n"); 
   printf("              the *.cmm and other sample CEnvi files, including Install.cmm\n"); 
   if defined( _WINDOWS_ ) { 
      printf("\nPress any key to exit..."); 
      getch(); 
   } 
   exit(EXIT_FAILURE); 
} 
 
 
GetInstallDirectory(Executable)   // return current dir that is not on a floppy 
{ 
   // current source directory from the name of the executable 
   CurDir = SplitFileName(FullPath(Executable)).dir; 
   assert( CurDir != NULL  &&  CurDir[0] != 0 ); 
 
   // check that current directory is not floppy A: or B: 
   if ( CurDir[0] == 'A'  ||  CurDir[0] == 'B' ) { 
      printf("\nCannot install CEnvi from a floppy.\n\a\n"); 
      GiveInstructionsAndExit(); 
   } 
 
   // Have found the directory Install.cmm is in, and so check that 
   // CEnvi.exe is also in the same directory. 
   if ( NULL == Directory(strcat(strcpy(temp,CurDir),"CEnvi.exe")) ) { 
      printf("\nThis installation assumes that CEnvi.exe is in the same directory as\n"); 
      printf("Install.cmm.  Could not find CEnvi.exe in the Install.cmm directory.\n\a\n"); 
      GiveInstructionsAndExit(); 
   } 
 
   // remove extra backslash if at end of name (i.e., not root directory) 
   if ( strcmp(CurDir+1,":\\") ) 
      CurDir[strlen(CurDir)-1] = 0; 
 
   // return the result 
   return(CurDir); 
} 
 
 
Fatal(Format)  // like printf() but also beeps and exits program 
{ 
   va_start(parameters,Format); 
   printf("\a\n");  // beep 
   vprintf(Format,parameters); 
   exit(EXIT_FAILURE); 
} 
 
 
GetYesOrNo()   // prompt for Yes or No, and return entered boolean TRUE 
{              // if YES else FALSE if NO. 
   printf(" (Y/N) "); 
   while( TRUE ) { // forever 
      key = toupper(getch()); 
      if ( key != 'Y' && key != 'N' ) 
         printf("\a");  // beep 
      else 
         break; 
   } 
   printf("%c\n",key); 
   return( key == 'Y' ); 
} 
 
 
CopyFile(Source,Destination) // copy file from source to destination 
{ 
   // open source and destination files 
   src = fopen(Source,"rb"); 
   if ( src == NULL ) 
      Fatal("Could not open source file \"%s\" for reading.",Source); 
   dest = fopen(Destination,"wb"); 
   if ( dest == NULL ) 
      Fatal("Could not open file \"%s\" for writing.",Destination); 
 
   // read chunks from source, and copy to destination 
   #define  COPY_CHUNK_SIZE   500 
   while ( 0 != (size = fread(buf,COPY_CHUNK_SIZE,src)) ) { 
      fwrite(buf,size,dest); 
   } 
 
   // close the files 
   fclose(dest); 
   fclose(src); 
} 
 
 
SkipWhitespace(str) 
{ 
   while( isspace(str[0]) ) 
      str++; 
} 
 
 
AlreadyInPath(Dir,Path) // search through path for this Dir, return True if found, else False 
{ 
   len = strlen(Dir) 
   p = Path; 
   do { 
      if ( 0 == strnicmp(p,Dir,len)  && (p[len]==0 || p[len]==';') ) 
         return(True) 
      p = strchr(p,';') 
   } while( p++ != NULL ) 
   return(False) 
} 
 
 
AlterEVarLine(text,EVar,Dir) 
   // If this text is a line setting the EVar environment variable, and if 
   // Dir is not already in it, then add Dir.  Return TRUE if this is 
   // a line for EVar, and False if it is not. 
{ 
   FoundEVar = FALSE; // assume this is not the line 
   // determine if text is of the type "EVAR=" or "set EVAR=" 
   SkipWhitespace(c = text); 
   // if the next statement is "SET" then skip it 
   if ( !strncmpi(c,"SET",3) ) { 
      // Skip beyond the SET statement 
      c += 3; 
      SkipWhitespace(c); 
   } 
   // test if this next part is the variable name 
   EVarLen = strlen(EVar); 
   if ( !strncmpi(c,EVar,EVarLen) ) { 
      c += EVarLen; 
      if ( isspace(c[0])  ||  c[0] == '=' ) { 
         // THIS IS IT.  This line describes the EVar. 
         SkipWhitespace(c); 
         if ( c[0] == '=' ) { 
            c++; 
            SkipWhitespace(c); 
         } 
         FoundEVar = TRUE; 
         // If Dir is not already in this line then add Dir at the end. 
         // Check each dir as value between semicolons (;) 
         SkipWhitespace(c); 
         if ( !AlreadyInPath(Dir,c) ) { 
            // add this to the end of the existing path 
            if ( c[strlen(c)-1] != ';' ) 
               strcat(c,";"); 
            strcat(c,Dir); 
         } 
      } 
   } 
   return(FoundEVar); 
} 
 
DosOrOS2Install(Dir,FileName,BackupFileName) 
{ 
   // append the PATH statement so that it contains this directory, and 
   // also add the CMMPATH environment variable.  But give user a choice 
   // of whether to do this first; if they choose not to then tell them 
   // what they must do by hand. 
   printf("\nIf you choose, install will add the directory:\n\n"); 
   printf("    \"%s\"\n\n",Dir); 
   printf("to the PATH environment variable in your %s file.  Install will\n",FileName); 
   printf("also add this directory to the CMMPATH environment variable in that\n"); 
   printf("file.  If you select to make these changes to %s, then\n",FileName); 
   printf("install will backup the current version of %s to %s.\n",FileName,BackupFileName); 
   printf("\n\nShould these changes be made to %s?",FileName); 
   if ( GetYesOrNo() ) { 
      printf("Making changes to %s...",FileName); 
      // user chose to make automatic changes.  Do so now 
      CopyFile(FileName,BackupFileName); 
 
      // will now read the backup file, and if any PATH or CMMPATH line is 
      // encountered then will alter it, else just copy line exactly. 
      src = fopen(BackupFileName,"rt"); 
      if ( src == NULL ) 
         Fatal("Could not open source file \"%s\" for reading.",BackupFileName); 
      dest = fopen(FileName,"wt"); 
      if ( dest == NULL ) 
         Fatal("Could not open source file \"%s\" for reading.",BackupFileName); 
      SetPath = SetCmmPath = False; 
      while ( NULL != (line = fgets(src)) ) { 
         // remove the pesky newline if there is one 
         if ( PeskyNewLine = (line[strlen(line)-1] == '\n') ) 
            line[strlen(line)-1] = 0; 
         if ( AlterEVarLine(line,"PATH",Dir) ) 
            SetPath = True; 
         if ( AlterEVarLine(line,"CMMPATH",Dir) ) 
            SetCmmPath = True; 
         fputs(line,dest); 
         if ( PeskyNewLine ) 
            fputs("\n",dest); 
      } 
      fclose(src); 
      // if haven't already written PATH or CMMPATH, then do so now 
      if ( !SetPath ) 
         fprintf(dest,"\nSET PATH=%s\n",Dir); 
      if ( !SetCmmPath ) 
         fprintf(dest,"\nSET CMMPATH=%s\n",Dir); 
      fclose(dest); 
      printf("\n%s has been altered.\n",FileName); 
      printf("Changes will take effect after you reboot.\n"); 
   } else { 
      // user choose not to automatically install, so describe what the user 
      // needs to do by hand to make it work. 
      ScreenClear(); 
      printf("\nThe PATH environment variable is used to find executable files, such as\n"); 
      printf("CEnvi.exe, and batch files, such as those included in this CEnvi\n"); 
      printf("unregistered shareware release.  The CMMPATH environment variable is\n"); 
      printf("used by CEnvi to find common source code that may be included\n"); 
      printf("in other CEnvi source files.\n\n"); 
      printf("You chose not to have Install automatically alter %s.\n\n",FileName); 
      printf("You may wish to try Install.cmm again, or to make these modifications\n"); 
      printf("to %s by hand.\n",FileName); 
   } 
} 
 
 
WindowsInstall(Dir) 
{ 
   // If the user chooses, then add CMM Extensions and also add 
   // CMMPATH setting to WIN.INI. 
   printf("\nIf you choose, install will add the directory:\n\n"); 
   printf("    \"%s\"\n\n",Dir); 
   printf("as a CMMPATH profile string in you WIN.INI file.  Install will also\n"); 
   printf("also add the .CMM extension to WIN.INI so that you can execute any\n"); 
   printf("*.CMM file simply by double-clicking on it.\n"); 
   printf("\n\nShould these changes be made to WIN.INI?"); 
   if ( GetYesOrNo() ) { 
      printf("Making changes to WIN.INI..."); 
      // add extensions 
      sprintf(extension,"%s\\CENVI.EXE ^.CMM",Dir); 
      WriteProfileString("Extensions","CMM",extension); 
      // add CMMPATH 
      WriteProfileString("CEnvi","CMMPATH",Dir); 
      TellEveryoneThatWinIniHasChanged(); 
      printf("\n"); 
   } else { 
      // user choose not to automatically install, so describe what the user 
      // needs to do by hand to make it work. 
      ScreenClear(); 
      printf("The .CMM extension in WIN.INI would allow you to execute CMM code simply by\n"); 
      printf("double-clicking the file name.  The CMMPATH profile string allows CEnvi to\n"); 
      printf("find Cmm source code or code library that may be in a different directory.\n"); 
      printf("\n"); 
      printf("You chose not to have Install automatically alter WIN.INI\n"); 
      printf("\n"); 
      printf("You may wish to make these changes by hand; if so, then add the line:\n"); 
      printf("     CMM=%s\\CENVI.EXE ^.CMM\n",Dir); 
      printf("to the [Extensions] section of WIN.INI.  At the end of WIN.INI you may also\n"); 
      printf("want to add these lines:\n"); 
      printf("    [CEnvi]\n"); 
      printf("    CMMPATH=%s\n",Dir); 
   } 
} 
 
 
WriteProfileString(ApplicationName,KeyName,KeyValue) 
   // This is a wrapper for the WriteProfileString in the Windows Kernel. 
{ 
   DynamicLink("KERNEL","WRITEPROFILESTRING",SWORD16,PASCAL, 
               ApplicationName,KeyName,KeyValue); 
} 
 
 
TellEveryoneThatWinIniHasChanged() 
{ 
   #define HWND_BROADCAST  0xFFFF 
   #define WM_WININICHANGE 0x001A 
   DynamicLink("USER","SENDMESSAGE",SWORD16,PASCAL, 
               HWND_BROADCAST,WM_WININICHANGE,0,0,0); 
}