1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-18 15:30:21 +00:00

The release version of my package install suite. Please see man pages

for info.
This commit is contained in:
Jordan K. Hubbard 1993-08-26 01:19:55 +00:00
parent 24a82630a2
commit 6d946b2e52
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/unlabeled-1.1.1/; revision=327
35 changed files with 3115 additions and 0 deletions

View File

@ -0,0 +1,3 @@
SUBDIR=lib add create delete info
.include <bsd.subdir.mk>

View File

@ -0,0 +1 @@
BINDIR?= /usr/local/bin

View File

@ -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>

View File

@ -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 */

View File

@ -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;
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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

View File

@ -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>

View File

@ -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 */

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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 */

View File

@ -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);
}

View File

@ -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 */
}

View File

@ -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

View File

@ -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>

View File

@ -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 */

View File

@ -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);
}

View File

@ -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();
}

View File

@ -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

View File

@ -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;
}
}

View File

@ -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>

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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';
}
}

View File

@ -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;
}

View File

@ -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;
}
}