diff options
author | jkh <jkh@FreeBSD.org> | 1993-08-26 01:19:55 +0000 |
---|---|---|
committer | jkh <jkh@FreeBSD.org> | 1993-08-26 01:19:55 +0000 |
commit | 853359bf72fadae03d169c7590626357dcdcd77a (patch) | |
tree | b3cb91ab036ba2deccf4af07caf09c2bf6b4b88e /usr.sbin | |
parent | 19f81735f54b5e96ee67854c561dd24aba4bb00d (diff) | |
parent | e83dde8008ab2f058dd1aa3ff1d31f1eeeaac82e (diff) | |
download | FreeBSD-src-853359bf72fadae03d169c7590626357dcdcd77a.zip FreeBSD-src-853359bf72fadae03d169c7590626357dcdcd77a.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r327,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'usr.sbin')
35 files changed, 3115 insertions, 0 deletions
diff --git a/usr.sbin/pkg_install/Makefile b/usr.sbin/pkg_install/Makefile new file mode 100644 index 0000000..37a1f05 --- /dev/null +++ b/usr.sbin/pkg_install/Makefile @@ -0,0 +1,3 @@ +SUBDIR=lib add create delete info + +.include <bsd.subdir.mk> diff --git a/usr.sbin/pkg_install/Makefile.inc b/usr.sbin/pkg_install/Makefile.inc new file mode 100644 index 0000000..363c20a --- /dev/null +++ b/usr.sbin/pkg_install/Makefile.inc @@ -0,0 +1 @@ +BINDIR?= /usr/local/bin diff --git a/usr.sbin/pkg_install/add/Makefile b/usr.sbin/pkg_install/add/Makefile new file mode 100644 index 0000000..d91baba --- /dev/null +++ b/usr.sbin/pkg_install/add/Makefile @@ -0,0 +1,8 @@ +PROG= pkg_add + +CFLAGS+= -I${.CURDIR}/../lib +LDADD+= -L${.CURDIR}/../lib -linstall + +SRCS= main.c perform.c futil.c extract.c + +.include <bsd.prog.mk> diff --git a/usr.sbin/pkg_install/add/add.h b/usr.sbin/pkg_install/add/add.h new file mode 100644 index 0000000..8206f0f --- /dev/null +++ b/usr.sbin/pkg_install/add/add.h @@ -0,0 +1,39 @@ +/* $Id: add.h,v 1.3 1993/08/24 09:23:13 jkh Exp $ */ + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Include and define various things wanted by the add command. + * + */ + +#ifndef _INST_ADD_H_INCLUDE +#define _INST_ADD_H_INCLUDE + +extern char *Prefix; +extern Boolean NoInstall; +extern Boolean NoRecord; +extern char *Mode; +extern char *Owner; +extern char *Group; +extern char *Directory; +extern char *PkgName; + +int make_hierarchy(char *); +void extract_plist(char *, Package *); +void apply_perms(char *, char *); + +#endif /* _INST_ADD_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/add/extract.c b/usr.sbin/pkg_install/add/extract.c new file mode 100644 index 0000000..62ae03e --- /dev/null +++ b/usr.sbin/pkg_install/add/extract.c @@ -0,0 +1,101 @@ +#ifndef lint +static const char *rcsid = "$Id: extract.c,v 1.4 1993/08/24 09:23:14 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the package extraction code for the add module. + * + */ + +#include "lib.h" +#include "add.h" + +void +extract_plist(char *home, Package *pkg) +{ + PackingList p = pkg->head; + char *last_file; + + /* Reset the world */ + Owner = NULL; + Group = NULL; + Mode = NULL; + last_file = NULL; + Directory = home; + + /* Do it */ + while (p) { + switch(p->type) { + case PLIST_NAME: + PkgName = p->name; + if (Verbose) + printf("extract: Package name is %s\n", p->name); + break; + + case PLIST_FILE: + last_file = p->name; + if (Verbose) + printf("extract: %s/%s\n", Directory, p->name); + if (!Fake) { + copy_hierarchy(Directory, p->name, TRUE); + apply_perms(Directory, p->name); + } + break; + + case PLIST_CWD: + if (Verbose) + printf("extract: CWD to %s\n", p->name); + if (strcmp(p->name, ".")) { + if (!Fake && make_hierarchy(p->name) == FAIL) + barf("Unable make directory '%s'.", p->name); + Directory = p->name; + } + else + Directory = home; + break; + + case PLIST_CMD: + if (Verbose) + printf("extract: exec cmd '%s' (lastfile = %s)\n", p->name, + last_file); + if (!Fake && vsystem(p->name, last_file)) + whinge("Command '%s' failed.", p->name); + break; + + case PLIST_CHMOD: + Mode = p->name; + break; + + case PLIST_CHOWN: + Owner = p->name; + break; + + case PLIST_CHGRP: + Group = p->name; + break; + + case PLIST_COMMENT: + break; + + case PLIST_IGNORE: + p = p->next; + break; + } + p = p->next; + } +} diff --git a/usr.sbin/pkg_install/add/futil.c b/usr.sbin/pkg_install/add/futil.c new file mode 100644 index 0000000..2b70f5b --- /dev/null +++ b/usr.sbin/pkg_install/add/futil.c @@ -0,0 +1,86 @@ +#ifndef lint +static const char *rcsid = "$Id: futil.c,v 1.3 1993/08/26 08:12:25 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Miscellaneous file access utilities. + * + */ + +#include "lib.h" +#include "add.h" + +/* + * Assuming dir is a desired directory name, make it and all intervening + * directories necessary. + */ + +int +make_hierarchy(char *dir) +{ + char *cp1, *cp2; + + if (dir[0] == '/') + cp1 = cp2 = dir + 1; + else + cp1 = cp2 = dir; + while (cp2) { + if ((cp2 = index(cp1, '/')) !=NULL ) + *cp2 = '\0'; + if (fexists(dir)) { + if (!isdir(dir)) + return FAIL; + } + else { + if (vsystem("mkdir %s", dir)) + return FAIL; + apply_perms(NULL, dir); + } + /* Put it back */ + if (cp2) { + *cp2 = '/'; + cp1 = cp2 + 1; + } + } + return SUCCESS; +} + +/* Using permission defaults, apply them as necessary */ +void +apply_perms(char *dir, char *file) +{ + char fname[FILENAME_MAX]; + + if (!dir || *file == '/') /* absolute path? */ + strcpy(fname, file); + else + sprintf(fname, "%s/%s", dir, file); + if (Mode) + if (vsystem("chmod -R %s %s", Mode, fname)) + whinge("Couldn't change mode of '%s' to '%s'.", + fname, Mode); + if (Owner) + if (vsystem("chown -R %s %s", Owner, fname)) + whinge("Couldn't change owner of '%s' to '%s'.", + fname, Owner); + if (Group) + if (vsystem("chgrp -R %s %s", Group, fname)) + whinge("Couldn't change group of '%s' to '%s'.", + fname, Group); +} + diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c new file mode 100644 index 0000000..679dd12 --- /dev/null +++ b/usr.sbin/pkg_install/add/main.c @@ -0,0 +1,119 @@ +#ifndef lint +static char *rcsid = "$Id: main.c,v 1.5 1993/08/26 08:46:54 jkh Exp $"; +#endif + +/* + * + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the add module. + * + */ + +#include "lib.h" +#include "add.h" + +static char Options[] = "hvIRnp:"; + +char *Prefix = NULL; +Boolean NoInstall = FALSE; +Boolean NoRecord = FALSE; + +char *Mode = NULL; +char *Owner = NULL; +char *Group = NULL; +char *PkgName = NULL; +char *Directory = NULL; + +int +main(int argc, char **argv) +{ + int ch, err; + char **pkgs, **start; + char *prog_name = argv[0]; + + pkgs = start = argv; + while ((ch = getopt(argc, argv, Options)) != EOF) + switch(ch) { + case 'v': + Verbose = TRUE; + break; + + case 'p': + Prefix = optarg; + break; + + case 'I': + NoInstall = TRUE; + break; + + case 'R': + NoRecord = TRUE; + break; + + case 'n': + Fake = TRUE; + Verbose = TRUE; + break; + + case 'h': + case '?': + default: + usage(prog_name, NULL); + break; + } + + argc -= optind; + argv += optind; + + /* Get all the remaining package names, if any */ + while (*argv) + *pkgs++ = *argv++; + + /* If no packages, yelp */ + if (pkgs == start) + usage(prog_name, "Missing package name(s)"); + *pkgs = NULL; + if ((err = pkg_perform(start)) != NULL) { + if (Verbose) + fprintf(stderr, "%d package addition(s) failed.\n", err); + return err; + } + else + return 0; +} + +void +usage(const char *name, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (fmt) { + fprintf(stderr, "%s: ", name); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n\n"); + } + va_end(args); + fprintf(stderr, "Usage: %s [args] pkg [ .. pkg ]\n", name); + fprintf(stderr, "Where args are one or more of:\n\n"); + fprintf(stderr, "-v verbose\n"); + fprintf(stderr, "-p arg override prefix with arg\n"); + fprintf(stderr, "-I don't execute pkg install script, if any\n"); + fprintf(stderr, "-R don't record installation (can't delete!)\n"); + fprintf(stderr, "-n don't actually install, just show steps\n"); + exit(1); +} diff --git a/usr.sbin/pkg_install/add/perform.c b/usr.sbin/pkg_install/add/perform.c new file mode 100644 index 0000000..c86922b --- /dev/null +++ b/usr.sbin/pkg_install/add/perform.c @@ -0,0 +1,205 @@ +#ifndef lint +static const char *rcsid = "$Id: perform.c,v 1.7 1993/08/26 08:46:55 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the main body of the add module. + * + */ + +#include "lib.h" +#include "add.h" + +#include <signal.h> + +static int pkg_do(char *); +static char *find_name(Package *); +static int sanity_check(char *); +static char LogDir[FILENAME_MAX]; + + +int +pkg_perform(char **pkgs) +{ + int i, err_cnt = 0; + + signal(SIGINT, cleanup); + signal(SIGHUP, cleanup); + + for (i = 0; pkgs[i]; i++) + err_cnt += pkg_do(pkgs[i]); + return err_cnt; +} + +static Package Plist; + +/* This is seriously ugly code following. Written very fast! */ +static int +pkg_do(char *pkg) +{ + char pkg_fullname[FILENAME_MAX]; + FILE *cfile; + char *home; + int code = 0; + + /* Reset some state */ + if (Plist.head) + free_plist(&Plist); + LogDir[0] = '\0'; + home = make_playpen(); + if (pkg[0] == '/') /* full pathname? */ + strcpy(pkg_fullname, pkg); + else + sprintf(pkg_fullname, "%s/%s", home, pkg); + if (!fexists(pkg_fullname)) { + whinge("Can't open package '%s'.", pkg_fullname); + return 1; + } + + if (unpack(pkg_fullname, NULL)) + return 1; + + if (sanity_check(pkg_fullname)) + return 1; + + cfile = fopen(CONTENTS_FNAME, "r"); + if (!cfile) { + whinge("Unable to open %s file.", CONTENTS_FNAME); + goto fail; + } + /* If we have a prefix, add it now */ + if (Prefix) + add_plist(&Plist, PLIST_CWD, Prefix); + else + add_plist(&Plist, PLIST_CWD, home); + read_plist(&Plist, cfile); + fclose(cfile); + PkgName = find_name(&Plist); + if (fexists(REQUIRE_FNAME)) { + vsystem("chmod +x %s", REQUIRE_FNAME); /* be sure */ + if (Verbose) + printf("Running requirements file first for %s..\n", PkgName); + if (vsystem("%s %s INSTALL", REQUIRE_FNAME, PkgName)) { + whinge("Package %s fails requirements - not installed.", + pkg_fullname); + goto fail; + } + } + if (!NoInstall && fexists(INSTALL_FNAME)) { + vsystem("chmod +x %s", INSTALL_FNAME); /* make sure */ + if (Verbose) + printf("Running install with PRE-INSTALL for %s..\n", PkgName); + if (vsystem("%s %s PRE-INSTALL", INSTALL_FNAME, PkgName)) { + whinge("Install script returned error status."); + goto fail; + } + } + extract_plist(home, &Plist); + if (!NoInstall && fexists(INSTALL_FNAME)) { + if (Verbose) + printf("Running install with POST-INSTALL for %s..\n", PkgName); + if (vsystem("%s %s POST-INSTALL", INSTALL_FNAME, PkgName)) { + whinge("Install script returned error status."); + goto fail; + } + } + if (!NoRecord && !Fake) { + if (getuid() != 0) + whinge("Not running as root - trying to record install anyway."); + if (!PkgName) { + whinge("No package name! Can't record package, sorry."); + code = 1; + goto success; /* well, partial anyway */ + } + sprintf(LogDir, "%s/%s", LOG_DIR, PkgName); + if (Verbose) + printf("Attempting to record package into %s..\n", LogDir); + if (make_hierarchy(LogDir)) { + whinge("Can't record package into '%s', you're on your own!", + LogDir); + bzero(LogDir, FILENAME_MAX); + code = 1; + goto success; /* close enough for government work */ + } + if (fexists(DEINSTALL_FNAME)) + copy_file(".", DEINSTALL_FNAME, LogDir); + if (fexists(REQUIRE_FNAME)) + copy_file(".", REQUIRE_FNAME, LogDir); + copy_file(".", CONTENTS_FNAME, LogDir); + copy_file(".", DESC_FNAME, LogDir); + copy_file(".", COMMENT_FNAME, LogDir); + if (Verbose) + printf("Package %s registered in %s\n", PkgName, LogDir); + } + goto success; + + fail: + /* Nuke the whole (installed) show */ + if (!Fake) + delete_package(FALSE, &Plist); + + success: + /* delete the packing list contents */ + leave_playpen(); + + return code; +} + +static int +sanity_check(char *pkg) +{ + if (!fexists(CONTENTS_FNAME)) { + whinge("Package %s has no CONTENTS file!", pkg); + return 1; + } + if (!fexists(COMMENT_FNAME)) { + whinge("Package %s has no COMMENT file!", pkg); + return 1; + } + if (!fexists(DESC_FNAME)) { + whinge("Package %s has no DESC file!", pkg); + return 1; + } + return 0; +} + +static char * +find_name(Package *pkg) +{ + PackingList p = pkg->head; + + while (p) { + if (p->type == PLIST_NAME) + return p->name; + p = p->next; + } + return "anonymous"; +} + +void +cleanup(int signo) +{ + if (Plist.head) { + if (!Fake) + delete_package(FALSE, &Plist); + free_plist(&Plist); + } + if (!Fake && LogDir[0]) + vsystem("%s -rf %s", REMOVE_CMD, LogDir); + leave_playpen(); +} diff --git a/usr.sbin/pkg_install/add/pkg_add.1 b/usr.sbin/pkg_install/add/pkg_add.1 new file mode 100644 index 0000000..4e332b7 --- /dev/null +++ b/usr.sbin/pkg_install/add/pkg_add.1 @@ -0,0 +1,125 @@ +.\" +.\" FreeBSD install - a package for the installation and maintainance +.\" of non-core utilities. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" Jordan K. Hubbard +.\" +.\" +.\" @(#)pkg_add.1 +.\" +.TH pkg_add 1 "July 18, 1993" "" "FreeBSD" + +.SH NAME +pkg_add - a utility for installing software package distributions. +.SH SYNOPSIS +.na +.B pkg_add +.RB [options] +.RB "pkg-name\ [.. pkg-name]" + +.SH DESCRIPTION +The +.B pkg_add +command is used to extract packages that have been previously created +with the +.B pkg_create +command. + +.SH OPTIONS +.TP +The following command line options are supported. +.TP +.B \-v +Turns on verbose output. +.B "Optional." +.TP +.B \-I +If an installation script exists for a given package, do not execute it. +.B "Optional." +.TP +.B \-n +Don't actually install a package, just report the steps that +would be taken if it was. +.B "Optional." +.TP +.B \-R +Do not record the installation of a package. This means +that you cannot deinstall it later, so only use this option if +you know what you are doing! +.B "Optional." +.TP +.BI "\-p\ " prefix +Sets +.I prefix +as the directory in which to extract files from any packages +which do not explicitly set theirs. +.B "Optional." +.PP +.SH "TECHNICAL DETAILS" +.B +pkg_add +is fairly simple. It simply extracts the requested packages into +the current working directory and then performs the following steps: +.PP +If the package contains a +.B require +file (see +.B pkg_create +), then this is executed first with the flag +.b INSTALL +to see whether or not installation should +continue (a non-zero exit status means no). +.PP +If an +.B install +script exists for the package, it is then executed as follows: +.PP +First, before installing files in the data set, the +.B install +script is called with the flags +.PP +.B <script> +.I pkg-name PRE-INSTALL +.PP +Where +.I pkg-name +is the name of the package in question and +.I PRE-INSTALL +is a keyword denoting that this is the "pre installation" pass. +Files are then copied from the packing list into their new homes, as expected, +and the +.B install +script is then executed a second time with the flags +.PP +.B <script> +.I pkg-name POST-INSTALL +.PP +This all allows you to write an +.B install +script that does "before and after" actions. +.PP +After installation is complete, a copy of the packing list, in addition +to any +.B deinstall +script the package might have, is copied into /var/pkg/<pkg-name> +for subsequent possible use by +.B pkg-delete. +.PP +.SH BUGS +Sure to be some. +.SH "SEE ALSO" +.BR pkg_create "(" 1 ")," +.BR pkg_info "(" 1 ")," +.BR pkg_delete "(" 1 ")," +.SH AUTHORS +Jordan Hubbard + diff --git a/usr.sbin/pkg_install/create/Makefile b/usr.sbin/pkg_install/create/Makefile new file mode 100644 index 0000000..01e6b20 --- /dev/null +++ b/usr.sbin/pkg_install/create/Makefile @@ -0,0 +1,8 @@ +PROG= pkg_create + +CFLAGS+= -I${.CURDIR}/../lib +LDADD+= -L${.CURDIR}/../lib -linstall + +SRCS= main.c perform.c pl.c + +.include <bsd.prog.mk> diff --git a/usr.sbin/pkg_install/create/create.h b/usr.sbin/pkg_install/create/create.h new file mode 100644 index 0000000..2e1e73c --- /dev/null +++ b/usr.sbin/pkg_install/create/create.h @@ -0,0 +1,39 @@ +/* $Id: create.h,v 1.3 1993/08/24 09:23:32 jkh Exp $ */ + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Include and define various things wanted by the create command. + * + */ + +#ifndef _INST_CREATE_H_INCLUDE +#define _INST_CREATE_H_INCLUDE + +extern char *Prefix; +extern char *Comment; +extern char *Desc; +extern char *Install; +extern char *DeInstall; +extern char *Contents; +extern char *Require; + +void check_list(char *, Package *); +void usage(const char *, const char *, ...); +int pkg_perform(char **); +void copy_plist(char *, Package *); + +#endif /* _INST_CREATE_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/create/main.c b/usr.sbin/pkg_install/create/main.c new file mode 100644 index 0000000..63f6699 --- /dev/null +++ b/usr.sbin/pkg_install/create/main.c @@ -0,0 +1,125 @@ +#ifndef lint +static const char *rcsid = "$Id: main.c,v 1.3 1993/08/20 08:52:39 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the create module. + * + */ + +#include "lib.h" +#include "create.h" + +static char Options[] = "hvf:p:c:d:i:k:r:"; + +char *Prefix = NULL; +char *Comment = NULL; +char *Desc = NULL; +char *Install = NULL; +char *DeInstall = NULL; +char *Contents = NULL; +char *Require = NULL; + +int +main(int argc, char **argv) +{ + int ch; + char **pkgs, **start; + char *prog_name = argv[0]; + + pkgs = start = argv; + while ((ch = getopt(argc, argv, Options)) != EOF) + switch(ch) { + case 'v': + Verbose = TRUE; + break; + + case 'p': + Prefix = optarg; + break; + + case 'f': + Contents = optarg; + break; + + case 'c': + Comment = optarg; + break; + + case 'd': + Desc = optarg; + break; + + case 'i': + Install = optarg; + break; + + case 'k': + DeInstall = optarg; + break; + + case 'r': + Require = optarg; + break; + + case 'h': + case '?': + default: + usage(prog_name, NULL); + break; + } + + argc -= optind; + argv += optind; + + /* Get all the remaining package names, if any */ + while (*argv) + *pkgs++ = *argv++; + + /* If no packages, yelp */ + if (pkgs == start) + usage(prog_name, "Missing package name"); + *pkgs = NULL; + if (start[1]) + usage(prog_name, "Only one package name allowed\n\t('%s' extraneous)", + start[1]); + if (!pkg_perform(start)) { + if (Verbose) + fprintf(stderr, "Package creation failed.\n"); + return 1; + } + else + return 0; +} + +void +usage(const char *name, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (fmt) { + fprintf(stderr, "%s: ", name); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n\n"); + } + va_end(args); + fprintf(stderr, "Usage: %s [args] pkg\n\n", name); + fprintf(stderr, "Where args are one or more of:\n\n"); + + fprintf(stderr, "-c [-]file Get one-line comment from file (-or arg)\n"); + fprintf(stderr, "-d [-]file Get description from file (-or arg)\n"); + fprintf(stderr, "-f file get list of files from file (- for stdin)\n"); + fprintf(stderr, "-i script install script\n"); + fprintf(stderr, "-p arg install prefix will be arg\n"); + fprintf(stderr, "-k script de-install script\n"); + fprintf(stderr, "-r script pre/post requirements script\n"); + fprintf(stderr, "-v verbose\n"); + exit(1); +} diff --git a/usr.sbin/pkg_install/create/perform.c b/usr.sbin/pkg_install/create/perform.c new file mode 100644 index 0000000..634188b --- /dev/null +++ b/usr.sbin/pkg_install/create/perform.c @@ -0,0 +1,165 @@ +#ifndef lint +static const char *rcsid = "$Id: perform.c,v 1.4 1993/08/26 08:12:52 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the main body of the create module. + * + */ + +#include "lib.h" +#include "create.h" + +#include <signal.h> + +static void sanity_check(void); +static void make_dist(char *, char *, char *, Package *); + +int +pkg_perform(char **pkgs) +{ + char *pkg = *pkgs; /* Only one arg to create */ + char *home, *cp; + FILE *pkg_in, *fp; + Package plist; + char *suffix; /* What we tack on to the end of the finished package */ + + /* Preliminary setup */ + sanity_check(); + if (Verbose) + printf("Creating package %s\n", pkg); + get_dash_string(&Comment); + get_dash_string(&Desc); + if (!strcmp(Contents, "-")) + pkg_in = stdin; + else { + pkg_in = fopen(Contents, "r"); + if (!pkg_in) + barf("Unable to open contents file '%s' for input.", Contents); + } + plist.head = plist.tail = NULL; + + /* Break the package name into base and desired suffix (if any) */ + if ((cp = index(pkg, '.')) != NULL) { + suffix = cp + 1; + *cp = '\0'; + } + else + suffix = "tgz"; + + /* Register the package name (base part) */ + add_plist(&plist, PLIST_NAME, pkg); + if (Prefix) + add_plist(&plist, PLIST_CWD, Prefix); + + /* Slurp in the packing list */ + read_plist(&plist, pkg_in); + + /* Make a directory to stomp around in */ + home = make_playpen(); + signal(SIGINT, cleanup); + signal(SIGHUP, cleanup); + + /* Make first "real contents" pass over it */ + check_list(home, &plist); + copy_plist(home, &plist); + mark_plist(&plist); + + /* Now put the release specific items in */ + add_plist(&plist, PLIST_CWD, "."); + write_file(COMMENT_FNAME, Comment); + add_plist(&plist, PLIST_IGNORE, NULL); + add_plist(&plist, PLIST_FILE, COMMENT_FNAME); + write_file(DESC_FNAME, Desc); + add_plist(&plist, PLIST_IGNORE, NULL); + add_plist(&plist, PLIST_FILE, DESC_FNAME); + + if (Install) { + copy_file(home, Install, INSTALL_FNAME); + add_plist(&plist, PLIST_IGNORE, NULL); + add_plist(&plist, PLIST_FILE, INSTALL_FNAME); + } + if (DeInstall) { + copy_file(home, DeInstall, DEINSTALL_FNAME); + add_plist(&plist, PLIST_IGNORE, NULL); + add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME); + } + if (Require) { + copy_file(home, Require, REQUIRE_FNAME); + add_plist(&plist, PLIST_IGNORE, NULL); + add_plist(&plist, PLIST_FILE, REQUIRE_FNAME); + } + + /* Run through the list again, picking up extra "local" items */ + check_list(".", &plist); + copy_plist(".", &plist); + mark_plist(&plist); + + /* Finally, write out the packing list */ + fp = fopen(CONTENTS_FNAME, "w"); + if (!fp) + barf("Can't open file %s for writing.", CONTENTS_FNAME); + write_plist(&plist, fp); + if (fclose(fp)) + barf("Error while closing %s.", CONTENTS_FNAME); + + /* And stick it into a tar ball */ + make_dist(home, pkg, suffix, &plist); + + /* Cleanup */ + free(Comment); + free(Desc); + free_plist(&plist); + cleanup(0); + return TRUE; /* Success */ +} + +static void +make_dist(char *home, char *pkg, char *suffix, Package *plist) +{ + char tball[FILENAME_MAX]; + char args[10]; + + sprintf(tball, "%s/%s.%s", home, pkg, suffix); + if (index(suffix, 'z')) /* Compress/gzip? */ + strcpy(args, "z"); + if (Verbose) + printf("Creating gzip'd tar ball in '%s', contents:\n", tball); + strcat(args, "cf"); + if (vsystem("tar %s %s .", args, tball)) + barf("tar command failed!"); +} + +static void +sanity_check() +{ + if (!Comment) + barf("Required package comment string is missing (-c comment)."); + if (!Desc) + barf("Required package description string is missing (-d desc)."); + if (!Contents) + barf("Required package contents list is missing (-f [-]file)."); +} + + +/* Clean up those things that would otherwise hang around */ +void +cleanup(int sig) +{ + leave_playpen(); +} diff --git a/usr.sbin/pkg_install/create/pkg_create.1 b/usr.sbin/pkg_install/create/pkg_create.1 new file mode 100644 index 0000000..dd0e967 --- /dev/null +++ b/usr.sbin/pkg_install/create/pkg_create.1 @@ -0,0 +1,185 @@ +.\" +.\" FreeBSD install - a package for the installation and maintainance +.\" of non-core utilities. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" Jordan K. Hubbard +.\" +.\" +.\" @(#)pkg_create.1 +.\" +.TH pkg_create 1 "July 18, 1993" "" "FreeBSD" + +.SH NAME +pkg_create - a utility for creating software package distributions. +.SH SYNOPSIS +.na +.B pkg_create +.RB [options] +.RB pkg-name + +.SH DESCRIPTION +The +.B pkg_create +command is used to create packages that will subsequently be fed to +one of the package extraction/info utilities. The input description +and command line arguments for the creation of a package are not +really meant to be human-generated, though it is easy enough to +do so. It is more expected that you will use a front-end tool for +the job rather than muddling through it yourself. Nonetheless, a short +description of the input syntax is included in this document. + +.SH OPTIONS +.TP +The following command line options are supported. +.TP +.B \-v +Turns on verbose output. +.B "Optional." +.TP +.BI "\-c\ " [-]desc +Fetch package "one line description" from file +.I desc +or, if preceeded by +.B - +, the argument itself. This string should also +give some idea of which version of the product (if any) the package +represents. +.B "Mandatory." +.TP +.BI "\-d\ " [-]desc +Fetch long description for package from file +.I desc +or, if preceeded by +.B - +, the argument itself. +.B "Mandatory." +.TP +.BI "\-f\ " file +Fetch "packing list" for package from +.I file +or +.B stdin +if +.I file +is a +.B - +(dash). +.B "Mandatory." +.TP +.BI "\-i\ " script +Sets +.I script +to be the install procedure for the package. This can be any +executable program (or shell script). It will be invoked automatically +when the package is later installed. +.B "Optional." +.TP +.BI "\-p\ " prefix +Sets +.I prefix +As the initial directory "base" to start from in selecting files for +the package. +.B "Optional." +.TP +.BI "\-k\ " script +Sets +.I script +to be the de-install procedure for the package. This can be any +executable program (or shell script). It will be invoked automatically +when the package is later (if ever) de-installed. +.B "Optional." +.TP +.BI "\-r\ " script +Sets +.I script +to be the "requirements" procedure for the package. This can be any +executable program (or shell script). It will be invoked automatically +at installation/deinstallation time to determine whether or not +installation/deinstallation should proceed. +.B "Optional." +.PP +.SH "TECHNICAL DETAILS" +The "packing list" format (see \fB-f\fR) is fairly simple, being +nothing more than a single column of filenames to include in the +package. However, since absolute pathnames are generally a bad idea +for a package that could be installed potentially anywhere, there is +another method of specifying where things are supposed to go +and, optionally, what ownership and mode information they should be +installed with. This is done by imbeding specialized command sequences +in the packing list. Briefly described, these sequences are: +.TP +.BI "@cwd\ " directory +Sets the internal directory pointer to point to +.I directory. +All subsequent filenames will be assumed relative to this directory. +.TP +.BI "@exec\ " command +Execute +.I command +as part of the unpacking process. If +.I command +contains a `%s' sequence somewhere in it, it will be expanded to +the name of the last filename extracted. In practice, such +weird things should be unnecessary in all but the most extenuating +circumstances, but it's there should you need it nonetheless. +.TP +.BI "@mode\ " mode +Sets default permission for all subsequently extracted files to +.I mode. +Format is the same as that used by the +.B chmod +command (well, considering that it's later handed off to it, that's +no surprise). Use without an arg to set back to default (extraction) +permissions. +.TP +.BI "@owner\ " user +Sets default ownership for all subsequently extracted files to +.I user. +Use without an arg to set back to default (extraction) +ownership. +.TP +.BI "@group\ " group +Sets default group ownership for all subsequently extracted files to +.I group. +Use without an arg to set back to default (extraction) +group ownership. +.TP +.BI "@comment\ " string +Imbed a comment in the packing list. Useful in +trying to document some particularly hairy sequence that +may trip someone up later. +.TP +.BI "@ignore\ " file +Used internally to tell extraction to ignore the next file (don't +copy it anywhere), as it's used for some special purpose. Also useful +if you want to pack some specialized datafiles in with a distribution +for your install script (or something) and want to have the installer +ignore it. +.TP +.BI "@name\ " name +Sets the name of the package. This is mandatory and is usually +put at the top. This name is potentially different than the name of +the file it came in, and is used when keeping track of the package +for later deinstallation. Note that +.B pkg_create +currently derives this field from the package name and adds it +automatically. + +.SH BUGS +Sure to be some. +.SH "SEE ALSO" +.BR pkg_add "(" 1 ")," +.BR pkg_info "(" 1 ")," +.BR pkg_delete "(" 1 ")," +.SH AUTHORS +Jordan Hubbard + diff --git a/usr.sbin/pkg_install/create/pl.c b/usr.sbin/pkg_install/create/pl.c new file mode 100644 index 0000000..3b9a2d0 --- /dev/null +++ b/usr.sbin/pkg_install/create/pl.c @@ -0,0 +1,104 @@ +#ifndef lint +static const char *rcsid = "$Id: pl.c,v 1.4 1993/08/26 08:12:53 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Routines for dealing with the packing list. + * + */ + +#include "lib.h" +#include "create.h" + +#define QUERY_GZIP \ +"File '%s' appears to be gzip'd.\nWould you like to unpack it first" +#define UNZIP "gzip -d %s" + +#define QUERY_COMPRESS \ +"File '%s' appears to be compressed.\nWould you like to unpack it first" +#define UNCOMPRESS "compress -d %s" + +/* Check a list for files that require preconversion */ +void +check_list(char *home, Package *pkg) +{ + char cmd[FILENAME_MAX]; + char name[FILENAME_MAX]; + char *where = home; + PackingList p = pkg->head; + + while (p) { + if (p->type == PLIST_CWD) + where = p->name; + else if (p->type == PLIST_IGNORE) + p = p->next; + else if (p->type == PLIST_FILE) { + cmd[0] = '\0'; + sprintf(name, "%s/%s", where, p->name); + /* gzip? */ + if ((suffix(name, "gz") || suffix(name, "z")) && + y_or_n(TRUE, QUERY_GZIP, name)) + sprintf(cmd, UNZIP, name); + + /* Compress? */ + else if (suffix(name, "Z") && y_or_n(TRUE, QUERY_COMPRESS, name)) + sprintf(cmd, UNCOMPRESS, name); + + if (*cmd) { + if (Verbose) + printf("Uncompressing-> %s\n", cmd); + if (system(cmd)) + barf("%s failed!", cmd); + nuke_suffix(p->name); + } + } + p = p->next; + } +} + +/* + * Copy unmarked files in packing list to playpen - marked files + * have already been copied in an earlier pass through the list. + */ +void +copy_plist(char *home, Package *plist) +{ + PackingList p = plist->head; + char *where = home; + + while (p) { + if (p->type == PLIST_CWD) + where = p->name; + else if (p->type == PLIST_IGNORE) + p = p->next; + else if (p->type == PLIST_FILE && !p->marked) { + char fn[FILENAME_MAX]; + + /* First, look for it in the "home" dir */ + sprintf(fn, "%s/%s", home, p->name); + if (fexists(fn)) + copy_hierarchy(home, p->name, FALSE); + /* + * Otherwise, try along the actual extraction path.. + */ + else + copy_hierarchy(where, p->name, FALSE); + } + p = p->next; + } +} diff --git a/usr.sbin/pkg_install/delete/Makefile b/usr.sbin/pkg_install/delete/Makefile new file mode 100644 index 0000000..16a110f9 --- /dev/null +++ b/usr.sbin/pkg_install/delete/Makefile @@ -0,0 +1,8 @@ +PROG= pkg_delete + +CFLAGS+= -I${.CURDIR}/../lib +LDADD+= -L${.CURDIR}/../lib -linstall + +SRCS= main.c perform.c + +.include <bsd.prog.mk> diff --git a/usr.sbin/pkg_install/delete/delete.h b/usr.sbin/pkg_install/delete/delete.h new file mode 100644 index 0000000..2828cdf --- /dev/null +++ b/usr.sbin/pkg_install/delete/delete.h @@ -0,0 +1,31 @@ +/* $Id$ */ + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Include and define various things wanted by the delete command. + * + */ + +#ifndef _INST_DELETE_H_INCLUDE +#define _INST_DELETE_H_INCLUDE + +extern char *Prefix; +extern Boolean NoDeInstall; +extern char *Directory; +extern char *PkgName; + +#endif /* _INST_DELETE_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/delete/main.c b/usr.sbin/pkg_install/delete/main.c new file mode 100644 index 0000000..63bc65d --- /dev/null +++ b/usr.sbin/pkg_install/delete/main.c @@ -0,0 +1,108 @@ +#ifndef lint +static char *rcsid = "$Id: main.c,v 1.4 1993/08/26 08:47:02 jkh Exp $"; +#endif + +/* + * + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the delete module. + * + */ + +#include "lib.h" +#include "delete.h" + +static char Options[] = "hvDnp:"; + +char *Prefix = NULL; +Boolean NoDeInstall = FALSE; + +int +main(int argc, char **argv) +{ + int ch, err; + char **pkgs, **start; + char *prog_name = argv[0]; + + pkgs = start = argv; + while ((ch = getopt(argc, argv, Options)) != EOF) + switch(ch) { + case 'v': + Verbose = TRUE; + break; + + case 'p': + Prefix = optarg; + break; + + case 'D': + NoDeInstall = TRUE; + break; + + case 'n': + Fake = TRUE; + Verbose = TRUE; + break; + + case 'h': + case '?': + default: + usage(prog_name, NULL); + break; + } + + argc -= optind; + argv += optind; + + /* Get all the remaining package names, if any */ + /* Get all the remaining package names, if any */ + while (*argv) + *pkgs++ = *argv++; + + /* If no packages, yelp */ + if (pkgs == start) + usage(prog_name, "Missing package name(s)"); + *pkgs = NULL; + if ((err = pkg_perform(start)) != NULL) { + if (Verbose) + fprintf(stderr, "%d package deletion(s) failed.\n", err); + return err; + } + else + return 0; +} + +void +usage(const char *name, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (fmt) { + fprintf(stderr, "%s: ", name); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n\n"); + } + va_end(args); + fprintf(stderr, "Usage: %s [args] pkg [ .. pkg ]\n", name); + fprintf(stderr, "Where args are one or more of:\n\n"); + fprintf(stderr, "-v verbose\n"); + fprintf(stderr, "-p arg override prefix with arg\n"); + fprintf(stderr, "-D don't execute pkg de-install script, if any\n"); + fprintf(stderr, "-n don't actually de-install, just show steps\n"); + exit(1); +} diff --git a/usr.sbin/pkg_install/delete/perform.c b/usr.sbin/pkg_install/delete/perform.c new file mode 100644 index 0000000..2694a0a --- /dev/null +++ b/usr.sbin/pkg_install/delete/perform.c @@ -0,0 +1,119 @@ +#ifndef lint +static const char *rcsid = "$Id: perform.c,v 1.1 1993/08/20 08:53:36 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the main body of the delete module. + * + */ + +#include "lib.h" +#include "delete.h" + +static int pkg_do(char *); +static void sanity_check(char *); +static char LogDir[FILENAME_MAX]; + + +int +pkg_perform(char **pkgs) +{ + int i, err_cnt = 0; + + for (i = 0; pkgs[i]; i++) + err_cnt += pkg_do(pkgs[i]); + return err_cnt; +} + +static Package Plist; + +/* This is seriously ugly code following. Written very fast! */ +static int +pkg_do(char *pkg) +{ + FILE *cfile; + char home[FILENAME_MAX]; + + /* Reset some state */ + if (Plist.head) + free_plist(&Plist); + + sprintf(LogDir, "%s/%s", LOG_DIR, pkg); + if (!fexists(LogDir)) { + whinge("No such package '%s' installed.", pkg); + return 1; + } + if (!getcwd(home, FILENAME_MAX)) + barf("Unable to get current working directory!"); + if (chdir(LogDir) == FAIL) { + whinge("Unable to change directory to %s! Deinstall failed.", LogDir); + return 1; + } + sanity_check(LogDir); + if (fexists(REQUIRE_FNAME)) { + if (Verbose) + printf("Executing 'require' script.\n"); + vsystem("chmod +x %s", REQUIRE_FNAME); /* be sure */ + if (vsystem("%s %s DEINSTALL", REQUIRE_FNAME, pkg)) { + whinge("Package %s fails requirements - not deleted.", pkg); + return 1; + } + } + cfile = fopen(CONTENTS_FNAME, "r"); + if (!cfile) { + whinge("Unable to open '%s' file.", CONTENTS_FNAME); + return 1; + } + /* If we have a prefix, add it now */ + if (Prefix) + add_plist(&Plist, PLIST_CWD, Prefix); + read_plist(&Plist, cfile); + fclose(cfile); + if (!NoDeInstall && fexists(DEINSTALL_FNAME)) { + if (Fake) + printf("Would execute de-install script at this point.\n"); + else { + vsystem("chmod +x %s", DEINSTALL_FNAME); /* make sure */ + if (vsystem("%s %s DEINSTALL", DEINSTALL_FNAME, pkg)) { + whinge("De-Install script returned error status."); + return 1; + } + } + } + if (chdir(home) == FAIL) + barf("Toto! This doesn't look like Kansas anymore!"); + delete_package(FALSE, &Plist); + if (!Fake && vsystem("%s -r %s", REMOVE_CMD, LogDir)) { + whinge("Couldn't remove log entry in %s, de-install failed.", LogDir); + return 1; + } + return 0; +} + +static void +sanity_check(char *pkg) +{ + if (!fexists(CONTENTS_FNAME)) + barf("Installed package %s has no %s file!", pkg, CONTENTS_FNAME); +} + +void +cleanup(int sig) +{ + /* Nothing to do */ +} diff --git a/usr.sbin/pkg_install/delete/pkg_delete.1 b/usr.sbin/pkg_install/delete/pkg_delete.1 new file mode 100644 index 0000000..d9da7f1 --- /dev/null +++ b/usr.sbin/pkg_install/delete/pkg_delete.1 @@ -0,0 +1,107 @@ +.\" +.\" FreeBSD install - a package for the installation and maintainance +.\" of non-core utilities. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" Jordan K. Hubbard +.\" +.\" +.\" @(#)pkg_delete.1 +.\" +.TH pkg_delete 1 "July 18, 1993" "" "FreeBSD" + +.SH NAME +pkg_delete - a utility for deleting previously installed software package distributions. +.SH SYNOPSIS +.na +.B pkg_delete +.RB [options] +.RB "pkg-name\ [.. pkg-name]" + +.SH DESCRIPTION +The +.B pkg_delete +command is used to delete packages that have been previously installed +with the +.B pkg_add +command. + +.SH OPTIONS +.TP +The following command line options are supported. +.TP +.B \-v +Turns on verbose output. +.B "Optional." +.TP +.B \-D +If an de-installation script exists for a given package, do not execute it. +.B "Optional." +.TP +.B \-n +Don't actually de-install a package, just report the steps that +would be taken if it was. +.B "Optional." +.TP +.BI "\-p\ " prefix +Sets +.I prefix +as the directory in which to delete files from any installed packages +which do not explicitly set theirs. +.B "Optional." +.PP +.SH "TECHNICAL DETAILS" +.B +pkg_delete +does pretty much what it says. It looks for a package in /var/db/pkg +and sets about deleting the files that make up the package and, finally, +the record of the package itself. +.PP +If the package contains a +.B require +file (see +.B pkg_create +), then this is executed first with the flag +.B DEINSTALL +to see whether or not de-installation should continue (a non-zero exit +status means no). +.PP +If a +.B de-install +script exists for the package, it is executed before any files are removed. +It is this script's responsibility to clean up any additional messy details +around the package's installation, since all +.B pkg_delete +knows how to do is delete the files created in the original distribution. +The +.B de-install +script is called with the flags +.PP +.B <script> +.I pkg-name DEINSTALL +.PP +Where +.I pkg-name +is the name of the package in question and +.I DEINSTALL +is a keyword denoting that this is a deinstallation. Passing the keyword +lets you potentially write only one program/script that handles all +aspects of installation and deletion. +.PP +.SH BUGS +Sure to be some. +.SH "SEE ALSO" +.BR pkg_create "(" 1 ")," +.BR pkg_info "(" 1 ")," +.BR pkg_add "(" 1 ")," +.SH AUTHORS +Jordan Hubbard + diff --git a/usr.sbin/pkg_install/info/Makefile b/usr.sbin/pkg_install/info/Makefile new file mode 100644 index 0000000..2b4f04e --- /dev/null +++ b/usr.sbin/pkg_install/info/Makefile @@ -0,0 +1,8 @@ +PROG= pkg_info + +CFLAGS+= -I${.CURDIR}/../lib +LDADD+= -L${.CURDIR}/../lib -linstall + +SRCS= main.c perform.c show.c + +.include <bsd.prog.mk> diff --git a/usr.sbin/pkg_install/info/info.h b/usr.sbin/pkg_install/info/info.h new file mode 100644 index 0000000..9584afb --- /dev/null +++ b/usr.sbin/pkg_install/info/info.h @@ -0,0 +1,41 @@ +/* $Id: info.h,v 1.3 1993/08/26 08:47:04 jkh Exp $ */ + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 23 August 1993 + * + * Include and define various things wanted by the info command. + * + */ + +#ifndef _INST_INFO_H_INCLUDE +#define _INST_INFO_H_INCLUDE + +#define SHOW_COMMENT 0x1 +#define SHOW_DESC 0x2 +#define SHOW_PLIST 0x4 +#define SHOW_INSTALL 0x8 +#define SHOW_DEINSTALL 0x10 +#define SHOW_REQUIRE 0x20 +#define SHOW_PREFIX 0x40 +#define SHOW_INDEX 0x80 + +extern int Flags; +extern Boolean AllInstalled; + +extern void show_file(char *, char *); +extern void show_plist(char *, Package *, plist_t); + +#endif /* _INST_INFO_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c new file mode 100644 index 0000000..9a5e540 --- /dev/null +++ b/usr.sbin/pkg_install/info/main.c @@ -0,0 +1,138 @@ +#ifndef lint +static char *rcsid = "$Header: /usr1/cvs/jkh/pkg_install/info/main.c,v 1.4 1993/08/26 08:47:05 jkh Exp $"; +#endif + +/* + * + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * This is the add module. + * + */ + +#include "lib.h" +#include "info.h" + +static char Options[] = "acdfikrpIvh"; + +int Flags = 0; +Boolean AllInstalled = FALSE; + +int +main(int argc, char **argv) +{ + int ch; + char **pkgs, **start; + char *prog_name = argv[0]; + + pkgs = start = argv; + while ((ch = getopt(argc, argv, Options)) != EOF) + switch(ch) { + case 'a': + AllInstalled = TRUE; + break; + + case 'v': + Verbose = TRUE; + /* Reasonable definition of 'everything' */ + Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL | + SHOW_DEINSTALL | SHOW_REQUIRE; + break; + + case 'I': + Flags |= SHOW_INDEX; + break; + + case 'p': + Flags |= SHOW_PREFIX; + break; + + case 'c': + Flags |= SHOW_COMMENT; + break; + + case 'd': + Flags |= SHOW_DESC; + break; + + case 'f': + Flags |= SHOW_PLIST; + break; + + case 'i': + Flags |= SHOW_INSTALL; + break; + + case 'k': + Flags |= SHOW_DEINSTALL; + break; + + case 'r': + Flags |= SHOW_REQUIRE; + break; + + case 'h': + case '?': + default: + usage(prog_name, NULL); + break; + } + + argc -= optind; + argv += optind; + + /* Set some reasonable defaults */ + if (!Flags) + Flags = SHOW_COMMENT | SHOW_DESC; + + /* Get all the remaining package names, if any */ + while (*argv) + *pkgs++ = *argv++; + + /* If no packages, yelp */ + if (pkgs == start && !AllInstalled) + usage(prog_name, "Missing package name(s)"); + *pkgs = NULL; + return pkg_perform(start); +} + +void +usage(const char *name, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + if (fmt) { + fprintf(stderr, "%s: ", name); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n\n"); + } + va_end(args); + fprintf(stderr, "Usage: %s [args] pkg [ .. pkg ]\n", name); + fprintf(stderr, "Where args are one or more of:\n\n"); + fprintf(stderr, "-a show all installed packages (if any)\n"); + fprintf(stderr, "-I print 'index' of packages\n"); + fprintf(stderr, "-c print `one line comment'\n"); + fprintf(stderr, "-d print description\n"); + fprintf(stderr, "-f show packing list\n"); + fprintf(stderr, "-i show install script\n"); + fprintf(stderr, "-k show deinstall script\n"); + fprintf(stderr, "-r show requirements script\n"); + fprintf(stderr, "-p show prefix\n"); + fprintf(stderr, "-v show all information\n"); + fprintf(stderr, "\n[no args = -c -d]\n"); + exit(1); +} diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c new file mode 100644 index 0000000..3a38421 --- /dev/null +++ b/usr.sbin/pkg_install/info/perform.c @@ -0,0 +1,144 @@ +#ifndef lint +static const char *rcsid = "$Id: perform.c,v 1.3 1993/08/26 08:47:06 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 23 Aug 1993 + * + * This is the main body of the info module. + * + */ + +#include "lib.h" +#include "info.h" + +#include <signal.h> + +static int pkg_do(char *); + +int +pkg_perform(char **pkgs) +{ + int i, err_cnt = 0; + + signal(SIGINT, cleanup); + + /* Overriding action? */ + if (AllInstalled) { + if (isdir(LOG_DIR)) { + DIR *dirp; + struct dirent *dp; + + dirp = opendir(LOG_DIR); + if (dirp) { + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) + err_cnt += pkg_do(dp->d_name); + } + (void)closedir(dirp); + } + else + ++err_cnt; + } + } + for (i = 0; pkgs[i]; i++) + err_cnt += pkg_do(pkgs[i]); + return err_cnt; +} + +static int +pkg_do(char *pkg) +{ + Boolean installed = FALSE; + char log_dir[FILENAME_MAX]; + char *home; + Package plist; + FILE *fp; + + if (fexists(pkg)) { + char fname[FILENAME_MAX]; + + home = make_playpen(); + if (pkg[0] == '/') + strcpy(fname, pkg); + else + sprintf(fname, "%s/%s", home, pkg); + if (unpack(fname, "+*")) { + whinge("Error during unpacking, no info for '%s' available.", pkg); + return 1; + } + } + else { + sprintf(log_dir, "%s/%s", LOG_DIR, pkg); + if (!fexists(log_dir)) { + whinge("Can't find package '%s' installed or in a file!", pkg); + return 1; + } + if (chdir(log_dir) == FAIL) { + whinge("Can't change directory to '%s'!", log_dir); + return 1; + } + installed = TRUE; + } + + /* Suck in the contents list */ + plist.head = plist.tail = NULL; + fp = fopen(CONTENTS_FNAME, "r"); + if (!fp) { + whinge("Unable to open %s file.", CONTENTS_FNAME); + return 1; + } + /* If we have a prefix, add it now */ + read_plist(&plist, fp); + fclose(fp); + + /* + * Index is special info type that has to override all others to make + * any sense. + */ + if (Flags & SHOW_INDEX) { + char fname[FILENAME_MAX]; + + sprintf(fname, "%s\t", pkg); + show_file(fname, COMMENT_FNAME); + } + else { + /* Start showing the package contents */ + printf("Information for %s:\n\n", pkg); + if (Flags & SHOW_COMMENT) + show_file("Comment:\n", COMMENT_FNAME); + if (Flags & SHOW_DESC) + show_file("Description:\n", DESC_FNAME); + if (Flags & SHOW_PLIST) + show_plist("Packing list:\n", &plist, (plist_t)-1); + if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) + show_file("Install script:\n", INSTALL_FNAME); + if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) + show_file("De-Install script:\n", DEINSTALL_FNAME); + if (Flags & SHOW_PREFIX) + show_plist("Prefix(s):\n", &plist, PLIST_CWD); + putchar('\014'); + } + free_plist(&plist); + leave_playpen(); + return 0; +} + +void +cleanup(int sig) +{ + leave_playpen(); +} diff --git a/usr.sbin/pkg_install/info/pkg_info.1 b/usr.sbin/pkg_install/info/pkg_info.1 new file mode 100644 index 0000000..d74c1ff --- /dev/null +++ b/usr.sbin/pkg_install/info/pkg_info.1 @@ -0,0 +1,78 @@ +.\" +.\" FreeBSD install - a package for the installation and maintainance +.\" of non-core utilities. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" Jordan K. Hubbard +.\" +.\" +.\" @(#)pkg_info.1 +.\" +.TH pkg_info 1 "July 18, 1993" "" "FreeBSD" + +.SH NAME +pkg_info - a utility for getting information on software package distributions. +.SH SYNOPSIS +.na +.B pkg_info +.RB [options] +.RB "pkg-file|pkg-name\ [.. pkg-file|pkg-name]" + +.SH DESCRIPTION +The +.B pkg_info +command is used to dump out information for packages, either packed up in +files or already installed on the system +with the +.B pkg_create +command. + +.SH OPTIONS +.TP +The following command line options are supported. +.TP +.B \-a +Show all currently installed packages. +.TP +.B \-v +Turns on verbose output. +.TP +.B \-p +Show the installation prefix for each package. +.TP +.B \-c +Show the comment (one liner) field for each package. +.TP +.B \-d +Show the long description field for each package. +.TP +.B \-i +Show the install script (if any) for each package. +.TP +.B \-k +Show the de-install script (if any) for each package. +.TP +.B \-r +Show the requirements script (if any) for each package. +.PP +.SH "TECHNICAL DETAILS" +Package info is either extracted from files supplied on the +command line, or from already installed package information +in /var/db/pkg/<pkg-name>. +.SH BUGS +Sure to be some. +.SH "SEE ALSO" +.BR pkg_add "(" 1 ")," +.BR pkg_create "(" 1 ")," +.BR pkg_delete "(" 1 ")," +.SH AUTHORS +Jordan Hubbard + diff --git a/usr.sbin/pkg_install/info/show.c b/usr.sbin/pkg_install/info/show.c new file mode 100644 index 0000000..8e73e88 --- /dev/null +++ b/usr.sbin/pkg_install/info/show.c @@ -0,0 +1,110 @@ +#ifndef lint +static const char *rcsid = "$Id: show.c,v 1.3 1993/08/26 08:47:07 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 23 Aug 1993 + * + * Various display routines for the info module. + * + */ + +#include "lib.h" +#include "info.h" + +void +show_file(char *title, char *fname) +{ + FILE *fp; + char line[1024]; + int n; + + printf(title); + fp = fopen(fname, "r"); + if (!fp) { + whinge("show_file: Can't open '%s' for reading.", fname); + return; + } + while (n = fread(line, 1, 1024, fp)) + fwrite(line, 1, n, stdout); + fclose(fp); + printf("\n"); /* just in case */ +} + +/* Show a packing list item type. If type is -1, show all */ +void +show_plist(char *title, Package *plist, plist_t type) +{ + PackingList p; + Boolean ign = FALSE; + + printf(title); + p = plist->head; + while (p) { + if (p->type != type && type != -1) { + p = p->next; + continue; + } + switch(p->type) { + case PLIST_FILE: + if (ign) { + printf("File: %s (ignored)\n", p->name); + ign = FALSE; + } + else + printf("File: %s\n", p->name); + break; + + case PLIST_CWD: + printf("\tCWD to %s\n", p->name); + break; + + case PLIST_CMD: + printf("\tEXEC '%s'\n", p->name); + break; + + case PLIST_CHMOD: + printf("\tCHMOD to %s\n", p->name ? p->name : "(no default)"); + break; + + case PLIST_CHOWN: + printf("\tCHOWN to %s\n", p->name ? p->name : "(no default)"); + break; + + case PLIST_CHGRP: + printf("\tCHGRP to %s\n", p->name ? p->name : "(no default)"); + break; + + case PLIST_COMMENT: + printf("\tComment: %s\n", p->name); + break; + + case PLIST_IGNORE: + ign = TRUE; + break; + + case PLIST_NAME: + printf("\tPackage name: %s\n", p->name); + break; + + default: + barf("Unknown command type %d (%s)\n", p->type, p->name); + break; + } + p = p->next; + } +} + diff --git a/usr.sbin/pkg_install/lib/Makefile b/usr.sbin/pkg_install/lib/Makefile new file mode 100644 index 0000000..72da098 --- /dev/null +++ b/usr.sbin/pkg_install/lib/Makefile @@ -0,0 +1,9 @@ +LIB= install +SRCS= file.c msg.c plist.c str.c exec.c global.c pen.c +NOPROFILE= yes +CFLAGS+= -g -Wall + +install: + @echo -n + +.include <bsd.lib.mk> diff --git a/usr.sbin/pkg_install/lib/exec.c b/usr.sbin/pkg_install/lib/exec.c new file mode 100644 index 0000000..6f1a672 --- /dev/null +++ b/usr.sbin/pkg_install/lib/exec.c @@ -0,0 +1,48 @@ +#ifndef lint +static const char *rcsid = "$Id: exec.c,v 1.3 1993/08/24 09:24:04 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Miscellaneous system routines. + * + */ + +#include "lib.h" + +/* + * Unusual system() substitute. Accepts format string and args, + * builds and executes command. Returns exit code. + */ + +int +vsystem(const char *fmt, ...) +{ + va_list args; + char cmd[FILENAME_MAX * 2]; /* reasonable default for what I do */ + int ret; + + va_start(args, fmt); + vsprintf(cmd, fmt, args); +#ifdef DEBUG +printf("Executing %s\n", cmd); +#endif + ret = system(cmd); + va_end(args); + return ret; +} + diff --git a/usr.sbin/pkg_install/lib/file.c b/usr.sbin/pkg_install/lib/file.c new file mode 100644 index 0000000..ac7e4d7 --- /dev/null +++ b/usr.sbin/pkg_install/lib/file.c @@ -0,0 +1,164 @@ +#ifndef lint +static const char *rcsid = "$Id: file.c,v 1.5 1993/08/26 08:13:48 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Miscellaneous file access utilities. + * + */ + +#include "lib.h" + +/* Quick check to see if a file exists */ +Boolean +fexists(char *fname) +{ + if (!access(fname, F_OK)) + return TRUE; + return FALSE; +} + +/* Quick check to see if something is a directory */ +Boolean +isdir(char *fname) +{ + struct stat sb; + + if (stat(fname, &sb) != FAIL && + (sb.st_mode & S_IFDIR)) + return TRUE; + else + return FALSE; +} + +/* Check to see if file is a dir, and is empty */ +Boolean +isempty(char *fname) +{ + if (isdir(fname)) { + DIR *dirp; + struct dirent *dp; + + dirp = opendir(fname); + if (!dirp) + return FALSE; /* no perms, leave it alone */ + for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { + if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) { + closedir(dirp); + return FALSE; + } + } + (void)closedir(dirp); + return TRUE; + } + return FALSE; +} + +char * +get_file_contents(char *fname) +{ + char *contents; + struct stat sb; + int fd; + + if (stat(fname, &sb) == FAIL) + barf("Can't stat '%s'.", fname); + + contents = (char *)malloc(sb.st_size + 1); + fd = open(fname, O_RDONLY, 0); + if (fd == FAIL) + barf("Unable to open '%s' for reading.", fname); + if (read(fd, contents, sb.st_size) != sb.st_size) + barf("Short read on '%s' - did not get %d bytes.", fname, sb.st_size); + close(fd); + contents[sb.st_size] = '\0'; + return contents; +} + +/* Write the contents of "str" to a file */ +void +write_file(char *name, char *str) +{ + FILE *fp; + int len; + + fp = fopen(name, "w"); + if (!fp) + barf("Can't fopen '%s' for writing.", name); + len = strlen(str); + if (fwrite(str, 1, len, fp) != len) + barf("Short fwrite on '%s', tried to write %d bytes.", name, len); + if (fclose(fp)) + barf("failure to fclose '%s'.", name); +} + +void +copy_file(char *dir, char *fname, char *to) +{ + if (vsystem("cp -p -r %s/%s %s", dir, fname, to)) + barf("Couldn't copy %s/%s to %s!", dir, fname, to); +} + +/* + * Copy a hierarchy (possibly from dir) to the current directory, or + * if "to" is TRUE, from the current directory to a location someplace + * else. + * + * Though slower, using tar to copy preserves symlinks and everything + * without me having to write some big hairy routine to do it. + */ +void +copy_hierarchy(char *dir, char *fname, Boolean to) +{ + char cmd[FILENAME_MAX * 3]; + + if (!to) { + /* If absolute path, use it */ + if (*fname == '/') + dir = "/"; + sprintf(cmd, "tar cf - -C %s %s | tar xpf -", dir, fname); + } + else + sprintf(cmd, "tar cf - %s | tar xpf - -C %s", fname, dir); + if (system(cmd)) + barf("copy_file: Couldn't perform '%s'", cmd); +} + +/* Unpack a tar file */ +int +unpack(char *pkg, char *flist) +{ + char args[10], suffix[80], *cp; + + /* + * Figure out by a crude heuristic whether this or not this is probably + * compressed. + */ + cp = rindex(pkg, '.'); + if (cp) { + strcpy(suffix, cp + 1); + if (index(suffix, 'z') || index(suffix, 'Z')) + strcpy(args, "z"); + } + strcat(args, "xpf"); + if (vsystem("tar %s %s %s", args, pkg, flist ? flist : "")) { + whinge("Tar extract of %s failed!", pkg); + return 1; + } + return 0; +} diff --git a/usr.sbin/pkg_install/lib/global.c b/usr.sbin/pkg_install/lib/global.c new file mode 100644 index 0000000..f5eda0e --- /dev/null +++ b/usr.sbin/pkg_install/lib/global.c @@ -0,0 +1,31 @@ +#ifndef lint +static const char *rcsid = "$Id$"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + + * 18 July 1993 + * + * Semi-convenient place to stick some needed globals. + * + */ + +#include "lib.h" + +/* These two are global for all utils */ +Boolean Verbose = FALSE; +Boolean Fake = FALSE; + diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h new file mode 100644 index 0000000..05d43e7 --- /dev/null +++ b/usr.sbin/pkg_install/lib/lib.h @@ -0,0 +1,143 @@ +/* $Id: lib.h,v 1.4 1993/08/24 09:24:07 jkh Exp $ */ + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Include and define various things wanted by the library routines. + * + */ + +#ifndef _INST_LIB_LIB_H_ +#define _INST_LIB_LIB_H_ + +/* Includes */ +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <unistd.h> +#include <ctype.h> +#include <dirent.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/file.h> + +/* Macros */ +#define SUCCESS (0) +#define FAIL (-1) + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +/* Usually "rm", but often "echo" during debugging! */ +#define REMOVE_CMD "rm" + +/* Usually "rm", but often "echo" during debugging! */ +#define RMDIR_CMD "rmdir" + +/* Where we put logging information */ +#define LOG_DIR "/var/db/pkg" + +/* The names of our "special" files */ +#define CONTENTS_FNAME "+CONTENTS" +#define COMMENT_FNAME "+COMMENT" +#define DESC_FNAME "+DESC" +#define INSTALL_FNAME "+INSTALL" +#define DEINSTALL_FNAME "+DEINSTALL" +#define REQUIRE_FNAME "+REQUIRE" + +#define CMD_CHAR '@' /* prefix for extended PLIST cmd */ + +enum _plist_t { + PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD, + PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT, + PLIST_IGNORE, PLIST_NAME +}; +typedef enum _plist_t plist_t; + +/* Types */ +typedef unsigned int Boolean; + +struct _plist { + struct _plist *prev, *next; + char *name; + Boolean marked; + plist_t type; +}; +typedef struct _plist *PackingList; + +struct _pack { + struct _plist *head, *tail; +}; +typedef struct _pack Package; + +/* Prototypes */ +/* Misc */ +int vsystem(const char *, ...); +void cleanup(int); +char *make_playpen(void); +void leave_playpen(void); + +/* String */ +char *get_dash_string(char **); +char *copy_string(char *); +Boolean suffix(char *, char *); +void nuke_suffix(char *); +void str_lowercase(char *); + +/* File */ +Boolean fexists(char *); +Boolean isdir(char *); +Boolean isempty(char *); +char *get_file_contents(char *); +void write_file(char *, char *); +void copy_file(char *, char *, char *); +void copy_hierarchy(char *, char *, Boolean); +int delete_hierarchy(char *, Boolean); +int unpack(char *, char *); + +/* Msg */ +void upchuck(const char *); +void barf(const char *, ...); +void whinge(const char *, ...); +Boolean y_or_n(Boolean, const char *, ...); + +/* Packing list */ +PackingList new_plist_entry(void); +PackingList last_plist(Package *); +void free_plist(Package *); +void mark_plist(Package *); +void csum_plist_entry(char *, PackingList); +void add_plist(Package *, int, char *); +void write_plist(Package *, FILE *); +void read_plist(Package *, FILE *); +int plist_cmd(char *, char **); +void delete_package(Boolean, Package *); + +/* For all */ +void usage(const char *, const char *, ...); +int pkg_perform(char **); + +/* Externs */ +extern Boolean Verbose; +extern Boolean Fake; + +#endif /* _INST_LIB_LIB_H_ */ diff --git a/usr.sbin/pkg_install/lib/msg.c b/usr.sbin/pkg_install/lib/msg.c new file mode 100644 index 0000000..4c74290 --- /dev/null +++ b/usr.sbin/pkg_install/lib/msg.c @@ -0,0 +1,97 @@ +#ifndef lint +static const char *rcsid = "$Id: msg.c,v 1.2 1993/08/16 14:20:18 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + + * 18 July 1993 + * + * Miscellaneous message routines. + * + */ + +#include "lib.h" + +/* Die a relatively simple death */ +void +upchuck(const char *err) +{ + fprintf(stderr, "Fatal error during execution: "); + perror(err); + cleanup(0); + exit(1); +} + +/* Die a more complex death */ +void +barf(const char *err, ...) +{ + va_list args; + + va_start(args, err); + vfprintf(stderr, err, args); + fputc('\n', stderr); + va_end(args); + cleanup(0); + exit(2); +} + +/* Get annoyed about something but don't go to pieces over it */ +void +whinge(const char *err, ...) +{ + va_list args; + + va_start(args, err); + vfprintf(stderr, err, args); + fputc('\n', stderr); + va_end(args); +} + +/* + * As a yes/no question, prompting from the varargs string and using + * default if user just hits return. + */ +Boolean +y_or_n(Boolean def, const char *msg, ...) +{ + va_list args; + int ch = 0; + FILE *tty; + + va_start(args, msg); + /* + * Need to open /dev/tty because file collection may have been + * collected on stdin + */ + tty = fopen("/dev/tty", "r"); + if (!tty) + barf("Can't open /dev/tty!\n"); + while (ch != 'Y' && ch != 'N') { + vfprintf(stderr, msg, args); + if (def) + fprintf(stderr, " [yes]? "); + else + fprintf(stderr, " [no]? "); + fflush(stderr); + ch = toupper(fgetc(tty)); + if (ch == '\n') + ch = (def) ? 'Y' : 'N'; + } + return (ch == 'Y') ? TRUE : FALSE; +} + + diff --git a/usr.sbin/pkg_install/lib/pen.c b/usr.sbin/pkg_install/lib/pen.c new file mode 100644 index 0000000..8a3416f --- /dev/null +++ b/usr.sbin/pkg_install/lib/pen.c @@ -0,0 +1,63 @@ +#ifndef lint +static const char *rcsid = "$Id: pen.c,v 1.1 1993/08/24 09:24:08 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Routines for managing the "play pen". + * + */ + +#include "lib.h" + +/* For keeping track of where we are */ +static char Cwd[FILENAME_MAX]; +static char Pen[FILENAME_MAX]; + + +/* + * Make a temporary directory to play in and chdir() to it, returning + * pathname of previous working directory. + */ +char * +make_playpen(void) +{ + if (!getcwd(Cwd, FILENAME_MAX)) + upchuck("getcwd"); + strcpy(Pen, "/tmp/instmp.XXXXXX"); + if (!mktemp(Pen)) + barf("Can't mktemp '%s'.", Pen); + if (mkdir(Pen, 0755) == FAIL) + barf("Can't mkdir '%s'.", Pen); + if (chdir(Pen) == FAIL) + barf("Can't chdir to '%s'.", Pen); + return Cwd; +} + +/* Convenience routine for getting out of playpen */ +void +leave_playpen(void) +{ + if (Cwd[0]) { + if (chdir(Cwd) == FAIL) + barf("Can't chdir back to '%s'.", Cwd); + if (vsystem("rm -rf %s", Pen)) + fprintf(stderr, "Couldn't remove temporary dir '%s'\n", Pen); + Cwd[0] = '\0'; + } +} + diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c new file mode 100644 index 0000000..f2992c6 --- /dev/null +++ b/usr.sbin/pkg_install/lib/plist.c @@ -0,0 +1,270 @@ +#ifndef lint +static const char *rcsid = "$Id: plist.c,v 1.5 1993/08/26 08:13:49 jkh Exp $"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * General packing list routines. + * + */ + +#include "lib.h" + +/* Add an item to a packing list */ +void +add_plist(Package *p, int type, char *arg) +{ + PackingList tmp; + + tmp = new_plist_entry(); + tmp->name = copy_string(arg); + tmp->type = type; + + if (!p->head) + p->head = p->tail = tmp; + else { + tmp->prev = p->tail; + p->tail->next = tmp; + p->tail = tmp; + } +} + +/* Return the last (most recent) entry in a packing list */ +PackingList +last_plist(Package *p) +{ + return p->tail; +} + +/* Mark all items in a packing list to prevent iteration over them */ +void +mark_plist(Package *pkg) +{ + PackingList p = pkg->head; + + while (p) { + p->marked = TRUE; + p = p->next; + } +} + +/* Allocate a new packing list entry */ +PackingList +new_plist_entry(void) +{ + PackingList ret; + + ret = (PackingList)malloc(sizeof(struct _plist)); + bzero(ret, sizeof(struct _plist)); + return ret; +} + +/* Free an entire packing list */ +void +free_plist(Package *pkg) +{ + PackingList p = pkg->head; + + while (p) { + PackingList p1 = p->next; + + free(p->name); + free(p); + p = p1; + } + pkg->head = pkg->tail = NULL; +} + +/* + * For an ascii string denoting a plist command, return its code and + * optionally its argument(s) + */ +int +plist_cmd(char *s, char **arg) +{ + char cmd[FILENAME_MAX + 20]; /* 20 == fudge for max cmd len */ + char *cp, *sp; + + strcpy(cmd, s); + str_lowercase(cmd); + cp = cmd; + sp = s; + while (*cp) { + if (isspace(*cp)) { + *cp = '\0'; + while (isspace(*sp)) /* Never sure if macro, increment later */ + ++sp; + break; + } + ++cp, ++sp; + } + if (arg) + *arg = sp; + if (!strcmp(cmd, "cwd")) + return PLIST_CWD; + else if (!strcmp(cmd, "exec")) + return PLIST_CMD; + else if (!strcmp(cmd, "mode")) + return PLIST_CHMOD; + else if (!strcmp(cmd, "owner")) + return PLIST_CHOWN; + else if (!strcmp(cmd, "group")) + return PLIST_CHGRP; + else if (!strcmp(cmd, "comment")) + return PLIST_COMMENT; + else if (!strcmp(cmd, "ignore")) + return PLIST_IGNORE; + else if (!strcmp(cmd, "name")) + return PLIST_NAME; + else + return FAIL; +} + +/* Read a packing list from a file */ +void +read_plist(Package *pkg, FILE *fp) +{ + char *cp, pline[FILENAME_MAX]; + int cmd; + + while (fgets(pline, FILENAME_MAX, fp)) { + int len = strlen(pline) - 1; + + while (isspace(pline[len])) + pline[len--] = '\0'; + if (!len) + continue; + cp = pline; + if (pline[0] == CMD_CHAR) { + cmd = plist_cmd(pline + 1, &cp); + if (cmd == FAIL) + barf("Bad command '%s'", pline); + } + else + cmd = PLIST_FILE; + add_plist(pkg, cmd, cp); + } +} + +/* Write a packing list to a file, converting commands to ascii equivs */ +void +write_plist(Package *pkg, FILE *fp) +{ + PackingList plist = pkg->head; + + while (plist) { + switch(plist->type) { + case PLIST_FILE: + fprintf(fp, "%s\n", plist->name); + break; + + case PLIST_CWD: + fprintf(fp, "%ccwd %s\n", CMD_CHAR, plist->name); + break; + + case PLIST_CMD: + fprintf(fp, "%cexec %s\n", CMD_CHAR, plist->name); + break; + + case PLIST_CHMOD: + fprintf(fp, "%cchmod %s\n", CMD_CHAR, + plist->name ? plist->name : ""); + break; + + case PLIST_CHOWN: + fprintf(fp, "%cchown %s\n", CMD_CHAR, + plist->name ? plist->name : ""); + break; + + case PLIST_CHGRP: + fprintf(fp, "%cchgrp %s\n", CMD_CHAR, + plist->name ? plist->name : ""); + break; + + case PLIST_COMMENT: + fprintf(fp, "%ccomment %s\n", CMD_CHAR, plist->name); + break; + + case PLIST_IGNORE: + fprintf(fp, "%cignore\n", CMD_CHAR); + break; + + case PLIST_NAME: + fprintf(fp, "%cname %s\n", CMD_CHAR, plist->name); + break; + + default: + barf("Unknown command type %d (%s)\n", plist->type, plist->name); + break; + } + plist = plist->next; + } +} + +/* Delete the results of a package installation, not the packaging itself */ +void +delete_package(Boolean ign_err, Package *pkg) +{ + PackingList p = pkg->head; + char *Where = "."; + + while (p) { + if (p->type == PLIST_CWD) { + Where = p->name; + if (Verbose) + printf("Delete: (CWD to %s)\n", Where); + } + else if (p->type == PLIST_IGNORE) + p = p->next; + else if (p->type == PLIST_FILE) { + char full_name[FILENAME_MAX]; + + sprintf(full_name, "%s/%s", Where, p->name); + if (Verbose) + printf("Delete: %s\n", full_name); + + if (!Fake && delete_hierarchy(full_name, ign_err)) + whinge("Unable to completely remove file '%s'", full_name); + } + p = p->next; + } +} + +/* Selectively delete a hierarchy */ +int +delete_hierarchy(char *dir, Boolean ign_err) +{ + char *cp1, *cp2; + + cp1 = cp2 = dir; + if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir)) + return 1; + while (cp2) { + if ((cp2 = rindex(cp1, '/')) != NULL) + *cp2 = '\0'; + if (!isempty(dir)) + return 0; + if (vsystem("%s %s", RMDIR_CMD, dir) && ign_err) + return 1; + /* Put it back */ + if (cp2) { + *cp2 = '/'; + cp1 = cp2 - 1; + } + } + return 0; +} diff --git a/usr.sbin/pkg_install/lib/str.c b/usr.sbin/pkg_install/lib/str.c new file mode 100644 index 0000000..8d68f92 --- /dev/null +++ b/usr.sbin/pkg_install/lib/str.c @@ -0,0 +1,85 @@ +#ifndef lint +static const char *rcsid = "$Id"; +#endif + +/* + * FreeBSD install - a package for the installation and maintainance + * of non-core utilities. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * Jordan K. Hubbard + * 18 July 1993 + * + * Miscellaneous string utilities. + * + */ + +#include "lib.h" + +char * +get_dash_string(char **str) +{ + char *s = *str; + + if (*s == '-') + *str = copy_string(s + 1); + else + *str = get_file_contents(s); + return *str; +} + +char * +copy_string(char *str) +{ + char *ret; + + if (!str) + ret = NULL; + else { + ret = (char *)malloc(strlen(str) + 1); + strcpy(ret, str); + } + return ret; +} + +/* Return TRUE if 'str' ends in suffix 'suff' */ +Boolean +suffix(char *str, char *suff) +{ + char *idx; + Boolean ret = FALSE; + + idx = rindex(str, '.'); + if (idx && !strcmp(idx + 1, suff)) + ret = TRUE; + return ret; +} + +/* Assuming str has a suffix, brutally murder it! */ +void +nuke_suffix(char *str) +{ + char *idx; + + idx = rindex(str, '.'); + if (idx) + *idx = '\0'; /* Yow! Don't try this on a const! */ +} + +/* Lowercase a whole string */ +void +str_lowercase(char *str) +{ + while (*str) { + *str = tolower(*str); + ++str; + } +} |