"Fossies" - the Fresh Open Source Software Archive

Member "epm-4.5.1/portable.c" (18 Nov 2020, 87047 Bytes) of package /linux/privat/epm-4.5.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "portable.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.5_vs_4.5.1.

    1 /*
    2  * Portable package gateway for the ESP Package Manager (EPM).
    3  *
    4  * Copyright 1999-2017 by Michael R Sweet
    5  * Copyright 1999-2010 by Easy Software Products.
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2, or (at your option)
   10  * any later version.
   11  *
   12  * This program is distributed in the hope that it will be useful,
   13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   15  * GNU General Public License for more details.
   16  */
   17 
   18 /*
   19  * Include necessary headers...
   20  */
   21 
   22 #include "epm.h"
   23 
   24 
   25 /*
   26  * Local functions...
   27  */
   28 
   29 static void clean_distfiles(const char *directory, const char *prodname,
   30                         const char *platname, dist_t *dist,
   31                 const char *subpackage);
   32 static int  write_combined(const char *title, const char *directory,
   33                        const char *prodname, const char *platname,
   34                    dist_t *dist, const char **files,
   35                    time_t deftime, const char *setup,
   36                    const char *types);
   37 static int  write_commands(dist_t *dist, FILE *fp, int type,
   38                        const char *subpackage);
   39 static FILE *write_common(dist_t *dist, const char *title,
   40                   int rootsize, int usrsize,
   41                       const char *filename, const char *subpackage);
   42 static int  write_confcheck(FILE *fp);
   43 static int  write_depends(const char *prodname, dist_t *dist, FILE *fp,
   44                       const char *subpackage);
   45 static int  write_distfiles(const char *directory, const char *prodname,
   46                         const char *platname, dist_t *dist,
   47                 time_t deftime, const char *subpackage);
   48 static int  write_install(dist_t *dist, const char *prodname,
   49                   int rootsize, int usrsize,
   50                       const char *directory,
   51                       const char *subpackage);
   52 static int  write_instfiles(tarf_t *tarfile, const char *directory,
   53                         const char *prodname, const char *platname,
   54                     const char **files, const char *destdir,
   55                 const char *subpackage);
   56 static int  write_patch(dist_t *dist, const char *prodname,
   57                 int rootsize, int usrsize,
   58                     const char *directory,
   59                     const char *subpackage);
   60 static int  write_remove(dist_t *dist, const char *prodname,
   61                  int rootsize, int usrsize,
   62                      const char *directory,
   63                      const char *subpackage);
   64 static int  write_space_checks(const char *prodname, FILE *fp,
   65                            const char *sw, const char *ss,
   66                    int rootsize, int usrsize);
   67 
   68 
   69 /*
   70  * 'make_portable()' - Make a portable software distribution package.
   71  */
   72 
   73 int                 /* O - 1 = success, 0 = fail */
   74 make_portable(const char     *prodname, /* I - Product short name */
   75               const char     *directory,/* I - Directory for distribution files */
   76               const char     *platname, /* I - Platform name */
   77               dist_t         *dist, /* I - Distribution information */
   78           struct utsname *platform, /* I - Platform information */
   79               const char     *setup,    /* I - Setup GUI image */
   80               const char     *types)    /* I - Setup GUI install types */
   81 {
   82   int       i;          /* Looping var */
   83   int       havepatchfiles;     /* 1 if we have patch files, 0 otherwise */
   84   time_t    deftime;        /* File creation time */
   85   file_t    *file;          /* Software file */
   86   static const char *distfiles[] =  /* Distribution files */
   87         {
   88           "install",
   89           "license",
   90           "readme",
   91           "remove",
   92           "ss",
   93           "sw",
   94           NULL
   95         };
   96   static const char *patchfiles[] = /* Patch files */
   97         {
   98           "patch",
   99           "license",
  100           "pss",
  101           "psw",
  102           "readme",
  103           "remove",
  104           NULL
  105         };
  106 
  107 
  108   REF(platform);
  109 
  110   if (Verbosity)
  111     puts("Creating PORTABLE distribution...");
  112 
  113  /*
  114   * See if we need to make a patch distribution...
  115   */
  116 
  117   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
  118     if (isupper((int)file->type))
  119       break;
  120 
  121   havepatchfiles = i > 0;
  122 
  123   deftime = time(NULL);
  124 
  125  /*
  126   * Build the main package and all of the subpackages...
  127   */
  128 
  129   if (write_distfiles(directory, prodname, platname, dist, deftime, NULL))
  130     return (1);
  131 
  132   for (i = 0; i < dist->num_subpackages; i ++)
  133     if (write_distfiles(directory, prodname, platname, dist, deftime,
  134                         dist->subpackages[i]))
  135       return (1);
  136 
  137  /*
  138   * Create the distribution archives...
  139   */
  140 
  141   if (write_combined("distribution", directory, prodname, platname, dist,
  142                      distfiles, deftime, setup, types))
  143     return (1);
  144 
  145   if (havepatchfiles)
  146     if (write_combined("patch", directory, prodname, platname, dist,
  147                        patchfiles, deftime, setup, types))
  148       return (1);
  149 
  150  /*
  151   * Cleanup...
  152   */
  153 
  154   if (!KeepFiles)
  155   {
  156     clean_distfiles(directory, prodname, platname, dist, NULL);
  157 
  158     for (i = 0; i < dist->num_subpackages; i ++)
  159       clean_distfiles(directory, prodname, platname, dist,
  160                       dist->subpackages[i]);
  161   }
  162 
  163  /*
  164   * Return!
  165   */
  166 
  167   return (0);
  168 }
  169 
  170 
  171 /*
  172  * 'clean_distfiles()' - Remove temporary software distribution files...
  173  */
  174 
  175 static void
  176 clean_distfiles(const char *directory,  /* I - Directory */
  177             const char *prodname,   /* I - Product name */
  178                 const char *platname,   /* I - Platform name */
  179             dist_t     *dist,   /* I - Distribution */
  180             const char *subpackage) /* I - Subpackage */
  181 {
  182   char      prodfull[255],      /* Full name of product */
  183         filename[1024];     /* Name of temporary file */
  184 
  185 
  186  /*
  187   * Figure out the full name of the distribution...
  188   */
  189 
  190   if (subpackage)
  191     snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
  192   else
  193     strlcpy(prodfull, prodname, sizeof(prodfull));
  194 
  195  /*
  196   * Remove the distribution files...
  197   */
  198 
  199   if (Verbosity)
  200     printf("Removing %s temporary files...\n", prodfull);
  201 
  202   snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull);
  203   unlink(filename);
  204 
  205   snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull);
  206   unlink(filename);
  207 
  208   snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull);
  209   unlink(filename);
  210 
  211   snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull);
  212   unlink(filename);
  213 
  214   snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull);
  215   unlink(filename);
  216 
  217   snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull);
  218   unlink(filename);
  219 
  220   snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull);
  221   unlink(filename);
  222 
  223   snprintf(filename, sizeof(filename), "%s/%s.ss", directory, prodfull);
  224   unlink(filename);
  225 
  226   snprintf(filename, sizeof(filename), "%s/%s.sw", directory, prodfull);
  227   unlink(filename);
  228 }
  229 
  230 
  231 /*
  232  * 'write_combined()' - Write all of the distribution files in tar files.
  233  */
  234 
  235 static int              /* O - 0 on success, -1 on failure */
  236 write_combined(const char *title,   /* I - Title */
  237                const char *directory,   /* I - Output directory */
  238            const char *prodname,    /* I - Base product name */
  239            const char *platname,    /* I - Platform name */
  240            dist_t     *dist,    /* I - Distribution */
  241            const char **files,  /* I - Files */
  242            time_t     deftime,  /* I - Default timestamp */
  243            const char *setup,   /* I - Setup program */
  244            const char *types)   /* I - Setup types file */
  245 {
  246   int       i;          /* Looping var */
  247   tarf_t    *tarfile;       /* Distribution tar file */
  248   char      tarfilename[1024],  /* Name of tar file */
  249         filename[1024];     /* Name of temporary file */
  250 #ifdef __APPLE__
  251   FILE      *fp;            /* Plist file... */
  252 #endif /* __APPLE__ */
  253   struct stat   srcstat;        /* Source file information */
  254   const char    *destdir;       /* Destination directory */
  255   const char    *setup_img;     /* Setup image name */
  256 
  257 
  258  /*
  259   * Figure out the filename...
  260   */
  261 
  262   if (dist->release[0])
  263     snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s-%s", directory,
  264              prodname, dist->version, dist->release);
  265   else
  266     snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s", directory, prodname,
  267              dist->version);
  268 
  269   if (!strcmp(title, "patch"))
  270     strlcat(tarfilename, "-patch", sizeof(tarfilename));
  271 
  272   if (platname[0])
  273   {
  274     strlcat(tarfilename, "-", sizeof(tarfilename));
  275     strlcat(tarfilename, platname, sizeof(tarfilename));
  276   }
  277 
  278   strlcat(tarfilename, ".tar.gz", sizeof(tarfilename));
  279 
  280  /*
  281   * Open output file...
  282   */
  283 
  284   if ((tarfile = tar_open(tarfilename, 1)) == NULL)
  285   {
  286     fprintf(stderr, "epm: Unable to create output pipe to gzip -\n     %s\n",
  287             strerror(errno));
  288     return (-1);
  289   }
  290 
  291   if (Verbosity)
  292     printf("Writing %s archive:\n", title);
  293 
  294 #ifdef __APPLE__
  295   if (setup)
  296   {
  297    /*
  298     * Create directories for the setup application...
  299     */
  300 
  301     if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
  302                    "Install.app", NULL) < 0)
  303     {
  304       tar_close(tarfile);
  305       return (-1);
  306     }
  307 
  308     if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
  309                    "Install.app/Contents", NULL) < 0)
  310     {
  311       tar_close(tarfile);
  312       return (-1);
  313     }
  314 
  315     if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
  316                    "Install.app/Contents/MacOS", NULL) < 0)
  317     {
  318       tar_close(tarfile);
  319       return (-1);
  320     }
  321 
  322     if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root",
  323                    "Install.app/Contents/Resources", NULL) < 0)
  324     {
  325       tar_close(tarfile);
  326       return (-1);
  327     }
  328 
  329    /*
  330     * Then copy the data files...
  331     */
  332 
  333     snprintf(filename, sizeof(filename), "%s/default.icns", DataDir);
  334     stat(filename, &srcstat);
  335 
  336     if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
  337                    srcstat.st_size, srcstat.st_mtime, "root", "root",
  338            "Install.app/Contents/Resources/setup.icns", NULL) < 0)
  339     {
  340       tar_close(tarfile);
  341       return (-1);
  342     }
  343 
  344     if (tar_file(tarfile, filename) < 0)
  345     {
  346       tar_close(tarfile);
  347       return (-1);
  348     }
  349 
  350     if (Verbosity)
  351       printf("    %7.0fk setup.icns\n", (srcstat.st_size + 1023) / 1024.0);
  352 
  353     snprintf(filename, sizeof(filename), "%s/%s.setup.plist", directory,
  354              prodname);
  355     if ((fp = fopen(filename, "w")) == NULL)
  356     {
  357       fprintf(stderr, "epm: Error writing %s -\n    %s\n", filename,
  358               strerror(errno));
  359       tar_close(tarfile);
  360       return (-1);
  361     }
  362 
  363     fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  364         "<plist version=\"0.9\">\n"
  365         "    <dict>\n"
  366         "   <key>CFBundleInfoDictionaryVersion</key>\n"
  367         "   <string>6.0</string>\n"
  368         "   <key>CFBundleExecutable</key>\n"
  369         "   <string>setup</string>\n"
  370         "   <key>CFBundleIdentifier</key>\n"
  371         "   <string>org.msweet.epmsetup</string>\n"
  372         "   <key>CFBundleVersion</key>\n"
  373         "   <string>%s</string>\n"
  374         "   <key>CFBundleDevelopmentRegion</key>\n"
  375         "   <string>English</string>\n"
  376         "   <key>NSHumanReadableCopyright</key>\n"
  377         "   <string>Copyright %s</string>\n"
  378         "   <key>CFAppleHelpAnchor</key>\n"
  379         "   <string>help</string>\n"
  380         "   <key>CFBundleName</key>\n"
  381         "   <string>Installer for %s</string>\n"
  382         "   <key>CFBundlePackageType</key>\n"
  383         "   <string>APPL</string>\n"
  384         "   <key>CFBundleSignature</key>\n"
  385         "   <string>FLTK</string>\n"
  386         "   <key>CFBundleIconFile</key>\n"
  387         "   <string>setup.icns</string>\n"
  388         "   <key>CFBundleShortVersionString</key>\n"
  389         "   <string>%s</string>\n"
  390         "   <key>CFBundleGetInfoString</key>\n"
  391         "   <string>%s, Copyright %s</string>\n"
  392         "    </dict>\n"
  393         "</plist>\n",
  394             dist->version,
  395         dist->copyright,
  396         dist->product,
  397         dist->version,
  398         dist->version, dist->copyright);
  399     fclose(fp);
  400 
  401     stat(filename, &srcstat);
  402 
  403     if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
  404                    srcstat.st_size, srcstat.st_mtime, "root", "root",
  405            "Install.app/Contents/Info.plist", NULL) < 0)
  406     {
  407       tar_close(tarfile);
  408       return (-1);
  409     }
  410 
  411     if (tar_file(tarfile, filename) < 0)
  412     {
  413       tar_close(tarfile);
  414       return (-1);
  415     }
  416 
  417     if (!KeepFiles)
  418       unlink(filename);
  419 
  420     if (Verbosity)
  421       printf("    %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0);
  422   }
  423 
  424   destdir = "Install.app/Contents/Resources/";
  425 
  426 #else /* !__APPLE__ */
  427   destdir = "";
  428 #endif /* __APPLE__ */
  429 
  430  /*
  431   * Write installer files...
  432   */
  433 
  434   if (write_instfiles(tarfile, directory, prodname, platname, files, destdir,
  435                       NULL))
  436   {
  437     tar_close(tarfile);
  438     return (-1);
  439   }
  440 
  441   for (i = 0; i < dist->num_subpackages; i ++)
  442     if (write_instfiles(tarfile, directory, prodname, platname, files, destdir,
  443                     dist->subpackages[i]))
  444     {
  445       tar_close(tarfile);
  446       return (-1);
  447     }
  448 
  449  /*
  450   * Now the setup files...
  451   */
  452 
  453   if (setup)
  454   {
  455    /*
  456     * Include the ESP Software Installation Wizard (setup)...
  457     */
  458 
  459     if (stat(SetupProgram, &srcstat))
  460     {
  461       fprintf(stderr, "epm: Unable to stat GUI setup program %s: %s\n", SetupProgram, strerror(errno));
  462       tar_close(tarfile);
  463       return (-1);
  464     }
  465 
  466 #ifdef __APPLE__
  467     if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
  468                srcstat.st_mtime, "root", "root",
  469            "Install.app/Contents/MacOS/setup", NULL) < 0)
  470 #else
  471     if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
  472                srcstat.st_mtime, "root", "root", "setup", NULL) < 0)
  473 #endif /* __APPLE__ */
  474     {
  475       tar_close(tarfile);
  476       return (-1);
  477     }
  478 
  479     if (tar_file(tarfile, SetupProgram) < 0)
  480     {
  481       tar_close(tarfile);
  482       return (-1);
  483     }
  484 
  485     if (Verbosity)
  486       printf("    %7.0fk setup\n", (srcstat.st_size + 1023) / 1024.0);
  487 
  488    /*
  489     * And the image file...
  490     */
  491 
  492     stat(setup, &srcstat);
  493 
  494     if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".gif"))
  495       setup_img = "setup.gif";
  496     else if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".jpg"))
  497       setup_img = "setup.jpg";
  498     else if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".png"))
  499       setup_img = "setup.png";
  500     else
  501       setup_img = "setup.xpm";
  502 
  503     snprintf(filename, sizeof(filename), "%s%s", destdir, setup_img);
  504 
  505     if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size,
  506                srcstat.st_mtime, "root", "root", filename, NULL) < 0)
  507     {
  508       tar_close(tarfile);
  509       return (-1);
  510     }
  511 
  512     if (tar_file(tarfile, setup) < 0)
  513     {
  514       tar_close(tarfile);
  515       return (-1);
  516     }
  517 
  518     if (Verbosity)
  519       printf("    %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img);
  520 
  521    /*
  522     * And the types file...
  523     */
  524 
  525     if (types)
  526     {
  527       stat(types, &srcstat);
  528       snprintf(filename, sizeof(filename), "%ssetup.types", destdir);
  529 
  530       if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size,
  531              srcstat.st_mtime, "root", "root", filename, NULL) < 0)
  532       {
  533         tar_close(tarfile);
  534     return (-1);
  535       }
  536 
  537       if (tar_file(tarfile, types) < 0)
  538       {
  539         tar_close(tarfile);
  540     return (-1);
  541       }
  542 
  543       if (Verbosity)
  544         printf("    %7.0fk setup.types\n", (srcstat.st_size + 1023) / 1024.0);
  545     }
  546 
  547    /*
  548     * And finally the uninstall stuff...
  549     */
  550 
  551 #ifdef __APPLE__
  552     if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
  553                    "Uninstall.app", NULL) < 0)
  554     {
  555       tar_close(tarfile);
  556       return (-1);
  557     }
  558 
  559     if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
  560                    "Uninstall.app/Contents", NULL) < 0)
  561     {
  562       tar_close(tarfile);
  563       return (-1);
  564     }
  565 
  566     if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
  567                    "Uninstall.app/Contents/MacOS", NULL) < 0)
  568     {
  569       tar_close(tarfile);
  570       return (-1);
  571     }
  572 
  573     if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root",
  574                    "Uninstall.app/Contents/Resources", NULL) < 0)
  575     {
  576       tar_close(tarfile);
  577       return (-1);
  578     }
  579 
  580    /*
  581     * Then copy the data files...
  582     */
  583 
  584     snprintf(filename, sizeof(filename), "%s/default.icns", DataDir);
  585     stat(filename, &srcstat);
  586 
  587     if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
  588                    srcstat.st_size, srcstat.st_mtime, "root", "root",
  589            "Uninstall.app/Contents/Resources/uninst.icns", NULL) < 0)
  590     {
  591       tar_close(tarfile);
  592       return (-1);
  593     }
  594 
  595     if (tar_file(tarfile, filename) < 0)
  596     {
  597       tar_close(tarfile);
  598       return (-1);
  599     }
  600 
  601     if (Verbosity)
  602       printf("    %7.0fk uninst.icns\n", (srcstat.st_size + 1023) / 1024.0);
  603 
  604     snprintf(filename, sizeof(filename), "%s/%s.uninst.plist", directory,
  605              prodname);
  606     if ((fp = fopen(filename, "w")) == NULL)
  607     {
  608       fprintf(stderr, "epm: Error writing %s -\n    %s\n", filename,
  609               strerror(errno));
  610       tar_close(tarfile);
  611       return (-1);
  612     }
  613 
  614     fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
  615         "<plist version=\"0.9\">\n"
  616         "    <dict>\n"
  617         "   <key>CFBundleInfoDictionaryVersion</key>\n"
  618         "   <string>6.0</string>\n"
  619         "   <key>CFBundleExecutable</key>\n"
  620         "   <string>uninst</string>\n"
  621         "   <key>CFBundleIdentifier</key>\n"
  622         "   <string>org.msweet.epmuninst</string>\n"
  623         "   <key>CFBundleVersion</key>\n"
  624         "   <string>%s</string>\n"
  625         "   <key>CFBundleDevelopmentRegion</key>\n"
  626         "   <string>English</string>\n"
  627         "   <key>NSHumanReadableCopyright</key>\n"
  628         "   <string>Copyright %s</string>\n"
  629         "   <key>CFAppleHelpAnchor</key>\n"
  630         "   <string>help</string>\n"
  631         "   <key>CFBundleName</key>\n"
  632         "   <string>Uninstaller for %s</string>\n"
  633         "   <key>CFBundlePackageType</key>\n"
  634         "   <string>APPL</string>\n"
  635         "   <key>CFBundleSignature</key>\n"
  636         "   <string>FLTK</string>\n"
  637         "   <key>CFBundleIconFile</key>\n"
  638         "   <string>uninst.icns</string>\n"
  639         "   <key>CFBundleShortVersionString</key>\n"
  640         "   <string>%s</string>\n"
  641         "   <key>CFBundleGetInfoString</key>\n"
  642         "   <string>%s, Copyright %s</string>\n"
  643         "    </dict>\n"
  644         "</plist>\n",
  645             dist->version,
  646         dist->copyright,
  647         dist->product,
  648         dist->version,
  649         dist->version, dist->copyright);
  650     fclose(fp);
  651 
  652     stat(filename, &srcstat);
  653 
  654     if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222),
  655                    srcstat.st_size, srcstat.st_mtime, "root", "root",
  656            "Uninstall.app/Contents/Info.plist", NULL) < 0)
  657     {
  658       tar_close(tarfile);
  659       return (-1);
  660     }
  661 
  662     if (tar_file(tarfile, filename) < 0)
  663     {
  664       tar_close(tarfile);
  665       return (-1);
  666     }
  667 
  668     if (!KeepFiles)
  669       unlink(filename);
  670 
  671     if (Verbosity)
  672       printf("    %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0);
  673 #endif /* __APPLE__ */
  674 
  675    /*
  676     * Include the ESP Software Removal Wizard (uninst)...
  677     */
  678 
  679     if (stat(UninstProgram, &srcstat))
  680     {
  681       fprintf(stderr, "epm: Unable to stat GUI uninstall program %s: %s\n", UninstProgram, strerror(errno));
  682       tar_close(tarfile);
  683       return (-1);
  684     }
  685 
  686 #ifdef __APPLE__
  687     if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
  688                srcstat.st_mtime, "root", "root",
  689            "Uninstall.app/Contents/MacOS/uninst", NULL) < 0)
  690 #else
  691     if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size,
  692                srcstat.st_mtime, "root", "root", "uninst", NULL) < 0)
  693 #endif /* __APPLE__ */
  694     {
  695       tar_close(tarfile);
  696       return (-1);
  697     }
  698 
  699     if (tar_file(tarfile, UninstProgram) < 0)
  700     {
  701       tar_close(tarfile);
  702       return (-1);
  703     }
  704 
  705     if (Verbosity)
  706       printf("    %7.0fk uninst\n", (srcstat.st_size + 1023) / 1024.0);
  707 
  708 #ifdef __APPLE__
  709    /*
  710     * And the image file...
  711     */
  712 
  713     stat(setup, &srcstat);
  714 
  715     snprintf(filename, sizeof(filename), "Uninstall.app/Contents/Resources/%s",
  716              setup_img);
  717 
  718     if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size,
  719                srcstat.st_mtime, "root", "root", filename, NULL) < 0)
  720     {
  721       tar_close(tarfile);
  722       return (-1);
  723     }
  724 
  725     if (tar_file(tarfile, setup) < 0)
  726     {
  727       tar_close(tarfile);
  728       return (-1);
  729     }
  730 
  731     if (Verbosity)
  732       printf("    %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img);
  733 #endif /* __APPLE__ */
  734   }
  735 
  736   if (Verbosity)
  737   {
  738     puts("     ------- ----------------------------------------");
  739     printf("    %7.0fk %s-%s", tarfile->blocks * 0.5f, prodname, dist->version);
  740     if (dist->release[0])
  741       printf("-%s", dist->release);
  742     if (!strcmp(title, "patch"))
  743       fputs("-patch", stdout);
  744     if (platname[0])
  745       printf("-%s", platname);
  746     puts(".tar");
  747   }
  748 
  749   tar_close(tarfile);
  750 
  751   if (Verbosity)
  752   {
  753     stat(tarfilename, &srcstat);
  754 
  755     puts("     ------- ----------------------------------------");
  756     printf("    %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0,
  757            tarfilename);
  758   }
  759 
  760 #ifdef __APPLE__
  761   {
  762     char    dmgfilename[1024];  /* Disk image filename */
  763 
  764 
  765    /*
  766     * Make a disk image containing the package files...
  767     */
  768 
  769     if (dist->release[0])
  770       snprintf(filename, sizeof(filename), "%s/%s-%s-%s", directory, prodname,
  771            dist->version, dist->release);
  772     else
  773       snprintf(filename, sizeof(filename), "%s/%s-%s", directory, prodname,
  774            dist->version);
  775 
  776     if (!strcmp(title, "patch"))
  777       strlcat(filename, "-patch", sizeof(filename));
  778 
  779     if (platname[0])
  780     {
  781       strlcat(filename, "-", sizeof(filename));
  782       strlcat(filename, platname, sizeof(filename));
  783     }
  784 
  785     snprintf(dmgfilename, sizeof(dmgfilename), "%s.dmg", filename);
  786 
  787     mkdir(filename, 0777);
  788 
  789     if (run_command(filename, "tar xvzf ../%s", strrchr(tarfilename, '/') + 1))
  790     {
  791       fputs("epm: Unable to create disk image template folder!\n", stderr);
  792       return (1);
  793     }
  794 
  795     if (run_command(NULL, "hdiutil create -ov -srcfolder %s %s",
  796             filename, dmgfilename))
  797     {
  798       fputs("epm: Unable to create disk image!\n", stderr);
  799       return (1);
  800     }
  801 
  802     if (!KeepFiles)
  803       unlink_directory(filename);
  804 
  805     if (Verbosity)
  806     {
  807       stat(dmgfilename, &srcstat);
  808 
  809       printf("    %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0,
  810          dmgfilename);
  811     }
  812   }
  813 #endif /* __APPLE__ */
  814 
  815   return (0);
  816 }
  817 
  818 
  819 /*
  820  * 'write_commands()' - Write commands.
  821  */
  822 
  823 static int              /* O - 0 on success, -1 on failure */
  824 write_commands(dist_t     *dist,    /* I - Distribution */
  825                FILE       *fp,      /* I - File pointer */
  826                int        type,     /* I - Type of commands to write */
  827                const char *subpackage)  /* I - Subsystem */
  828 {
  829   int           i;      /* Looping var */
  830   command_t     *c;     /* Current command */
  831   static const char *commands[] =   /* Command strings */
  832             {
  833               "pre-install",
  834               "post-install",
  835               "pre-patch",
  836               "post-patch",
  837               "pre-remove",
  838               "post-remove"
  839             };
  840 
  841 
  842   for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++)
  843     if (c->type == type && c->subpackage == subpackage)
  844       break;
  845 
  846   if (i)
  847   {
  848     fprintf(fp, "echo Running %s commands...\n", commands[type]);
  849 
  850     for (; i > 0; i --, c ++)
  851       if (c->type == type && c->subpackage == subpackage)
  852         if (fprintf(fp, "%s\n", c->command) < 1)
  853         {
  854           perror("epm: Error writing command");
  855           return (-1);
  856         }
  857   }
  858 
  859   return (0);
  860 }
  861 
  862 
  863 /*
  864  * 'write_common()' - Write the common shell script header.
  865  */
  866 
  867 static FILE *               /* O - File pointer */
  868 write_common(dist_t     *dist,      /* I - Distribution */
  869              const char *title,     /* I - "Installation", etc... */
  870              int        rootsize,   /* I - Size of root files in kbytes */
  871          int        usrsize,    /* I - Size of /usr files in kbytes */
  872              const char *filename,  /* I - Script to create */
  873          const char *subpackage)    /* I - Subpackage name */
  874 {
  875   int   i;              /* Looping var */
  876   FILE  *fp;                /* File pointer */
  877   char  line[1024],         /* Line buffer */
  878     *start,             /* Start of line */
  879     *ptr;               /* Pointer into line */
  880 
  881 
  882  /*
  883   * Remove any existing copy of the file...
  884   */
  885 
  886   unlink(filename);
  887 
  888  /*
  889   * Create the script file...
  890   */
  891 
  892   if ((fp = fopen(filename, "w")) == NULL)
  893     return (NULL);
  894 
  895  /*
  896   * Update the permissions on the file...
  897   */
  898 
  899   fchmod(fileno(fp), 0755);
  900 
  901  /*
  902   * Write the standard header...
  903   */
  904 
  905   fputs("#!/bin/sh\n", fp);
  906   fprintf(fp, "# %s script for %s version %s.\n", title,
  907           dist->product, dist->version);
  908   fputs("# Produced using " EPM_VERSION " (https://michaelrsweet.github.io/epm).\n", fp);
  909   fprintf(fp, "#%%product %s", dist->product);
  910   if (subpackage)
  911   {
  912     for (i = 0; i < dist->num_descriptions; i ++)
  913       if (dist->descriptions[i].subpackage == subpackage)
  914     break;
  915 
  916     if (i < dist->num_descriptions)
  917     {
  918       strlcpy(line, dist->descriptions[i].description, sizeof(line));
  919       if ((ptr = strchr(line, '\n')) != NULL)
  920         *ptr = '\0';
  921 
  922       fprintf(fp, " - %s", line);
  923     }
  924   }
  925   fputs("\n", fp);
  926   fprintf(fp, "#%%vendor %s\n", dist->vendor);
  927   fprintf(fp, "#%%copyright %s\n", dist->copyright);
  928   fprintf(fp, "#%%version %s %d\n", dist->version, dist->vernumber);
  929 
  930   for (i = 0; i < dist->num_descriptions; i ++)
  931     if (dist->descriptions[i].subpackage == subpackage)
  932       break;
  933 
  934   if (i < dist->num_descriptions)
  935   {
  936    /*
  937     * Just do descriptions for this subpackage...
  938     */
  939 
  940     for (; i < dist->num_descriptions; i ++)
  941       if (dist->descriptions[i].subpackage == subpackage)
  942       {
  943         strlcpy(line, dist->descriptions[i].description, sizeof(line));
  944 
  945         for (start = line; start; start = ptr)
  946     {
  947       if ((ptr = strchr(start, '\n')) != NULL)
  948             *ptr++ = '\0';
  949 
  950       fprintf(fp, "#%%description %s\n", start);
  951     }
  952       }
  953   }
  954   else
  955   {
  956    /*
  957     * Just do descriptions for the main package...
  958     */
  959 
  960     for (i = 0; i < dist->num_descriptions; i ++)
  961       if (dist->descriptions[i].subpackage == NULL)
  962       {
  963         strlcpy(line, dist->descriptions[i].description, sizeof(line));
  964 
  965         for (start = line; start; start = ptr)
  966     {
  967       if ((ptr = strchr(start, '\n')) != NULL)
  968             *ptr++ = '\0';
  969 
  970       fprintf(fp, "#%%description %s\n", start);
  971     }
  972       }
  973   }
  974 
  975   fprintf(fp, "#%%rootsize %d\n", rootsize);
  976   fprintf(fp, "#%%usrsize %d\n", usrsize);
  977   fputs("#\n", fp);
  978 
  979   fputs("PATH=/usr/gnu/bin:/usr/xpg4/bin:/bin:/usr/bin:/usr/ucb:${PATH}\n", fp);
  980   fputs("SHELL=/bin/sh\n", fp);
  981   fputs("case \"`uname`\" in\n", fp);
  982   fputs("\tDarwin*)\n", fp);
  983   fputs("\tcase \"`id -un`\" in\n", fp);
  984   fputs("\t\troot)\n", fp);
  985   fputs("\t\t;;\n", fp);
  986   fputs("\t\t*)\n", fp);
  987   fprintf(fp, "\t\techo Sorry, you must have administrative priviledges to %s this software.\n",
  988           title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch");
  989   fputs("\t\texit 1\n", fp);
  990   fputs("\t\t;;\n", fp);
  991   fputs("\tesac\n", fp);
  992   fputs("\t;;\n", fp);
  993   fputs("\t*)\n", fp);
  994   fputs("\tcase \"`id`\" in\n", fp);
  995   fputs("\t\tuid=0*)\n", fp);
  996   fputs("\t\t;;\n", fp);
  997   fputs("\t\t*)\n", fp);
  998   fprintf(fp, "\t\techo Sorry, you must be root to %s this software.\n",
  999           title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch");
 1000   fputs("\t\texit 1\n", fp);
 1001   fputs("\t\t;;\n", fp);
 1002   fputs("\tesac\n", fp);
 1003   fputs("\t;;\n", fp);
 1004   fputs("esac\n", fp);
 1005 
 1006   qprintf(fp, "echo Copyright %s\n", dist->copyright);
 1007   fprintf(fp, "# Reset umask for %s...\n",
 1008           title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch");
 1009   fputs("umask 002\n", fp);
 1010 
 1011   write_confcheck(fp);
 1012 
 1013  /*
 1014   * Return the file pointer...
 1015   */
 1016 
 1017   return (fp);
 1018 }
 1019 
 1020 
 1021 /*
 1022  * 'write_confcheck()' - Write the echo check to find the right echo options.
 1023  */
 1024 
 1025 static int              /* O - -1 on error, 0 on success */
 1026 write_confcheck(FILE *fp)       /* I - Script file */
 1027 {
 1028  /*
 1029   * This is a simplified version of the autoconf test for echo; basically
 1030   * we ignore the Stardent Vistra SVR4 case, since 1) we've never heard of
 1031   * this OS, and 2) it doesn't provide the same functionality, specifically
 1032   * the omission of a newline when prompting the user for some text.
 1033   */
 1034 
 1035   fputs("# Determine correct echo options...\n", fp);
 1036   fputs("if (echo \"testing\\c\"; echo 1,2,3) | grep c >/dev/null; then\n", fp);
 1037   fputs("   ac_n=-n\n", fp);
 1038   fputs("   ac_c=\n", fp);
 1039   fputs("else\n", fp);
 1040   fputs("   ac_n=\n", fp);
 1041   fputs("   ac_c='\\c'\n", fp);
 1042   fputs("fi\n", fp);
 1043 
 1044  /*
 1045   * This is a check for the correct options to use with the "tar"
 1046   * command.
 1047   */
 1048 
 1049   fputs("# Determine correct extract options for the tar command...\n", fp);
 1050   fputs("if test `uname` = Darwin; then\n", fp);
 1051   fputs("   ac_tar=\"tar -xpPf\"\n", fp);
 1052   fputs("elif test \"`tar --help 2>&1 | grep GNU`\" = \"\"; then\n", fp);
 1053   fputs("   ac_tar=\"tar -xpf\"\n", fp);
 1054   fputs("else\n", fp);
 1055   fputs("   ac_tar=\"tar -xpPf\"\n", fp);
 1056   fputs("fi\n", fp);
 1057 
 1058   return (0);
 1059 }
 1060 
 1061 
 1062 /*
 1063  * 'write_depends()' - Write dependencies.
 1064  */
 1065 
 1066 static int              /* O - 0 on success, - 1 on failure */
 1067 write_depends(const char *prodname, /* I - Product name */
 1068               dist_t     *dist,     /* I - Distribution */
 1069               FILE       *fp,       /* I - File pointer */
 1070           const char *subpackage)   /* I - Subpackage */
 1071 {
 1072   int           i;      /* Looping var */
 1073   depend_t      *d;     /* Current dependency */
 1074   const char        *product;   /* Product/file to depend on */
 1075   static const char *depends[] =    /* Dependency strings */
 1076             {
 1077               "requires",
 1078               "incompat",
 1079               "replaces",
 1080               "provides"
 1081             };
 1082 
 1083 
 1084   for (i = 0, d = dist->depends; i < dist->num_depends; i ++, d ++)
 1085     if (d->subpackage == subpackage)
 1086     {
 1087       if (!strcmp(d->product, "_self"))
 1088         product = prodname;
 1089       else
 1090         product = d->product;
 1091 
 1092       fprintf(fp, "#%%%s %s %d %d\n", depends[(int)d->type], product,
 1093               d->vernumber[0], d->vernumber[1]);
 1094 
 1095       switch (d->type)
 1096       {
 1097     case DEPEND_REQUIRES :
 1098             if (product[0] == '/')
 1099             {
 1100              /*
 1101               * Require a file...
 1102               */
 1103 
 1104               qprintf(fp, "if test ! -r %s -a ! -h %s; then\n",
 1105                       product, product);
 1106               qprintf(fp, " echo Sorry, you must first install \\'%s\\'!\n",
 1107                   product);
 1108               fputs("   exit 1\n", fp);
 1109               fputs("fi\n", fp);
 1110             }
 1111             else
 1112             {
 1113              /*
 1114               * Require a product...
 1115               */
 1116 
 1117               fprintf(fp, "if test ! -x %s/%s.remove; then\n",
 1118                       SoftwareDir, product);
 1119               fprintf(fp, " if test -x %s.install; then\n",
 1120                       product);
 1121               fprintf(fp, "     echo Installing required %s software...\n",
 1122                       product);
 1123               fprintf(fp, "     ./%s.install now\n", product);
 1124               fputs("   else\n", fp);
 1125               fprintf(fp, "     echo Sorry, you must first install \\'%s\\'!\n",
 1126                   product);
 1127               fputs("       exit 1\n", fp);
 1128               fputs("   fi\n", fp);
 1129               fputs("fi\n", fp);
 1130 
 1131               if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX)
 1132           {
 1133            /*
 1134         * Do version number checking...
 1135         */
 1136 
 1137             fprintf(fp, "installed=`grep \'^#%%version\' "
 1138                         "%s/%s.remove | awk \'{print $3}\'`\n",
 1139                     SoftwareDir, product);
 1140 
 1141             fputs("if test x$installed = x; then\n", fp);
 1142         fputs(" installed=0\n", fp);
 1143         fputs("fi\n", fp);
 1144 
 1145         fprintf(fp, "if test $installed -lt %d -o $installed -gt %d; then\n",
 1146                 d->vernumber[0], d->vernumber[1]);
 1147             fprintf(fp, "   if test -x %s.install; then\n",
 1148                     product);
 1149             fprintf(fp, "       echo Installing required %s software...\n",
 1150                     product);
 1151             fprintf(fp, "       ./%s.install now\n", product);
 1152             fputs(" else\n", fp);
 1153             fprintf(fp, "       echo Sorry, you must first install \\'%s\\' version %s to %s!\n",
 1154                 product, d->version[0], d->version[1]);
 1155             fputs("     exit 1\n", fp);
 1156             fputs(" fi\n", fp);
 1157             fputs("fi\n", fp);
 1158           }
 1159             }
 1160         break;
 1161 
 1162     case DEPEND_INCOMPAT :
 1163             if (product[0] == '/')
 1164             {
 1165              /*
 1166               * Incompatible with a file...
 1167               */
 1168 
 1169               qprintf(fp, "if test -r %s -o -h %s; then\n",
 1170                       product, product);
 1171               qprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\'!\n",
 1172                   product);
 1173               fputs("   echo Please remove it first.\n", fp);
 1174               fputs("   exit 1\n", fp);
 1175               fputs("fi\n", fp);
 1176             }
 1177             else
 1178             {
 1179              /*
 1180               * Incompatible with a product...
 1181               */
 1182 
 1183               fprintf(fp, "if test -x %s/%s.remove; then\n",
 1184                       SoftwareDir, product);
 1185 
 1186               if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX)
 1187           {
 1188            /*
 1189         * Do version number checking...
 1190         */
 1191 
 1192             fprintf(fp, "   installed=`grep \'^#%%version\' "
 1193                         "%s/%s.remove | awk \'{print $3}\'`\n",
 1194             SoftwareDir, product);
 1195 
 1196             fputs(" if test x$installed = x; then\n", fp);
 1197         fputs("     installed=0\n", fp);
 1198         fputs(" fi\n", fp);
 1199 
 1200         fprintf(fp, "   if test $installed -ge %d -a $installed -le %d; then\n",
 1201                 d->vernumber[0], d->vernumber[1]);
 1202             fprintf(fp, "       echo Sorry, this software is incompatible with \\'%s\\' version %s to %s!\n",
 1203                 product, d->version[0], d->version[1]);
 1204             fprintf(fp, "       echo Please remove it first by running \\'%s/%s.remove\\'.\n",
 1205                 SoftwareDir, product);
 1206             fputs("     exit 1\n", fp);
 1207             fputs(" fi\n", fp);
 1208           }
 1209           else
 1210           {
 1211             fprintf(fp, "   echo Sorry, this software is incompatible with \\'%s\\'!\n",
 1212                 product);
 1213             fprintf(fp, "   echo Please remove it first by running \\'%s/%s.remove\\'.\n",
 1214                 SoftwareDir, product);
 1215             fputs(" exit 1\n", fp);
 1216           }
 1217 
 1218               fputs("fi\n", fp);
 1219             }
 1220         break;
 1221 
 1222     case DEPEND_REPLACES :
 1223             fprintf(fp, "if test -x %s/%s.remove; then\n", SoftwareDir,
 1224                 product);
 1225 
 1226             if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX)
 1227         {
 1228          /*
 1229           * Do version number checking...
 1230           */
 1231 
 1232               fprintf(fp, " installed=`grep \'^#%%version\' "
 1233                       "%s/%s.remove | awk \'{print $3}\'`\n",
 1234                       SoftwareDir, product);
 1235 
 1236               fputs("   if test x$installed = x; then\n", fp);
 1237           fputs("       installed=0\n", fp);
 1238           fputs("   fi\n", fp);
 1239 
 1240           fprintf(fp, " if test $installed -ge %d -a $installed -le %d; then\n",
 1241                   d->vernumber[0], d->vernumber[1]);
 1242               fprintf(fp, "     echo Automatically replacing \\'%s\\'...\n",
 1243                   product);
 1244               fprintf(fp, "     %s/%s.remove now\n",
 1245                   SoftwareDir, product);
 1246               fputs("   fi\n", fp);
 1247         }
 1248         else
 1249         {
 1250               fprintf(fp, " echo Automatically replacing \\'%s\\'...\n",
 1251                   product);
 1252               fprintf(fp, " %s/%s.remove now\n",
 1253                   SoftwareDir, product);
 1254             }
 1255 
 1256             fputs("fi\n", fp);
 1257         break;
 1258       }
 1259     }
 1260 
 1261   return (0);
 1262 }
 1263 
 1264 
 1265 /*
 1266  * 'write_distfiles()' - Write a software distribution...
 1267  */
 1268 
 1269 static int              /* O - -1 on error, 0 on success */
 1270 write_distfiles(const char *directory,  /* I - Directory */
 1271             const char *prodname,   /* I - Product name */
 1272                 const char *platname,   /* I - Platform name */
 1273             dist_t     *dist,   /* I - Distribution */
 1274         time_t     deftime, /* I - Default file time */
 1275             const char *subpackage) /* I - Subpackage */
 1276 {
 1277   int       i;          /* Looping var */
 1278   int       havepatchfiles;     /* 1 if we have patch files, 0 otherwise */
 1279   tarf_t    *tarfile;       /* Distribution tar file */
 1280   char      prodfull[255],      /* Full name of product */
 1281         swname[255],        /* Name of distribution tar file */
 1282         pswname[255],       /* Name of patch tar file */
 1283         filename[1024];     /* Name of temporary file */
 1284   struct stat   srcstat;        /* Source file information */
 1285   file_t    *file;          /* Software file */
 1286   int       rootsize,       /* Size of files in root partition */
 1287         usrsize;        /* Size of files in /usr partition */
 1288   int       prootsize,      /* Size of patch files in root partition */
 1289         pusrsize;       /* Size of patch files in /usr partition */
 1290 
 1291 
 1292  /*
 1293   * Figure out the full name of the distribution...
 1294   */
 1295 
 1296   if (subpackage)
 1297     snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
 1298   else
 1299     strlcpy(prodfull, prodname, sizeof(prodfull));
 1300 
 1301  /*
 1302   * See if we need to make a patch distribution...
 1303   */
 1304 
 1305   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1306     if (isupper((int)file->type) && file->subpackage == subpackage)
 1307       break;
 1308 
 1309   havepatchfiles = i > 0;
 1310 
 1311  /*
 1312   * Copy the license and readme files...
 1313   */
 1314 
 1315   if (Verbosity)
 1316     printf("Copying %s license and readme files...\n", prodfull);
 1317 
 1318   if (dist->license[0])
 1319   {
 1320     snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull);
 1321     if (copy_file(filename, dist->license, 0444, getuid(), getgid()))
 1322       return (1);
 1323   }
 1324 
 1325   if (dist->readme[0])
 1326   {
 1327     snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull);
 1328     if (copy_file(filename, dist->readme, 0444, getuid(), getgid()))
 1329       return (1);
 1330   }
 1331 
 1332  /*
 1333   * Create the non-shared software distribution file...
 1334   */
 1335 
 1336   if (Verbosity)
 1337     puts("Creating non-shared software distribution file...");
 1338 
 1339   snprintf(swname, sizeof(swname), "%s.sw", prodfull);
 1340   snprintf(filename, sizeof(filename), "%s/%s", directory, swname);
 1341 
 1342   unlink(filename);
 1343   if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
 1344   {
 1345     fprintf(stderr, "epm: Unable to create file \"%s\" -\n     %s\n",
 1346             filename, strerror(errno));
 1347     return (1);
 1348   }
 1349 
 1350   for (i = dist->num_files, file = dist->files, rootsize = 0, prootsize = 0;
 1351        i > 0;
 1352        i --, file ++)
 1353     if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
 1354       switch (tolower(file->type))
 1355       {
 1356     case 'f' : /* Regular file */
 1357     case 'c' : /* Config file */
 1358     case 'i' : /* Init script */
 1359             if (stat(file->src, &srcstat))
 1360         {
 1361           fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
 1362           tar_close(tarfile);
 1363           return (1);
 1364         }
 1365 
 1366             rootsize += (srcstat.st_size + 1023) / 1024;
 1367 
 1368             if (isupper(file->type & 255))
 1369               prootsize += (srcstat.st_size + 1023) / 1024;
 1370 
 1371            /*
 1372         * Configuration files are extracted to the config file name with
 1373         * .N appended; add a bit of script magic to check if the config
 1374         * file already exists, and if not we copy the .N to the config
 1375         * file location...
 1376         */
 1377 
 1378         if (tolower(file->type) == 'c')
 1379           snprintf(filename, sizeof(filename), "%s.N", file->dst);
 1380         else if (tolower(file->type) == 'i')
 1381           snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir,
 1382                    file->dst);
 1383         else
 1384               strlcpy(filename, file->dst, sizeof(filename));
 1385 
 1386             if (Verbosity > 1)
 1387           printf("%s -> %s...\n", file->src, filename);
 1388 
 1389         if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
 1390                        srcstat.st_mtime, file->user, file->group,
 1391                filename, NULL) < 0)
 1392         {
 1393           tar_close(tarfile);
 1394           return (1);
 1395         }
 1396 
 1397         if (tar_file(tarfile, file->src) < 0)
 1398         {
 1399           tar_close(tarfile);
 1400           return (1);
 1401         }
 1402         break;
 1403 
 1404     case 'd' : /* Create directory */
 1405             if (Verbosity > 1)
 1406           printf("Directory %s...\n", file->dst);
 1407 
 1408             rootsize ++;
 1409 
 1410             if (isupper(file->type & 255))
 1411               prootsize ++;
 1412         break;
 1413 
 1414     case 'l' : /* Link file */
 1415             if (Verbosity > 1)
 1416           printf("%s -> %s...\n", file->src, file->dst);
 1417 
 1418         if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
 1419                        file->user, file->group, file->dst, file->src) < 0)
 1420         {
 1421           tar_close(tarfile);
 1422           return (1);
 1423         }
 1424 
 1425             rootsize ++;
 1426 
 1427             if (isupper(file->type & 255))
 1428               prootsize ++;
 1429         break;
 1430       }
 1431 
 1432   tar_close(tarfile);
 1433 
 1434  /*
 1435   * Create the shared software distribution file...
 1436   */
 1437 
 1438   if (Verbosity)
 1439     puts("Creating shared software distribution file...");
 1440 
 1441   snprintf(swname, sizeof(swname), "%s.ss", prodfull);
 1442   snprintf(filename, sizeof(filename), "%s/%s", directory, swname);
 1443 
 1444   unlink(filename);
 1445   if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
 1446   {
 1447     fprintf(stderr, "epm: Unable to create file \"%s\" -\n     %s\n",
 1448             filename, strerror(errno));
 1449     return (1);
 1450   }
 1451 
 1452   for (i = dist->num_files, file = dist->files, usrsize = 0, pusrsize = 0;
 1453        i > 0;
 1454        i --, file ++)
 1455     if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
 1456       switch (tolower(file->type))
 1457       {
 1458     case 'f' : /* Regular file */
 1459     case 'c' : /* Config file */
 1460     case 'i' : /* Init script */
 1461             if (stat(file->src, &srcstat))
 1462         {
 1463           fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
 1464           tar_close(tarfile);
 1465           return (1);
 1466         }
 1467 
 1468             usrsize += (srcstat.st_size + 1023) / 1024;
 1469 
 1470             if (isupper(file->type & 255))
 1471               pusrsize += (srcstat.st_size + 1023) / 1024;
 1472 
 1473            /*
 1474         * Configuration files are extracted to the config file name with
 1475         * .N appended; add a bit of script magic to check if the config
 1476         * file already exists, and if not we copy the .N to the config
 1477         * file location...
 1478         */
 1479 
 1480         if (tolower(file->type) == 'c')
 1481           snprintf(filename, sizeof(filename), "%s.N", file->dst);
 1482         else if (tolower(file->type) == 'i')
 1483           snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir,
 1484                    file->dst);
 1485         else
 1486               strlcpy(filename, file->dst, sizeof(filename));
 1487 
 1488             if (Verbosity > 1)
 1489           printf("%s -> %s...\n", file->src, filename);
 1490 
 1491         if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
 1492                        srcstat.st_mtime, file->user, file->group,
 1493                filename, NULL) < 0)
 1494         {
 1495           tar_close(tarfile);
 1496           return (1);
 1497         }
 1498 
 1499         if (tar_file(tarfile, file->src) < 0)
 1500         {
 1501           tar_close(tarfile);
 1502           return (1);
 1503         }
 1504         break;
 1505 
 1506     case 'd' : /* Create directory */
 1507             if (Verbosity > 1)
 1508           printf("%s...\n", file->dst);
 1509 
 1510         usrsize ++;
 1511 
 1512             if (isupper(file->type & 255))
 1513               pusrsize ++;
 1514         break;
 1515 
 1516     case 'l' : /* Link file */
 1517             if (Verbosity > 1)
 1518           printf("%s -> %s...\n", file->src, file->dst);
 1519 
 1520         if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
 1521                        file->user, file->group, file->dst, file->src) < 0)
 1522         {
 1523           tar_close(tarfile);
 1524           return (1);
 1525         }
 1526 
 1527         usrsize ++;
 1528 
 1529             if (isupper(file->type & 255))
 1530               pusrsize ++;
 1531         break;
 1532       }
 1533 
 1534   tar_close(tarfile);
 1535 
 1536  /*
 1537   * Create the patch distribution files...
 1538   */
 1539 
 1540   if (havepatchfiles)
 1541   {
 1542     if (Verbosity)
 1543       puts("Creating non-shared software patch file...");
 1544 
 1545     snprintf(pswname, sizeof(pswname), "%s.psw", prodfull);
 1546     snprintf(filename, sizeof(filename), "%s/%s", directory, pswname);
 1547 
 1548     unlink(filename);
 1549     if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
 1550     {
 1551       fprintf(stderr, "epm: Unable to create file \"%s\" -\n     %s\n",
 1552               filename, strerror(errno));
 1553       return (1);
 1554     }
 1555 
 1556     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1557       if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
 1558     switch (file->type)
 1559     {
 1560       case 'C' : /* Config file */
 1561       case 'F' : /* Regular file */
 1562           case 'I' : /* Init script */
 1563               if (stat(file->src, &srcstat))
 1564           {
 1565         fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
 1566         tar_close(tarfile);
 1567         return (1);
 1568           }
 1569 
 1570              /*
 1571           * Configuration files are extracted to the config file name with
 1572           * .N appended; add a bit of script magic to check if the config
 1573           * file already exists, and if not we copy the .N to the config
 1574           * file location...
 1575           */
 1576 
 1577           if (file->type == 'C')
 1578         snprintf(filename, sizeof(filename), "%s.N", file->dst);
 1579           else if (file->type == 'I')
 1580         snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir,
 1581                  file->dst);
 1582           else
 1583             strlcpy(filename, file->dst, sizeof(filename));
 1584 
 1585               if (Verbosity > 1)
 1586         printf("%s -> %s...\n", file->src, filename);
 1587 
 1588           if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
 1589                          srcstat.st_mtime, file->user, file->group,
 1590                  filename, NULL) < 0)
 1591           {
 1592         tar_close(tarfile);
 1593         return (1);
 1594           }
 1595 
 1596           if (tar_file(tarfile, file->src) < 0)
 1597           {
 1598         tar_close(tarfile);
 1599         return (1);
 1600           }
 1601           break;
 1602 
 1603       case 'd' : /* Create directory */
 1604               if (Verbosity > 1)
 1605         printf("%s...\n", file->dst);
 1606           break;
 1607 
 1608       case 'L' : /* Link file */
 1609               if (Verbosity > 1)
 1610         printf("%s -> %s...\n", file->src, file->dst);
 1611 
 1612           if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
 1613                          file->user, file->group, file->dst, file->src) < 0)
 1614           {
 1615         tar_close(tarfile);
 1616         return (1);
 1617           }
 1618           break;
 1619     }
 1620 
 1621     tar_close(tarfile);
 1622 
 1623     if (Verbosity)
 1624       puts("Creating shared software patch file...");
 1625 
 1626     snprintf(pswname, sizeof(pswname), "%s.pss", prodfull);
 1627     snprintf(filename, sizeof(filename), "%s/%s", directory, pswname);
 1628 
 1629     unlink(filename);
 1630     if ((tarfile = tar_open(filename, CompressFiles)) == NULL)
 1631     {
 1632       fprintf(stderr, "epm: Unable to create file \"%s\" -\n     %s\n",
 1633               filename, strerror(errno));
 1634       return (1);
 1635     }
 1636 
 1637     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1638       if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
 1639     switch (file->type)
 1640     {
 1641       case 'C' : /* Config file */
 1642       case 'F' : /* Regular file */
 1643           case 'I' : /* Init script */
 1644               if (stat(file->src, &srcstat))
 1645           {
 1646         fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno));
 1647         tar_close(tarfile);
 1648         return (1);
 1649           }
 1650 
 1651              /*
 1652           * Configuration files are extracted to the config file name with
 1653           * .N appended; add a bit of script magic to check if the config
 1654           * file already exists, and if not we copy the .N to the config
 1655           * file location...
 1656           */
 1657 
 1658           if (file->type == 'C')
 1659         snprintf(filename, sizeof(filename), "%s.N", file->dst);
 1660           else if (file->type == 'I')
 1661         snprintf(filename, sizeof(filename), "%s/init.d/%s",
 1662                  SoftwareDir, file->dst);
 1663           else
 1664             strlcpy(filename, file->dst, sizeof(filename));
 1665 
 1666               if (Verbosity > 1)
 1667         printf("%s -> %s...\n", file->src, filename);
 1668 
 1669           if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size,
 1670                          srcstat.st_mtime, file->user, file->group,
 1671                  filename, NULL) < 0)
 1672           {
 1673         tar_close(tarfile);
 1674         return (1);
 1675           }
 1676 
 1677           if (tar_file(tarfile, file->src) < 0)
 1678           {
 1679         tar_close(tarfile);
 1680         return (1);
 1681           }
 1682           break;
 1683 
 1684       case 'd' : /* Create directory */
 1685               if (Verbosity > 1)
 1686         printf("%s...\n", file->dst);
 1687           break;
 1688 
 1689       case 'L' : /* Link file */
 1690               if (Verbosity > 1)
 1691         printf("%s -> %s...\n", file->src, file->dst);
 1692 
 1693           if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime,
 1694                          file->user, file->group, file->dst, file->src) < 0)
 1695           {
 1696         tar_close(tarfile);
 1697         return (1);
 1698           }
 1699           break;
 1700     }
 1701 
 1702     tar_close(tarfile);
 1703   }
 1704 
 1705  /*
 1706   * Create the scripts...
 1707   */
 1708 
 1709   if (write_install(dist, prodname, rootsize, usrsize, directory, subpackage))
 1710     return (1);
 1711 
 1712   if (havepatchfiles)
 1713     if (write_patch(dist, prodname, prootsize, pusrsize, directory, subpackage))
 1714       return (1);
 1715 
 1716   if (write_remove(dist, prodname, rootsize, usrsize, directory, subpackage))
 1717     return (1);
 1718 
 1719  /*
 1720   * Return...
 1721   */
 1722 
 1723   return (0);
 1724 }
 1725 
 1726 
 1727 /*
 1728  * 'write_install()' - Write the installation script.
 1729  */
 1730 
 1731 static int              /* O - -1 on error, 0 on success */
 1732 write_install(dist_t     *dist,     /* I - Software distribution */
 1733               const char *prodname, /* I - Product name */
 1734               int        rootsize,  /* I - Size of root files in kbytes */
 1735           int        usrsize,   /* I - Size of /usr files in kbytes */
 1736           const char *directory,    /* I - Directory */
 1737           const char *subpackage)   /* I - Subpackage */
 1738 {
 1739   int       i;          /* Looping var */
 1740   int       col;            /* Column in the output */
 1741   FILE      *scriptfile;        /* Install script */
 1742   char      prodfull[255];      /* Full product name */
 1743   char      filename[1024];     /* Name of temporary file */
 1744   file_t    *file;          /* Software file */
 1745   const char    *runlevels;     /* Run levels */
 1746   int       number;         /* Start/stop number */
 1747 
 1748 
 1749   if (Verbosity)
 1750     puts("Writing installation script...");
 1751 
 1752   if (subpackage)
 1753     snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
 1754   else
 1755     strlcpy(prodfull, prodname, sizeof(prodfull));
 1756 
 1757   snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull);
 1758 
 1759   if ((scriptfile = write_common(dist, "Installation", rootsize, usrsize,
 1760                                  filename, subpackage)) == NULL)
 1761   {
 1762     fprintf(stderr, "epm: Unable to create installation script \"%s\" -\n"
 1763                     "     %s\n", filename, strerror(errno));
 1764     return (-1);
 1765   }
 1766 
 1767   fputs("if test \"$*\" = \"now\"; then\n", scriptfile);
 1768   fputs("   echo Software license silently accepted via command-line option.\n", scriptfile);
 1769   fputs("else\n", scriptfile);
 1770   fputs("   echo \"\"\n", scriptfile);
 1771   qprintf(scriptfile, " echo This installation script will install the %s\n",
 1772           dist->product);
 1773   qprintf(scriptfile, " echo software version %s on your system.\n",
 1774           dist->version);
 1775   fputs("   echo \"\"\n", scriptfile);
 1776   fputs("   while true ; do\n", scriptfile);
 1777   fputs("       echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile);
 1778   fputs("       read yesno\n", scriptfile);
 1779   fputs("       case \"$yesno\" in\n", scriptfile);
 1780   fputs("           y | yes | Y | Yes | YES)\n", scriptfile);
 1781   fputs("           break\n", scriptfile);
 1782   fputs("           ;;\n", scriptfile);
 1783   fputs("           n | no | N | No | NO)\n", scriptfile);
 1784   fputs("           exit 1\n", scriptfile);
 1785   fputs("           ;;\n", scriptfile);
 1786   fputs("           *)\n", scriptfile);
 1787   fputs("           echo Please enter yes or no.\n", scriptfile);
 1788   fputs("           ;;\n", scriptfile);
 1789   fputs("       esac\n", scriptfile);
 1790   fputs("   done\n", scriptfile);
 1791 
 1792   if (dist->license[0])
 1793   {
 1794     fprintf(scriptfile, "   more %s.license\n", prodfull);
 1795     fputs(" echo \"\"\n", scriptfile);
 1796     fputs(" while true ; do\n", scriptfile);
 1797     fputs("     echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile);
 1798     fputs("     read yesno\n", scriptfile);
 1799     fputs("     case \"$yesno\" in\n", scriptfile);
 1800     fputs("         y | yes | Y | Yes | YES)\n", scriptfile);
 1801     fputs("         break\n", scriptfile);
 1802     fputs("         ;;\n", scriptfile);
 1803     fputs("         n | no | N | No | NO)\n", scriptfile);
 1804     fputs("         exit 1\n", scriptfile);
 1805     fputs("         ;;\n", scriptfile);
 1806     fputs("         *)\n", scriptfile);
 1807     fputs("         echo Please enter yes or no.\n", scriptfile);
 1808     fputs("         ;;\n", scriptfile);
 1809     fputs("     esac\n", scriptfile);
 1810     fputs(" done\n", scriptfile);
 1811   }
 1812 
 1813   fputs("fi\n", scriptfile);
 1814   fprintf(scriptfile, "if test -x %s/%s.remove; then\n", SoftwareDir, prodfull);
 1815   fprintf(scriptfile, " echo Removing old versions of %s software...\n",
 1816           prodfull);
 1817   fprintf(scriptfile, " %s/%s.remove now\n", SoftwareDir, prodfull);
 1818   fputs("fi\n", scriptfile);
 1819 
 1820   write_space_checks(prodfull, scriptfile, rootsize ? "sw" : NULL,
 1821                      usrsize ? "ss" : NULL, rootsize, usrsize);
 1822   write_depends(prodname, dist, scriptfile, subpackage);
 1823   write_commands(dist, scriptfile, COMMAND_PRE_INSTALL, subpackage);
 1824 
 1825   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1826     if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 1827         strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
 1828       break;
 1829 
 1830   if (i)
 1831   {
 1832     fputs("echo Backing up old versions of non-shared files to be installed...\n", scriptfile);
 1833 
 1834     col = fputs("for file in", scriptfile);
 1835     for (; i > 0; i --, file ++)
 1836       if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 1837           strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
 1838       {
 1839         if (col > 80)
 1840       col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
 1841     else
 1842           col += qprintf(scriptfile, " %s", file->dst);
 1843       }
 1844 
 1845     fputs("; do\n", scriptfile);
 1846     fputs(" if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile);
 1847     fputs("     mv -f \"$file\" \"$file.O\"\n", scriptfile);
 1848     fputs(" fi\n", scriptfile);
 1849     fputs("done\n", scriptfile);
 1850   }
 1851 
 1852   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1853     if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 1854         strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
 1855       break;
 1856 
 1857   if (i)
 1858   {
 1859     fputs("if test -w /usr ; then\n", scriptfile);
 1860     fputs(" echo Backing up old versions of shared files to be installed...\n", scriptfile);
 1861 
 1862     col = fputs("   for file in", scriptfile);
 1863     for (; i > 0; i --, file ++)
 1864       if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 1865           strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
 1866       {
 1867         if (col > 80)
 1868       col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
 1869     else
 1870           col += qprintf(scriptfile, " %s", file->dst);
 1871       }
 1872 
 1873     fputs("; do\n", scriptfile);
 1874     fputs("     if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile);
 1875     fputs("         mv -f \"$file\" \"$file.O\"\n", scriptfile);
 1876     fputs("     fi\n", scriptfile);
 1877     fputs(" done\n", scriptfile);
 1878     fputs("fi\n", scriptfile);
 1879   }
 1880 
 1881   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1882     if (tolower(file->type) == 'd' && file->subpackage == subpackage)
 1883       break;
 1884 
 1885   if (i)
 1886   {
 1887     fputs("echo Creating installation directories...\n", scriptfile);
 1888 
 1889     for (; i > 0; i --, file ++)
 1890       if (tolower(file->type) == 'd' && file->subpackage == subpackage)
 1891       {
 1892     qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n",
 1893             file->dst, file->dst, file->dst);
 1894     qprintf(scriptfile, "   mkdir -p %s\n", file->dst);
 1895     fputs("else\n", scriptfile);
 1896     qprintf(scriptfile, "   if test -f %s; then\n", file->dst);
 1897     qprintf(scriptfile, "       echo Error: %s already exists as a regular file!\n",
 1898             file->dst);
 1899     fputs("     exit 1\n", scriptfile);
 1900     fputs(" fi\n", scriptfile);
 1901     fputs("fi\n", scriptfile);
 1902     qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
 1903     qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
 1904     qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst);
 1905       }
 1906   }
 1907 
 1908   fputs("echo Installing software...\n", scriptfile);
 1909 
 1910   if (rootsize)
 1911   {
 1912     if (CompressFiles)
 1913       fprintf(scriptfile, "gzip -dc %s.sw | $ac_tar -\n", prodfull);
 1914     else
 1915       fprintf(scriptfile, "$ac_tar %s.sw\n", prodfull);
 1916   }
 1917 
 1918   if (usrsize)
 1919   {
 1920     fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile);
 1921     if (CompressFiles)
 1922       fprintf(scriptfile, " gzip -dc %s.ss | $ac_tar -\n", prodfull);
 1923     else
 1924       fprintf(scriptfile, " $ac_tar %s.ss\n", prodfull);
 1925     fputs("fi\n", scriptfile);
 1926   }
 1927 
 1928   fprintf(scriptfile, "if test -d %s; then\n", SoftwareDir);
 1929   fprintf(scriptfile, " rm -f %s/%s.remove\n", SoftwareDir, prodfull);
 1930   fputs("else\n", scriptfile);
 1931   fprintf(scriptfile, " mkdir -p %s\n", SoftwareDir);
 1932   fputs("fi\n", scriptfile);
 1933   fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir);
 1934   fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull);
 1935 
 1936   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1937     if (tolower(file->type) == 'c' && file->subpackage == subpackage)
 1938       break;
 1939 
 1940   if (i)
 1941   {
 1942     fputs("echo Checking configuration files...\n", scriptfile);
 1943 
 1944     col = fputs("for file in", scriptfile);
 1945     for (; i > 0; i --, file ++)
 1946       if (tolower(file->type) == 'c' && file->subpackage == subpackage)
 1947       {
 1948         if (col > 80)
 1949       col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
 1950     else
 1951           col += qprintf(scriptfile, " %s", file->dst);
 1952       }
 1953 
 1954     fputs("; do\n", scriptfile);
 1955     fputs(" if test ! -f \"$file\"; then\n", scriptfile);
 1956     fputs("     cp \"$file.N\" \"$file\"\n", scriptfile);
 1957     fputs(" fi\n", scriptfile);
 1958     fputs("done\n", scriptfile);
 1959   }
 1960 
 1961   fputs("echo Updating file permissions...\n", scriptfile);
 1962 
 1963   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1964     if (strncmp(file->dst, "/usr", 4) != 0 &&
 1965         strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
 1966       switch (tolower(file->type))
 1967       {
 1968     case 'c' :
 1969         qprintf(scriptfile, "chown %s %s.N\n", file->user, file->dst);
 1970         qprintf(scriptfile, "chgrp %s %s.N\n", file->group, file->dst);
 1971     case 'f' :
 1972         qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
 1973         qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
 1974         break;
 1975       }
 1976 
 1977   fputs("if test -f /usr/.writetest; then\n", scriptfile);
 1978   fputs("   rm -f /usr/.writetest\n", scriptfile);
 1979   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1980     if (strncmp(file->dst, "/usr", 4) == 0 &&
 1981         strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
 1982       switch (tolower(file->type))
 1983       {
 1984     case 'c' :
 1985         qprintf(scriptfile, "   chown %s %s.N\n", file->user, file->dst);
 1986         qprintf(scriptfile, "   chgrp %s %s.N\n", file->group, file->dst);
 1987     case 'f' :
 1988         qprintf(scriptfile, "   chown %s %s\n", file->user, file->dst);
 1989         qprintf(scriptfile, "   chgrp %s %s\n", file->group, file->dst);
 1990         break;
 1991       }
 1992   fputs("fi\n", scriptfile);
 1993 
 1994   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 1995     if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 1996       break;
 1997 
 1998   if (i)
 1999   {
 2000     fputs("echo Setting up init scripts...\n", scriptfile);
 2001 
 2002    /*
 2003     * Find where the frigging init scripts go...
 2004     */
 2005 
 2006     fputs("rcdir=\"\"\n", scriptfile);
 2007     fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile);
 2008     fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o "
 2009           "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile);
 2010     fputs("     rcdir=\"$dir\"\n", scriptfile);
 2011     fputs(" fi\n", scriptfile);
 2012     fputs("done\n", scriptfile);
 2013     fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile);
 2014     fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile);
 2015     fputs("     for file in", scriptfile);
 2016     for (; i > 0; i --, file ++)
 2017       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2018         qprintf(scriptfile, " %s", file->dst);
 2019     fputs("; do\n", scriptfile);
 2020     fputs("         rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile);
 2021     qprintf(scriptfile, "           ln -s %s/init.d/$file "
 2022                         "/usr/local/etc/rc.d/$file.sh\n",
 2023             SoftwareDir);
 2024     fputs("     done\n", scriptfile);
 2025     fputs(" else\n", scriptfile);
 2026     fputs("     echo Unable to determine location of startup scripts!\n", scriptfile);
 2027     fputs(" fi\n", scriptfile);
 2028     fputs("else\n", scriptfile);
 2029     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2030       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2031       {
 2032     fputs(" if test -d $rcdir/init.d; then\n", scriptfile);
 2033     qprintf(scriptfile, "       /bin/rm -f $rcdir/init.d/%s\n", file->dst);
 2034     qprintf(scriptfile, "       /bin/ln -s %s/init.d/%s "
 2035                     "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst);
 2036     fputs(" else\n", scriptfile);
 2037     fputs("     if test -d /etc/init.d; then\n", scriptfile);
 2038     qprintf(scriptfile, "           /bin/rm -f /etc/init.d/%s\n", file->dst);
 2039     qprintf(scriptfile, "           /bin/ln -s %s/init.d/%s "
 2040                     "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst);
 2041     fputs("     fi\n", scriptfile);
 2042     fputs(" fi\n", scriptfile);
 2043 
 2044     for (runlevels = get_runlevels(dist->files + i, "0235");
 2045              isdigit(*runlevels & 255);
 2046          runlevels ++)
 2047     {
 2048       if (*runlevels == '0')
 2049             number = get_stop(file, 0);
 2050       else
 2051         number = get_start(file, 99);
 2052 
 2053           fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels);
 2054       qprintf(scriptfile, "     /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n",
 2055               *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst);
 2056       qprintf(scriptfile, "     /bin/ln -s %s/init.d/%s "
 2057                               "$rcdir/rc%c.d/%c%02d%s\n",
 2058                   SoftwareDir, file->dst, *runlevels,
 2059           *runlevels == '0' ? 'K' : 'S', number, file->dst);
 2060       fputs("   fi\n", scriptfile);
 2061         }
 2062 
 2063 #ifdef __sgi
 2064         fputs(" if test -x /etc/chkconfig; then\n", scriptfile);
 2065         qprintf(scriptfile, "       /etc/chkconfig -f %s on\n", file->dst);
 2066         fputs(" fi\n", scriptfile);
 2067 #endif /* __sgi */
 2068 
 2069       }
 2070 
 2071     fputs("fi\n", scriptfile);
 2072   }
 2073 
 2074   write_commands(dist, scriptfile, COMMAND_POST_INSTALL, subpackage);
 2075 
 2076   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2077     if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2078       qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst);
 2079 
 2080   fputs("echo Installation is complete.\n", scriptfile);
 2081 
 2082   fclose(scriptfile);
 2083 
 2084   return (0);
 2085 }
 2086 
 2087 
 2088 /*
 2089  * 'write_instfiles()' - Write the installer files to the tar file...
 2090  */
 2091 
 2092 static int              /* O - 0 = success, -1 on failure */
 2093 write_instfiles(tarf_t     *tarfile,    /* I - Distribution tar file */
 2094                 const char *directory,  /* I - Output directory */
 2095                 const char *prodname,   /* I - Base product name */
 2096             const char *platname,   /* I - Platform name */
 2097             const char **files, /* I - Files */
 2098         const char *destdir,    /* I - Destination directory in tar file */
 2099             const char *subpackage) /* I - Subpackage */
 2100 {
 2101   int       i;          /* Looping var */
 2102   char      srcname[1024],      /* Name of source file in distribution */
 2103         dstname[1024],      /* Name of destination file in distribution */
 2104         prodfull[255];      /* Full name of product */
 2105   struct stat   srcstat;        /* Source file information */
 2106 
 2107 
 2108   if (subpackage)
 2109     snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
 2110   else
 2111     strlcpy(prodfull, prodname, sizeof(prodfull));
 2112 
 2113   for (i = 0; files[i] != NULL; i ++)
 2114   {
 2115     snprintf(srcname, sizeof(srcname), "%s/%s.%s", directory, prodfull, files[i]);
 2116     snprintf(dstname, sizeof(dstname), "%s%s.%s", destdir, prodfull, files[i]);
 2117 
 2118     if (stat(srcname, &srcstat))
 2119     {
 2120       if (!i)
 2121         break;
 2122       else
 2123         continue;
 2124     }
 2125 
 2126     if (srcstat.st_size == 0)
 2127       continue;
 2128 
 2129     if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & 07555,
 2130                    srcstat.st_size, srcstat.st_mtime, "root", "root",
 2131            dstname, NULL) < 0)
 2132     {
 2133       return (-1);
 2134     }
 2135 
 2136     if (tar_file(tarfile, srcname) < 0)
 2137       return (-1);
 2138 
 2139     if (Verbosity)
 2140       printf("    %7.0fk %s.%s\n", (srcstat.st_size + 1023) / 1024.0,
 2141          prodfull, files[i]);
 2142   }
 2143 
 2144   return (0);
 2145 }
 2146 
 2147 
 2148 /*
 2149  * 'write_patch()' - Write the patch script.
 2150  */
 2151 
 2152 static int              /* O - -1 on error, 0 on success */
 2153 write_patch(dist_t     *dist,       /* I - Software distribution */
 2154             const char *prodname,   /* I - Product name */
 2155             int        rootsize,    /* I - Size of root files in kbytes */
 2156         int        usrsize,     /* I - Size of /usr files in kbytes */
 2157         const char *directory,  /* I - Directory */
 2158         const char *subpackage) /* I - Subpackage */
 2159 {
 2160   int       i;          /* Looping var */
 2161   FILE      *scriptfile;        /* Patch script */
 2162   char      filename[1024];     /* Name of temporary file */
 2163   char      prodfull[255];      /* Full product name */
 2164   file_t    *file;          /* Software file */
 2165   const char    *runlevels;     /* Run levels */
 2166   int       number;         /* Start/stop number */
 2167 
 2168 
 2169   if (Verbosity)
 2170     puts("Writing patch script...");
 2171 
 2172   if (subpackage)
 2173     snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
 2174   else
 2175     strlcpy(prodfull, prodname, sizeof(prodfull));
 2176 
 2177   snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull);
 2178 
 2179   if ((scriptfile = write_common(dist, "Patch", rootsize, usrsize,
 2180                                  filename, subpackage)) == NULL)
 2181   {
 2182     fprintf(stderr, "epm: Unable to create patch script \"%s\" -\n"
 2183                     "     %s\n", filename, strerror(errno));
 2184     return (-1);
 2185   }
 2186 
 2187   fputs("if test \"$*\" = \"now\"; then\n", scriptfile);
 2188   fputs("   echo Software license silently accepted via command-line option.\n", scriptfile);
 2189   fputs("else\n", scriptfile);
 2190   fputs("   echo \"\"\n", scriptfile);
 2191   qprintf(scriptfile, " echo This installation script will patch the %s\n",
 2192           dist->product);
 2193   qprintf(scriptfile, " echo software to version %s on your system.\n", dist->version);
 2194   fputs("   echo \"\"\n", scriptfile);
 2195   fputs("   while true ; do\n", scriptfile);
 2196   fputs("       echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile);
 2197   fputs("       read yesno\n", scriptfile);
 2198   fputs("       case \"$yesno\" in\n", scriptfile);
 2199   fputs("           y | yes | Y | Yes | YES)\n", scriptfile);
 2200   fputs("           break\n", scriptfile);
 2201   fputs("           ;;\n", scriptfile);
 2202   fputs("           n | no | N | No | NO)\n", scriptfile);
 2203   fputs("           exit 1\n", scriptfile);
 2204   fputs("           ;;\n", scriptfile);
 2205   fputs("           *)\n", scriptfile);
 2206   fputs("           echo Please enter yes or no.\n", scriptfile);
 2207   fputs("           ;;\n", scriptfile);
 2208   fputs("       esac\n", scriptfile);
 2209   fputs("   done\n", scriptfile);
 2210 
 2211   if (dist->license[0])
 2212   {
 2213     fprintf(scriptfile, "   more %s.license\n", prodfull);
 2214     fputs(" echo \"\"\n", scriptfile);
 2215     fputs(" while true ; do\n", scriptfile);
 2216     fputs("     echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile);
 2217     fputs("     read yesno\n", scriptfile);
 2218     fputs("     case \"$yesno\" in\n", scriptfile);
 2219     fputs("         y | yes | Y | Yes | YES)\n", scriptfile);
 2220     fputs("         break\n", scriptfile);
 2221     fputs("         ;;\n", scriptfile);
 2222     fputs("         n | no | N | No | NO)\n", scriptfile);
 2223     fputs("         exit 1\n", scriptfile);
 2224     fputs("         ;;\n", scriptfile);
 2225     fputs("         *)\n", scriptfile);
 2226     fputs("         echo Please enter yes or no.\n", scriptfile);
 2227     fputs("         ;;\n", scriptfile);
 2228     fputs("     esac\n", scriptfile);
 2229     fputs(" done\n", scriptfile);
 2230   }
 2231 
 2232   fputs("fi\n", scriptfile);
 2233 
 2234   write_space_checks(prodfull, scriptfile, rootsize ? "psw" : NULL,
 2235                      usrsize ? "pss" : NULL, rootsize, usrsize);
 2236   write_depends(prodname, dist, scriptfile, subpackage);
 2237 
 2238   fprintf(scriptfile, "if test ! -x %s/%s.remove; then\n",
 2239           SoftwareDir, prodfull);
 2240   fputs("   echo You do not appear to have the base software installed!\n",
 2241         scriptfile);
 2242   fputs("   echo Please install the full distribution instead.\n", scriptfile);
 2243   fputs("   exit 1\n", scriptfile);
 2244   fputs("fi\n", scriptfile);
 2245 
 2246   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2247     if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2248       qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst);
 2249 
 2250   write_commands(dist, scriptfile, COMMAND_PRE_PATCH, subpackage);
 2251 
 2252   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2253     if (file->type == 'D' && file->subpackage == subpackage)
 2254       break;
 2255 
 2256   if (i)
 2257   {
 2258     fputs("echo Creating new installation directories...\n", scriptfile);
 2259 
 2260     for (; i > 0; i --, file ++)
 2261       if (file->type == 'D' && file->subpackage == subpackage)
 2262       {
 2263     qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n",
 2264             file->dst, file->dst, file->dst);
 2265     qprintf(scriptfile, "   mkdir -p %s\n", file->dst);
 2266     fputs("else\n", scriptfile);
 2267     qprintf(scriptfile, "   if test -f %s; then\n", file->dst);
 2268     qprintf(scriptfile, "       echo Error: %s already exists as a regular file!\n",
 2269             file->dst);
 2270     fputs("     exit 1\n", scriptfile);
 2271     fputs(" fi\n", scriptfile);
 2272     fputs("fi\n", scriptfile);
 2273     qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
 2274     qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
 2275     qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst);
 2276       }
 2277   }
 2278 
 2279   fputs("echo Patching software...\n", scriptfile);
 2280 
 2281   if (rootsize)
 2282   {
 2283     if (CompressFiles)
 2284       fprintf(scriptfile, "gzip -dc %s.psw | $ac_tar -\n", prodfull);
 2285     else
 2286       fprintf(scriptfile, "$ac_tar %s.psw\n", prodfull);
 2287   }
 2288 
 2289   if (usrsize)
 2290   {
 2291     fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile);
 2292     if (CompressFiles)
 2293       fprintf(scriptfile, " gzip -dc %s.pss | $ac_tar -\n", prodfull);
 2294     else
 2295       fprintf(scriptfile, " $ac_tar %s.pss\n", prodfull);
 2296     fputs("fi\n", scriptfile);
 2297   }
 2298 
 2299   fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull);
 2300   fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir);
 2301   fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull);
 2302 
 2303   fputs("echo Updating file permissions...\n", scriptfile);
 2304 
 2305   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2306     if (strncmp(file->dst, "/usr", 4) != 0 &&
 2307         strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
 2308       switch (file->type)
 2309       {
 2310     case 'C' :
 2311     case 'F' :
 2312         qprintf(scriptfile, "chown %s %s\n", file->user, file->dst);
 2313         qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst);
 2314         break;
 2315       }
 2316 
 2317   fputs("if test -f /usr/.writetest; then\n", scriptfile);
 2318   fputs("   rm -f /usr/.writetest\n", scriptfile);
 2319   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2320     if (strncmp(file->dst, "/usr", 4) == 0 &&
 2321         strcmp(file->user, "root") != 0 && file->subpackage == subpackage)
 2322       switch (file->type)
 2323       {
 2324     case 'C' :
 2325     case 'F' :
 2326         qprintf(scriptfile, "   chown %s %s\n", file->user, file->dst);
 2327         qprintf(scriptfile, "   chgrp %s %s\n", file->group, file->dst);
 2328         break;
 2329       }
 2330   fputs("fi\n", scriptfile);
 2331 
 2332   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2333     if (file->type == 'C' && file->subpackage == subpackage)
 2334       break;
 2335 
 2336   if (i)
 2337   {
 2338     fputs("echo Checking configuration files...\n", scriptfile);
 2339 
 2340     fputs("for file in", scriptfile);
 2341     for (; i > 0; i --, file ++)
 2342       if (file->type == 'C' && file->subpackage == subpackage)
 2343         qprintf(scriptfile, " %s", file->dst);
 2344 
 2345     fputs("; do\n", scriptfile);
 2346     fputs(" if test ! -f \"$file\"; then\n", scriptfile);
 2347     fputs("     cp \"$file.N\" \"$file\"\n", scriptfile);
 2348     fputs(" fi\n", scriptfile);
 2349     fputs("done\n", scriptfile);
 2350   }
 2351 
 2352   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2353     if (file->type == 'R' && file->subpackage == subpackage)
 2354       break;
 2355 
 2356   if (i)
 2357   {
 2358     fputs("echo Removing files that are no longer used...\n", scriptfile);
 2359 
 2360     fputs("for file in", scriptfile);
 2361     for (; i > 0; i --, file ++)
 2362       if (file->type == 'R' && file->subpackage == subpackage)
 2363         qprintf(scriptfile, " %s", file->dst);
 2364 
 2365     fputs("; do\n", scriptfile);
 2366     fputs(" rm -f \"$file\"\n", scriptfile);
 2367     fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile);
 2368     fputs("     mv -f \"$file.O\" \"$file\"\n", scriptfile);
 2369     fputs(" fi\n", scriptfile);
 2370     fputs("done\n", scriptfile);
 2371   }
 2372 
 2373   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2374     if (file->type == 'I' && file->subpackage == subpackage)
 2375       break;
 2376 
 2377   if (i)
 2378   {
 2379     fputs("echo Setting up init scripts...\n", scriptfile);
 2380 
 2381    /*
 2382     * Find where the frigging init scripts go...
 2383     */
 2384 
 2385     fputs("rcdir=\"\"\n", scriptfile);
 2386     fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile);
 2387     fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o "
 2388           "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile);
 2389     fputs("     rcdir=\"$dir\"\n", scriptfile);
 2390     fputs(" fi\n", scriptfile);
 2391     fputs("done\n", scriptfile);
 2392     fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile);
 2393     fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile);
 2394     fputs("     for file in", scriptfile);
 2395     for (; i > 0; i --, file ++)
 2396       if (tolower(file->type) == 'I' && file->subpackage == subpackage)
 2397         qprintf(scriptfile, " %s", file->dst);
 2398     fputs("; do\n", scriptfile);
 2399     fputs("         rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile);
 2400     qprintf(scriptfile, "           ln -s %s/init.d/$file "
 2401                         "/usr/local/etc/rc.d/$file.sh\n",
 2402             SoftwareDir);
 2403     fputs("     done\n", scriptfile);
 2404     fputs(" else\n", scriptfile);
 2405     fputs("     echo Unable to determine location of startup scripts!\n", scriptfile);
 2406     fputs(" fi\n", scriptfile);
 2407     fputs("else\n", scriptfile);
 2408     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2409       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2410       {
 2411     fputs(" if test -d $rcdir/init.d; then\n", scriptfile);
 2412     qprintf(scriptfile, "       /bin/rm -f $rcdir/init.d/%s\n", file->dst);
 2413     qprintf(scriptfile, "       /bin/ln -s %s/init.d/%s "
 2414                     "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst);
 2415     fputs(" else\n", scriptfile);
 2416     fputs("     if test -d /etc/init.d; then\n", scriptfile);
 2417     qprintf(scriptfile, "           /bin/rm -f /etc/init.d/%s\n", file->dst);
 2418     qprintf(scriptfile, "           /bin/ln -s %s/init.d/%s "
 2419                     "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst);
 2420     fputs("     fi\n", scriptfile);
 2421     fputs(" fi\n", scriptfile);
 2422 
 2423     for (runlevels = get_runlevels(dist->files + i, "0235");
 2424              isdigit(*runlevels & 255);
 2425          runlevels ++)
 2426     {
 2427       if (*runlevels == '0')
 2428             number = get_stop(file, 0);
 2429       else
 2430         number = get_start(file, 99);
 2431 
 2432           fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels);
 2433       qprintf(scriptfile, "     /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n",
 2434               *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst);
 2435       qprintf(scriptfile, "     /bin/ln -s %s/init.d/%s "
 2436                               "$rcdir/rc%c.d/%c%02d%s\n",
 2437           SoftwareDir, file->dst, *runlevels,
 2438           *runlevels == '0' ? 'K' : 'S', number, file->dst);
 2439       fputs("   fi\n", scriptfile);
 2440         }
 2441 
 2442 #ifdef __sgi
 2443         fputs(" if test -x /etc/chkconfig; then\n", scriptfile);
 2444         qprintf(scriptfile, "       /etc/chkconfig -f %s on\n", file->dst);
 2445         fputs(" fi\n", scriptfile);
 2446 #endif /* __sgi */
 2447       }
 2448 
 2449     fputs("fi\n", scriptfile);
 2450   }
 2451 
 2452   write_commands(dist, scriptfile, COMMAND_POST_PATCH, subpackage);
 2453 
 2454   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2455     if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2456       qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst);
 2457 
 2458   fputs("echo Patching is complete.\n", scriptfile);
 2459 
 2460   fclose(scriptfile);
 2461 
 2462   return (0);
 2463 }
 2464 
 2465 
 2466 /*
 2467  * 'write_remove()' - Write the removal script.
 2468  */
 2469 
 2470 static int              /* O - -1 on error, 0 on success */
 2471 write_remove(dist_t     *dist,      /* I - Software distribution */
 2472              const char *prodname,  /* I - Product name */
 2473              int        rootsize,   /* I - Size of root files in kbytes */
 2474          int        usrsize,    /* I - Size of /usr files in kbytes */
 2475          const char *directory, /* I - Directory */
 2476          const char *subpackage)    /* I - Subpackage */
 2477 {
 2478   int       i;          /* Looping var */
 2479   int       col;            /* Current column */
 2480   FILE      *scriptfile;        /* Remove script */
 2481   char      filename[1024];     /* Name of temporary file */
 2482   char      prodfull[255];      /* Full product name */
 2483   file_t    *file;          /* Software file */
 2484   const char    *runlevels;     /* Run levels */
 2485   int       number;         /* Start/stop number */
 2486 
 2487 
 2488   if (Verbosity)
 2489     puts("Writing removal script...");
 2490 
 2491   if (subpackage)
 2492     snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage);
 2493   else
 2494     strlcpy(prodfull, prodname, sizeof(prodfull));
 2495 
 2496   snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull);
 2497 
 2498   if ((scriptfile = write_common(dist, "Removal", rootsize, usrsize,
 2499                                  filename, subpackage)) == NULL)
 2500   {
 2501     fprintf(stderr, "epm: Unable to create removal script \"%s\" -\n"
 2502                     "     %s\n", filename, strerror(errno));
 2503     return (-1);
 2504   }
 2505 
 2506   fputs("if test ! \"$*\" = \"now\"; then\n", scriptfile);
 2507   fputs("   echo \"\"\n", scriptfile);
 2508   qprintf(scriptfile, " echo This removal script will remove the %s\n",
 2509           dist->product);
 2510   qprintf(scriptfile, " echo software version %s from your system.\n",
 2511           dist->version);
 2512   fputs("   echo \"\"\n", scriptfile);
 2513   fputs("   while true ; do\n", scriptfile);
 2514   fputs("       echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile);
 2515   fputs("       read yesno\n", scriptfile);
 2516   fputs("       case \"$yesno\" in\n", scriptfile);
 2517   fputs("           y | yes | Y | Yes | YES)\n", scriptfile);
 2518   fputs("           break\n", scriptfile);
 2519   fputs("           ;;\n", scriptfile);
 2520   fputs("           n | no | N | No | NO)\n", scriptfile);
 2521   fputs("           exit 1\n", scriptfile);
 2522   fputs("           ;;\n", scriptfile);
 2523   fputs("           *)\n", scriptfile);
 2524   fputs("           echo Please enter yes or no.\n", scriptfile);
 2525   fputs("           ;;\n", scriptfile);
 2526   fputs("       esac\n", scriptfile);
 2527   fputs("   done\n", scriptfile);
 2528   fputs("fi\n", scriptfile);
 2529 
 2530  /*
 2531   * Find any removal commands in the list file...
 2532   */
 2533 
 2534   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2535     if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2536       qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst);
 2537 
 2538   write_commands(dist, scriptfile, COMMAND_PRE_REMOVE, subpackage);
 2539 
 2540   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2541     if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2542       break;
 2543 
 2544   if (i)
 2545   {
 2546     fputs("echo Cleaning up init scripts...\n", scriptfile);
 2547 
 2548    /*
 2549     * Find where the frigging init scripts go...
 2550     */
 2551 
 2552     fputs("rcdir=\"\"\n", scriptfile);
 2553     fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile);
 2554     fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o "
 2555           "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile);
 2556     fputs("     rcdir=\"$dir\"\n", scriptfile);
 2557     fputs(" fi\n", scriptfile);
 2558     fputs("done\n", scriptfile);
 2559     fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile);
 2560     fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile);
 2561     fputs("     for file in", scriptfile);
 2562     for (; i > 0; i --, file ++)
 2563       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2564         qprintf(scriptfile, " %s", file->dst);
 2565     fputs("; do\n", scriptfile);
 2566     fputs("         rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile);
 2567     fputs("     done\n", scriptfile);
 2568     fputs(" else\n", scriptfile);
 2569     fputs("     echo Unable to determine location of startup scripts!\n", scriptfile);
 2570     fputs(" fi\n", scriptfile);
 2571     fputs("else\n", scriptfile);
 2572     for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2573       if (tolower(file->type) == 'i' && file->subpackage == subpackage)
 2574       {
 2575         qprintf(scriptfile, "   %s/init.d/%s stop\n", SoftwareDir, file->dst);
 2576 
 2577     fputs(" if test -d $rcdir/init.d; then\n", scriptfile);
 2578     qprintf(scriptfile, "       /bin/rm -f $rcdir/init.d/%s\n", file->dst);
 2579     fputs(" else\n", scriptfile);
 2580     fputs("     if test -d /etc/init.d; then\n", scriptfile);
 2581     qprintf(scriptfile, "           /bin/rm -f /etc/init.d/%s\n", file->dst);
 2582     fputs("     fi\n", scriptfile);
 2583     fputs(" fi\n", scriptfile);
 2584 
 2585     for (runlevels = get_runlevels(dist->files + i, "0235");
 2586              isdigit(*runlevels & 255);
 2587          runlevels ++)
 2588     {
 2589       if (*runlevels == '0')
 2590             number = get_stop(file, 0);
 2591       else
 2592         number = get_start(file, 99);
 2593 
 2594           fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels);
 2595       qprintf(scriptfile, "     /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n",
 2596               *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst);
 2597       fputs("   fi\n", scriptfile);
 2598         }
 2599 
 2600 #ifdef __sgi
 2601         fputs(" if test -x /etc/chkconfig; then\n", scriptfile);
 2602         qprintf(scriptfile, "       rm -f /etc/config/%s\n", file->dst);
 2603         fputs(" fi\n", scriptfile);
 2604 #endif /* __sgi */
 2605       }
 2606 
 2607     fputs("fi\n", scriptfile);
 2608   }
 2609 
 2610   fputs("echo Removing/restoring installed files...\n", scriptfile);
 2611 
 2612   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2613     if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 2614         strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
 2615       break;
 2616 
 2617   if (i)
 2618   {
 2619     col = fputs("for file in", scriptfile);
 2620     for (; i > 0; i --, file ++)
 2621       if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 2622           strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage)
 2623       {
 2624         if (col > 80)
 2625       col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
 2626     else
 2627           col += qprintf(scriptfile, " %s", file->dst);
 2628       }
 2629 
 2630     fputs("; do\n", scriptfile);
 2631     fputs(" rm -f \"$file\"\n", scriptfile);
 2632     fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile);
 2633     fputs("     mv -f \"$file.O\" \"$file\"\n", scriptfile);
 2634     fputs(" fi\n", scriptfile);
 2635     fputs("done\n", scriptfile);
 2636   }
 2637 
 2638   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2639     if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 2640         strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
 2641       break;
 2642 
 2643   if (i)
 2644   {
 2645     fputs("if test -w /usr ; then\n", scriptfile);
 2646     col = fputs("   for file in", scriptfile);
 2647     for (; i > 0; i --, file ++)
 2648       if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') &&
 2649           strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage)
 2650       {
 2651         if (col > 80)
 2652       col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
 2653     else
 2654           col += qprintf(scriptfile, " %s", file->dst);
 2655       }
 2656 
 2657     fputs("; do\n", scriptfile);
 2658     fputs("     rm -f \"$file\"\n", scriptfile);
 2659     fputs("     if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile);
 2660     fputs("         mv -f \"$file.O\" \"$file\"\n", scriptfile);
 2661     fputs("     fi\n", scriptfile);
 2662     fputs(" done\n", scriptfile);
 2663     fputs("fi\n", scriptfile);
 2664   }
 2665 
 2666   fputs("echo Checking configuration files...\n", scriptfile);
 2667 
 2668   for (i = dist->num_files, file = dist->files; i > 0; i --, file ++)
 2669     if (tolower(file->type) == 'c' && file->subpackage == subpackage)
 2670       break;
 2671 
 2672   if (i)
 2673   {
 2674     col = fputs("for file in", scriptfile);
 2675     for (; i > 0; i --, file ++)
 2676       if (tolower(file->type) == 'c' && file->subpackage == subpackage)
 2677       {
 2678         if (col > 80)
 2679       col = qprintf(scriptfile, " \\\n%s", file->dst) - 2;
 2680     else
 2681           col += qprintf(scriptfile, " %s", file->dst);
 2682       }
 2683 
 2684     fputs("; do\n", scriptfile);
 2685     fputs(" if cmp -s \"$file\" \"$file.N\"; then\n", scriptfile);
 2686     fputs("     # Config file not changed\n", scriptfile);
 2687     fputs("     rm -f \"$file\"\n", scriptfile);
 2688     fputs(" fi\n", scriptfile);
 2689     fputs(" rm -f \"$file.N\"\n", scriptfile);
 2690     fputs("done\n", scriptfile);
 2691   }
 2692 
 2693   for (i = dist->num_files, file = dist->files + i - 1; i > 0; i --, file --)
 2694     if (tolower(file->type) == 'd' && file->subpackage == subpackage)
 2695       break;
 2696 
 2697   if (i)
 2698   {
 2699     fputs("echo Removing empty installation directories...\n", scriptfile);
 2700 
 2701     for (; i > 0; i --, file --)
 2702       if (tolower(file->type) == 'd' && file->subpackage == subpackage)
 2703       {
 2704     qprintf(scriptfile, "if test -d %s; then\n", file->dst);
 2705     qprintf(scriptfile, "   rmdir %s >/dev/null 2>&1\n", file->dst);
 2706     fputs("fi\n", scriptfile);
 2707       }
 2708   }
 2709 
 2710   write_commands(dist, scriptfile, COMMAND_POST_REMOVE, subpackage);
 2711 
 2712   fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull);
 2713 
 2714   fputs("echo Removal is complete.\n", scriptfile);
 2715 
 2716   fclose(scriptfile);
 2717 
 2718   return (0);
 2719 }
 2720 
 2721 
 2722 /*
 2723  * 'write_space_checks()' - Write disk space checks for the installer.
 2724  */
 2725 
 2726 static int              /* O - 0 on success, -1 on error */
 2727 write_space_checks(const char *prodname,/* I - Distribution name */
 2728                    FILE       *fp,  /* I - File to write to */
 2729                    const char *sw,  /* I - / archive */
 2730            const char *ss,  /* I - /usr archive */
 2731            int        rootsize, /* I - / install size in kbytes */
 2732            int        usrsize)  /* I - /usr install size in kbytes */
 2733 {
 2734   fputs("case `uname` in\n", fp);
 2735   fputs("   AIX)\n", fp);
 2736   fputs("   dfroot=`df -k / | tr '\\n' ' '`\n", fp);
 2737   fputs("   dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
 2738   fputs("   fsroot=`echo $dfroot | awk '{print $15}'`\n", fp);
 2739   fputs("   sproot=`echo $dfroot | awk '{print $11}'`\n", fp);
 2740   fputs("   fsusr=`echo $dfusr | awk '{print $15}'`\n", fp);
 2741   fputs("   spusr=`echo $dfusr | awk '{print $11}'`\n", fp);
 2742   fputs("   ;;\n\n", fp);
 2743   fputs("   HP-UX)\n", fp);
 2744   fputs("   dfroot=`df -k / | tr '\\n' ' '`\n", fp);
 2745   fputs("   dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
 2746   fputs("   fsroot=`echo $dfroot | awk '{print $1}'`\n", fp);
 2747   fputs("   sproot=`echo $dfroot | awk '{print $9}'`\n", fp);
 2748   fputs("   fsusr=`echo $dfusr | awk '{print $1}'`\n", fp);
 2749   fputs("   spusr=`echo $dfusr | awk '{print $9}'`\n", fp);
 2750   fputs("   ;;\n\n", fp);
 2751   fputs("   IRIX*)\n", fp);
 2752   fputs("   dfroot=`df -k / | tr '\\n' ' '`\n", fp);
 2753   fputs("   dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
 2754   fputs("   fsroot=`echo $dfroot | awk '{print $15}'`\n", fp);
 2755   fputs("   sproot=`echo $dfroot | awk '{print $13}'`\n", fp);
 2756   fputs("   fsusr=`echo $dfusr | awk '{print $15}'`\n", fp);
 2757   fputs("   spusr=`echo $dfusr | awk '{print $13}'`\n", fp);
 2758   fputs("   ;;\n\n", fp);
 2759   fputs("   SCO*)\n", fp);
 2760   fputs("   dfroot=`df -k -B / | tr '\\n' ' '`\n", fp);
 2761   fputs("   dfusr=`df -k -B /usr | tr '\\n' ' '`\n", fp);
 2762   fputs("   fsroot=`echo $dfroot | awk '{print $13}'`\n", fp);
 2763   fputs("   sproot=`echo $dfroot | awk '{print $11}'`\n", fp);
 2764   fputs("   fsusr=`echo $dfusr | awk '{print $13}'`\n", fp);
 2765   fputs("   spusr=`echo $dfusr | awk '{print $11}'`\n", fp);
 2766   fputs("   ;;\n\n", fp);
 2767   fputs("   *)\n", fp);
 2768   fputs("   dfroot=`df -k / | tr '\\n' ' '`\n", fp);
 2769   fputs("   dfusr=`df -k /usr | tr '\\n' ' '`\n", fp);
 2770   fputs("   fsroot=`echo $dfroot | awk '{print $13}'`\n", fp);
 2771   fputs("   sproot=`echo $dfroot | awk '{print $11}'`\n", fp);
 2772   fputs("   fsusr=`echo $dfusr | awk '{print $13}'`\n", fp);
 2773   fputs("   spusr=`echo $dfusr | awk '{print $11}'`\n", fp);
 2774   fputs("   ;;\n", fp);
 2775   fputs("esac\n", fp);
 2776   fputs("\n", fp);
 2777 
 2778   fputs("if test x$sproot = x -o x$spusr = x; then\n", fp);
 2779   fputs("   echo WARNING: Unable to determine available disk space\\; "
 2780         "installing blindly...\n", fp);
 2781   fputs("else\n", fp);
 2782   fputs("   if test x$fsroot = x$fsusr; then\n", fp);
 2783   fprintf(fp, "     if test %d -gt $sproot; then\n", rootsize + usrsize);
 2784   fputs("           echo Not enough free disk space for "
 2785         "software:\n", fp);
 2786   fprintf(fp, "         echo You need %d kbytes but only have "
 2787               "$sproot kbytes available.\n", rootsize + usrsize);
 2788   fputs("           exit 1\n", fp);
 2789   fputs("       fi\n", fp);
 2790   fputs("   else\n", fp);
 2791   fprintf(fp, "     if test %d -gt $sproot; then\n", rootsize);
 2792   fputs("           echo Not enough free disk space for "
 2793         "software:\n", fp);
 2794   fprintf(fp, "         echo You need %d kbytes in / but only have "
 2795               "$sproot kbytes available.\n", rootsize);
 2796   fputs("           exit 1\n", fp);
 2797   fputs("       fi\n", fp);
 2798   fputs("\n", fp);
 2799   fprintf(fp, "     if test %d -gt $spusr; then\n", usrsize);
 2800   fputs("           echo Not enough free disk space for "
 2801         "software:\n", fp);
 2802   fprintf(fp, "         echo You need %d kbytes in /usr but only have "
 2803               "$spusr kbytes available.\n", usrsize);
 2804   fputs("           exit 1\n", fp);
 2805   fputs("       fi\n", fp);
 2806   fputs("   fi\n", fp);
 2807   fputs("fi\n", fp);
 2808 
 2809   return (0);
 2810 }