home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Apps / DevTools / SmartPackage / Sources / SmartInstaller / Controller.m < prev    next >
Encoding:
Text File  |  1994-04-18  |  5.4 KB  |  191 lines

  1.  
  2. /*
  3.  * Controller.m: the controlling object of the Smart Installer application.
  4.  *
  5.  * Copyright (C) 1994, Yves Arrouye <Yves.Arrouye@imag.fr>
  6.  *
  7.  */
  8.  
  9. /*
  10.  * The Smart Installer application and the Smart Package utility suite may be
  11.  * copied and distributed freely, as long as an acknowledgement of the author's
  12.  * work, with its name and address, is kept. The code may not be distributed if
  13.  * it has been modified. Modified code propositions should be directed to the
  14.  * author who will made them if necessary and redistribute the packages.
  15.  *
  16.  */
  17.  
  18. #import <string.h>
  19.  
  20. #import <sys/types.h>
  21. #import <sys/dir.h>
  22.  
  23. #import "Controller.h"
  24. #import "SmartInstaller.h"
  25.  
  26. @implementation Controller
  27.  
  28. enum exit_codes {
  29.     EXIT_OK,            // No error
  30.     
  31.     EXIT_USAGE,            // Bad usage
  32.     
  33.     EXIT_NO_ROOT,        // Not located on the root of the filesystem
  34.     EXIT_NO_PACKAGE,        // Cannot find a package
  35.     EXIT_NO_UNICITY,        // Multiple packages on disk
  36.     EXIT_NO_INSTALL,        // The user does not want to deo the install
  37.     EXIT_NO_FORK,        // Cannot fork
  38.     EXIT_NO_SHELL        // Cannot run in a shell
  39. };
  40.  
  41.  
  42. - installPackageAndExit:sender
  43. {
  44.     exit([installer installPackage]);
  45.     
  46.     return self;    // Oh sure...
  47. }
  48.  
  49. - (int)getPackage:(char*)name inDirectory:(const char*)where
  50. {
  51.     int count = 0;
  52.     DIR* dirp = opendir(where);
  53.  
  54.     if (dirp) {
  55.         struct direct* entry;
  56.     
  57.     while (entry = readdir(dirp)) {
  58.         if (!strcmp(entry->d_name + entry->d_namlen - 4, ".pkg")) {
  59.             if (!count) {
  60.             strcpy(name, entry->d_name);
  61.         }
  62.         ++count;
  63.         }
  64.     }
  65.     
  66.     closedir(dirp);
  67.     }
  68.     
  69.     return count;
  70. }
  71.  
  72. - appDidInit:sender
  73. {    
  74.     const char* from;        // Package directory
  75.     const char* to = "";    // Destination directory
  76.     
  77.     [NXApp deactivateSelf];
  78.     
  79.     // First, check the number of arguments that we got, and get them.
  80.     
  81.     if (NXArgc == 1) {
  82.         static char singleFromDir[MAXPATHLEN + 1];
  83.     const char* myDirectory = [[NXBundle mainBundle] directory];
  84.     char* cptr;
  85.     
  86.         strcpy(singleFromDir, myDirectory);
  87.     if ((cptr = strchr(singleFromDir + 1, '/')) &&
  88.         !strchr(cptr + 1, '/')) {
  89.         
  90.         int pkgCount;
  91.         
  92.         *cptr++ = '\0';
  93.         
  94.         // Now we have the name of the disk, look for a package
  95.         
  96.         pkgCount = [self getPackage:cptr inDirectory:singleFromDir];
  97.         
  98.         if (!pkgCount) {
  99.             NXRunLocalizedAlertPanel("Localizable", "No Package",
  100.             "Unable to find a package to install on the disk %s. Click Quit to terminate the application.",
  101.             "Quit", NULL, NULL, singleFromDir + 1);
  102.         exit(EXIT_NO_PACKAGE);
  103.         } else if (pkgCount != 1) {
  104.             NXRunLocalizedAlertPanel("Localizable", "Too Many Packages",
  105.             "There should be only one package on the disk %s. Click Quit to terminate the application.",
  106.             "Quit", NULL, NULL, singleFromDir + 1);
  107.         exit(EXIT_NO_UNICITY);
  108.         }
  109.         
  110.         cptr[-1] = '/';
  111.         from = singleFromDir;
  112.         
  113.         if (NXRunLocalizedAlertPanel("Localizable",
  114.             "Smart Installer",
  115.         "The %s package is about to be installed. While waiting for Installer to be launched, please be patient and insert disks as they are asked for. Now click Install to install the package (or click Quit to terminate).",
  116.         "Install", "Quit", NULL, cptr) != NX_ALERTDEFAULT) {
  117.         exit(EXIT_NO_INSTALL);
  118.         }
  119.         
  120.         // We must fork and re-launch ourselves after having copied the
  121.         // app in /tmp, otherwise we would not be able to eject a disk
  122.         // because we are on it...
  123.         
  124.         switch (fork()) {
  125.             case -1:
  126.             NXRunLocalizedAlertPanel("Localizable",
  127.             "Smart Installer",
  128.             "Cannot fork a process to do the package installation. Click Quit to terminate.",
  129.             "Quit", NULL, NULL);
  130.             exit(EXIT_NO_FORK);
  131.             break;
  132.         
  133.         case 0: {
  134.             char cmdLine[2048];
  135.             
  136.             sprintf(cmdLine, "(cd \"%s\"/..; /bin/tar cf - `/usr/bin/basename \"%s\"`) | (cd /tmp; tar xf -); /tmp/`/usr/bin/basename \"%s\"`/`/usr/bin/basename \"%s\" .app` \"%s\" \"%s\"",
  137.             from, myDirectory, myDirectory, myDirectory, from, to);
  138.             
  139.             if (execl("/bin/sh", "sh", "-c", cmdLine, 0) == -1) {
  140.             NXRunLocalizedAlertPanel("Localizable",
  141.                 "Smart Installer",
  142.                 "Cannot run a shell (/bin/sh) to do the installation. Click Quit to terminate.",
  143.                 "Quit", NULL, NULL);
  144.             exit(EXIT_NO_SHELL);
  145.             }
  146.             break;
  147.         }
  148.         
  149.         default:
  150.             exit(EXIT_OK);
  151.         }
  152.     } else {
  153.         NXRunLocalizedAlertPanel("Localizable", "Smart Installer",
  154.         "The application is not located where it expects to be (on the root of the disk file system). Please tell your vendor about that...",
  155.         "Quit", NULL, NULL);
  156.         exit(EXIT_NO_ROOT);
  157.     }
  158.     } else if (NXArgc != 3) {
  159.         NXRunLocalizedAlertPanel("Localizable", "Smart Installer",
  160.         "Bad number of arguments (got %d, expected 0 or 2). Please do not launch this application yourself unless it is supplied on the root of the disk file system.",
  161.         "Quit", NULL, NULL, NXArgc - 1);
  162.         
  163.     exit(EXIT_USAGE);
  164.  
  165. #ifdef SMART_CHECK_LOCATION
  166.  
  167.     } else if ([[installer class] isLocationRoot]) { 
  168.             NXRunLocalizedAlertPanel("Localizable", "Smart Installer",
  169.         "The application is not located where it expects to be (on the root of the disk file system). Please tell your vendor about that...",
  170.         "Quit", NULL, NULL);
  171.         exit(EXIT_NO_ROOT);
  172.         
  173. #endif
  174.  
  175.     } else {
  176.     from = NXArgv[1];
  177.     to = NXArgv[2];
  178.     }
  179.     
  180.     [installer setPackage:from andDestination:to];
  181.     
  182.     // Then install the package
  183.     
  184.     [self perform:@selector(installPackageAndExit:) with:self afterDelay:0
  185.         cancelPrevious:YES];
  186.     
  187.     return self;
  188. }
  189.  
  190. @end
  191.