]> cygwin.com Git - cygwin-apps/setup.git/blob - package_meta.cc
2002-01-04 Jan Nieuwenhuizen <janneke@gnu.org>
[cygwin-apps/setup.git] / package_meta.cc
1 /*
2 * Copyright (c) 2001, Robert Collins.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * A copy of the GNU General Public License can be found at
10 * http://www.gnu.org/
11 *
12 * Written by Robert Collins <rbtcollins@hotmail.com>
13 *
14 */
15
16 #if 0
17 static const char *cvsid =
18 "\n%%% $Id$\n";
19 #endif
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <unistd.h>
24 #include <strings.h>
25 #include "concat.h"
26
27 #include "io_stream.h"
28 #include "compress.h"
29
30 #include "filemanip.h"
31 #include "hash.h"
32 #include "log.h"
33 /* io_stream needs a bit of tweaking to get rid of this. TODO */
34 #include "mount.h"
35 /* this goes at the same time */
36 #include "win32.h"
37
38
39 #include "category.h"
40 #include "script.h"
41
42 #include "package_version.h"
43 #include "cygpackage.h"
44 #include "package_meta.h"
45 #include "package_db.h"
46
47 static const char *standard_dirs[] = {
48 "/bin",
49 "/etc",
50 "/lib",
51 "/tmp",
52 "/usr",
53 "/usr/bin",
54 "/usr/lib",
55 "/usr/src",
56 "/usr/local",
57 "/usr/local/bin",
58 "/usr/local/etc",
59 "/usr/local/lib",
60 "/usr/tmp",
61 "/var/run",
62 "/var/tmp",
63 0
64 };
65
66 void
67 hash::add_subdirs (char const *tpath)
68 {
69 char *nonp, *pp;
70 char *path = strdup (tpath);
71 for (nonp = path; *nonp == '\\' || *nonp == '/'; nonp++);
72 for (pp = path + strlen (path) - 1; pp > nonp; pp--)
73 if (*pp == '/' || *pp == '\\')
74 {
75 int i, s = 0;
76 char c = *pp;
77 *pp = 0;
78 for (i = 0; standard_dirs[i]; i++)
79 if (strcmp (standard_dirs[i] + 1, path) == 0)
80 {
81 s = 1;
82 break;
83 }
84 if (s == 0)
85 add (path);
86 *pp = c;
87 }
88 }
89
90 void
91 packagemeta::add_version (packageversion & thepkg)
92 {
93 versions.registerbyobject (thepkg);
94 }
95
96 /* assumption: package thepkg is already in the metadata list. */
97 void
98 packagemeta::set_installed (packageversion & thepkg)
99 {
100 packageversion *temp = versions.getbykey (thepkg.key);
101 if (temp == &thepkg)
102 installed = &thepkg;
103 }
104
105 /* uninstall a package if it's installed */
106 void
107 packagemeta::uninstall ()
108 {
109 if (installed)
110 {
111 /* this will need to be pushed down to the version, or even the source level
112 * to allow differences between formats to be seamlessly managed
113 * but for now: here is ok
114 */
115 hash dirs;
116 const char *line = installed->getfirstfile ();
117
118 try_run_script ("/etc/preremove/", name);
119 while (line)
120 {
121 dirs.add_subdirs (line);
122
123 char *d = cygpath ("/", line, NULL);
124 DWORD dw = GetFileAttributes (d);
125 if (dw != 0xffffffff && !(dw & FILE_ATTRIBUTE_DIRECTORY))
126 {
127 log (LOG_BABBLE, "unlink %s", d);
128 DeleteFile (d);
129 }
130 line = installed->getnextfile ();
131 }
132 installed->uninstall ();
133
134 dirs.reverse_sort ();
135 char *subdir = 0;
136 while ((subdir = dirs.enumerate (subdir)) != 0)
137 {
138 char *d = cygpath ("/", subdir, NULL);
139 if (RemoveDirectory (d))
140 log (LOG_BABBLE, "rmdir %s", d);
141 }
142 try_run_script ("/etc/postremove/", name);
143 }
144 installed = 0;
145 }
146
147
148 void
149 packagemeta::add_category (Category & cat)
150 {
151 /* add a new record for the package list */
152 CategoryPackage & catpack = Categories.registerbykey (cat);
153 catpack.pkg = this;
154 }
155
156 char const *
157 packagemeta::SDesc () const
158 {
159 return versions[1]->SDesc ();
160 };
161
162 /* Return an appropriate caption given the current action. */
163 char const *
164 packagemeta::action_caption ()
165 {
166 if (!desired && installed)
167 return "Uninstall";
168 else if (!desired)
169 return "Skip";
170 else if (desired == installed && desired->binpicked)
171 {
172 packagedb db;
173 return db.task == PackageDB_Install ? "Reinstall" : "Retrieve";
174 }
175 else if (desired == installed && desired->srcpicked)
176 /* FIXME: Redo source should come up if the tarball is already present locally */
177 return "Source";
178 else if (desired == installed) /* and neither src nor bin */
179 return "Keep";
180 else
181 return desired->Canonical_version ();
182 }
183
184 /* Set the next action given a current action. */
185 void
186 packagemeta::set_action (packageversion * default_version)
187 {
188 /* actions are the following:
189
190 for install modes (from net/local)
191 for each version:
192 install this version
193 install the source for this version
194 and a boolean flag - force install to allow reinstallation, or bypassing requirements
195 globally:
196 install the source for the current version.
197
198 to uninstall a package, the desired version is set to NULL;
199
200 for mirroring modes (download only)
201 for each version
202 download this version
203 download source for this version
204
205 these are represented by the following:
206 the desired pointer in the packagemetadata indicated which version we are operating on.
207 if we are operating on the installed version, reinstall is a valid option.
208 for the selected version, forceinstall means Do an install no matter what, and
209 srcpicked means download the source.
210
211 The default action for any installed package is to install the 'curr version'
212 if it is not already installed.
213
214 The default action for any non-installed package is to do nothing.
215
216 To achieve a no-op, set desired==installed, and if (installed) set forceinstall=0 and
217 srcpicked = 0;
218
219 Iteration through versions should follow the following rules:
220 selected radio button (prev/curr/test) (show as reinstall if that is the
221 current version) ->source only (only if the package is installed) ->oldest version....s
222 kip version of radio button...
223 newest version->uninstall->no-op->selected radio button.
224
225 If any state cannot be set (ie because (say) no prev entry exists for a package
226 simply progress to the next option.
227
228 */
229
230 /* We were set to uninstall the package */
231 if (!desired && installed)
232 {
233 /* No-op - keep whatever we've got */
234 desired = installed;
235 if (desired)
236 {
237 desired->binpicked = 0;
238 desired->srcpicked = 0;
239 }
240 return;
241 }
242 else if (desired == installed
243 && (!installed
244 || !(installed->binpicked || installed->srcpicked)))
245 /* Install the default trust version - this is a 'reinstall' for installed
246 * packages */
247 {
248 desired = NULL;
249 /* No-op */
250 desired = default_version;
251 if (desired)
252 {
253 desired->binpicked = 1;
254 return;
255 }
256 }
257 /* are we currently on the radio button selection and installed */
258 if (desired == default_version && installed &&
259 (!desired || desired->binpicked)
260 && (desired &&
261 (desired->src.Cached () || desired->src.sites.number ())))
262 {
263 /* source only this file */
264 desired = installed;
265 desired->binpicked = 0;
266 desired->srcpicked = 1;
267 return;
268 }
269 /* are we currently on source only or on the radio button but not installed */
270 else if ((desired == installed && installed
271 && installed->srcpicked) || desired == default_version)
272 {
273 /* move onto the loop through versions */
274 desired = versions[1];
275 if (desired == default_version)
276 desired = versions.number () > 1 ? versions[2] : NULL;
277 if (desired)
278 {
279 desired->binpicked = 1;
280 desired->srcpicked = 0;
281 }
282 return;
283 }
284 else
285 {
286 /* preserve the src tick box */
287 int source = desired->srcpicked;
288 /* bump the version selected, skipping the radio button trust along the way */
289 size_t n;
290 for (n = 1;
291 n <= versions.number ()
292 && desired != versions[n]; n++);
293 /* n points at pkg->desired */
294 n++;
295 if (n <= versions.number ())
296 {
297 if (default_version == versions[n])
298 n++;
299 if (n <= versions.number ())
300 {
301 desired = versions[n];
302 desired->srcpicked = source;
303 return;
304 }
305 }
306 /* went past the end - uninstall the package */
307 desired = NULL;
308 }
309 }
This page took 0.048437 seconds and 5 git commands to generate.