/* * Portable package gateway for the ESP Package Manager (EPM). * * Copyright 1999-2017 by Michael R Sweet * Copyright 1999-2010 by Easy Software Products. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* * Include necessary headers... */ #include "epm.h" /* * Local functions... */ static void clean_distfiles(const char *directory, const char *prodname, const char *platname, dist_t *dist, const char *subpackage); static int write_combined(const char *title, const char *directory, const char *prodname, const char *platname, dist_t *dist, const char **files, time_t deftime, const char *setup, const char *types); static int write_commands(dist_t *dist, FILE *fp, int type, const char *subpackage); static FILE *write_common(dist_t *dist, const char *title, int rootsize, int usrsize, const char *filename, const char *subpackage); static int write_confcheck(FILE *fp); static int write_depends(const char *prodname, dist_t *dist, FILE *fp, const char *subpackage); static int write_distfiles(const char *directory, const char *prodname, const char *platname, dist_t *dist, time_t deftime, const char *subpackage); static int write_install(dist_t *dist, const char *prodname, int rootsize, int usrsize, const char *directory, const char *subpackage); static int write_instfiles(tarf_t *tarfile, const char *directory, const char *prodname, const char *platname, const char **files, const char *destdir, const char *subpackage); static int write_patch(dist_t *dist, const char *prodname, int rootsize, int usrsize, const char *directory, const char *subpackage); static int write_remove(dist_t *dist, const char *prodname, int rootsize, int usrsize, const char *directory, const char *subpackage); static int write_space_checks(const char *prodname, FILE *fp, const char *sw, const char *ss, int rootsize, int usrsize); /* * 'make_portable()' - Make a portable software distribution package. */ int /* O - 1 = success, 0 = fail */ make_portable(const char *prodname, /* I - Product short name */ const char *directory,/* I - Directory for distribution files */ const char *platname, /* I - Platform name */ dist_t *dist, /* I - Distribution information */ struct utsname *platform, /* I - Platform information */ const char *setup, /* I - Setup GUI image */ const char *types) /* I - Setup GUI install types */ { int i; /* Looping var */ int havepatchfiles; /* 1 if we have patch files, 0 otherwise */ time_t deftime; /* File creation time */ file_t *file; /* Software file */ static const char *distfiles[] = /* Distribution files */ { "install", "license", "readme", "remove", "ss", "sw", NULL }; static const char *patchfiles[] = /* Patch files */ { "patch", "license", "pss", "psw", "readme", "remove", NULL }; REF(platform); if (Verbosity) puts("Creating PORTABLE distribution..."); /* * See if we need to make a patch distribution... */ for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (isupper((int)file->type)) break; havepatchfiles = i > 0; deftime = time(NULL); /* * Build the main package and all of the subpackages... */ if (write_distfiles(directory, prodname, platname, dist, deftime, NULL)) return (1); for (i = 0; i < dist->num_subpackages; i ++) if (write_distfiles(directory, prodname, platname, dist, deftime, dist->subpackages[i])) return (1); /* * Create the distribution archives... */ if (write_combined("distribution", directory, prodname, platname, dist, distfiles, deftime, setup, types)) return (1); if (havepatchfiles) if (write_combined("patch", directory, prodname, platname, dist, patchfiles, deftime, setup, types)) return (1); /* * Cleanup... */ if (!KeepFiles) { clean_distfiles(directory, prodname, platname, dist, NULL); for (i = 0; i < dist->num_subpackages; i ++) clean_distfiles(directory, prodname, platname, dist, dist->subpackages[i]); } /* * Return! */ return (0); } /* * 'clean_distfiles()' - Remove temporary software distribution files... */ static void clean_distfiles(const char *directory, /* I - Directory */ const char *prodname, /* I - Product name */ const char *platname, /* I - Platform name */ dist_t *dist, /* I - Distribution */ const char *subpackage) /* I - Subpackage */ { char prodfull[255], /* Full name of product */ filename[1024]; /* Name of temporary file */ /* * Figure out the full name of the distribution... */ if (subpackage) snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); else strlcpy(prodfull, prodname, sizeof(prodfull)); /* * Remove the distribution files... */ if (Verbosity) printf("Removing %s temporary files...\n", prodfull); snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.psw", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.ss", directory, prodfull); unlink(filename); snprintf(filename, sizeof(filename), "%s/%s.sw", directory, prodfull); unlink(filename); } /* * 'write_combined()' - Write all of the distribution files in tar files. */ static int /* O - 0 on success, -1 on failure */ write_combined(const char *title, /* I - Title */ const char *directory, /* I - Output directory */ const char *prodname, /* I - Base product name */ const char *platname, /* I - Platform name */ dist_t *dist, /* I - Distribution */ const char **files, /* I - Files */ time_t deftime, /* I - Default timestamp */ const char *setup, /* I - Setup program */ const char *types) /* I - Setup types file */ { int i; /* Looping var */ tarf_t *tarfile; /* Distribution tar file */ char tarfilename[1024], /* Name of tar file */ filename[1024]; /* Name of temporary file */ #ifdef __APPLE__ FILE *fp; /* Plist file... */ #endif /* __APPLE__ */ struct stat srcstat; /* Source file information */ const char *destdir; /* Destination directory */ const char *setup_img; /* Setup image name */ /* * Figure out the filename... */ if (dist->release[0]) snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s-%s", directory, prodname, dist->version, dist->release); else snprintf(tarfilename, sizeof(tarfilename), "%s/%s-%s", directory, prodname, dist->version); if (!strcmp(title, "patch")) strlcat(tarfilename, "-patch", sizeof(tarfilename)); if (platname[0]) { strlcat(tarfilename, "-", sizeof(tarfilename)); strlcat(tarfilename, platname, sizeof(tarfilename)); } strlcat(tarfilename, ".tar.gz", sizeof(tarfilename)); /* * Open output file... */ if ((tarfile = tar_open(tarfilename, 1)) == NULL) { fprintf(stderr, "epm: Unable to create output pipe to gzip -\n %s\n", strerror(errno)); return (-1); } if (Verbosity) printf("Writing %s archive:\n", title); #ifdef __APPLE__ if (setup) { /* * Create directories for the setup application... */ if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", "Install.app", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", "Install.app/Contents", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", "Install.app/Contents/MacOS", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_header(tarfile, TAR_DIR, (mode_t)0755, (size_t)0, deftime, "root", "root", "Install.app/Contents/Resources", NULL) < 0) { tar_close(tarfile); return (-1); } /* * Then copy the data files... */ snprintf(filename, sizeof(filename), "%s/default.icns", DataDir); stat(filename, &srcstat); if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), srcstat.st_size, srcstat.st_mtime, "root", "root", "Install.app/Contents/Resources/setup.icns", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_file(tarfile, filename) < 0) { tar_close(tarfile); return (-1); } if (Verbosity) printf(" %7.0fk setup.icns\n", (srcstat.st_size + 1023) / 1024.0); snprintf(filename, sizeof(filename), "%s/%s.setup.plist", directory, prodname); if ((fp = fopen(filename, "w")) == NULL) { fprintf(stderr, "epm: Error writing %s -\n %s\n", filename, strerror(errno)); tar_close(tarfile); return (-1); } fprintf(fp, "\n" "\n" " \n" " CFBundleInfoDictionaryVersion\n" " 6.0\n" " CFBundleExecutable\n" " setup\n" " CFBundleIdentifier\n" " org.msweet.epmsetup\n" " CFBundleVersion\n" " %s\n" " CFBundleDevelopmentRegion\n" " English\n" " NSHumanReadableCopyright\n" " Copyright %s\n" " CFAppleHelpAnchor\n" " help\n" " CFBundleName\n" " Installer for %s\n" " CFBundlePackageType\n" " APPL\n" " CFBundleSignature\n" " FLTK\n" " CFBundleIconFile\n" " setup.icns\n" " CFBundleShortVersionString\n" " %s\n" " CFBundleGetInfoString\n" " %s, Copyright %s\n" " \n" "\n", dist->version, dist->copyright, dist->product, dist->version, dist->version, dist->copyright); fclose(fp); stat(filename, &srcstat); if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), srcstat.st_size, srcstat.st_mtime, "root", "root", "Install.app/Contents/Info.plist", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_file(tarfile, filename) < 0) { tar_close(tarfile); return (-1); } if (!KeepFiles) unlink(filename); if (Verbosity) printf(" %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0); } destdir = "Install.app/Contents/Resources/"; #else /* !__APPLE__ */ destdir = ""; #endif /* __APPLE__ */ /* * Write installer files... */ if (write_instfiles(tarfile, directory, prodname, platname, files, destdir, NULL)) { tar_close(tarfile); return (-1); } for (i = 0; i < dist->num_subpackages; i ++) if (write_instfiles(tarfile, directory, prodname, platname, files, destdir, dist->subpackages[i])) { tar_close(tarfile); return (-1); } /* * Now the setup files... */ if (setup) { /* * Include the ESP Software Installation Wizard (setup)... */ if (stat(SetupProgram, &srcstat)) { fprintf(stderr, "epm: Unable to stat GUI setup program %s: %s\n", SetupProgram, strerror(errno)); tar_close(tarfile); return (-1); } #ifdef __APPLE__ if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, srcstat.st_mtime, "root", "root", "Install.app/Contents/MacOS/setup", NULL) < 0) #else if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, srcstat.st_mtime, "root", "root", "setup", NULL) < 0) #endif /* __APPLE__ */ { tar_close(tarfile); return (-1); } if (tar_file(tarfile, SetupProgram) < 0) { tar_close(tarfile); return (-1); } if (Verbosity) printf(" %7.0fk setup\n", (srcstat.st_size + 1023) / 1024.0); /* * And the image file... */ stat(setup, &srcstat); if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".gif")) setup_img = "setup.gif"; else if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".jpg")) setup_img = "setup.jpg"; else if (strlen(setup) > 4 && !strcmp(setup + strlen(setup) - 4, ".png")) setup_img = "setup.png"; else setup_img = "setup.xpm"; snprintf(filename, sizeof(filename), "%s%s", destdir, setup_img); if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, srcstat.st_mtime, "root", "root", filename, NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_file(tarfile, setup) < 0) { tar_close(tarfile); return (-1); } if (Verbosity) printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img); /* * And the types file... */ if (types) { stat(types, &srcstat); snprintf(filename, sizeof(filename), "%ssetup.types", destdir); if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, srcstat.st_mtime, "root", "root", filename, NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_file(tarfile, types) < 0) { tar_close(tarfile); return (-1); } if (Verbosity) printf(" %7.0fk setup.types\n", (srcstat.st_size + 1023) / 1024.0); } /* * And finally the uninstall stuff... */ #ifdef __APPLE__ if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", "Uninstall.app", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", "Uninstall.app/Contents", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", "Uninstall.app/Contents/MacOS", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_header(tarfile, TAR_DIR, 0755, 0, deftime, "root", "root", "Uninstall.app/Contents/Resources", NULL) < 0) { tar_close(tarfile); return (-1); } /* * Then copy the data files... */ snprintf(filename, sizeof(filename), "%s/default.icns", DataDir); stat(filename, &srcstat); if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), srcstat.st_size, srcstat.st_mtime, "root", "root", "Uninstall.app/Contents/Resources/uninst.icns", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_file(tarfile, filename) < 0) { tar_close(tarfile); return (-1); } if (Verbosity) printf(" %7.0fk uninst.icns\n", (srcstat.st_size + 1023) / 1024.0); snprintf(filename, sizeof(filename), "%s/%s.uninst.plist", directory, prodname); if ((fp = fopen(filename, "w")) == NULL) { fprintf(stderr, "epm: Error writing %s -\n %s\n", filename, strerror(errno)); tar_close(tarfile); return (-1); } fprintf(fp, "\n" "\n" " \n" " CFBundleInfoDictionaryVersion\n" " 6.0\n" " CFBundleExecutable\n" " uninst\n" " CFBundleIdentifier\n" " org.msweet.epmuninst\n" " CFBundleVersion\n" " %s\n" " CFBundleDevelopmentRegion\n" " English\n" " NSHumanReadableCopyright\n" " Copyright %s\n" " CFAppleHelpAnchor\n" " help\n" " CFBundleName\n" " Uninstaller for %s\n" " CFBundlePackageType\n" " APPL\n" " CFBundleSignature\n" " FLTK\n" " CFBundleIconFile\n" " uninst.icns\n" " CFBundleShortVersionString\n" " %s\n" " CFBundleGetInfoString\n" " %s, Copyright %s\n" " \n" "\n", dist->version, dist->copyright, dist->product, dist->version, dist->version, dist->copyright); fclose(fp); stat(filename, &srcstat); if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & (~0222), srcstat.st_size, srcstat.st_mtime, "root", "root", "Uninstall.app/Contents/Info.plist", NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_file(tarfile, filename) < 0) { tar_close(tarfile); return (-1); } if (!KeepFiles) unlink(filename); if (Verbosity) printf(" %7.0fk Info.plist\n", (srcstat.st_size + 1023) / 1024.0); #endif /* __APPLE__ */ /* * Include the ESP Software Removal Wizard (uninst)... */ if (stat(UninstProgram, &srcstat)) { fprintf(stderr, "epm: Unable to stat GUI uninstall program %s: %s\n", UninstProgram, strerror(errno)); tar_close(tarfile); return (-1); } #ifdef __APPLE__ if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, srcstat.st_mtime, "root", "root", "Uninstall.app/Contents/MacOS/uninst", NULL) < 0) #else if (tar_header(tarfile, TAR_NORMAL, 0555, srcstat.st_size, srcstat.st_mtime, "root", "root", "uninst", NULL) < 0) #endif /* __APPLE__ */ { tar_close(tarfile); return (-1); } if (tar_file(tarfile, UninstProgram) < 0) { tar_close(tarfile); return (-1); } if (Verbosity) printf(" %7.0fk uninst\n", (srcstat.st_size + 1023) / 1024.0); #ifdef __APPLE__ /* * And the image file... */ stat(setup, &srcstat); snprintf(filename, sizeof(filename), "Uninstall.app/Contents/Resources/%s", setup_img); if (tar_header(tarfile, TAR_NORMAL, 0444, srcstat.st_size, srcstat.st_mtime, "root", "root", filename, NULL) < 0) { tar_close(tarfile); return (-1); } if (tar_file(tarfile, setup) < 0) { tar_close(tarfile); return (-1); } if (Verbosity) printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, setup_img); #endif /* __APPLE__ */ } if (Verbosity) { puts(" ------- ----------------------------------------"); printf(" %7.0fk %s-%s", tarfile->blocks * 0.5f, prodname, dist->version); if (dist->release[0]) printf("-%s", dist->release); if (!strcmp(title, "patch")) fputs("-patch", stdout); if (platname[0]) printf("-%s", platname); puts(".tar"); } tar_close(tarfile); if (Verbosity) { stat(tarfilename, &srcstat); puts(" ------- ----------------------------------------"); printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, tarfilename); } #ifdef __APPLE__ { char dmgfilename[1024]; /* Disk image filename */ /* * Make a disk image containing the package files... */ if (dist->release[0]) snprintf(filename, sizeof(filename), "%s/%s-%s-%s", directory, prodname, dist->version, dist->release); else snprintf(filename, sizeof(filename), "%s/%s-%s", directory, prodname, dist->version); if (!strcmp(title, "patch")) strlcat(filename, "-patch", sizeof(filename)); if (platname[0]) { strlcat(filename, "-", sizeof(filename)); strlcat(filename, platname, sizeof(filename)); } snprintf(dmgfilename, sizeof(dmgfilename), "%s.dmg", filename); mkdir(filename, 0777); if (run_command(filename, "tar xvzf ../%s", strrchr(tarfilename, '/') + 1)) { fputs("epm: Unable to create disk image template folder!\n", stderr); return (1); } if (run_command(NULL, "hdiutil create -ov -srcfolder %s %s", filename, dmgfilename)) { fputs("epm: Unable to create disk image!\n", stderr); return (1); } if (!KeepFiles) unlink_directory(filename); if (Verbosity) { stat(dmgfilename, &srcstat); printf(" %7.0fk %s\n", (srcstat.st_size + 1023) / 1024.0, dmgfilename); } } #endif /* __APPLE__ */ return (0); } /* * 'write_commands()' - Write commands. */ static int /* O - 0 on success, -1 on failure */ write_commands(dist_t *dist, /* I - Distribution */ FILE *fp, /* I - File pointer */ int type, /* I - Type of commands to write */ const char *subpackage) /* I - Subsystem */ { int i; /* Looping var */ command_t *c; /* Current command */ static const char *commands[] = /* Command strings */ { "pre-install", "post-install", "pre-patch", "post-patch", "pre-remove", "post-remove" }; for (i = dist->num_commands, c = dist->commands; i > 0; i --, c ++) if (c->type == type && c->subpackage == subpackage) break; if (i) { fprintf(fp, "echo Running %s commands...\n", commands[type]); for (; i > 0; i --, c ++) if (c->type == type && c->subpackage == subpackage) if (fprintf(fp, "%s\n", c->command) < 1) { perror("epm: Error writing command"); return (-1); } } return (0); } /* * 'write_common()' - Write the common shell script header. */ static FILE * /* O - File pointer */ write_common(dist_t *dist, /* I - Distribution */ const char *title, /* I - "Installation", etc... */ int rootsize, /* I - Size of root files in kbytes */ int usrsize, /* I - Size of /usr files in kbytes */ const char *filename, /* I - Script to create */ const char *subpackage) /* I - Subpackage name */ { int i; /* Looping var */ FILE *fp; /* File pointer */ char line[1024], /* Line buffer */ *start, /* Start of line */ *ptr; /* Pointer into line */ /* * Remove any existing copy of the file... */ unlink(filename); /* * Create the script file... */ if ((fp = fopen(filename, "w")) == NULL) return (NULL); /* * Update the permissions on the file... */ fchmod(fileno(fp), 0755); /* * Write the standard header... */ fputs("#!/bin/sh\n", fp); fprintf(fp, "# %s script for %s version %s.\n", title, dist->product, dist->version); fputs("# Produced using " EPM_VERSION " (https://michaelrsweet.github.io/epm).\n", fp); fprintf(fp, "#%%product %s", dist->product); if (subpackage) { for (i = 0; i < dist->num_descriptions; i ++) if (dist->descriptions[i].subpackage == subpackage) break; if (i < dist->num_descriptions) { strlcpy(line, dist->descriptions[i].description, sizeof(line)); if ((ptr = strchr(line, '\n')) != NULL) *ptr = '\0'; fprintf(fp, " - %s", line); } } fputs("\n", fp); fprintf(fp, "#%%vendor %s\n", dist->vendor); fprintf(fp, "#%%copyright %s\n", dist->copyright); fprintf(fp, "#%%version %s %d\n", dist->version, dist->vernumber); for (i = 0; i < dist->num_descriptions; i ++) if (dist->descriptions[i].subpackage == subpackage) break; if (i < dist->num_descriptions) { /* * Just do descriptions for this subpackage... */ for (; i < dist->num_descriptions; i ++) if (dist->descriptions[i].subpackage == subpackage) { strlcpy(line, dist->descriptions[i].description, sizeof(line)); for (start = line; start; start = ptr) { if ((ptr = strchr(start, '\n')) != NULL) *ptr++ = '\0'; fprintf(fp, "#%%description %s\n", start); } } } else { /* * Just do descriptions for the main package... */ for (i = 0; i < dist->num_descriptions; i ++) if (dist->descriptions[i].subpackage == NULL) { strlcpy(line, dist->descriptions[i].description, sizeof(line)); for (start = line; start; start = ptr) { if ((ptr = strchr(start, '\n')) != NULL) *ptr++ = '\0'; fprintf(fp, "#%%description %s\n", start); } } } fprintf(fp, "#%%rootsize %d\n", rootsize); fprintf(fp, "#%%usrsize %d\n", usrsize); fputs("#\n", fp); fputs("PATH=/usr/gnu/bin:/usr/xpg4/bin:/bin:/usr/bin:/usr/ucb:${PATH}\n", fp); fputs("SHELL=/bin/sh\n", fp); fputs("case \"`uname`\" in\n", fp); fputs("\tDarwin*)\n", fp); fputs("\tcase \"`id -un`\" in\n", fp); fputs("\t\troot)\n", fp); fputs("\t\t;;\n", fp); fputs("\t\t*)\n", fp); fprintf(fp, "\t\techo Sorry, you must have administrative priviledges to %s this software.\n", title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch"); fputs("\t\texit 1\n", fp); fputs("\t\t;;\n", fp); fputs("\tesac\n", fp); fputs("\t;;\n", fp); fputs("\t*)\n", fp); fputs("\tcase \"`id`\" in\n", fp); fputs("\t\tuid=0*)\n", fp); fputs("\t\t;;\n", fp); fputs("\t\t*)\n", fp); fprintf(fp, "\t\techo Sorry, you must be root to %s this software.\n", title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch"); fputs("\t\texit 1\n", fp); fputs("\t\t;;\n", fp); fputs("\tesac\n", fp); fputs("\t;;\n", fp); fputs("esac\n", fp); qprintf(fp, "echo Copyright %s\n", dist->copyright); fprintf(fp, "# Reset umask for %s...\n", title[0] == 'I' ? "install" : title[0] == 'R' ? "remove" : "patch"); fputs("umask 002\n", fp); write_confcheck(fp); /* * Return the file pointer... */ return (fp); } /* * 'write_confcheck()' - Write the echo check to find the right echo options. */ static int /* O - -1 on error, 0 on success */ write_confcheck(FILE *fp) /* I - Script file */ { /* * This is a simplified version of the autoconf test for echo; basically * we ignore the Stardent Vistra SVR4 case, since 1) we've never heard of * this OS, and 2) it doesn't provide the same functionality, specifically * the omission of a newline when prompting the user for some text. */ fputs("# Determine correct echo options...\n", fp); fputs("if (echo \"testing\\c\"; echo 1,2,3) | grep c >/dev/null; then\n", fp); fputs(" ac_n=-n\n", fp); fputs(" ac_c=\n", fp); fputs("else\n", fp); fputs(" ac_n=\n", fp); fputs(" ac_c='\\c'\n", fp); fputs("fi\n", fp); /* * This is a check for the correct options to use with the "tar" * command. */ fputs("# Determine correct extract options for the tar command...\n", fp); fputs("if test `uname` = Darwin; then\n", fp); fputs(" ac_tar=\"tar -xpPf\"\n", fp); fputs("elif test \"`tar --help 2>&1 | grep GNU`\" = \"\"; then\n", fp); fputs(" ac_tar=\"tar -xpf\"\n", fp); fputs("else\n", fp); fputs(" ac_tar=\"tar -xpPf\"\n", fp); fputs("fi\n", fp); return (0); } /* * 'write_depends()' - Write dependencies. */ static int /* O - 0 on success, - 1 on failure */ write_depends(const char *prodname, /* I - Product name */ dist_t *dist, /* I - Distribution */ FILE *fp, /* I - File pointer */ const char *subpackage) /* I - Subpackage */ { int i; /* Looping var */ depend_t *d; /* Current dependency */ const char *product; /* Product/file to depend on */ static const char *depends[] = /* Dependency strings */ { "requires", "incompat", "replaces", "provides" }; for (i = 0, d = dist->depends; i < dist->num_depends; i ++, d ++) if (d->subpackage == subpackage) { if (!strcmp(d->product, "_self")) product = prodname; else product = d->product; fprintf(fp, "#%%%s %s %d %d\n", depends[(int)d->type], product, d->vernumber[0], d->vernumber[1]); switch (d->type) { case DEPEND_REQUIRES : if (product[0] == '/') { /* * Require a file... */ qprintf(fp, "if test ! -r %s -a ! -h %s; then\n", product, product); qprintf(fp, " echo Sorry, you must first install \\'%s\\'!\n", product); fputs(" exit 1\n", fp); fputs("fi\n", fp); } else { /* * Require a product... */ fprintf(fp, "if test ! -x %s/%s.remove; then\n", SoftwareDir, product); fprintf(fp, " if test -x %s.install; then\n", product); fprintf(fp, " echo Installing required %s software...\n", product); fprintf(fp, " ./%s.install now\n", product); fputs(" else\n", fp); fprintf(fp, " echo Sorry, you must first install \\'%s\\'!\n", product); fputs(" exit 1\n", fp); fputs(" fi\n", fp); fputs("fi\n", fp); if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX) { /* * Do version number checking... */ fprintf(fp, "installed=`grep \'^#%%version\' " "%s/%s.remove | awk \'{print $3}\'`\n", SoftwareDir, product); fputs("if test x$installed = x; then\n", fp); fputs(" installed=0\n", fp); fputs("fi\n", fp); fprintf(fp, "if test $installed -lt %d -o $installed -gt %d; then\n", d->vernumber[0], d->vernumber[1]); fprintf(fp, " if test -x %s.install; then\n", product); fprintf(fp, " echo Installing required %s software...\n", product); fprintf(fp, " ./%s.install now\n", product); fputs(" else\n", fp); fprintf(fp, " echo Sorry, you must first install \\'%s\\' version %s to %s!\n", product, d->version[0], d->version[1]); fputs(" exit 1\n", fp); fputs(" fi\n", fp); fputs("fi\n", fp); } } break; case DEPEND_INCOMPAT : if (product[0] == '/') { /* * Incompatible with a file... */ qprintf(fp, "if test -r %s -o -h %s; then\n", product, product); qprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\'!\n", product); fputs(" echo Please remove it first.\n", fp); fputs(" exit 1\n", fp); fputs("fi\n", fp); } else { /* * Incompatible with a product... */ fprintf(fp, "if test -x %s/%s.remove; then\n", SoftwareDir, product); if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX) { /* * Do version number checking... */ fprintf(fp, " installed=`grep \'^#%%version\' " "%s/%s.remove | awk \'{print $3}\'`\n", SoftwareDir, product); fputs(" if test x$installed = x; then\n", fp); fputs(" installed=0\n", fp); fputs(" fi\n", fp); fprintf(fp, " if test $installed -ge %d -a $installed -le %d; then\n", d->vernumber[0], d->vernumber[1]); fprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\' version %s to %s!\n", product, d->version[0], d->version[1]); fprintf(fp, " echo Please remove it first by running \\'%s/%s.remove\\'.\n", SoftwareDir, product); fputs(" exit 1\n", fp); fputs(" fi\n", fp); } else { fprintf(fp, " echo Sorry, this software is incompatible with \\'%s\\'!\n", product); fprintf(fp, " echo Please remove it first by running \\'%s/%s.remove\\'.\n", SoftwareDir, product); fputs(" exit 1\n", fp); } fputs("fi\n", fp); } break; case DEPEND_REPLACES : fprintf(fp, "if test -x %s/%s.remove; then\n", SoftwareDir, product); if (d->vernumber[0] > 0 || d->vernumber[1] < INT_MAX) { /* * Do version number checking... */ fprintf(fp, " installed=`grep \'^#%%version\' " "%s/%s.remove | awk \'{print $3}\'`\n", SoftwareDir, product); fputs(" if test x$installed = x; then\n", fp); fputs(" installed=0\n", fp); fputs(" fi\n", fp); fprintf(fp, " if test $installed -ge %d -a $installed -le %d; then\n", d->vernumber[0], d->vernumber[1]); fprintf(fp, " echo Automatically replacing \\'%s\\'...\n", product); fprintf(fp, " %s/%s.remove now\n", SoftwareDir, product); fputs(" fi\n", fp); } else { fprintf(fp, " echo Automatically replacing \\'%s\\'...\n", product); fprintf(fp, " %s/%s.remove now\n", SoftwareDir, product); } fputs("fi\n", fp); break; } } return (0); } /* * 'write_distfiles()' - Write a software distribution... */ static int /* O - -1 on error, 0 on success */ write_distfiles(const char *directory, /* I - Directory */ const char *prodname, /* I - Product name */ const char *platname, /* I - Platform name */ dist_t *dist, /* I - Distribution */ time_t deftime, /* I - Default file time */ const char *subpackage) /* I - Subpackage */ { int i; /* Looping var */ int havepatchfiles; /* 1 if we have patch files, 0 otherwise */ tarf_t *tarfile; /* Distribution tar file */ char prodfull[255], /* Full name of product */ swname[255], /* Name of distribution tar file */ pswname[255], /* Name of patch tar file */ filename[1024]; /* Name of temporary file */ struct stat srcstat; /* Source file information */ file_t *file; /* Software file */ int rootsize, /* Size of files in root partition */ usrsize; /* Size of files in /usr partition */ int prootsize, /* Size of patch files in root partition */ pusrsize; /* Size of patch files in /usr partition */ /* * Figure out the full name of the distribution... */ if (subpackage) snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); else strlcpy(prodfull, prodname, sizeof(prodfull)); /* * See if we need to make a patch distribution... */ for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (isupper((int)file->type) && file->subpackage == subpackage) break; havepatchfiles = i > 0; /* * Copy the license and readme files... */ if (Verbosity) printf("Copying %s license and readme files...\n", prodfull); if (dist->license[0]) { snprintf(filename, sizeof(filename), "%s/%s.license", directory, prodfull); if (copy_file(filename, dist->license, 0444, getuid(), getgid())) return (1); } if (dist->readme[0]) { snprintf(filename, sizeof(filename), "%s/%s.readme", directory, prodfull); if (copy_file(filename, dist->readme, 0444, getuid(), getgid())) return (1); } /* * Create the non-shared software distribution file... */ if (Verbosity) puts("Creating non-shared software distribution file..."); snprintf(swname, sizeof(swname), "%s.sw", prodfull); snprintf(filename, sizeof(filename), "%s/%s", directory, swname); unlink(filename); if ((tarfile = tar_open(filename, CompressFiles)) == NULL) { fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", filename, strerror(errno)); return (1); } for (i = dist->num_files, file = dist->files, rootsize = 0, prootsize = 0; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) switch (tolower(file->type)) { case 'f' : /* Regular file */ case 'c' : /* Config file */ case 'i' : /* Init script */ if (stat(file->src, &srcstat)) { fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno)); tar_close(tarfile); return (1); } rootsize += (srcstat.st_size + 1023) / 1024; if (isupper(file->type & 255)) prootsize += (srcstat.st_size + 1023) / 1024; /* * Configuration files are extracted to the config file name with * .N appended; add a bit of script magic to check if the config * file already exists, and if not we copy the .N to the config * file location... */ if (tolower(file->type) == 'c') snprintf(filename, sizeof(filename), "%s.N", file->dst); else if (tolower(file->type) == 'i') snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir, file->dst); else strlcpy(filename, file->dst, sizeof(filename)); if (Verbosity > 1) printf("%s -> %s...\n", file->src, filename); if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, srcstat.st_mtime, file->user, file->group, filename, NULL) < 0) { tar_close(tarfile); return (1); } if (tar_file(tarfile, file->src) < 0) { tar_close(tarfile); return (1); } break; case 'd' : /* Create directory */ if (Verbosity > 1) printf("Directory %s...\n", file->dst); rootsize ++; if (isupper(file->type & 255)) prootsize ++; break; case 'l' : /* Link file */ if (Verbosity > 1) printf("%s -> %s...\n", file->src, file->dst); if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, file->user, file->group, file->dst, file->src) < 0) { tar_close(tarfile); return (1); } rootsize ++; if (isupper(file->type & 255)) prootsize ++; break; } tar_close(tarfile); /* * Create the shared software distribution file... */ if (Verbosity) puts("Creating shared software distribution file..."); snprintf(swname, sizeof(swname), "%s.ss", prodfull); snprintf(filename, sizeof(filename), "%s/%s", directory, swname); unlink(filename); if ((tarfile = tar_open(filename, CompressFiles)) == NULL) { fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", filename, strerror(errno)); return (1); } for (i = dist->num_files, file = dist->files, usrsize = 0, pusrsize = 0; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) switch (tolower(file->type)) { case 'f' : /* Regular file */ case 'c' : /* Config file */ case 'i' : /* Init script */ if (stat(file->src, &srcstat)) { fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno)); tar_close(tarfile); return (1); } usrsize += (srcstat.st_size + 1023) / 1024; if (isupper(file->type & 255)) pusrsize += (srcstat.st_size + 1023) / 1024; /* * Configuration files are extracted to the config file name with * .N appended; add a bit of script magic to check if the config * file already exists, and if not we copy the .N to the config * file location... */ if (tolower(file->type) == 'c') snprintf(filename, sizeof(filename), "%s.N", file->dst); else if (tolower(file->type) == 'i') snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir, file->dst); else strlcpy(filename, file->dst, sizeof(filename)); if (Verbosity > 1) printf("%s -> %s...\n", file->src, filename); if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, srcstat.st_mtime, file->user, file->group, filename, NULL) < 0) { tar_close(tarfile); return (1); } if (tar_file(tarfile, file->src) < 0) { tar_close(tarfile); return (1); } break; case 'd' : /* Create directory */ if (Verbosity > 1) printf("%s...\n", file->dst); usrsize ++; if (isupper(file->type & 255)) pusrsize ++; break; case 'l' : /* Link file */ if (Verbosity > 1) printf("%s -> %s...\n", file->src, file->dst); if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, file->user, file->group, file->dst, file->src) < 0) { tar_close(tarfile); return (1); } usrsize ++; if (isupper(file->type & 255)) pusrsize ++; break; } tar_close(tarfile); /* * Create the patch distribution files... */ if (havepatchfiles) { if (Verbosity) puts("Creating non-shared software patch file..."); snprintf(pswname, sizeof(pswname), "%s.psw", prodfull); snprintf(filename, sizeof(filename), "%s/%s", directory, pswname); unlink(filename); if ((tarfile = tar_open(filename, CompressFiles)) == NULL) { fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", filename, strerror(errno)); return (1); } for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) switch (file->type) { case 'C' : /* Config file */ case 'F' : /* Regular file */ case 'I' : /* Init script */ if (stat(file->src, &srcstat)) { fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno)); tar_close(tarfile); return (1); } /* * Configuration files are extracted to the config file name with * .N appended; add a bit of script magic to check if the config * file already exists, and if not we copy the .N to the config * file location... */ if (file->type == 'C') snprintf(filename, sizeof(filename), "%s.N", file->dst); else if (file->type == 'I') snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir, file->dst); else strlcpy(filename, file->dst, sizeof(filename)); if (Verbosity > 1) printf("%s -> %s...\n", file->src, filename); if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, srcstat.st_mtime, file->user, file->group, filename, NULL) < 0) { tar_close(tarfile); return (1); } if (tar_file(tarfile, file->src) < 0) { tar_close(tarfile); return (1); } break; case 'd' : /* Create directory */ if (Verbosity > 1) printf("%s...\n", file->dst); break; case 'L' : /* Link file */ if (Verbosity > 1) printf("%s -> %s...\n", file->src, file->dst); if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, file->user, file->group, file->dst, file->src) < 0) { tar_close(tarfile); return (1); } break; } tar_close(tarfile); if (Verbosity) puts("Creating shared software patch file..."); snprintf(pswname, sizeof(pswname), "%s.pss", prodfull); snprintf(filename, sizeof(filename), "%s/%s", directory, pswname); unlink(filename); if ((tarfile = tar_open(filename, CompressFiles)) == NULL) { fprintf(stderr, "epm: Unable to create file \"%s\" -\n %s\n", filename, strerror(errno)); return (1); } for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) switch (file->type) { case 'C' : /* Config file */ case 'F' : /* Regular file */ case 'I' : /* Init script */ if (stat(file->src, &srcstat)) { fprintf(stderr, "epm: Cannot stat \"%s\": %s\n", file->src, strerror(errno)); tar_close(tarfile); return (1); } /* * Configuration files are extracted to the config file name with * .N appended; add a bit of script magic to check if the config * file already exists, and if not we copy the .N to the config * file location... */ if (file->type == 'C') snprintf(filename, sizeof(filename), "%s.N", file->dst); else if (file->type == 'I') snprintf(filename, sizeof(filename), "%s/init.d/%s", SoftwareDir, file->dst); else strlcpy(filename, file->dst, sizeof(filename)); if (Verbosity > 1) printf("%s -> %s...\n", file->src, filename); if (tar_header(tarfile, TAR_NORMAL, file->mode, srcstat.st_size, srcstat.st_mtime, file->user, file->group, filename, NULL) < 0) { tar_close(tarfile); return (1); } if (tar_file(tarfile, file->src) < 0) { tar_close(tarfile); return (1); } break; case 'd' : /* Create directory */ if (Verbosity > 1) printf("%s...\n", file->dst); break; case 'L' : /* Link file */ if (Verbosity > 1) printf("%s -> %s...\n", file->src, file->dst); if (tar_header(tarfile, TAR_SYMLINK, file->mode, 0, deftime, file->user, file->group, file->dst, file->src) < 0) { tar_close(tarfile); return (1); } break; } tar_close(tarfile); } /* * Create the scripts... */ if (write_install(dist, prodname, rootsize, usrsize, directory, subpackage)) return (1); if (havepatchfiles) if (write_patch(dist, prodname, prootsize, pusrsize, directory, subpackage)) return (1); if (write_remove(dist, prodname, rootsize, usrsize, directory, subpackage)) return (1); /* * Return... */ return (0); } /* * 'write_install()' - Write the installation script. */ static int /* O - -1 on error, 0 on success */ write_install(dist_t *dist, /* I - Software distribution */ const char *prodname, /* I - Product name */ int rootsize, /* I - Size of root files in kbytes */ int usrsize, /* I - Size of /usr files in kbytes */ const char *directory, /* I - Directory */ const char *subpackage) /* I - Subpackage */ { int i; /* Looping var */ int col; /* Column in the output */ FILE *scriptfile; /* Install script */ char prodfull[255]; /* Full product name */ char filename[1024]; /* Name of temporary file */ file_t *file; /* Software file */ const char *runlevels; /* Run levels */ int number; /* Start/stop number */ if (Verbosity) puts("Writing installation script..."); if (subpackage) snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); else strlcpy(prodfull, prodname, sizeof(prodfull)); snprintf(filename, sizeof(filename), "%s/%s.install", directory, prodfull); if ((scriptfile = write_common(dist, "Installation", rootsize, usrsize, filename, subpackage)) == NULL) { fprintf(stderr, "epm: Unable to create installation script \"%s\" -\n" " %s\n", filename, strerror(errno)); return (-1); } fputs("if test \"$*\" = \"now\"; then\n", scriptfile); fputs(" echo Software license silently accepted via command-line option.\n", scriptfile); fputs("else\n", scriptfile); fputs(" echo \"\"\n", scriptfile); qprintf(scriptfile, " echo This installation script will install the %s\n", dist->product); qprintf(scriptfile, " echo software version %s on your system.\n", dist->version); fputs(" echo \"\"\n", scriptfile); fputs(" while true ; do\n", scriptfile); fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile); fputs(" read yesno\n", scriptfile); fputs(" case \"$yesno\" in\n", scriptfile); fputs(" y | yes | Y | Yes | YES)\n", scriptfile); fputs(" break\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" n | no | N | No | NO)\n", scriptfile); fputs(" exit 1\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" *)\n", scriptfile); fputs(" echo Please enter yes or no.\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" esac\n", scriptfile); fputs(" done\n", scriptfile); if (dist->license[0]) { fprintf(scriptfile, " more %s.license\n", prodfull); fputs(" echo \"\"\n", scriptfile); fputs(" while true ; do\n", scriptfile); fputs(" echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile); fputs(" read yesno\n", scriptfile); fputs(" case \"$yesno\" in\n", scriptfile); fputs(" y | yes | Y | Yes | YES)\n", scriptfile); fputs(" break\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" n | no | N | No | NO)\n", scriptfile); fputs(" exit 1\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" *)\n", scriptfile); fputs(" echo Please enter yes or no.\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" esac\n", scriptfile); fputs(" done\n", scriptfile); } fputs("fi\n", scriptfile); fprintf(scriptfile, "if test -x %s/%s.remove; then\n", SoftwareDir, prodfull); fprintf(scriptfile, " echo Removing old versions of %s software...\n", prodfull); fprintf(scriptfile, " %s/%s.remove now\n", SoftwareDir, prodfull); fputs("fi\n", scriptfile); write_space_checks(prodfull, scriptfile, rootsize ? "sw" : NULL, usrsize ? "ss" : NULL, rootsize, usrsize); write_depends(prodname, dist, scriptfile, subpackage); write_commands(dist, scriptfile, COMMAND_PRE_INSTALL, subpackage); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) break; if (i) { fputs("echo Backing up old versions of non-shared files to be installed...\n", scriptfile); col = fputs("for file in", scriptfile); for (; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) { if (col > 80) col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; else col += qprintf(scriptfile, " %s", file->dst); } fputs("; do\n", scriptfile); fputs(" if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile); fputs(" mv -f \"$file\" \"$file.O\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); } for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) break; if (i) { fputs("if test -w /usr ; then\n", scriptfile); fputs(" echo Backing up old versions of shared files to be installed...\n", scriptfile); col = fputs(" for file in", scriptfile); for (; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) { if (col > 80) col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; else col += qprintf(scriptfile, " %s", file->dst); } fputs("; do\n", scriptfile); fputs(" if test -d \"$file\" -o -f \"$file\" -o -h \"$file\"; then\n", scriptfile); fputs(" mv -f \"$file\" \"$file.O\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs(" done\n", scriptfile); fputs("fi\n", scriptfile); } for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'd' && file->subpackage == subpackage) break; if (i) { fputs("echo Creating installation directories...\n", scriptfile); for (; i > 0; i --, file ++) if (tolower(file->type) == 'd' && file->subpackage == subpackage) { qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n", file->dst, file->dst, file->dst); qprintf(scriptfile, " mkdir -p %s\n", file->dst); fputs("else\n", scriptfile); qprintf(scriptfile, " if test -f %s; then\n", file->dst); qprintf(scriptfile, " echo Error: %s already exists as a regular file!\n", file->dst); fputs(" exit 1\n", scriptfile); fputs(" fi\n", scriptfile); fputs("fi\n", scriptfile); qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst); } } fputs("echo Installing software...\n", scriptfile); if (rootsize) { if (CompressFiles) fprintf(scriptfile, "gzip -dc %s.sw | $ac_tar -\n", prodfull); else fprintf(scriptfile, "$ac_tar %s.sw\n", prodfull); } if (usrsize) { fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile); if (CompressFiles) fprintf(scriptfile, " gzip -dc %s.ss | $ac_tar -\n", prodfull); else fprintf(scriptfile, " $ac_tar %s.ss\n", prodfull); fputs("fi\n", scriptfile); } fprintf(scriptfile, "if test -d %s; then\n", SoftwareDir); fprintf(scriptfile, " rm -f %s/%s.remove\n", SoftwareDir, prodfull); fputs("else\n", scriptfile); fprintf(scriptfile, " mkdir -p %s\n", SoftwareDir); fputs("fi\n", scriptfile); fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir); fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'c' && file->subpackage == subpackage) break; if (i) { fputs("echo Checking configuration files...\n", scriptfile); col = fputs("for file in", scriptfile); for (; i > 0; i --, file ++) if (tolower(file->type) == 'c' && file->subpackage == subpackage) { if (col > 80) col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; else col += qprintf(scriptfile, " %s", file->dst); } fputs("; do\n", scriptfile); fputs(" if test ! -f \"$file\"; then\n", scriptfile); fputs(" cp \"$file.N\" \"$file\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); } fputs("echo Updating file permissions...\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) != 0 && strcmp(file->user, "root") != 0 && file->subpackage == subpackage) switch (tolower(file->type)) { case 'c' : qprintf(scriptfile, "chown %s %s.N\n", file->user, file->dst); qprintf(scriptfile, "chgrp %s %s.N\n", file->group, file->dst); case 'f' : qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); break; } fputs("if test -f /usr/.writetest; then\n", scriptfile); fputs(" rm -f /usr/.writetest\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) == 0 && strcmp(file->user, "root") != 0 && file->subpackage == subpackage) switch (tolower(file->type)) { case 'c' : qprintf(scriptfile, " chown %s %s.N\n", file->user, file->dst); qprintf(scriptfile, " chgrp %s %s.N\n", file->group, file->dst); case 'f' : qprintf(scriptfile, " chown %s %s\n", file->user, file->dst); qprintf(scriptfile, " chgrp %s %s\n", file->group, file->dst); break; } fputs("fi\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) break; if (i) { fputs("echo Setting up init scripts...\n", scriptfile); /* * Find where the frigging init scripts go... */ fputs("rcdir=\"\"\n", scriptfile); fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile); fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o " "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile); fputs(" rcdir=\"$dir\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile); fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile); fputs(" for file in", scriptfile); for (; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) qprintf(scriptfile, " %s", file->dst); fputs("; do\n", scriptfile); fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile); qprintf(scriptfile, " ln -s %s/init.d/$file " "/usr/local/etc/rc.d/$file.sh\n", SoftwareDir); fputs(" done\n", scriptfile); fputs(" else\n", scriptfile); fputs(" echo Unable to determine location of startup scripts!\n", scriptfile); fputs(" fi\n", scriptfile); fputs("else\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) { fputs(" if test -d $rcdir/init.d; then\n", scriptfile); qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst); fputs(" else\n", scriptfile); fputs(" if test -d /etc/init.d; then\n", scriptfile); qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst); qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst); fputs(" fi\n", scriptfile); fputs(" fi\n", scriptfile); for (runlevels = get_runlevels(dist->files + i, "0235"); isdigit(*runlevels & 255); runlevels ++) { if (*runlevels == '0') number = get_stop(file, 0); else number = get_start(file, 99); fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels); qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " "$rcdir/rc%c.d/%c%02d%s\n", SoftwareDir, file->dst, *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); fputs(" fi\n", scriptfile); } #ifdef __sgi fputs(" if test -x /etc/chkconfig; then\n", scriptfile); qprintf(scriptfile, " /etc/chkconfig -f %s on\n", file->dst); fputs(" fi\n", scriptfile); #endif /* __sgi */ } fputs("fi\n", scriptfile); } write_commands(dist, scriptfile, COMMAND_POST_INSTALL, subpackage); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst); fputs("echo Installation is complete.\n", scriptfile); fclose(scriptfile); return (0); } /* * 'write_instfiles()' - Write the installer files to the tar file... */ static int /* O - 0 = success, -1 on failure */ write_instfiles(tarf_t *tarfile, /* I - Distribution tar file */ const char *directory, /* I - Output directory */ const char *prodname, /* I - Base product name */ const char *platname, /* I - Platform name */ const char **files, /* I - Files */ const char *destdir, /* I - Destination directory in tar file */ const char *subpackage) /* I - Subpackage */ { int i; /* Looping var */ char srcname[1024], /* Name of source file in distribution */ dstname[1024], /* Name of destination file in distribution */ prodfull[255]; /* Full name of product */ struct stat srcstat; /* Source file information */ if (subpackage) snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); else strlcpy(prodfull, prodname, sizeof(prodfull)); for (i = 0; files[i] != NULL; i ++) { snprintf(srcname, sizeof(srcname), "%s/%s.%s", directory, prodfull, files[i]); snprintf(dstname, sizeof(dstname), "%s%s.%s", destdir, prodfull, files[i]); if (stat(srcname, &srcstat)) { if (!i) break; else continue; } if (srcstat.st_size == 0) continue; if (tar_header(tarfile, TAR_NORMAL, srcstat.st_mode & 07555, srcstat.st_size, srcstat.st_mtime, "root", "root", dstname, NULL) < 0) { return (-1); } if (tar_file(tarfile, srcname) < 0) return (-1); if (Verbosity) printf(" %7.0fk %s.%s\n", (srcstat.st_size + 1023) / 1024.0, prodfull, files[i]); } return (0); } /* * 'write_patch()' - Write the patch script. */ static int /* O - -1 on error, 0 on success */ write_patch(dist_t *dist, /* I - Software distribution */ const char *prodname, /* I - Product name */ int rootsize, /* I - Size of root files in kbytes */ int usrsize, /* I - Size of /usr files in kbytes */ const char *directory, /* I - Directory */ const char *subpackage) /* I - Subpackage */ { int i; /* Looping var */ FILE *scriptfile; /* Patch script */ char filename[1024]; /* Name of temporary file */ char prodfull[255]; /* Full product name */ file_t *file; /* Software file */ const char *runlevels; /* Run levels */ int number; /* Start/stop number */ if (Verbosity) puts("Writing patch script..."); if (subpackage) snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); else strlcpy(prodfull, prodname, sizeof(prodfull)); snprintf(filename, sizeof(filename), "%s/%s.patch", directory, prodfull); if ((scriptfile = write_common(dist, "Patch", rootsize, usrsize, filename, subpackage)) == NULL) { fprintf(stderr, "epm: Unable to create patch script \"%s\" -\n" " %s\n", filename, strerror(errno)); return (-1); } fputs("if test \"$*\" = \"now\"; then\n", scriptfile); fputs(" echo Software license silently accepted via command-line option.\n", scriptfile); fputs("else\n", scriptfile); fputs(" echo \"\"\n", scriptfile); qprintf(scriptfile, " echo This installation script will patch the %s\n", dist->product); qprintf(scriptfile, " echo software to version %s on your system.\n", dist->version); fputs(" echo \"\"\n", scriptfile); fputs(" while true ; do\n", scriptfile); fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile); fputs(" read yesno\n", scriptfile); fputs(" case \"$yesno\" in\n", scriptfile); fputs(" y | yes | Y | Yes | YES)\n", scriptfile); fputs(" break\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" n | no | N | No | NO)\n", scriptfile); fputs(" exit 1\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" *)\n", scriptfile); fputs(" echo Please enter yes or no.\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" esac\n", scriptfile); fputs(" done\n", scriptfile); if (dist->license[0]) { fprintf(scriptfile, " more %s.license\n", prodfull); fputs(" echo \"\"\n", scriptfile); fputs(" while true ; do\n", scriptfile); fputs(" echo $ac_n \"Do you agree with the terms of this license? $ac_c\"\n", scriptfile); fputs(" read yesno\n", scriptfile); fputs(" case \"$yesno\" in\n", scriptfile); fputs(" y | yes | Y | Yes | YES)\n", scriptfile); fputs(" break\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" n | no | N | No | NO)\n", scriptfile); fputs(" exit 1\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" *)\n", scriptfile); fputs(" echo Please enter yes or no.\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" esac\n", scriptfile); fputs(" done\n", scriptfile); } fputs("fi\n", scriptfile); write_space_checks(prodfull, scriptfile, rootsize ? "psw" : NULL, usrsize ? "pss" : NULL, rootsize, usrsize); write_depends(prodname, dist, scriptfile, subpackage); fprintf(scriptfile, "if test ! -x %s/%s.remove; then\n", SoftwareDir, prodfull); fputs(" echo You do not appear to have the base software installed!\n", scriptfile); fputs(" echo Please install the full distribution instead.\n", scriptfile); fputs(" exit 1\n", scriptfile); fputs("fi\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst); write_commands(dist, scriptfile, COMMAND_PRE_PATCH, subpackage); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (file->type == 'D' && file->subpackage == subpackage) break; if (i) { fputs("echo Creating new installation directories...\n", scriptfile); for (; i > 0; i --, file ++) if (file->type == 'D' && file->subpackage == subpackage) { qprintf(scriptfile, "if test ! -d %s -a ! -f %s -a ! -h %s; then\n", file->dst, file->dst, file->dst); qprintf(scriptfile, " mkdir -p %s\n", file->dst); fputs("else\n", scriptfile); qprintf(scriptfile, " if test -f %s; then\n", file->dst); qprintf(scriptfile, " echo Error: %s already exists as a regular file!\n", file->dst); fputs(" exit 1\n", scriptfile); fputs(" fi\n", scriptfile); fputs("fi\n", scriptfile); qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); qprintf(scriptfile, "chmod %o %s\n", file->mode, file->dst); } } fputs("echo Patching software...\n", scriptfile); if (rootsize) { if (CompressFiles) fprintf(scriptfile, "gzip -dc %s.psw | $ac_tar -\n", prodfull); else fprintf(scriptfile, "$ac_tar %s.psw\n", prodfull); } if (usrsize) { fputs("if echo Write Test >/usr/.writetest 2>/dev/null; then\n", scriptfile); if (CompressFiles) fprintf(scriptfile, " gzip -dc %s.pss | $ac_tar -\n", prodfull); else fprintf(scriptfile, " $ac_tar %s.pss\n", prodfull); fputs("fi\n", scriptfile); } fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull); fprintf(scriptfile, "cp %s.remove %s\n", prodfull, SoftwareDir); fprintf(scriptfile, "chmod 544 %s/%s.remove\n", SoftwareDir, prodfull); fputs("echo Updating file permissions...\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) != 0 && strcmp(file->user, "root") != 0 && file->subpackage == subpackage) switch (file->type) { case 'C' : case 'F' : qprintf(scriptfile, "chown %s %s\n", file->user, file->dst); qprintf(scriptfile, "chgrp %s %s\n", file->group, file->dst); break; } fputs("if test -f /usr/.writetest; then\n", scriptfile); fputs(" rm -f /usr/.writetest\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (strncmp(file->dst, "/usr", 4) == 0 && strcmp(file->user, "root") != 0 && file->subpackage == subpackage) switch (file->type) { case 'C' : case 'F' : qprintf(scriptfile, " chown %s %s\n", file->user, file->dst); qprintf(scriptfile, " chgrp %s %s\n", file->group, file->dst); break; } fputs("fi\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (file->type == 'C' && file->subpackage == subpackage) break; if (i) { fputs("echo Checking configuration files...\n", scriptfile); fputs("for file in", scriptfile); for (; i > 0; i --, file ++) if (file->type == 'C' && file->subpackage == subpackage) qprintf(scriptfile, " %s", file->dst); fputs("; do\n", scriptfile); fputs(" if test ! -f \"$file\"; then\n", scriptfile); fputs(" cp \"$file.N\" \"$file\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); } for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (file->type == 'R' && file->subpackage == subpackage) break; if (i) { fputs("echo Removing files that are no longer used...\n", scriptfile); fputs("for file in", scriptfile); for (; i > 0; i --, file ++) if (file->type == 'R' && file->subpackage == subpackage) qprintf(scriptfile, " %s", file->dst); fputs("; do\n", scriptfile); fputs(" rm -f \"$file\"\n", scriptfile); fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile); fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); } for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (file->type == 'I' && file->subpackage == subpackage) break; if (i) { fputs("echo Setting up init scripts...\n", scriptfile); /* * Find where the frigging init scripts go... */ fputs("rcdir=\"\"\n", scriptfile); fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile); fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o " "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile); fputs(" rcdir=\"$dir\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile); fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile); fputs(" for file in", scriptfile); for (; i > 0; i --, file ++) if (tolower(file->type) == 'I' && file->subpackage == subpackage) qprintf(scriptfile, " %s", file->dst); fputs("; do\n", scriptfile); fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile); qprintf(scriptfile, " ln -s %s/init.d/$file " "/usr/local/etc/rc.d/$file.sh\n", SoftwareDir); fputs(" done\n", scriptfile); fputs(" else\n", scriptfile); fputs(" echo Unable to determine location of startup scripts!\n", scriptfile); fputs(" fi\n", scriptfile); fputs("else\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) { fputs(" if test -d $rcdir/init.d; then\n", scriptfile); qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " "$rcdir/init.d/%s\n", SoftwareDir, file->dst, file->dst); fputs(" else\n", scriptfile); fputs(" if test -d /etc/init.d; then\n", scriptfile); qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst); qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " "/etc/init.d/%s\n", SoftwareDir, file->dst, file->dst); fputs(" fi\n", scriptfile); fputs(" fi\n", scriptfile); for (runlevels = get_runlevels(dist->files + i, "0235"); isdigit(*runlevels & 255); runlevels ++) { if (*runlevels == '0') number = get_stop(file, 0); else number = get_start(file, 99); fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels); qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); qprintf(scriptfile, " /bin/ln -s %s/init.d/%s " "$rcdir/rc%c.d/%c%02d%s\n", SoftwareDir, file->dst, *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); fputs(" fi\n", scriptfile); } #ifdef __sgi fputs(" if test -x /etc/chkconfig; then\n", scriptfile); qprintf(scriptfile, " /etc/chkconfig -f %s on\n", file->dst); fputs(" fi\n", scriptfile); #endif /* __sgi */ } fputs("fi\n", scriptfile); } write_commands(dist, scriptfile, COMMAND_POST_PATCH, subpackage); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) qprintf(scriptfile, "%s/init.d/%s start\n", SoftwareDir, file->dst); fputs("echo Patching is complete.\n", scriptfile); fclose(scriptfile); return (0); } /* * 'write_remove()' - Write the removal script. */ static int /* O - -1 on error, 0 on success */ write_remove(dist_t *dist, /* I - Software distribution */ const char *prodname, /* I - Product name */ int rootsize, /* I - Size of root files in kbytes */ int usrsize, /* I - Size of /usr files in kbytes */ const char *directory, /* I - Directory */ const char *subpackage) /* I - Subpackage */ { int i; /* Looping var */ int col; /* Current column */ FILE *scriptfile; /* Remove script */ char filename[1024]; /* Name of temporary file */ char prodfull[255]; /* Full product name */ file_t *file; /* Software file */ const char *runlevels; /* Run levels */ int number; /* Start/stop number */ if (Verbosity) puts("Writing removal script..."); if (subpackage) snprintf(prodfull, sizeof(prodfull), "%s-%s", prodname, subpackage); else strlcpy(prodfull, prodname, sizeof(prodfull)); snprintf(filename, sizeof(filename), "%s/%s.remove", directory, prodfull); if ((scriptfile = write_common(dist, "Removal", rootsize, usrsize, filename, subpackage)) == NULL) { fprintf(stderr, "epm: Unable to create removal script \"%s\" -\n" " %s\n", filename, strerror(errno)); return (-1); } fputs("if test ! \"$*\" = \"now\"; then\n", scriptfile); fputs(" echo \"\"\n", scriptfile); qprintf(scriptfile, " echo This removal script will remove the %s\n", dist->product); qprintf(scriptfile, " echo software version %s from your system.\n", dist->version); fputs(" echo \"\"\n", scriptfile); fputs(" while true ; do\n", scriptfile); fputs(" echo $ac_n \"Do you wish to continue? $ac_c\"\n", scriptfile); fputs(" read yesno\n", scriptfile); fputs(" case \"$yesno\" in\n", scriptfile); fputs(" y | yes | Y | Yes | YES)\n", scriptfile); fputs(" break\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" n | no | N | No | NO)\n", scriptfile); fputs(" exit 1\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" *)\n", scriptfile); fputs(" echo Please enter yes or no.\n", scriptfile); fputs(" ;;\n", scriptfile); fputs(" esac\n", scriptfile); fputs(" done\n", scriptfile); fputs("fi\n", scriptfile); /* * Find any removal commands in the list file... */ for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) qprintf(scriptfile, "%s/init.d/%s stop\n", SoftwareDir, file->dst); write_commands(dist, scriptfile, COMMAND_PRE_REMOVE, subpackage); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) break; if (i) { fputs("echo Cleaning up init scripts...\n", scriptfile); /* * Find where the frigging init scripts go... */ fputs("rcdir=\"\"\n", scriptfile); fputs("for dir in /sbin/rc.d /sbin /etc/rc.d /etc ; do\n", scriptfile); fputs(" if test -d $dir/rc2.d -o -h $dir/rc2.d -o " "-d $dir/rc3.d -o -h $dir/rc3.d; then\n", scriptfile); fputs(" rcdir=\"$dir\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); fputs("if test \"$rcdir\" = \"\" ; then\n", scriptfile); fputs(" if test -d /usr/local/etc/rc.d; then\n", scriptfile); fputs(" for file in", scriptfile); for (; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) qprintf(scriptfile, " %s", file->dst); fputs("; do\n", scriptfile); fputs(" rm -f /usr/local/etc/rc.d/$file.sh\n", scriptfile); fputs(" done\n", scriptfile); fputs(" else\n", scriptfile); fputs(" echo Unable to determine location of startup scripts!\n", scriptfile); fputs(" fi\n", scriptfile); fputs("else\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'i' && file->subpackage == subpackage) { qprintf(scriptfile, " %s/init.d/%s stop\n", SoftwareDir, file->dst); fputs(" if test -d $rcdir/init.d; then\n", scriptfile); qprintf(scriptfile, " /bin/rm -f $rcdir/init.d/%s\n", file->dst); fputs(" else\n", scriptfile); fputs(" if test -d /etc/init.d; then\n", scriptfile); qprintf(scriptfile, " /bin/rm -f /etc/init.d/%s\n", file->dst); fputs(" fi\n", scriptfile); fputs(" fi\n", scriptfile); for (runlevels = get_runlevels(dist->files + i, "0235"); isdigit(*runlevels & 255); runlevels ++) { if (*runlevels == '0') number = get_stop(file, 0); else number = get_start(file, 99); fprintf(scriptfile, " if test -d $rcdir/rc%c.d; then\n", *runlevels); qprintf(scriptfile, " /bin/rm -f $rcdir/rc%c.d/%c%02d%s\n", *runlevels, *runlevels == '0' ? 'K' : 'S', number, file->dst); fputs(" fi\n", scriptfile); } #ifdef __sgi fputs(" if test -x /etc/chkconfig; then\n", scriptfile); qprintf(scriptfile, " rm -f /etc/config/%s\n", file->dst); fputs(" fi\n", scriptfile); #endif /* __sgi */ } fputs("fi\n", scriptfile); } fputs("echo Removing/restoring installed files...\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) break; if (i) { col = fputs("for file in", scriptfile); for (; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) != 0 && file->subpackage == subpackage) { if (col > 80) col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; else col += qprintf(scriptfile, " %s", file->dst); } fputs("; do\n", scriptfile); fputs(" rm -f \"$file\"\n", scriptfile); fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile); fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs("done\n", scriptfile); } for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) break; if (i) { fputs("if test -w /usr ; then\n", scriptfile); col = fputs(" for file in", scriptfile); for (; i > 0; i --, file ++) if ((tolower(file->type) == 'f' || tolower(file->type) == 'l') && strncmp(file->dst, "/usr", 4) == 0 && file->subpackage == subpackage) { if (col > 80) col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; else col += qprintf(scriptfile, " %s", file->dst); } fputs("; do\n", scriptfile); fputs(" rm -f \"$file\"\n", scriptfile); fputs(" if test -d \"$file.O\" -o -f \"$file.O\" -o -h \"$file.O\"; then\n", scriptfile); fputs(" mv -f \"$file.O\" \"$file\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs(" done\n", scriptfile); fputs("fi\n", scriptfile); } fputs("echo Checking configuration files...\n", scriptfile); for (i = dist->num_files, file = dist->files; i > 0; i --, file ++) if (tolower(file->type) == 'c' && file->subpackage == subpackage) break; if (i) { col = fputs("for file in", scriptfile); for (; i > 0; i --, file ++) if (tolower(file->type) == 'c' && file->subpackage == subpackage) { if (col > 80) col = qprintf(scriptfile, " \\\n%s", file->dst) - 2; else col += qprintf(scriptfile, " %s", file->dst); } fputs("; do\n", scriptfile); fputs(" if cmp -s \"$file\" \"$file.N\"; then\n", scriptfile); fputs(" # Config file not changed\n", scriptfile); fputs(" rm -f \"$file\"\n", scriptfile); fputs(" fi\n", scriptfile); fputs(" rm -f \"$file.N\"\n", scriptfile); fputs("done\n", scriptfile); } for (i = dist->num_files, file = dist->files + i - 1; i > 0; i --, file --) if (tolower(file->type) == 'd' && file->subpackage == subpackage) break; if (i) { fputs("echo Removing empty installation directories...\n", scriptfile); for (; i > 0; i --, file --) if (tolower(file->type) == 'd' && file->subpackage == subpackage) { qprintf(scriptfile, "if test -d %s; then\n", file->dst); qprintf(scriptfile, " rmdir %s >/dev/null 2>&1\n", file->dst); fputs("fi\n", scriptfile); } } write_commands(dist, scriptfile, COMMAND_POST_REMOVE, subpackage); fprintf(scriptfile, "rm -f %s/%s.remove\n", SoftwareDir, prodfull); fputs("echo Removal is complete.\n", scriptfile); fclose(scriptfile); return (0); } /* * 'write_space_checks()' - Write disk space checks for the installer. */ static int /* O - 0 on success, -1 on error */ write_space_checks(const char *prodname,/* I - Distribution name */ FILE *fp, /* I - File to write to */ const char *sw, /* I - / archive */ const char *ss, /* I - /usr archive */ int rootsize, /* I - / install size in kbytes */ int usrsize) /* I - /usr install size in kbytes */ { fputs("case `uname` in\n", fp); fputs(" AIX)\n", fp); fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); fputs(" fsroot=`echo $dfroot | awk '{print $15}'`\n", fp); fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp); fputs(" fsusr=`echo $dfusr | awk '{print $15}'`\n", fp); fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp); fputs(" ;;\n\n", fp); fputs(" HP-UX)\n", fp); fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); fputs(" fsroot=`echo $dfroot | awk '{print $1}'`\n", fp); fputs(" sproot=`echo $dfroot | awk '{print $9}'`\n", fp); fputs(" fsusr=`echo $dfusr | awk '{print $1}'`\n", fp); fputs(" spusr=`echo $dfusr | awk '{print $9}'`\n", fp); fputs(" ;;\n\n", fp); fputs(" IRIX*)\n", fp); fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); fputs(" fsroot=`echo $dfroot | awk '{print $15}'`\n", fp); fputs(" sproot=`echo $dfroot | awk '{print $13}'`\n", fp); fputs(" fsusr=`echo $dfusr | awk '{print $15}'`\n", fp); fputs(" spusr=`echo $dfusr | awk '{print $13}'`\n", fp); fputs(" ;;\n\n", fp); fputs(" SCO*)\n", fp); fputs(" dfroot=`df -k -B / | tr '\\n' ' '`\n", fp); fputs(" dfusr=`df -k -B /usr | tr '\\n' ' '`\n", fp); fputs(" fsroot=`echo $dfroot | awk '{print $13}'`\n", fp); fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp); fputs(" fsusr=`echo $dfusr | awk '{print $13}'`\n", fp); fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp); fputs(" ;;\n\n", fp); fputs(" *)\n", fp); fputs(" dfroot=`df -k / | tr '\\n' ' '`\n", fp); fputs(" dfusr=`df -k /usr | tr '\\n' ' '`\n", fp); fputs(" fsroot=`echo $dfroot | awk '{print $13}'`\n", fp); fputs(" sproot=`echo $dfroot | awk '{print $11}'`\n", fp); fputs(" fsusr=`echo $dfusr | awk '{print $13}'`\n", fp); fputs(" spusr=`echo $dfusr | awk '{print $11}'`\n", fp); fputs(" ;;\n", fp); fputs("esac\n", fp); fputs("\n", fp); fputs("if test x$sproot = x -o x$spusr = x; then\n", fp); fputs(" echo WARNING: Unable to determine available disk space\\; " "installing blindly...\n", fp); fputs("else\n", fp); fputs(" if test x$fsroot = x$fsusr; then\n", fp); fprintf(fp, " if test %d -gt $sproot; then\n", rootsize + usrsize); fputs(" echo Not enough free disk space for " "software:\n", fp); fprintf(fp, " echo You need %d kbytes but only have " "$sproot kbytes available.\n", rootsize + usrsize); fputs(" exit 1\n", fp); fputs(" fi\n", fp); fputs(" else\n", fp); fprintf(fp, " if test %d -gt $sproot; then\n", rootsize); fputs(" echo Not enough free disk space for " "software:\n", fp); fprintf(fp, " echo You need %d kbytes in / but only have " "$sproot kbytes available.\n", rootsize); fputs(" exit 1\n", fp); fputs(" fi\n", fp); fputs("\n", fp); fprintf(fp, " if test %d -gt $spusr; then\n", usrsize); fputs(" echo Not enough free disk space for " "software:\n", fp); fprintf(fp, " echo You need %d kbytes in /usr but only have " "$spusr kbytes available.\n", usrsize); fputs(" exit 1\n", fp); fputs(" fi\n", fp); fputs(" fi\n", fp); fputs("fi\n", fp); return (0); }