2 * Copyright (c)2004 The DragonFly Project. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
16 * Neither the name of the DragonFly Project nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31 * OF THE POSSIBILITY OF SUCH DAMAGE.
36 * Manage installation etc of packages.
37 * $Id: package.c,v 1.24 2005/02/06 21:05:18 cpressey Exp $
46 #include "libaura/dict.h"
47 #include "libaura/fspred.h"
48 #include "libaura/popen.h"
50 #include "libdfui/dfui.h"
54 #include "functions.h"
59 * Determine whether a package is installed on a DragonFly HDD.
62 pkg_exists(struct i_fn_args
*a
, const char *pkg
)
64 return(is_dir("%smnt/var/db/pkg/%s", a
->os_root
, pkg
));
68 pkg_clean(struct i_fn_args
*a
, struct commands
*cmds
)
70 command_add(cmds
, "%s%s %smnt/ /%s '*'",
71 a
->os_root
, cmd_name(a
, "CHROOT"),
72 a
->os_root
, cmd_name(a
, "PKG_DELETE"));
77 * Copy a package from an installation CD onto a DragonFly HDD.
80 pkg_copy(struct i_fn_args
*a
, struct commands
*cmds
, const char *pkg_name
,
81 struct aura_dict
*seen
)
89 * Get all the packages that this package depends on, and
90 * recursively pkg_copy them first, if they're not already there.
92 * XXX We should be sending this command through a command chain
93 * right now so that we can get an accurate idea of what is being
94 * run and so that it will be logged. But unfortunately that's
95 * not feasible, since this function is building another command
96 * chain for later use. So we use a pipe.
98 if ((pipe
= aura_popen("%s%s -r %s", "r",
99 a
->os_root
, cmd_name(a
, "PKG_INFO"), pkg_name
)) == NULL
)
102 while (fgets(line
, 255, pipe
) != NULL
) {
104 * Only look at lines that begin with 'Dependency:'.
106 if (strncmp(line
, "Dependency:", 11) != 0)
108 rpkg_name
= &line
[12];
111 * Strip any trailing whitespace.
113 while (strlen(rpkg_name
) > 0 &&
114 isspace(rpkg_name
[strlen(rpkg_name
) - 1])) {
115 rpkg_name
[strlen(rpkg_name
) - 1] = '\0';
118 if (!pkg_exists(a
, rpkg_name
)) {
119 if (!pkg_copy(a
, cmds
, rpkg_name
, seen
)) {
126 snprintf(pkg_suffix
, 256, "tgz");
127 if (!pkg_exists(a
, pkg_name
) &&
128 !aura_dict_exists(seen
, pkg_name
, strlen(pkg_name
))) {
129 aura_dict_store(seen
,
130 pkg_name
, strlen(pkg_name
), "", 0);
131 command_add(cmds
, "%s%s -b %s %smnt/tmp/%s.%s",
132 a
->os_root
, cmd_name(a
, "PKG_CREATE"),
133 pkg_name
, a
->os_root
, pkg_name
, pkg_suffix
);
134 command_add(cmds
, "%s%s %smnt/ /%s /tmp/%s.%s",
135 a
->os_root
, cmd_name(a
, "CHROOT"),
136 a
->os_root
, cmd_name(a
, "PKG_ADD"),
137 pkg_name
, pkg_suffix
);
138 command_add(cmds
, "%s%s %smnt/tmp/%s.%s",
139 a
->os_root
, cmd_name(a
, "RM"),
140 a
->os_root
, pkg_name
, pkg_suffix
);
147 * Remove a package from a DragonFly HDD.
150 pkg_remove(struct i_fn_args
*a
, struct commands
*cmds
, const char *pkg_name
,
151 struct aura_dict
*seen
)
154 char *command
, *rpkg_name
;
156 int seen_required_by
= 0;
159 * Get all the packages that this package depends on, and
160 * recursively pkg_copy them first, if they're not already there.
163 "%s%s %smnt/ /%s -R %s",
164 a
->os_root
, cmd_name(a
, "CHROOT"),
165 a
->os_root
, cmd_name(a
, "PKG_INFO"),
167 pipe
= popen(command
, "r");
172 while (fgets(line
, 255, pipe
) != NULL
) {
174 * Only look at lines that follow the "Required by:" line.
176 if (seen_required_by
) {
179 * Strip any trailing whitespace.
181 while (strlen(rpkg_name
) > 0 &&
182 isspace(rpkg_name
[strlen(rpkg_name
) - 1])) {
183 rpkg_name
[strlen(rpkg_name
) - 1] = '\0';
186 if (strlen(rpkg_name
) > 0 && pkg_exists(a
, rpkg_name
)) {
187 if (!pkg_remove(a
, cmds
, rpkg_name
, seen
)) {
193 if (strncmp(line
, "Required by:", 12) != 0) {
194 seen_required_by
= 1;
200 if (pkg_exists(a
, pkg_name
) &&
201 !aura_dict_exists(seen
, pkg_name
, strlen(pkg_name
))) {
202 aura_dict_store(seen
,
203 pkg_name
, strlen(pkg_name
), "", 0);
204 command_add(cmds
, "%s%s %smnt/ /%s %s",
205 a
->os_root
, cmd_name(a
, "CHROOT"),
206 a
->os_root
, cmd_name(a
, "PKG_DELETE"),