1/* $NetBSD: pl.c,v 1.5 2021/04/10 19:49:59 nia Exp $ */ 2 3#ifdef HAVE_NBTOOL_CONFIG_H 4#include "nbtool_config.h" 5#else 6#if HAVE_CONFIG_H 7#include "config.h" 8#endif 9#include <nbcompat.h> 10#if HAVE_SYS_CDEFS_H 11#include <sys/cdefs.h> 12#endif 13#endif 14__RCSID("$NetBSD: pl.c,v 1.5 2021/04/10 19:49:59 nia Exp $"); 15 16/* 17 * FreeBSD install - a package for the installation and maintainance 18 * of non-core utilities. 19 * 20 * Redistribution and use in source and binary forms, with or without 21 * modification, are permitted provided that the following conditions 22 * are met: 23 * 1. Redistributions of source code must retain the above copyright 24 * notice, this list of conditions and the following disclaimer. 25 * 2. Redistributions in binary form must reproduce the above copyright 26 * notice, this list of conditions and the following disclaimer in the 27 * documentation and/or other materials provided with the distribution. 28 * 29 * Jordan K. Hubbard 30 * 18 July 1993 31 * 32 * Routines for dealing with the packing list. 33 * 34 */ 35 36#include "lib.h" 37#include "create.h" 38#if HAVE_ERR_H 39#include <err.h> 40#endif 41#ifndef NETBSD 42#include <nbcompat/md5.h> 43#else 44#include <md5.h> 45#endif 46 47/* 48 * Check that any symbolic link is relative to the prefix 49 */ 50static void 51CheckSymlink(char *name, char *prefix, size_t prefixcc) 52{ 53 char newtgt[MaxPathSize]; 54 char oldtgt[MaxPathSize]; 55 char *slash; 56 int slashc; 57 int cc; 58 int i; 59 60 if ((cc = readlink(name, oldtgt, sizeof(oldtgt) - 1)) > 0) { 61 oldtgt[cc] = 0; 62 if (strncmp(oldtgt, prefix, prefixcc) == 0 && oldtgt[prefixcc] == '/') { 63 for (slashc = 0, slash = &name[prefixcc + 1]; (slash = strchr(slash, '/')) != (char *) NULL; slash++, slashc++) { 64 } 65 for (cc = i = 0; i < slashc; i++) { 66 strlcpy(&newtgt[cc], "../", sizeof(newtgt) - cc); 67 cc += 3; 68 } 69 strlcpy(&newtgt[cc], &oldtgt[prefixcc + 1], sizeof(newtgt) - cc); 70 (void) fprintf(stderr, "Full pathname symlink `%s' is target of `%s' - adjusting to `%s'\n", oldtgt, name, newtgt); 71 if (unlink(name) != 0) { 72 warn("can't unlink `%s'", name); 73 } else if (symlink(newtgt, name) != 0) { 74 warn("can't symlink `%s' called `%s'", newtgt, name); 75 } 76 } 77 } 78} 79 80/* 81 * Check a list for files that require preconversion 82 */ 83void 84check_list(package_t *pkg, const char *PkgName) 85{ 86 struct stat st; 87 plist_t *tmp; 88 plist_t *p; 89 char buf[ChecksumHeaderLen + LegibleChecksumLen]; 90 char target[MaxPathSize + SymlinkHeaderLen]; 91 char name[MaxPathSize]; 92 char *cwd = NULL; 93 char *pkgname = NULL; 94 int cc; 95 96 for (p = pkg->head; p; p = p->next) { 97 switch (p->type) { 98 case PLIST_CWD: 99 cwd = p->name; 100 break; 101 case PLIST_NAME: 102 pkgname = p->name; 103 break; 104 case PLIST_IGNORE: 105 p = p->next; 106 break; 107 case PLIST_PKGDIR: 108 if (cwd == NULL) 109 errx(2, "@pkgdir without preceding @cwd found"); 110 if (pkgname == NULL) 111 errx(2, "@pkgdir without preceding @name found"); 112 break; 113 case PLIST_FILE: 114 if (cwd == NULL) 115 errx(2, "file without preceding @cwd found"); 116 (void) snprintf(name, sizeof(name), "%s%s%s", 117 cwd, 118 (strcmp(cwd, "/") == 0) ? "" : "/", 119 p->name); 120 if (lstat(name, &st) < 0) { 121 warnx("can't stat `%s'", name); 122 continue; 123 } 124 switch (st.st_mode & S_IFMT) { 125 case S_IFDIR: 126 warnx("Warning - directory `%s' in PLIST", name); 127 break; 128 case S_IFLNK: 129 if (RelativeLinks) { 130 CheckSymlink(name, cwd, strlen(cwd)); 131 } 132 (void) strlcpy(target, SYMLINK_HEADER, 133 sizeof(target)); 134 if ((cc = readlink(name, &target[SymlinkHeaderLen], 135 sizeof(target) - SymlinkHeaderLen - 1)) < 0) { 136 warnx("can't readlink `%s'", name); 137 continue; 138 } 139 target[SymlinkHeaderLen + cc] = 0x0; 140 tmp = new_plist_entry(); 141 tmp->name = xstrdup(target); 142 tmp->type = PLIST_COMMENT; 143 tmp->next = p->next; 144 tmp->prev = p; 145 if (p == pkg->tail) { 146 pkg->tail = tmp; 147 } 148 p->next = tmp; 149 p = tmp; 150 break; 151 case S_IFCHR: 152 warnx("Warning - char special device `%s' in PLIST", name); 153 break; 154 case S_IFBLK: 155 warnx("Warning - block special device `%s' in PLIST", name); 156 break; 157 default: 158 (void) strlcpy(buf, CHECKSUM_HEADER, 159 sizeof(buf)); 160 if (MD5File(name, &buf[ChecksumHeaderLen]) != (char *) NULL) { 161 tmp = new_plist_entry(); 162 tmp->name = xstrdup(buf); 163 tmp->type = PLIST_COMMENT; /* PLIST_MD5 - HF */ 164 tmp->next = p->next; 165 tmp->prev = p; 166 if (p == pkg->tail) { 167 pkg->tail = tmp; 168 } 169 p->next = tmp; 170 p = tmp; 171 } 172 break; 173 } 174 break; 175 default: 176 break; 177 } 178 } 179} 180