375a51926a
Completely ignore @src in pkg_create. Silently ignore the -L option. The combination of -I and -p are used by pkgsrc for the same result. Do not overwrite a string with itself using snprintf. This breaks setting the pkgdb directory internally on Linux. Explicitly check if the string is the same and otherwise just use xstrdup. Add support to query arbitrary variables with pkg_admin config-var.
212 lines
5.2 KiB
C
212 lines
5.2 KiB
C
/* $NetBSD: pl.c,v 1.1.1.4 2009/11/05 18:39:03 joerg Exp $ */
|
|
|
|
#if HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
#include <nbcompat.h>
|
|
#if HAVE_SYS_CDEFS_H
|
|
#include <sys/cdefs.h>
|
|
#endif
|
|
__RCSID("$NetBSD: pl.c,v 1.1.1.4 2009/11/05 18:39:03 joerg 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
|
|
*
|
|
* Routines for dealing with the packing list.
|
|
*
|
|
*/
|
|
|
|
#include "lib.h"
|
|
#include "create.h"
|
|
#if HAVE_ERR_H
|
|
#include <err.h>
|
|
#endif
|
|
#ifndef NETBSD
|
|
#include <nbcompat/md5.h>
|
|
#else
|
|
#include <md5.h>
|
|
#endif
|
|
|
|
/*
|
|
* Check that any symbolic link is relative to the prefix
|
|
*/
|
|
static void
|
|
CheckSymlink(char *name, char *prefix, size_t prefixcc)
|
|
{
|
|
char newtgt[MaxPathSize];
|
|
char oldtgt[MaxPathSize];
|
|
char *slash;
|
|
int slashc;
|
|
int cc;
|
|
int i;
|
|
|
|
if ((cc = readlink(name, oldtgt, sizeof(oldtgt) - 1)) > 0) {
|
|
oldtgt[cc] = 0;
|
|
if (strncmp(oldtgt, prefix, prefixcc) == 0 && oldtgt[prefixcc] == '/') {
|
|
for (slashc = 0, slash = &name[prefixcc + 1]; (slash = strchr(slash, '/')) != (char *) NULL; slash++, slashc++) {
|
|
}
|
|
for (cc = i = 0; i < slashc; i++) {
|
|
strlcpy(&newtgt[cc], "../", sizeof(newtgt) - cc);
|
|
cc += 3;
|
|
}
|
|
strlcpy(&newtgt[cc], &oldtgt[prefixcc + 1], sizeof(newtgt) - cc);
|
|
(void) fprintf(stderr, "Full pathname symlink `%s' is target of `%s' - adjusting to `%s'\n", oldtgt, name, newtgt);
|
|
if (unlink(name) != 0) {
|
|
warn("can't unlink `%s'", name);
|
|
} else if (symlink(newtgt, name) != 0) {
|
|
warn("can't symlink `%s' called `%s'", newtgt, name);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Check a list for files that require preconversion
|
|
*/
|
|
void
|
|
check_list(package_t *pkg, const char *PkgName)
|
|
{
|
|
struct stat st;
|
|
plist_t *tmp;
|
|
plist_t *p;
|
|
char buf[ChecksumHeaderLen + LegibleChecksumLen];
|
|
char target[MaxPathSize + SymlinkHeaderLen];
|
|
char name[MaxPathSize];
|
|
char *cwd = NULL;
|
|
char *pkgname = NULL;
|
|
int cc;
|
|
|
|
/* Open Package Database for writing */
|
|
if (update_pkgdb && !pkgdb_open(ReadWrite))
|
|
err(EXIT_FAILURE, "can't open pkgdb");
|
|
|
|
for (p = pkg->head; p; p = p->next) {
|
|
switch (p->type) {
|
|
case PLIST_CWD:
|
|
cwd = p->name;
|
|
break;
|
|
case PLIST_NAME:
|
|
pkgname = p->name;
|
|
break;
|
|
case PLIST_IGNORE:
|
|
p = p->next;
|
|
break;
|
|
case PLIST_PKGDIR:
|
|
if (cwd == NULL)
|
|
errx(2, "@pkgdir without preceding @cwd found");
|
|
if (pkgname == NULL)
|
|
errx(2, "@pkgdir without preceding @name found");
|
|
if (update_pkgdb) {
|
|
add_pkgdir(pkgname, cwd, p->name);
|
|
/* mkdir_p(cwd, p->name); */
|
|
}
|
|
break;
|
|
case PLIST_FILE:
|
|
/*
|
|
* pkgdb handling - usually, we enter files
|
|
* into the pkgdb as soon as they hit the disk,
|
|
* but as they are present before pkg_create
|
|
* starts, it's ok to do this somewhere here
|
|
*/
|
|
if (cwd == NULL)
|
|
errx(2, "file without preceding @cwd found");
|
|
if (update_pkgdb) {
|
|
char *s, t[MaxPathSize];
|
|
|
|
(void) snprintf(t, sizeof(t), "%s%s%s",
|
|
cwd,
|
|
(strcmp(cwd, "/") == 0) ? "" : "/",
|
|
p->name);
|
|
|
|
s = pkgdb_retrieve(t);
|
|
if (s && PlistOnly)
|
|
warnx("Overwriting %s - "
|
|
"pkg %s bogus/conflicting?", t, s);
|
|
else {
|
|
pkgdb_store(t, PkgName);
|
|
}
|
|
}
|
|
|
|
/* prepend DESTDIR if set? - HF */
|
|
(void) snprintf(name, sizeof(name), "%s%s%s",
|
|
cwd,
|
|
(strcmp(cwd, "/") == 0) ? "" : "/",
|
|
p->name);
|
|
if (lstat(name, &st) < 0) {
|
|
warnx("can't stat `%s'", name);
|
|
continue;
|
|
}
|
|
switch (st.st_mode & S_IFMT) {
|
|
case S_IFDIR:
|
|
warnx("Warning - directory `%s' in PLIST", name);
|
|
break;
|
|
case S_IFLNK:
|
|
if (RelativeLinks) {
|
|
CheckSymlink(name, cwd, strlen(cwd));
|
|
}
|
|
(void) strlcpy(target, SYMLINK_HEADER,
|
|
sizeof(target));
|
|
if ((cc = readlink(name, &target[SymlinkHeaderLen],
|
|
sizeof(target) - SymlinkHeaderLen - 1)) < 0) {
|
|
warnx("can't readlink `%s'", name);
|
|
continue;
|
|
}
|
|
target[SymlinkHeaderLen + cc] = 0x0;
|
|
tmp = new_plist_entry();
|
|
tmp->name = xstrdup(target);
|
|
tmp->type = PLIST_COMMENT;
|
|
tmp->next = p->next;
|
|
tmp->prev = p;
|
|
if (p == pkg->tail) {
|
|
pkg->tail = tmp;
|
|
}
|
|
p->next = tmp;
|
|
p = tmp;
|
|
break;
|
|
case S_IFCHR:
|
|
warnx("Warning - char special device `%s' in PLIST", name);
|
|
break;
|
|
case S_IFBLK:
|
|
warnx("Warning - block special device `%s' in PLIST", name);
|
|
break;
|
|
default:
|
|
(void) strlcpy(buf, CHECKSUM_HEADER,
|
|
sizeof(buf));
|
|
if (MD5File(name, &buf[ChecksumHeaderLen]) != (char *) NULL) {
|
|
tmp = new_plist_entry();
|
|
tmp->name = xstrdup(buf);
|
|
tmp->type = PLIST_COMMENT; /* PLIST_MD5 - HF */
|
|
tmp->next = p->next;
|
|
tmp->prev = p;
|
|
if (p == pkg->tail) {
|
|
pkg->tail = tmp;
|
|
}
|
|
p->next = tmp;
|
|
p = tmp;
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (update_pkgdb) {
|
|
pkgdb_close();
|
|
}
|
|
}
|