Annotation of pkgsrc/pkgtools/pkg_install/files/create/pl.c, Revision 1.7
1.7 ! grant 1: /* $NetBSD: pl.c,v 1.30 2004/01/15 09:33:39 agc Exp $ */
1.1 schmonz 2:
1.3 jlam 3: #if HAVE_CONFIG_H
4: #include "config.h"
5: #endif
1.4 jlam 6: #include <nbcompat.h>
1.3 jlam 7: #if HAVE_SYS_CDEFS_H
1.1 schmonz 8: #include <sys/cdefs.h>
1.3 jlam 9: #endif
1.1 schmonz 10: #ifndef lint
11: #if 0
12: static const char *rcsid = "from FreeBSD Id: pl.c,v 1.11 1997/10/08 07:46:35 charnier Exp";
13: #else
1.7 ! grant 14: __RCSID("$NetBSD: pl.c,v 1.30 2004/01/15 09:33:39 agc Exp $");
1.1 schmonz 15: #endif
16: #endif
17:
18: /*
19: * FreeBSD install - a package for the installation and maintainance
20: * of non-core utilities.
21: *
22: * Redistribution and use in source and binary forms, with or without
23: * modification, are permitted provided that the following conditions
24: * are met:
25: * 1. Redistributions of source code must retain the above copyright
26: * notice, this list of conditions and the following disclaimer.
27: * 2. Redistributions in binary form must reproduce the above copyright
28: * notice, this list of conditions and the following disclaimer in the
29: * documentation and/or other materials provided with the distribution.
30: *
31: * Jordan K. Hubbard
32: * 18 July 1993
33: *
34: * Routines for dealing with the packing list.
35: *
36: */
37:
38: #include "lib.h"
39: #include "create.h"
1.3 jlam 40: #if HAVE_ERR_H
1.1 schmonz 41: #include <err.h>
42: #endif
1.3 jlam 43: #if HAVE_MD5_H
1.1 schmonz 44: #include <md5.h>
45: #endif
46:
47: /*
48: * Check that any symbolic link is relative to the prefix
49: */
50: static void
51: CheckSymlink(char *name, char *prefix, size_t prefixcc)
52: {
53: char newtgt[MAXPATHLEN];
54: char oldtgt[MAXPATHLEN];
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++) {
1.6 jlam 66: strlcpy(&newtgt[cc], "../", sizeof(newtgt) - cc);
1.1 schmonz 67: cc += 3;
68: }
1.6 jlam 69: strlcpy(&newtgt[cc], &oldtgt[prefixcc + 1], sizeof(newtgt) - cc);
1.1 schmonz 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: * (Reversed) comparison routine for directory name sorting
82: */
83: static int
84: dircmp(const void *vp1, const void *vp2)
85: {
86: return strcmp((const char *) vp2, (const char *) vp1);
87: }
88:
89: /*
90: * Re-order the PLIST_DIR_RM entries into reverse alphabetic order
91: */
92: static void
93: reorder(package_t *pkg, int dirc)
94: {
95: plist_t *p;
96: char **dirv;
97: int i;
98:
99: if ((dirv = (char **) calloc(dirc, sizeof(char *))) == (char **) NULL) {
100: warn("No directory re-ordering will be done");
101: } else {
102: for (p = pkg->head, i = 0; p; p = p->next) {
103: if (p->type == PLIST_DIR_RM) {
104: dirv[i++] = p->name;
105: }
106: }
107: qsort(dirv, dirc, sizeof(char *), dircmp);
108: for (p = pkg->head, i = 0; p; p = p->next) {
109: if (p->type == PLIST_DIR_RM) {
110: p->name = dirv[i++];
111: }
112: }
113: (void) free(dirv);
114: }
115: }
116:
117: /*
118: * Check a list for files that require preconversion
119: */
120: void
121: check_list(char *home, package_t *pkg, const char *PkgName)
122: {
123: struct stat st;
124: plist_t *tmp;
125: plist_t *p;
1.7 ! grant 126: char buf[ChecksumHeaderLen + LegibleChecksumLen];
! 127: char target[FILENAME_MAX + SymlinkHeaderLen];
1.1 schmonz 128: char name[FILENAME_MAX];
129: char *cwd = home;
130: char *srcdir = NULL;
131: int dirc;
1.7 ! grant 132: int cc;
1.1 schmonz 133:
134: /* Open Package Database for writing */
1.2 jschauma 135: if (update_pkgdb && !pkgdb_open(ReadWrite)) {
1.1 schmonz 136: cleanup(0);
1.2 jschauma 137: err(EXIT_FAILURE, "can't open pkgdb");
1.1 schmonz 138: }
139:
140: for (dirc = 0, p = pkg->head; p; p = p->next) {
141: switch (p->type) {
142: case PLIST_CWD:
143: cwd = p->name;
144: break;
145: case PLIST_IGNORE:
146: p = p->next;
147: break;
148: case PLIST_SRC:
149: srcdir = p->name;
150: break;
151: case PLIST_DIR_RM:
152: dirc++;
153: break;
154: case PLIST_FILE:
155: /*
156: * pkgdb handling - usually, we enter files
157: * into the pkgdb as soon as they hit the disk,
158: * but as they are present before pkg_create
159: * starts, it's ok to do this somewhere here
160: */
161: if (update_pkgdb) {
162: char *s, t[FILENAME_MAX];
163:
1.3 jlam 164: (void) snprintf(t, sizeof(t), "%s%s%s",
165: cwd,
166: (strcmp(cwd, "/") == 0) ? "" : "/",
167: p->name);
1.1 schmonz 168:
169: s = pkgdb_retrieve(t);
170: #ifdef PKGDB_DEBUG
171: fprintf(stderr, "pkgdb_retrieve(\"%s\")=\"%s\"\n", t, s); /* pkgdb-debug - HF */
172: #endif
173: if (s && PlistOnly)
174: warnx("Overwriting %s - "
175: "pkg %s bogus/conflicting?", t, s);
176: else {
177: pkgdb_store(t, PkgName);
178: #ifdef PKGDB_DEBUG
179: fprintf(stderr, "pkgdb_store(\"%s\", \"%s\")\n", t, PkgName); /* pkgdb-debug - HF */
180: #endif
181: }
182: }
183:
184: if (cwd == home) {
185: /* no @cwd yet */
186: (void) snprintf(name, sizeof(name), "%s/%s", srcdir ? srcdir : cwd, p->name);
187: } else {
188: /* after @cwd */
189: /* prepend DESTDIR if set? - HF */
1.3 jlam 190: (void) snprintf(name, sizeof(name), "%s%s%s",
191: cwd,
192: (strcmp(cwd, "/") == 0) ? "" : "/",
193: p->name);
1.1 schmonz 194: }
195: if (lstat(name, &st) < 0) {
196: warnx("can't stat `%s'", name);
197: continue;
198: }
199: switch (st.st_mode & S_IFMT) {
200: case S_IFDIR:
201: p->type = PLIST_DIR_RM;
202: dirc++;
203: continue;
204: case S_IFLNK:
205: if (RelativeLinks) {
206: CheckSymlink(name, cwd, strlen(cwd));
207: }
1.7 ! grant 208: (void) strlcpy(target, SYMLINK_HEADER,
! 209: sizeof(target));
! 210: if ((cc = readlink(name, &target[SymlinkHeaderLen],
! 211: sizeof(target) - SymlinkHeaderLen)) < 0) {
! 212: warnx("can't readlink `%s'", name);
! 213: continue;
! 214: }
! 215: target[SymlinkHeaderLen + cc] = 0x0;
! 216: tmp = new_plist_entry();
! 217: tmp->name = strdup(target);
! 218: tmp->type = PLIST_COMMENT;
! 219: tmp->next = p->next;
! 220: tmp->prev = p;
! 221: if (p == pkg->tail) {
! 222: pkg->tail = tmp;
! 223: }
! 224: p->next = tmp;
! 225: p = tmp;
1.1 schmonz 226: break;
227: case S_IFCHR:
228: warnx("Warning - char special device `%s' in PLIST", name);
229: break;
230: case S_IFBLK:
231: warnx("Warning - block special device `%s' in PLIST", name);
232: break;
233: default:
1.3 jlam 234: (void) strlcpy(buf, CHECKSUM_HEADER,
235: sizeof(buf));
1.1 schmonz 236: if (MD5File(name, &buf[ChecksumHeaderLen]) != (char *) NULL) {
237: tmp = new_plist_entry();
238: tmp->name = strdup(buf);
239: tmp->type = PLIST_COMMENT; /* PLIST_MD5 - HF */
240: tmp->next = p->next;
241: tmp->prev = p;
242: if (p == pkg->tail) {
243: pkg->tail = tmp;
244: }
245: p->next = tmp;
246: p = tmp;
247: }
248: break;
249: }
250: break;
251: default:
252: break;
253: }
254: }
255:
256: if (update_pkgdb) {
257: pkgdb_close();
258: }
259:
260: if (ReorderDirs && dirc > 0) {
261: reorder(pkg, dirc);
262: }
263: }
CVSweb <webmaster@jp.NetBSD.org>