2 * FreeBSD install - a package for the installation and maintainance
3 * of non-core utilities.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
17 * Routines for dealing with the packing list.
19 * $FreeBSD: src/usr.sbin/pkg_install/create/pl.c,v 1.13.2.8 2002/08/31 19:31:02 obrien Exp $
20 * $DragonFly: src/usr.sbin/pkg_install/create/Attic/pl.c,v 1.2 2003/06/17 04:29:59 dillon Exp $
29 /* Check a list for files that require preconversion */
31 check_list(const char *home, Package *pkg)
33 const char *where = home;
34 const char *there = NULL;
35 char *cp, name[FILENAME_MAX], buf[33];
38 for (p = pkg->head; p != NULL; p = p->next)
54 sprintf(name, "%s/%s", there ? there : where, p->name);
55 if (issymlink(name)) {
57 char lnk[FILENAME_MAX];
59 if ((len = readlink(name, lnk, FILENAME_MAX)) > 0)
60 cp = MD5Data((unsigned char *)lnk, len, buf);
61 } else if (isfile(name)) {
62 /* Don't record MD5 checksum for device nodes and such */
63 cp = MD5File(name, buf);
67 PackingList tmp = new_plist_entry();
69 tmp->name = copy_string(strconcat("MD5:", cp));
70 tmp->type = PLIST_COMMENT;
85 trylink(const char *from, const char *to)
87 if (link(from, to) == 0)
89 if (errno == ENOENT) {
90 /* try making the container directory */
91 char *cp = strrchr(to, '/');
93 vsystem("mkdir -p %.*s", cp - to,
95 return link(from, to);
100 #define STARTSTRING "tar cf -"
101 #define TOOBIG(str) (int)strlen(str) + 6 + (int)strlen(home) + where_count > maxargs
102 #define PUSHOUT() /* push out string */ \
103 if (where_count > (int)sizeof(STARTSTRING)-1) { \
104 strcat(where_args, "|tar xpf -"); \
105 if (system(where_args)) { \
107 errx(2, "%s: can't invoke tar pipeline", __func__); \
109 memset(where_args, 0, maxargs); \
111 strcpy(where_args, STARTSTRING); \
112 where_count = sizeof(STARTSTRING)-1; \
116 * Copy unmarked files in packing list to playpen - marked files
117 * have already been copied in an earlier pass through the list.
120 copy_plist(const char *home, Package *plist)
122 PackingList p = plist->head;
123 const char *where = home;
124 const char *there = NULL, *mythere;
126 const char *last_chdir, *root = "/";
127 int maxargs, where_count = 0, add_count;
131 maxargs = sysconf(_SC_ARG_MAX);
133 * Some slop for the tar cmd text,
136 where_args = malloc(maxargs);
139 errx(2, "%s: can't get argument list space", __func__);
142 memset(where_args, 0, maxargs);
143 strcpy(where_args, STARTSTRING);
144 where_count = sizeof(STARTSTRING)-1;
147 if (stat(".", &stb) == 0)
150 curdir = (dev_t) -1; /*
151 * It's ok if this is a valid dev_t;
152 * this is just a hint for an
157 if (p->type == PLIST_CWD)
159 else if (p->type == PLIST_SRC)
161 else if (p->type == PLIST_IGNORE)
163 else if (p->type == PLIST_FILE && !p->marked) {
164 char fn[FILENAME_MAX];
167 /* First, look for it in the "home" dir */
168 sprintf(fn, "%s/%s", home, p->name);
170 if (lstat(fn, &stb) == 0 && stb.st_dev == curdir &&
171 S_ISREG(stb.st_mode)) {
173 * If we can link it to the playpen, that avoids a copy
176 if (p->name[0] != '/') {
178 * Don't link abspn stuff--it doesn't come from
181 if (trylink(fn, p->name) == 0) {
190 if (p->name[0] == '/') {
191 add_count = snprintf(&where_args[where_count],
192 maxargs - where_count,
194 last_chdir == root ? "" : "-C /",
198 add_count = snprintf(&where_args[where_count],
199 maxargs - where_count,
201 last_chdir == home ? "" : "-C ",
202 last_chdir == home ? "" : home,
206 if (add_count < 0 || add_count > maxargs - where_count) {
208 errx(2, "%s: oops, miscounted strings!", __func__);
210 where_count += add_count;
213 * Otherwise, try along the actual extraction path..
216 if (p->name[0] == '/')
218 else mythere = there;
219 sprintf(fn, "%s/%s", mythere ? mythere : where, p->name);
220 if (lstat(fn, &stb) == 0 && stb.st_dev == curdir &&
221 S_ISREG(stb.st_mode)) {
223 * If we can link it to the playpen, that avoids a copy
226 if (trylink(fn, p->name) == 0) {
231 if (TOOBIG(p->name)) {
234 if (last_chdir == (mythere ? mythere : where))
235 add_count = snprintf(&where_args[where_count],
236 maxargs - where_count,
239 add_count = snprintf(&where_args[where_count],
240 maxargs - where_count,
242 mythere ? mythere : where,
244 if (add_count < 0 || add_count > maxargs - where_count) {
246 errx(2, "%s: oops, miscounted strings!", __func__);
248 where_count += add_count;
249 last_chdir = (mythere ? mythere : where);