1.1 --- a/.gitignore Sun Jun 15 18:16:20 2008 -0400
1.2 +++ b/.gitignore Fri Jun 20 19:04:47 2008 -0400
1.3 @@ -1,10 +1,32 @@
1.4 -.gitignore
1.5 +aclocal.m4
1.6 +autom4te.cache
1.7 +compile
1.8 +config.guess
1.9 +config.h
1.10 +config.h.in
1.11 +config.log
1.12 +config.status
1.13 +config.sub
1.14 +configure
1.15 +depcomp
1.16 +INSTALL
1.17 +install-sh
1.18 +intltool-extract
1.19 +intltool-extract.in
1.20 +intltool-merge
1.21 +intltool-merge.in
1.22 +intltool-update
1.23 +intltool-update.in
1.24 +libtool
1.25 +ltmain.sh
1.26 +Makefile
1.27 +Makefile.in
1.28 +missing
1.29 +mkinstalldirs
1.30 +py-compile
1.31 +stamp-h1
1.32 *.o
1.33 +ChangeLog
1.34 +*.tar.gz
1.35 *~
1.36 -*.repo
1.37 -razor
1.38 -test-driver
1.39 -pkgs
1.40 -set
1.41 -primary.xml.gz
1.42 -filelists.xml.gz
1.43 +
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/AUTHORS Fri Jun 20 19:04:47 2008 -0400
2.3 @@ -0,0 +1,2 @@
2.4 +Kristian Høgsberg <krh@redhat.com>
2.5 +
3.1 --- a/DEPSOLVE.txt Sun Jun 15 18:16:20 2008 -0400
3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
3.3 @@ -1,364 +0,0 @@
3.4 -YUM vs RAZOR
3.5 -------------
3.6 -
3.7 -At a very high level, yum's depsolver does something roughly
3.8 -equivalent to:
3.9 -
3.10 - - For each package being installed or removed
3.11 -
3.12 - - For each relevant property (provides, requires, conflicts,
3.13 - obsoletes):
3.14 -
3.15 - - Figure out what additional packages need to be added to
3.16 - or removed from the system to satisfy this property
3.17 -
3.18 -which ends up being roughly O(N^2 * M) where N is the total number of
3.19 -properties and M is the number of packages being acted on.
3.20 -
3.21 -(I just figured that out off the top of my head, and I'm not totally
3.22 -familiar with the yum code, so it may be wrong.)
3.23 -
3.24 -Razor's depsolver is something like:
3.25 -
3.26 - - do {
3.27 -
3.28 - - For each property to be added to or removed from the system:
3.29 -
3.30 - - Figure out what packages need to be added to or removed
3.31 - from the system to satisfy this property
3.32 -
3.33 - - } until we stop adding/remove more packages
3.34 -
3.35 -with the key being that it's very easy to find the PROVIDES
3.36 -corresponding to a REQUIRES and vice versa, because the property
3.37 -arrays are sorted, and so all properties with the same "name" will be
3.38 -adjacent to one another in the array, allowing many dependencies to be
3.39 -satisified in essentially constant time. (Actually... we've been
3.40 -calling it constant, but it's really O(log N) for heavily-depended-on
3.41 -packages, because the more packages you have, the more variations on
3.42 -"requires foo", "requires foo = 1.1", "requires foo > 1.0", etc you're
3.43 -going to have to scan through.)
3.44 -
3.45 -Ideally though, each iteration of the inner loop body happens in
3.46 -constant time, and thus the inner loop as a whole is O(N), and thus
3.47 -the depsolver as a whole is O(N * M) (or at least, less than
3.48 -O(N * M * log N).
3.49 -
3.50 -
3.51 -FILE DEPENDENCIES
3.52 ------------------
3.53 -
3.54 -Whenever we add a package with a file REQUIRES to a razor_set, we also
3.55 -add a PROVIDES for that file to the package or packages which provide
3.56 -that file. This means that if we later add another package that
3.57 -requires the same file (eg, /bin/sh or /usr/bin/perl), we can resolve
3.58 -its file requirement exactly like we would resolve a property
3.59 -requirement, in nearly constant time.
3.60 -
3.61 -When adding a *new* file requirement (ie, a requirement on a file that
3.62 -no existing package depends on), we still have to scan through the
3.63 -file tree, which is O(log N) in the number of files.
3.64 -
3.65 -(AFAICT, there's no reason yum couldn't do the same optimization.
3.66 -Also, AFAICT, yum currently sticks property dependencies and file
3.67 -dependencies into the same hash table, so that if any package in the
3.68 -transaction has a file dependency, it causes *property* dependencies
3.69 -to become slower to resolve as well...)
3.70 -
3.71 -
3.72 -THE RULES
3.73 ----------
3.74 -
3.75 -This is what we have figured out for transaction-solving rules;
3.76 -neither yum nor rpm's algorithm seems to be explained in full
3.77 -anywhere...
3.78 -
3.79 - 1. Every requested install in the initial package set must be
3.80 - satisfied as either a new install or an update:
3.81 -
3.82 - - if the requested package name is the name of an upstream
3.83 - package:
3.84 -
3.85 - - if there is not a corresponding already-installed
3.86 - package, then install the upstream package
3.87 -
3.88 - - else if the upstream package is newer than the
3.89 - already-installed package, then update the package
3.90 -
3.91 - - else it's an error (UP_TO_DATE)
3.92 -
3.93 - - else if the requested package name is the name of an
3.94 - already-installed package:
3.95 -
3.96 - - if there is an upstream package that obsoletes the
3.97 - already-installed package, then behave as though the
3.98 - user had requested that that package be installed
3.99 - instead.
3.100 -
3.101 - - else it's an error (UP_TO_DATE or INSTALL_UNAVAILABLE?)
3.102 -
3.103 - - else it's an error (INSTALL_UNAVAILABLE)
3.104 -
3.105 - 2. Every requested removal in the initial package set must be
3.106 - satisfied as a removal. If any requested package name is not
3.107 - the name of an installed package, it's an error
3.108 - (REMOVE_NOT_INSTALLED)
3.109 -
3.110 - REQUIRES processing:
3.111 -
3.112 - 3. If a package being installed or updated-to REQUIRES a property
3.113 - that is not provided by any installed or to-be-installed
3.114 - package, we need to find an installable package that provides
3.115 - that property. If we find one, install/update it. If not, it's
3.116 - an error (UNSATISFIABLE). (If we find an upstream package
3.117 - providing the property that corresponds to a system package
3.118 - that's being removed, then it's a CONTRADICTION.)
3.119 -
3.120 - 4. If an already-installed package REQUIRES a property which is
3.121 - only provided by a package that is being removed, then that
3.122 - package needs to be removed as well.
3.123 -
3.124 - 5. If an already-installed package REQUIRES a property which is
3.125 - only provided by a package that is being upgraded or obsoleted
3.126 - (to a new package which does not provide that property), then:
3.127 -
3.128 - - if there is an update for the installed package, then update
3.129 - the installed package
3.130 -
3.131 - - else if there is another installable package that provides
3.132 - the required property, then install that.
3.133 -
3.134 - - else it's an error (UNSATISFIABLE?)
3.135 -
3.136 - CONFLICTS processing
3.137 -
3.138 - 6. If a package being installed or updated-to CONFLICTS with a
3.139 - property provided by an installed package:
3.140 -
3.141 - - if there is an update for the installed package, which the
3.142 - new package does not conflict with, then update the
3.143 - installed package.
3.144 -
3.145 - - else it's an error (NEW_CONFLICT)
3.146 -
3.147 - 7. If an already-installed package CONFLICTS with a property
3.148 - provided by a to-be-installed package:
3.149 -
3.150 - - if there is an update for the installed package, which does
3.151 - not conflict with the new package, then update the installed
3.152 - package.
3.153 -
3.154 - - else it's an error (NEW_CONFLICT)
3.155 -
3.156 - 8. If a package being installed or updated-to CONFLICTS with a
3.157 - property provided by a to-be-installed package, then it's an
3.158 - error (CONTRADICTION).
3.159 -
3.160 - OBSOLETES processing. NOTE: OBSOLETES are only matched against
3.161 - package names, not against arbitrary provided properties
3.162 -
3.163 - 9. If a package being installed or updated-to OBSOLETES an
3.164 - installed package, then obsolete that package. (ie, remove it,
3.165 - but treat it as updated for purposes of dangling REQUIRES).
3.166 -
3.167 - 10. If an already-installed package OBSOLETES a to-be-installed
3.168 - package, then it's an error. (ALREADY_OBSOLETE)
3.169 -
3.170 - 11. If a package being installed or updated-to OBSOLETES another
3.171 - package being installed or updated-to, then it's an error
3.172 - (CONTRADICTION).
3.173 -
3.174 -
3.175 -
3.176 -THE DEPSOLVER
3.177 --------------
3.178 -
3.179 -We start with two razor_sets, system and upstream, and a list of
3.180 -requested installations and removals.
3.181 -
3.182 - FIXME: what about multiple upstream repos? Having to deal with
3.183 - arbitrary numbers of razor_sets is possible, but will probably be
3.184 - messy... It might be easier to either store all upstream repo data
3.185 - in a single .repo file, or else merge all upstream .repo files
3.186 - together into a single razor_set at startup. (Or some combination
3.187 - of those.)
3.188 -
3.189 -We create a bit array of the packages in each set, indicating which
3.190 -ones are installed; the system bitarray starts out all 1s, and the
3.191 -upstream bitarray all 0s. Each bit is only allowed to change state
3.192 -once during the transaction; an installed package can be removed, or
3.193 -an uninstalled package installed, but trying to reinstall a removed
3.194 -package, or uninstall a newly-installed package is an error. This
3.195 -means the packages break down into four categories:
3.196 -
3.197 - - installed (1 bit in the system bit array)
3.198 - - to-be-removed (0 bit in the system bit array)
3.199 - - to-be-installed (1 bit in the upstream bit array)
3.200 - - installable (0 bit in the upstream bit array)
3.201 -
3.202 -
3.203 -Depsolver algorithm:
3.204 -
3.205 - - Create new razor_transaction_packages ("rtp"s) for each
3.206 - requested install or remove. These will be "unresolved", because
3.207 - we haven't yet found the razor_packages that correspond to them.
3.208 -
3.209 - - while there are new rtps:
3.210 -
3.211 - - sort the new rtps
3.212 -
3.213 - - Walk the system property list, upstream property list, and
3.214 - new rtp list in parallel, and:
3.215 -
3.216 - - For each uninstalled PROVIDES:
3.217 -
3.218 - - If the property is a valid package name (that is,
3.219 - either it's a package providing its own name, or it
3.220 - has a matching OBSOLETES), and it matches the name
3.221 - of a new rtp of type INSTALL or FORCED_UPDATE with
3.222 - an unresolved new_package:
3.223 -
3.224 - - If the upstream package has the same version as
3.225 - the system package, we have an UP_TO_DATE error
3.226 - (FIXME: not quite right. This doesn't deal with
3.227 - the case where we try to update an application
3.228 - because of a library update, and it turns out
3.229 - there's no new version of the application, but
3.230 - there IS a compat package containing the old
3.231 - version of the library.)
3.232 -
3.233 - - Otherwise, set the rtp's new_package to point to
3.234 - the package providing this property and set the
3.235 - appropriate bit in the upstream bit array.
3.236 -
3.237 - - For each to-be-installed non-file REQUIRES:
3.238 -
3.239 - - See if there's an installed or to-be-installed
3.240 - package that PROVIDES that property.
3.241 -
3.242 - - If not, see if there's an installable package that
3.243 - PROVIDES that property, and create a new INSTALL rtp
3.244 - for it if so.
3.245 -
3.246 - - If not, see if there's a to-be-removed package that
3.247 - PROVIDES that property. (If we find such a package,
3.248 - we have a CONTRADICTION error.)
3.249 -
3.250 - - If none of the above, then we have an UNSATISFIABLE
3.251 - error
3.252 -
3.253 - - For each to-be-installed file REQUIRES:
3.254 -
3.255 - - (We create fake file PROVIDES to match file REQUIRES
3.256 - when importing/merging razor sets, so if there is
3.257 - already another installed package that REQUIRES this
3.258 - file, there will be a PROVIDES listed for it as well.)
3.259 -
3.260 - - See if there's an installed package that PROVIDES
3.261 - that file.
3.262 -
3.263 - - If not, do a binary search of the system file tree
3.264 - looking to see if some installed package provides
3.265 - that file but does not have a PROVIDES for it.
3.266 -
3.267 - - If not, see if there's an installable package that
3.268 - PROVIDES that property, and create a new INSTALL rtp
3.269 - for it if so.
3.270 -
3.271 - - (If we actually work with multiple upstream
3.272 - razor_sets, then we will need to search the upstream
3.273 - file trees at this point, because it's possible that
3.274 - a package in one upstream repo would require a file
3.275 - in another upstream repo. But if we merge the
3.276 - multiple upstream repos into a single razor_set at
3.277 - some point, then we would not need to do that,
3.278 - because it would be guaranteed that we would have
3.279 - already created a fake PROVIDES if any package
3.280 - provides the file.)
3.281 -
3.282 - - If no installed or installable package provides the
3.283 - file, see if there's a to-be-removed package that
3.284 - provides the file. (If we find such a package, we
3.285 - have a CONTRADICTION error.)
3.286 -
3.287 - - If none of the above, then we have an UNSATISFIABLE
3.288 - error
3.289 -
3.290 - - For each to-be-installed PROVIDES:
3.291 -
3.292 - - Check if the new PROVIDES conflicts with an
3.293 - installed CONFLICTS. If so, create a new
3.294 - FORCED_UPDATE rtp for the installed package, so we
3.295 - can try to upgrade it to a non-conflicting version.
3.296 - (If we can't, we'll have an OLD_CONFLICT error.)
3.297 -
3.298 - - Check if the new PROVIDES conflicts with an
3.299 - installed OBSOLETES *and* the PROVIDES property
3.300 - corresponds to the name of its package. (That is,
3.301 - OBSOLETES are only matched against package names,
3.302 - not arbitrary provided properties.) If so, we have
3.303 - an ALREADY_OBSOLETE error.
3.304 -
3.305 - - Check if the new PROVIDES conflicts with a
3.306 - to-be-installed CONFLICTS. If so, we have a
3.307 - CONTRADICTION error.
3.308 -
3.309 - - For each to-be-installed CONFLICTS:
3.310 -
3.311 - - Basically the reverse of the previous case: check if
3.312 - the new CONFLICTS conflicts with an installed
3.313 - PROVIDES. If so, create a new FORCED_UPDATE rtp for
3.314 - the installed package, so we can try to upgrade it
3.315 - to a non-conflicting version. (If we can't, we'll
3.316 - have an NEW_CONFLICT error.)
3.317 -
3.318 - - Check if the new CONFLICTS conflicts with a
3.319 - to-be-installed PROVIDES. If so, we have a
3.320 - CONTRADICTION error.
3.321 -
3.322 - - For each to-be-installed OBSOLETES:
3.323 -
3.324 - - Check if there's an installed package that PROVIDES
3.325 - that property. If so, create an OBSOLETED rtp for
3.326 - the installed package.
3.327 -
3.328 - - If not, check if there's a to-be-installed package
3.329 - that PROVIDES that property. If so, we have a
3.330 - CONTRADICTION error.
3.331 -
3.332 -
3.333 - - For each installed PROVIDES:
3.334 -
3.335 - - If the property is a valid package name (that is,
3.336 - it's a package providing its own name), and it
3.337 - matches the name of a new rtp with an unresolved
3.338 - old_package, then set the rtp's old_package to point
3.339 - to the package providing this property and clear the
3.340 - appropriate bit in the system bit array.
3.341 -
3.342 - - For each to-be-removed PROVIDES:
3.343 -
3.344 - - If there's also an identical to-be-installed
3.345 - PROVIDES, we're ok and can skip this
3.346 -
3.347 - - Otherwise, for each installed REQUIRES of this
3.348 - property:
3.349 -
3.350 - - Look for some other installed or to-be-installed
3.351 - property that satisfies the REQUIRES.
3.352 -
3.353 - - If there isn't one, then for each installed
3.354 - package in this REQUIRES's package list:
3.355 -
3.356 - - If the PROVIDES was lost because the old
3.357 - package was REMOVEd (not FORCED_UPDATE or
3.358 - OBSOLETED), then create a new REMOVE rtp for
3.359 - this package.
3.360 -
3.361 - - Otherwise, create a new FORCED_UPDATE rtp
3.362 - for this package.
3.363 -
3.364 - - (We don't need to look at to-be-installed REQUIRES
3.365 - of this property, because if there are any, they
3.366 - will cause a CONTRADICTION error when we try to
3.367 - re-satisfy them the next time through.)
4.1 --- a/Makefile Sun Jun 15 18:16:20 2008 -0400
4.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
4.3 @@ -1,23 +0,0 @@
4.4 -CFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes -g
4.5 -LDLIBS = -lexpat -lz -g -lrpm -lcurl
4.6 -
4.7 -all : razor test-driver rpm-razor
4.8 -
4.9 -razor : razor.o yum.o main.o rpm.o types.o util.o
4.10 -
4.11 -*.o : razor.h razor-internal.h
4.12 -razor.o : types.h
4.13 -
4.14 -test-driver : razor.o types.o util.o test-driver.o
4.15 -
4.16 -rpm-razor : rpm-razor.o razor.o types.o util.o rpm.o
4.17 -
4.18 -test : test-driver
4.19 - ./test-driver test.xml
4.20 -
4.21 -reset : ./razor
4.22 - sudo rm -rf install
4.23 - ./razor init
4.24 -
4.25 -clean :
4.26 - rm -f *.o razor
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/Makefile.am Fri Jun 20 19:04:47 2008 -0400
5.3 @@ -0,0 +1,38 @@
5.4 +## Process this file with automake to produce Makefile.in
5.5 +
5.6 +SUBDIRS = data docs librazor src po
5.7 +
5.8 +# Creating ChangeLog from git log (taken from cairo/Makefile.am):
5.9 +ChangeLog: $(srcdir)/ChangeLog
5.10 +
5.11 +$(srcdir)/ChangeLog:
5.12 + @if test -d "$(srcdir)/.git"; then \
5.13 + (cd "$(srcdir)" && \
5.14 + ./missing --run git-log --stat) | fmt --split-only > $@.tmp \
5.15 + && mv -f $@.tmp $@ \
5.16 + || ($(RM) $@.tmp; \
5.17 + echo Failed to generate ChangeLog, your ChangeLog may be outdated >&2; \
5.18 + (test -f $@ || echo git-log is required to generate this file >> $@)); \
5.19 + else \
5.20 + test -f $@ || \
5.21 + (echo A git checkout and git-log is required to generate ChangeLog >&2 && \
5.22 + echo A git checkout and git-log is required to generate this file >> $@); \
5.23 + fi
5.24 +
5.25 +.PHONY: ChangeLog $(srcdir)/ChangeLog
5.26 +
5.27 +EXTRA_DIST = \
5.28 + TODO \
5.29 + ChangeLog \
5.30 + intltool-extract.in \
5.31 + intltool-merge.in \
5.32 + intltool-update.in
5.33 +
5.34 +DISTCLEANFILES = \
5.35 + intltool-extract \
5.36 + intltool-merge \
5.37 + intltool-update
5.38 +
5.39 +clean-local :
5.40 + rm -f *~
5.41 +
6.1 --- a/REPO.txt Sun Jun 15 18:16:20 2008 -0400
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,172 +0,0 @@
6.4 -The repo file format / razor_set data structure
6.5 ------------------------------------------------
6.6 -
6.7 -The repo starts with a header, containing some number of sections,
6.8 -terminated by a section with type 0:
6.9 -
6.10 - struct razor_set_header {
6.11 - uint32_t magic;
6.12 - uint32_t version;
6.13 - struct razor_set_section sections[0];
6.14 - };
6.15 -
6.16 - struct razor_set_section {
6.17 - uint32_t type;
6.18 - uint32_t offset;
6.19 - uint32_t size;
6.20 - };
6.21 -
6.22 -razor_set_open() mmaps the repo file, and creates a struct razor_set:
6.23 -
6.24 - struct razor_set {
6.25 - struct array string_pool;
6.26 - struct array packages;
6.27 - struct array properties;
6.28 - struct array files;
6.29 - struct array package_pool;
6.30 - struct array property_pool;
6.31 - struct array file_pool;
6.32 - struct razor_set_header *header;
6.33 - };
6.34 -
6.35 -by finding the sections with those IDs and creating "struct array"s
6.36 -pointing to the right places in the mmapped data. (This is the only
6.37 -processing needed when reading in the file; everything else is used
6.38 -exactly as-is.)
6.39 -
6.40 -
6.41 -The sections
6.42 -------------
6.43 -
6.44 -RAZOR_STRING_POOL
6.45 -
6.46 - Stores one copy of each string that appears in the repo. (At
6.47 - the moment, this is: package names, package versions, property
6.48 - names, property versions, and (basenames of) filenames.) The
6.49 - strings are arbitrarily-sized, 0-terminated, and not in any
6.50 - particular order (although the empty string always ends up
6.51 - being at offset 0).
6.52 -
6.53 -RAZOR_PACKAGES
6.54 -
6.55 - Array of struct razor_package; one for each package in the
6.56 - set, sorted by name.
6.57 -
6.58 -RAZOR_PROPERTIES
6.59 -
6.60 - Array of struct razor_property; one for each unique property
6.61 - in the set, sorted by type, then name, then relation type (eg,
6.62 - "<" or ">="), then version. (Properties with no version have
6.63 - relation type RAZOR_VERSION_EQUAL, and version "".)
6.64 -
6.65 -RAZOR_FILES
6.66 -
6.67 - Array of struct razor_entry; one for each file owned by any
6.68 - package in the set. The current sort order (which is subject
6.69 - to change) is breadth-first, sorted by basename. So eg: /, /bin,
6.70 - /dev, /etc, /bin/false, /bin/true, /dev/null, /etc/passwd.
6.71 -
6.72 -RAZOR_PACKAGE_POOL
6.73 -
6.74 - Array of struct list, with each list item containing the index
6.75 - of a struct razor_package in the packages section. See the
6.76 - discussion of lists below.
6.77 -
6.78 -RAZOR_PROPERTY_POOL
6.79 -
6.80 - Array of struct list, with each list item containing the index
6.81 - of a struct razor_property in the properties section. See the
6.82 - discussion of lists below.
6.83 -
6.84 -RAZOR_FILE_POOL
6.85 -
6.86 - Array of struct list, with each list item containing the index
6.87 - of a struct razor_entry in the files section. See the
6.88 - discussion of lists below.
6.89 -
6.90 -
6.91 -Data types
6.92 -----------
6.93 -Note that the exact layout of bits involves some historical accidents.
6.94 -(Particularly the fact that the "name" field in most structs loses its
6.95 -high bits to a flags field.)
6.96 -
6.97 -struct list_head
6.98 - uint list_ptr : 24;
6.99 - uint flags : 8;
6.100 -
6.101 -struct list
6.102 - uint data : 24;
6.103 - uint flags : 8;
6.104 -
6.105 - Used to store lists of package, property, or file IDs. "struct
6.106 - list_head" stores the head of the list, which points to one or
6.107 - more "struct list"s in the appropriate "pool" section.
6.108 - ("struct list" should probably be called "struct list_item".)
6.109 -
6.110 - "list_first(&head, &pool)" returns a "struct list *" pointing
6.111 - to the first element of the list (or NULL for an empty list),
6.112 - and "list_next(list)" will return successive elements, until
6.113 - NULL is returned. Each "list->data" contains the index of a
6.114 - package, property, or file in the corresponding section of the
6.115 - set.
6.116 -
6.117 - Peeking underneath the abstraction, a list_head's "flags" is
6.118 - 0xff if the list is empty, 0x80 if it contains a single
6.119 - element, or 0x00 if it contains more than one element. In the
6.120 - single-element case, that element is actually stored in the
6.121 - list_head directly rather than being stored in a pool (and so
6.122 - list_first() just casts the list_head* to a list* and returns
6.123 - it). For multi-element lists, list_ptr is the index in the
6.124 - pool of the first element of this list; the list continues
6.125 - through successive elements of the pool until one with
6.126 - non-zero flags is reached, indicating the end of the list.
6.127 -
6.128 -struct razor_package
6.129 - uint name : 24;
6.130 - uint flags : 8;
6.131 - uint version : 32;
6.132 - struct list_head properties;
6.133 - struct list_head files;
6.134 -
6.135 - name and version are indexes into string_pool. properties is a
6.136 - list of all of the package's properties, and files is a list
6.137 - of its files. flags is currently only used during razor_set
6.138 - merging, to keep track of which set a package came from.
6.139 -
6.140 -struct razor_property
6.141 - uint name : 24;
6.142 - uint flags : 6;
6.143 - uint type : 2;
6.144 - uint relation : 32;
6.145 - uint version : 32;
6.146 - struct list_head packages;
6.147 -
6.148 - name and version are indexes into string_pool. type is an enum
6.149 - razor_property_type (eg, RAZOR_PROPERTY_REQUIRES), and
6.150 - relation is an enum razor_version_relation (eg,
6.151 - RAZOR_VERSION_GREATER_OR_EQUAL). packages is a list of the
6.152 - packages that have this property. flags is currently unused.
6.153 -
6.154 -struct razor_entry
6.155 - uint name : 24;
6.156 - uint flags : 8;
6.157 - uint start : 32;
6.158 - struct list_head packages;
6.159 -
6.160 - name is an index into string_pool, giving the basename of the
6.161 - file. start is either 0, or an index pointing to another
6.162 - razor_entry that is the first child of this entry (for a
6.163 - non-empty directory). (Entry 0 is always the root of the tree,
6.164 - so no entry could have entry 0 as a child.) flags is 0x80
6.165 - (RAZOR_ENTRY_LAST) if an entry is the last entry in its
6.166 - directory. Otherwise it is 0.
6.167 -
6.168 - Note that given a pointer to a struct_razor_entry (eg, from a
6.169 - package's "files" list), there is no way to reconstruct its
6.170 - full name without walking the entire files array up to that
6.171 - point. Because of this and other problems (fix_file_map()), it
6.172 - seems like razor_entry should be modified to include a pointer
6.173 - to its parent. (Storing full paths instead of just basenames
6.174 - would also fix this problem, but that would use much more
6.175 - memory.)
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/autogen.sh Fri Jun 20 19:04:47 2008 -0400
7.3 @@ -0,0 +1,95 @@
7.4 +#!/bin/sh
7.5 +# Run this to generate all the initial makefiles, etc.
7.6 +
7.7 +srcdir=`dirname $0`
7.8 +test -z "$srcdir" && srcdir=.
7.9 +
7.10 +DIE=0
7.11 +
7.12 +(test -f $srcdir/configure.ac) || {
7.13 + echo -n "**Error**: Directory $srcdir does not look like the"
7.14 + echo " top-level package directory"
7.15 + exit 1
7.16 +}
7.17 +
7.18 +(autoconf --version) < /dev/null > /dev/null 2>&1 || {
7.19 + echo
7.20 + echo "**Error**: You must have autoconf installed."
7.21 + echo "Download the appropriate package for your distribution,"
7.22 + echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
7.23 + DIE=1
7.24 +}
7.25 +
7.26 +(grep "^AM_PROG_LIBTOOL" $srcdir/configure.ac >/dev/null) && {
7.27 + (libtool --version) < /dev/null > /dev/null 2>&1 || {
7.28 + echo
7.29 + echo "**Error**: You must have libtool installed."
7.30 + echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
7.31 + DIE=1
7.32 + }
7.33 +}
7.34 +
7.35 +(automake --version) < /dev/null > /dev/null 2>&1 || {
7.36 + echo
7.37 + echo "**Error**: You must have automake installed."
7.38 + echo "You can get it from: ftp://ftp.gnu.org/pub/gnu/"
7.39 + DIE=1
7.40 + NO_AUTOMAKE=yes
7.41 +}
7.42 +
7.43 +
7.44 +# if no automake, don't bother testing for aclocal
7.45 +test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || {
7.46 + echo
7.47 + echo "**Error**: Missing aclocal. The version of automake"
7.48 + echo "installed doesn't appear recent enough."
7.49 + echo "You can get automake from ftp://ftp.gnu.org/pub/gnu/"
7.50 + DIE=1
7.51 +}
7.52 +
7.53 +if test "$DIE" -eq 1; then
7.54 + exit 1
7.55 +fi
7.56 +
7.57 +if test -z "$*"; then
7.58 + echo "**Warning**: I am going to run configure with no arguments."
7.59 + echo "If you wish to pass any to it, please specify them on the"
7.60 + echo $0 " command line."
7.61 + echo
7.62 +fi
7.63 +
7.64 +case $CC in
7.65 +xlc )
7.66 + am_opt=--include-deps;;
7.67 +esac
7.68 +
7.69 + aclocalinclude="$ACLOCAL_FLAGS"
7.70 +
7.71 + if grep "^AM_PROG_LIBTOOL" configure.ac >/dev/null; then
7.72 + if test -z "$NO_LIBTOOLIZE" ; then
7.73 + echo "Running libtoolize..."
7.74 + libtoolize --force --copy
7.75 + fi
7.76 + fi
7.77 + echo "Running aclocal $aclocalinclude ..."
7.78 + aclocal $aclocalinclude
7.79 + if grep "^AM_CONFIG_HEADER" configure.ac >/dev/null; then
7.80 + echo "Running autoheader..."
7.81 + autoheader
7.82 + fi
7.83 + echo "Running automake --gnu -Wno-portability $am_opt ..."
7.84 + automake --add-missing --gnu -Wno-portability $am_opt
7.85 + echo "Running autoconf ..."
7.86 + autoconf
7.87 +
7.88 +intltoolize --copy --force --automake || exit 1
7.89 +
7.90 +conf_flags="--enable-maintainer-mode"
7.91 +
7.92 +if test x$NOCONFIGURE = x; then
7.93 + echo "Running $srcdir/configure $conf_flags $@ ..."
7.94 + $srcdir/configure $conf_flags "$@" \
7.95 + && echo "Now type make to compile." || exit 1
7.96 +else
7.97 + echo "Skipping configure process."
7.98 +fi
8.1 --- a/bash-completion.sh Sun Jun 15 18:16:20 2008 -0400
8.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
8.3 @@ -1,47 +0,0 @@
8.4 -__razor_commands () {
8.5 - local IFS=$'\n'
8.6 - COMPREPLY=($(IFS=: compgen -S' ' -W "info:list-requires:list-provides:list-files:list-file-packages:list-package-files:what-requires:what-provides:import-yum:import-rpmdb:validate:update:diff:install:init:download" -- $1))
8.7 -}
8.8 -
8.9 -__razor_packages () {
8.10 - local IFS=$'\n'
8.11 -
8.12 - COMPREPLY=($(./razor list --only-names "$1*" | while read p; do echo "$p "; done))
8.13 -}
8.14 -
8.15 -__razor_upstream_packages () {
8.16 - local IFS=$'\n'
8.17 -
8.18 - COMPREPLY=($(RAZOR_REPO=rawhide.repo ./razor list --only-names "$1*" | while read p; do echo "$p "; done))
8.19 -}
8.20 -
8.21 -__razor_files() {
8.22 - COMPREPLY=($(./razor list-files "$1*"))
8.23 -}
8.24 -
8.25 -__razor_requires() {
8.26 - COMPREPLY=($(compgen -W "$(./razor list-requires)" -- $1))
8.27 -}
8.28 -
8.29 -__razor_provides() {
8.30 - COMPREPLY=($(compgen -W "$(./razor list-provides)" -- $1))
8.31 -}
8.32 -
8.33 -__razor() {
8.34 - local cur="${COMP_WORDS[COMP_CWORD]}"
8.35 -
8.36 - if [ $COMP_CWORD = 1 ]; then
8.37 - __razor_commands $cur
8.38 - else
8.39 - case "${COMP_WORDS[1]}" in
8.40 - info|list-requires|list-provides|list-package-files)
8.41 - __razor_packages $cur ;;
8.42 - list-files|list-file-packages) __razor_files $cur ;;
8.43 - what-requires) __razor_requires $cur ;;
8.44 - what-provides) __razor_provides $cur ;;
8.45 - install|download) __razor_upstream_packages $cur ;;
8.46 - esac
8.47 - fi
8.48 -}
8.49 -
8.50 -complete -o nospace -F __razor razor
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/configure.ac Fri Jun 20 19:04:47 2008 -0400
9.3 @@ -0,0 +1,201 @@
9.4 +dnl Process this file with autoconf to produce a configure script.
9.5 +
9.6 +AC_PREREQ(2.59c)
9.7 +AC_INIT(razor, 0.8, krh@redhat.com)
9.8 +AM_INIT_AUTOMAKE(razor, 0.1)
9.9 +AM_CONFIG_HEADER(config.h)
9.10 +AM_MAINTAINER_MODE
9.11 +
9.12 +# libtool versioning - this applies to all libraries in this package
9.13 +#
9.14 +# See http://sources.redhat.com/autobook/autobook/autobook_91.html#SEC91 for details
9.15 +#
9.16 +LT_CURRENT=1
9.17 +LT_REVISION=0
9.18 +LT_AGE=0
9.19 +AC_SUBST(LT_CURRENT)
9.20 +AC_SUBST(LT_REVISION)
9.21 +AC_SUBST(LT_AGE)
9.22 +
9.23 +AC_ISC_POSIX
9.24 +AC_PROG_CC
9.25 +AM_PROG_CC_STDC
9.26 +AC_HEADER_STDC
9.27 +AM_PROG_LIBTOOL
9.28 +AC_PROG_MAKE_SET
9.29 +AC_PROG_LN_S
9.30 +AC_SYS_LARGEFILE
9.31 +AM_PROG_CC_C_O
9.32 +
9.33 +# Taken from dbus
9.34 +AC_ARG_ENABLE(ansi, [ --enable-ansi enable -ansi -pedantic gcc flags],enable_ansi=$enableval,enable_ansi=no)
9.35 +AC_ARG_ENABLE(verbose-mode, [ --enable-verbose-mode support verbose debug mode],enable_verbose_mode=$enableval,enable_verbose_mode=$USE_MAINTAINER_MODE)
9.36 +
9.37 +if test "${enable_verbose_mode}" != no; then
9.38 + # To get -rdynamic you pass -export-dynamic to libtool.
9.39 + AC_DEFINE(BUILT_R_DYNAMIC,1,[whether -export-dynamic was passed to libtool])
9.40 + R_DYNAMIC_LDFLAG=-export-dynamic
9.41 +else
9.42 + R_DYNAMIC_LDFLAG=
9.43 +fi
9.44 +AC_SUBST(R_DYNAMIC_LDFLAG)
9.45 +
9.46 +#### gcc warning flags
9.47 +
9.48 +if test "x$GCC" = "xyes"; then
9.49 + changequote(,)dnl
9.50 + case " $CFLAGS " in
9.51 + *[\ \ ]-Wall[\ \ ]*) ;;
9.52 + *) CFLAGS="$CFLAGS -Wall" ;;
9.53 + esac
9.54 +
9.55 + case " $CFLAGS " in
9.56 + *[\ \ ]-Wchar-subscripts[\ \ ]*) ;;
9.57 + *) CFLAGS="$CFLAGS -Wchar-subscripts" ;;
9.58 + esac
9.59 +
9.60 + case " $CFLAGS " in
9.61 + *[\ \ ]-Wmissing-declarations[\ \ ]*) ;;
9.62 + *) CFLAGS="$CFLAGS -Wmissing-declarations" ;;
9.63 + esac
9.64 +
9.65 + case " $CFLAGS " in
9.66 + *[\ \ ]-Wnested-externs[\ \ ]*) ;;
9.67 + *) CFLAGS="$CFLAGS -Wnested-externs" ;;
9.68 + esac
9.69 +
9.70 + case " $CFLAGS " in
9.71 + *[\ \ ]-Wcast-align[\ \ ]*) ;;
9.72 + *) CFLAGS="$CFLAGS -Wcast-align" ;;
9.73 + esac
9.74 +
9.75 + case " $CFLAGS " in
9.76 + *[\ \ ]-Wformat[\ \ ]*) ;;
9.77 + *) CFLAGS="$CFLAGS -Wformat" ;;
9.78 + esac
9.79 +
9.80 + case " $CFLAGS " in
9.81 + *[\ \ ]-Wformat-security[\ \ ]*) ;;
9.82 + *) CFLAGS="$CFLAGS -Wformat-security" ;;
9.83 + esac
9.84 +
9.85 + if test "x$enable_ansi" = "xyes"; then
9.86 + case " $CFLAGS " in
9.87 + *[\ \ ]-ansi[\ \ ]*) ;;
9.88 + *) CFLAGS="$CFLAGS -ansi" ;;
9.89 + esac
9.90 +
9.91 + case " $CFLAGS " in
9.92 + *[\ \ ]-D_POSIX_C_SOURCE*) ;;
9.93 + *) CFLAGS="$CFLAGS -D_POSIX_C_SOURCE=199309L" ;;
9.94 + esac
9.95 +
9.96 + case " $CFLAGS " in
9.97 + *[\ \ ]-D_BSD_SOURCE[\ \ ]*) ;;
9.98 + *) CFLAGS="$CFLAGS -D_BSD_SOURCE" ;;
9.99 + esac
9.100 +
9.101 + case " $CFLAGS " in
9.102 + *[\ \ ]-pedantic[\ \ ]*) ;;
9.103 + *) CFLAGS="$CFLAGS -pedantic" ;;
9.104 + esac
9.105 + fi
9.106 + changequote([,])dnl
9.107 +fi
9.108 +
9.109 +PKG_CHECK_MODULES(CURL, [libcurl])
9.110 +AC_SUBST(CURL_CFLAGS)
9.111 +AC_SUBST(CURL_LIBS)
9.112 +
9.113 +ZLIB_LIBS=""
9.114 +AC_ARG_WITH(zlib, [ --with-zlib=<dir> Use zlib from here],
9.115 + [
9.116 + zlib=$withval
9.117 + CPPFLAGS="$CPPFLAGS -I$withval/include"
9.118 + LDFLAGS="$LDFLAGS -L$withval/lib"
9.119 + ]
9.120 + )
9.121 +AC_CHECK_HEADERS(zlib.h, [AC_DEFINE(HAVE_ZLIB_H)],
9.122 + [AC_MSG_ERROR([Can't find zlib.h. Please install zlib.])])
9.123 +AC_CHECK_LIB(z, inflate, [ZLIB_LIBS="-lz"],
9.124 + [AC_MSG_ERROR([Can't find zlib library. Please install zlib.])])
9.125 +AC_SUBST(ZLIB_LIBS)
9.126 +
9.127 +EXPAT_LIB=""
9.128 +AC_ARG_WITH(expat, [ --with-expat=<dir> Use expat from here],
9.129 + [
9.130 + expat=$withval
9.131 + CPPFLAGS="$CPPFLAGS -I$withval/include"
9.132 + LDFLAGS="$LDFLAGS -L$withval/lib"
9.133 + ]
9.134 + )
9.135 +AC_CHECK_HEADERS(expat.h, [AC_DEFINE(HAVE_EXPAT_H)],
9.136 + [AC_MSG_ERROR([Can't find expat.h. Please install expat.])])
9.137 +AC_CHECK_LIB(expat, XML_ParserCreate, [EXPAT_LIBS="-lexpat"],
9.138 + [AC_MSG_ERROR([Can't find expat library. Please install expat.])])
9.139 +AC_SUBST(EXPAT_LIBS)
9.140 +
9.141 +RPM_LIB=""
9.142 +AC_ARG_WITH(rpm, [ --with-rpm=<dir> Use rpm from here],
9.143 + [
9.144 + rpm=$withval
9.145 + CPPFLAGS="$CPPFLAGS -I$withval/include"
9.146 + LDFLAGS="$LDFLAGS -L$withval/lib"
9.147 + ]
9.148 + )
9.149 +AC_CHECK_HEADERS(rpm/rpmlib.h, [],
9.150 + [AC_MSG_ERROR([Can't find rpm/rpmlib.h. Please install rpm-devel.])])
9.151 +AC_CHECK_LIB(rpm,rpmdbOpen,[RPM_LIBS="-lrpm"],
9.152 + [AC_MSG_ERROR([Can't find rpm library. Please install rpm-devel.])])
9.153 +AC_SUBST(RPM_LIBS)
9.154 +
9.155 +if test "x$GCC" = "xyes"; then
9.156 + LDFLAGS="-Wl,--as-needed $LDFLAGS"
9.157 +fi
9.158 +
9.159 +# *****************************
9.160 +# Make available to Makefile.am
9.161 +# *****************************
9.162 +AC_SUBST(SYSCONFDIR, $sysconfdir)
9.163 +
9.164 +# ********************
9.165 +# Internationalisation
9.166 +# ********************
9.167 +
9.168 +IT_PROG_INTLTOOL([0.36.0])
9.169 +GETTEXT_PACKAGE=razor
9.170 +AC_SUBST([GETTEXT_PACKAGE])
9.171 +AM_GLIB_GNU_GETTEXT
9.172 +AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE],["$GETTEXT_PACKAGE"],[gettext domain])
9.173 +
9.174 +AC_OUTPUT([
9.175 +Makefile
9.176 +data/razor.pc
9.177 +data/Makefile
9.178 +librazor/Makefile
9.179 +src/Makefile
9.180 +docs/Makefile
9.181 +po/Makefile.in
9.182 +])
9.183 +
9.184 +dnl ==========================================================================
9.185 +echo "
9.186 + razor $VERSION
9.187 + =================
9.188 +
9.189 + prefix: ${prefix}
9.190 + libdir: ${libdir}
9.191 + libexecdir: ${libexecdir}
9.192 + bindir: ${bindir}
9.193 + sbindir: ${sbindir}
9.194 + datadir: ${datadir}
9.195 + sysconfdir: ${sysconfdir}
9.196 + localstatedir: ${localstatedir}
9.197 + docdir: ${docdir}
9.198 +
9.199 + compiler: ${CC}
9.200 + cflags: ${CFLAGS}
9.201 + Maintainer mode: ${USE_MAINTAINER_MODE}
9.202 + Building verbose mode: ${enable_verbose_mode}
9.203 +"
9.204 +
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/contrib/razor.spec Fri Jun 20 19:04:47 2008 -0400
10.3 @@ -0,0 +1,100 @@
10.4 +Summary: Razor is a package management system replacing rpm and yum
10.5 +Name: razor
10.6 +Version: 0.1
10.7 +Release: 0.1%{?dist}
10.8 +License: GPLv2+
10.9 +Group: System Environment/Libraries
10.10 +URL: http://github.com/krh/razor/wikis
10.11 +Source0: http://people.freedesktop.org/~krh/releases/%{name}-%{version}.tar.gz
10.12 +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
10.13 +
10.14 +Requires: expat
10.15 +Requires: rpm-libs
10.16 +
10.17 +BuildRequires: expat-devel
10.18 +BuildRequires: libtool
10.19 +BuildRequires: gettext
10.20 +BuildRequires: libcurl-devel
10.21 +BuildRequires: rpm-devel
10.22 +BuildRequires: zlib-devel
10.23 +BuildRequires: perl(XML::Parser)
10.24 +
10.25 +%description
10.26 +Razor is a package management system replacing rpm and yum.
10.27 +Razor implements management of packages installed on the system,
10.28 +dependency solving, and upgrading in a small compact code base with
10.29 +minimal dependencies.
10.30 +
10.31 +%package libs
10.32 +Summary: Libraries for accessing razor
10.33 +Group: Development/Libraries
10.34 +Requires: expat >= %{dbus_version}
10.35 +Requires: %{name} = %{version}-%{release}
10.36 +
10.37 +%description libs
10.38 +Libraries for accessing razor.
10.39 +
10.40 +%package devel
10.41 +Summary: Libraries and headers for razor
10.42 +Group: Development/Libraries
10.43 +Requires: %{name} = %{version}-%{release}
10.44 +Requires: pkgconfig
10.45 +Requires: libcurl-devel
10.46 +Requires: rpm-devel
10.47 +Requires: zlib-devel
10.48 +
10.49 +%description devel
10.50 +Headers and libraries for razor.
10.51 +
10.52 +%prep
10.53 +%setup -q
10.54 +
10.55 +%build
10.56 +%configure
10.57 +
10.58 +make %{?_smp_mflags}
10.59 +
10.60 +%install
10.61 +rm -rf $RPM_BUILD_ROOT
10.62 +make install DESTDIR=$RPM_BUILD_ROOT
10.63 +
10.64 +rm -f $RPM_BUILD_ROOT%{_libdir}/librazor*.a
10.65 +rm -f $RPM_BUILD_ROOT%{_libdir}/librazor*.la
10.66 +mv $RPM_BUILD_ROOT%{_bindir}/rpm $RPM_BUILD_ROOT%{_bindir}/rpm-razor
10.67 +
10.68 +#%find_lang %name
10.69 +
10.70 +%clean
10.71 +rm -rf $RPM_BUILD_ROOT
10.72 +
10.73 +%post libs -p /sbin/ldconfig
10.74 +
10.75 +%postun libs -p /sbin/ldconfig
10.76 +
10.77 +%files
10.78 +# -f %{name}.lang
10.79 +%defattr(-,root,root,-)
10.80 +%doc README AUTHORS NEWS COPYING
10.81 +%dir %{_datadir}/doc/razor
10.82 +%doc %{_datadir}/doc/razor/*.txt
10.83 +%config %{_sysconfdir}/bash_completion.d/*.sh
10.84 +%{_bindir}/razor
10.85 +%{_bindir}/rpm-razor
10.86 +%exclude %{_libdir}/librazor*.so.*
10.87 +
10.88 +%files libs
10.89 +%defattr(-,root,root,-)
10.90 +%doc README AUTHORS NEWS COPYING
10.91 +%{_libdir}/*razor*.so.*
10.92 +
10.93 +%files devel
10.94 +%defattr(-,root,root,-)
10.95 +
10.96 +%{_libdir}/lib*.so
10.97 +%{_libdir}/pkgconfig/*
10.98 +%{_includedir}/*
10.99 +
10.100 +%changelog
10.101 +* Mon Jun 16 2008 Richard Hughes <richard@hughsie.com> 0.1-0.1
10.102 +- Initial version
10.103 +
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/data/.gitignore Fri Jun 20 19:04:47 2008 -0400
11.3 @@ -0,0 +1,2 @@
11.4 +razor.pc
11.5 +
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/data/Makefile.am Fri Jun 20 19:04:47 2008 -0400
12.3 @@ -0,0 +1,11 @@
12.4 +## Process this file with automake to produce Makefile.in
12.5 +
12.6 +pkgconfigdir = $(libdir)/pkgconfig
12.7 +pkgconfig_DATA = razor.pc
12.8 +
12.9 +bashcompletiondir = ${SYSCONFDIR}/bash_completion.d
12.10 +dist_bashcompletion_DATA = bash-completion.sh
12.11 +
12.12 +clean-local :
12.13 + rm -f *~
12.14 +
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/data/bash-completion.sh Fri Jun 20 19:04:47 2008 -0400
13.3 @@ -0,0 +1,47 @@
13.4 +__razor_commands () {
13.5 + local IFS=$'\n'
13.6 + COMPREPLY=($(IFS=: compgen -S' ' -W "info:list-requires:list-provides:list-files:list-file-packages:list-package-files:what-requires:what-provides:import-yum:import-rpmdb:validate:update:diff:install:init:download" -- $1))
13.7 +}
13.8 +
13.9 +__razor_packages () {
13.10 + local IFS=$'\n'
13.11 +
13.12 + COMPREPLY=($(./razor list --only-names "$1*" | while read p; do echo "$p "; done))
13.13 +}
13.14 +
13.15 +__razor_upstream_packages () {
13.16 + local IFS=$'\n'
13.17 +
13.18 + COMPREPLY=($(RAZOR_REPO=rawhide.repo ./razor list --only-names "$1*" | while read p; do echo "$p "; done))
13.19 +}
13.20 +
13.21 +__razor_files() {
13.22 + COMPREPLY=($(./razor list-files "$1*"))
13.23 +}
13.24 +
13.25 +__razor_requires() {
13.26 + COMPREPLY=($(compgen -W "$(./razor list-requires)" -- $1))
13.27 +}
13.28 +
13.29 +__razor_provides() {
13.30 + COMPREPLY=($(compgen -W "$(./razor list-provides)" -- $1))
13.31 +}
13.32 +
13.33 +__razor() {
13.34 + local cur="${COMP_WORDS[COMP_CWORD]}"
13.35 +
13.36 + if [ $COMP_CWORD = 1 ]; then
13.37 + __razor_commands $cur
13.38 + else
13.39 + case "${COMP_WORDS[1]}" in
13.40 + info|list-requires|list-provides|list-package-files)
13.41 + __razor_packages $cur ;;
13.42 + list-files|list-file-packages) __razor_files $cur ;;
13.43 + what-requires) __razor_requires $cur ;;
13.44 + what-provides) __razor_provides $cur ;;
13.45 + install|download) __razor_upstream_packages $cur ;;
13.46 + esac
13.47 + fi
13.48 +}
13.49 +
13.50 +complete -o nospace -F __razor razor
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/data/razor.pc.in Fri Jun 20 19:04:47 2008 -0400
14.3 @@ -0,0 +1,12 @@
14.4 +prefix=@prefix@
14.5 +exec_prefix=@exec_prefix@
14.6 +libdir=@libdir@
14.7 +includedir=@includedir@
14.8 +
14.9 +Name: razor
14.10 +Description: library for depsolving, installing and removing packages
14.11 +Version: @VERSION@
14.12 +Requires: expat curl
14.13 +Libs: -L${libdir} -lexpat -lz -lcurl
14.14 +Cflags: -I${includedir}/razor
14.15 +
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/docs/DEPSOLVE.txt Fri Jun 20 19:04:47 2008 -0400
15.3 @@ -0,0 +1,364 @@
15.4 +YUM vs RAZOR
15.5 +------------
15.6 +
15.7 +At a very high level, yum's depsolver does something roughly
15.8 +equivalent to:
15.9 +
15.10 + - For each package being installed or removed
15.11 +
15.12 + - For each relevant property (provides, requires, conflicts,
15.13 + obsoletes):
15.14 +
15.15 + - Figure out what additional packages need to be added to
15.16 + or removed from the system to satisfy this property
15.17 +
15.18 +which ends up being roughly O(N^2 * M) where N is the total number of
15.19 +properties and M is the number of packages being acted on.
15.20 +
15.21 +(I just figured that out off the top of my head, and I'm not totally
15.22 +familiar with the yum code, so it may be wrong.)
15.23 +
15.24 +Razor's depsolver is something like:
15.25 +
15.26 + - do {
15.27 +
15.28 + - For each property to be added to or removed from the system:
15.29 +
15.30 + - Figure out what packages need to be added to or removed
15.31 + from the system to satisfy this property
15.32 +
15.33 + - } until we stop adding/remove more packages
15.34 +
15.35 +with the key being that it's very easy to find the PROVIDES
15.36 +corresponding to a REQUIRES and vice versa, because the property
15.37 +arrays are sorted, and so all properties with the same "name" will be
15.38 +adjacent to one another in the array, allowing many dependencies to be
15.39 +satisified in essentially constant time. (Actually... we've been
15.40 +calling it constant, but it's really O(log N) for heavily-depended-on
15.41 +packages, because the more packages you have, the more variations on
15.42 +"requires foo", "requires foo = 1.1", "requires foo > 1.0", etc you're
15.43 +going to have to scan through.)
15.44 +
15.45 +Ideally though, each iteration of the inner loop body happens in
15.46 +constant time, and thus the inner loop as a whole is O(N), and thus
15.47 +the depsolver as a whole is O(N * M) (or at least, less than
15.48 +O(N * M * log N).
15.49 +
15.50 +
15.51 +FILE DEPENDENCIES
15.52 +-----------------
15.53 +
15.54 +Whenever we add a package with a file REQUIRES to a razor_set, we also
15.55 +add a PROVIDES for that file to the package or packages which provide
15.56 +that file. This means that if we later add another package that
15.57 +requires the same file (eg, /bin/sh or /usr/bin/perl), we can resolve
15.58 +its file requirement exactly like we would resolve a property
15.59 +requirement, in nearly constant time.
15.60 +
15.61 +When adding a *new* file requirement (ie, a requirement on a file that
15.62 +no existing package depends on), we still have to scan through the
15.63 +file tree, which is O(log N) in the number of files.
15.64 +
15.65 +(AFAICT, there's no reason yum couldn't do the same optimization.
15.66 +Also, AFAICT, yum currently sticks property dependencies and file
15.67 +dependencies into the same hash table, so that if any package in the
15.68 +transaction has a file dependency, it causes *property* dependencies
15.69 +to become slower to resolve as well...)
15.70 +
15.71 +
15.72 +THE RULES
15.73 +---------
15.74 +
15.75 +This is what we have figured out for transaction-solving rules;
15.76 +neither yum nor rpm's algorithm seems to be explained in full
15.77 +anywhere...
15.78 +
15.79 + 1. Every requested install in the initial package set must be
15.80 + satisfied as either a new install or an update:
15.81 +
15.82 + - if the requested package name is the name of an upstream
15.83 + package:
15.84 +
15.85 + - if there is not a corresponding already-installed
15.86 + package, then install the upstream package
15.87 +
15.88 + - else if the upstream package is newer than the
15.89 + already-installed package, then update the package
15.90 +
15.91 + - else it's an error (UP_TO_DATE)
15.92 +
15.93 + - else if the requested package name is the name of an
15.94 + already-installed package:
15.95 +
15.96 + - if there is an upstream package that obsoletes the
15.97 + already-installed package, then behave as though the
15.98 + user had requested that that package be installed
15.99 + instead.
15.100 +
15.101 + - else it's an error (UP_TO_DATE or INSTALL_UNAVAILABLE?)
15.102 +
15.103 + - else it's an error (INSTALL_UNAVAILABLE)
15.104 +
15.105 + 2. Every requested removal in the initial package set must be
15.106 + satisfied as a removal. If any requested package name is not
15.107 + the name of an installed package, it's an error
15.108 + (REMOVE_NOT_INSTALLED)
15.109 +
15.110 + REQUIRES processing:
15.111 +
15.112 + 3. If a package being installed or updated-to REQUIRES a property
15.113 + that is not provided by any installed or to-be-installed
15.114 + package, we need to find an installable package that provides
15.115 + that property. If we find one, install/update it. If not, it's
15.116 + an error (UNSATISFIABLE). (If we find an upstream package
15.117 + providing the property that corresponds to a system package
15.118 + that's being removed, then it's a CONTRADICTION.)
15.119 +
15.120 + 4. If an already-installed package REQUIRES a property which is
15.121 + only provided by a package that is being removed, then that
15.122 + package needs to be removed as well.
15.123 +
15.124 + 5. If an already-installed package REQUIRES a property which is
15.125 + only provided by a package that is being upgraded or obsoleted
15.126 + (to a new package which does not provide that property), then:
15.127 +
15.128 + - if there is an update for the installed package, then update
15.129 + the installed package
15.130 +
15.131 + - else if there is another installable package that provides
15.132 + the required property, then install that.
15.133 +
15.134 + - else it's an error (UNSATISFIABLE?)
15.135 +
15.136 + CONFLICTS processing
15.137 +
15.138 + 6. If a package being installed or updated-to CONFLICTS with a
15.139 + property provided by an installed package:
15.140 +
15.141 + - if there is an update for the installed package, which the
15.142 + new package does not conflict with, then update the
15.143 + installed package.
15.144 +
15.145 + - else it's an error (NEW_CONFLICT)
15.146 +
15.147 + 7. If an already-installed package CONFLICTS with a property
15.148 + provided by a to-be-installed package:
15.149 +
15.150 + - if there is an update for the installed package, which does
15.151 + not conflict with the new package, then update the installed
15.152 + package.
15.153 +
15.154 + - else it's an error (NEW_CONFLICT)
15.155 +
15.156 + 8. If a package being installed or updated-to CONFLICTS with a
15.157 + property provided by a to-be-installed package, then it's an
15.158 + error (CONTRADICTION).
15.159 +
15.160 + OBSOLETES processing. NOTE: OBSOLETES are only matched against
15.161 + package names, not against arbitrary provided properties
15.162 +
15.163 + 9. If a package being installed or updated-to OBSOLETES an
15.164 + installed package, then obsolete that package. (ie, remove it,
15.165 + but treat it as updated for purposes of dangling REQUIRES).
15.166 +
15.167 + 10. If an already-installed package OBSOLETES a to-be-installed
15.168 + package, then it's an error. (ALREADY_OBSOLETE)
15.169 +
15.170 + 11. If a package being installed or updated-to OBSOLETES another
15.171 + package being installed or updated-to, then it's an error
15.172 + (CONTRADICTION).
15.173 +
15.174 +
15.175 +
15.176 +THE DEPSOLVER
15.177 +-------------
15.178 +
15.179 +We start with two razor_sets, system and upstream, and a list of
15.180 +requested installations and removals.
15.181 +
15.182 + FIXME: what about multiple upstream repos? Having to deal with
15.183 + arbitrary numbers of razor_sets is possible, but will probably be
15.184 + messy... It might be easier to either store all upstream repo data
15.185 + in a single .repo file, or else merge all upstream .repo files
15.186 + together into a single razor_set at startup. (Or some combination
15.187 + of those.)
15.188 +
15.189 +We create a bit array of the packages in each set, indicating which
15.190 +ones are installed; the system bitarray starts out all 1s, and the
15.191 +upstream bitarray all 0s. Each bit is only allowed to change state
15.192 +once during the transaction; an installed package can be removed, or
15.193 +an uninstalled package installed, but trying to reinstall a removed
15.194 +package, or uninstall a newly-installed package is an error. This
15.195 +means the packages break down into four categories:
15.196 +
15.197 + - installed (1 bit in the system bit array)
15.198 + - to-be-removed (0 bit in the system bit array)
15.199 + - to-be-installed (1 bit in the upstream bit array)
15.200 + - installable (0 bit in the upstream bit array)
15.201 +
15.202 +
15.203 +Depsolver algorithm:
15.204 +
15.205 + - Create new razor_transaction_packages ("rtp"s) for each
15.206 + requested install or remove. These will be "unresolved", because
15.207 + we haven't yet found the razor_packages that correspond to them.
15.208 +
15.209 + - while there are new rtps:
15.210 +
15.211 + - sort the new rtps
15.212 +
15.213 + - Walk the system property list, upstream property list, and
15.214 + new rtp list in parallel, and:
15.215 +
15.216 + - For each uninstalled PROVIDES:
15.217 +
15.218 + - If the property is a valid package name (that is,
15.219 + either it's a package providing its own name, or it
15.220 + has a matching OBSOLETES), and it matches the name
15.221 + of a new rtp of type INSTALL or FORCED_UPDATE with
15.222 + an unresolved new_package:
15.223 +
15.224 + - If the upstream package has the same version as
15.225 + the system package, we have an UP_TO_DATE error
15.226 + (FIXME: not quite right. This doesn't deal with
15.227 + the case where we try to update an application
15.228 + because of a library update, and it turns out
15.229 + there's no new version of the application, but
15.230 + there IS a compat package containing the old
15.231 + version of the library.)
15.232 +
15.233 + - Otherwise, set the rtp's new_package to point to
15.234 + the package providing this property and set the
15.235 + appropriate bit in the upstream bit array.
15.236 +
15.237 + - For each to-be-installed non-file REQUIRES:
15.238 +
15.239 + - See if there's an installed or to-be-installed
15.240 + package that PROVIDES that property.
15.241 +
15.242 + - If not, see if there's an installable package that
15.243 + PROVIDES that property, and create a new INSTALL rtp
15.244 + for it if so.
15.245 +
15.246 + - If not, see if there's a to-be-removed package that
15.247 + PROVIDES that property. (If we find such a package,
15.248 + we have a CONTRADICTION error.)
15.249 +
15.250 + - If none of the above, then we have an UNSATISFIABLE
15.251 + error
15.252 +
15.253 + - For each to-be-installed file REQUIRES:
15.254 +
15.255 + - (We create fake file PROVIDES to match file REQUIRES
15.256 + when importing/merging razor sets, so if there is
15.257 + already another installed package that REQUIRES this
15.258 + file, there will be a PROVIDES listed for it as well.)
15.259 +
15.260 + - See if there's an installed package that PROVIDES
15.261 + that file.
15.262 +
15.263 + - If not, do a binary search of the system file tree
15.264 + looking to see if some installed package provides
15.265 + that file but does not have a PROVIDES for it.
15.266 +
15.267 + - If not, see if there's an installable package that
15.268 + PROVIDES that property, and create a new INSTALL rtp
15.269 + for it if so.
15.270 +
15.271 + - (If we actually work with multiple upstream
15.272 + razor_sets, then we will need to search the upstream
15.273 + file trees at this point, because it's possible that
15.274 + a package in one upstream repo would require a file
15.275 + in another upstream repo. But if we merge the
15.276 + multiple upstream repos into a single razor_set at
15.277 + some point, then we would not need to do that,
15.278 + because it would be guaranteed that we would have
15.279 + already created a fake PROVIDES if any package
15.280 + provides the file.)
15.281 +
15.282 + - If no installed or installable package provides the
15.283 + file, see if there's a to-be-removed package that
15.284 + provides the file. (If we find such a package, we
15.285 + have a CONTRADICTION error.)
15.286 +
15.287 + - If none of the above, then we have an UNSATISFIABLE
15.288 + error
15.289 +
15.290 + - For each to-be-installed PROVIDES:
15.291 +
15.292 + - Check if the new PROVIDES conflicts with an
15.293 + installed CONFLICTS. If so, create a new
15.294 + FORCED_UPDATE rtp for the installed package, so we
15.295 + can try to upgrade it to a non-conflicting version.
15.296 + (If we can't, we'll have an OLD_CONFLICT error.)
15.297 +
15.298 + - Check if the new PROVIDES conflicts with an
15.299 + installed OBSOLETES *and* the PROVIDES property
15.300 + corresponds to the name of its package. (That is,
15.301 + OBSOLETES are only matched against package names,
15.302 + not arbitrary provided properties.) If so, we have
15.303 + an ALREADY_OBSOLETE error.
15.304 +
15.305 + - Check if the new PROVIDES conflicts with a
15.306 + to-be-installed CONFLICTS. If so, we have a
15.307 + CONTRADICTION error.
15.308 +
15.309 + - For each to-be-installed CONFLICTS:
15.310 +
15.311 + - Basically the reverse of the previous case: check if
15.312 + the new CONFLICTS conflicts with an installed
15.313 + PROVIDES. If so, create a new FORCED_UPDATE rtp for
15.314 + the installed package, so we can try to upgrade it
15.315 + to a non-conflicting version. (If we can't, we'll
15.316 + have an NEW_CONFLICT error.)
15.317 +
15.318 + - Check if the new CONFLICTS conflicts with a
15.319 + to-be-installed PROVIDES. If so, we have a
15.320 + CONTRADICTION error.
15.321 +
15.322 + - For each to-be-installed OBSOLETES:
15.323 +
15.324 + - Check if there's an installed package that PROVIDES
15.325 + that property. If so, create an OBSOLETED rtp for
15.326 + the installed package.
15.327 +
15.328 + - If not, check if there's a to-be-installed package
15.329 + that PROVIDES that property. If so, we have a
15.330 + CONTRADICTION error.
15.331 +
15.332 +
15.333 + - For each installed PROVIDES:
15.334 +
15.335 + - If the property is a valid package name (that is,
15.336 + it's a package providing its own name), and it
15.337 + matches the name of a new rtp with an unresolved
15.338 + old_package, then set the rtp's old_package to point
15.339 + to the package providing this property and clear the
15.340 + appropriate bit in the system bit array.
15.341 +
15.342 + - For each to-be-removed PROVIDES:
15.343 +
15.344 + - If there's also an identical to-be-installed
15.345 + PROVIDES, we're ok and can skip this
15.346 +
15.347 + - Otherwise, for each installed REQUIRES of this
15.348 + property:
15.349 +
15.350 + - Look for some other installed or to-be-installed
15.351 + property that satisfies the REQUIRES.
15.352 +
15.353 + - If there isn't one, then for each installed
15.354 + package in this REQUIRES's package list:
15.355 +
15.356 + - If the PROVIDES was lost because the old
15.357 + package was REMOVEd (not FORCED_UPDATE or
15.358 + OBSOLETED), then create a new REMOVE rtp for
15.359 + this package.
15.360 +
15.361 + - Otherwise, create a new FORCED_UPDATE rtp
15.362 + for this package.
15.363 +
15.364 + - (We don't need to look at to-be-installed REQUIRES
15.365 + of this property, because if there are any, they
15.366 + will cause a CONTRADICTION error when we try to
15.367 + re-satisfy them the next time through.)
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/docs/Makefile.am Fri Jun 20 19:04:47 2008 -0400
16.3 @@ -0,0 +1,6 @@
16.4 +
16.5 +docsdir = $(datadir)/doc/razor
16.6 +dist_docs_DATA = \
16.7 + DEPSOLVE.txt \
16.8 + REPO.txt
16.9 +
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/docs/REPO.txt Fri Jun 20 19:04:47 2008 -0400
17.3 @@ -0,0 +1,172 @@
17.4 +The repo file format / razor_set data structure
17.5 +-----------------------------------------------
17.6 +
17.7 +The repo starts with a header, containing some number of sections,
17.8 +terminated by a section with type 0:
17.9 +
17.10 + struct razor_set_header {
17.11 + uint32_t magic;
17.12 + uint32_t version;
17.13 + struct razor_set_section sections[0];
17.14 + };
17.15 +
17.16 + struct razor_set_section {
17.17 + uint32_t type;
17.18 + uint32_t offset;
17.19 + uint32_t size;
17.20 + };
17.21 +
17.22 +razor_set_open() mmaps the repo file, and creates a struct razor_set:
17.23 +
17.24 + struct razor_set {
17.25 + struct array string_pool;
17.26 + struct array packages;
17.27 + struct array properties;
17.28 + struct array files;
17.29 + struct array package_pool;
17.30 + struct array property_pool;
17.31 + struct array file_pool;
17.32 + struct razor_set_header *header;
17.33 + };
17.34 +
17.35 +by finding the sections with those IDs and creating "struct array"s
17.36 +pointing to the right places in the mmapped data. (This is the only
17.37 +processing needed when reading in the file; everything else is used
17.38 +exactly as-is.)
17.39 +
17.40 +
17.41 +The sections
17.42 +------------
17.43 +
17.44 +RAZOR_STRING_POOL
17.45 +
17.46 + Stores one copy of each string that appears in the repo. (At
17.47 + the moment, this is: package names, package versions, property
17.48 + names, property versions, and (basenames of) filenames.) The
17.49 + strings are arbitrarily-sized, 0-terminated, and not in any
17.50 + particular order (although the empty string always ends up
17.51 + being at offset 0).
17.52 +
17.53 +RAZOR_PACKAGES
17.54 +
17.55 + Array of struct razor_package; one for each package in the
17.56 + set, sorted by name.
17.57 +
17.58 +RAZOR_PROPERTIES
17.59 +
17.60 + Array of struct razor_property; one for each unique property
17.61 + in the set, sorted by type, then name, then relation type (eg,
17.62 + "<" or ">="), then version. (Properties with no version have
17.63 + relation type RAZOR_VERSION_EQUAL, and version "".)
17.64 +
17.65 +RAZOR_FILES
17.66 +
17.67 + Array of struct razor_entry; one for each file owned by any
17.68 + package in the set. The current sort order (which is subject
17.69 + to change) is breadth-first, sorted by basename. So eg: /, /bin,
17.70 + /dev, /etc, /bin/false, /bin/true, /dev/null, /etc/passwd.
17.71 +
17.72 +RAZOR_PACKAGE_POOL
17.73 +
17.74 + Array of struct list, with each list item containing the index
17.75 + of a struct razor_package in the packages section. See the
17.76 + discussion of lists below.
17.77 +
17.78 +RAZOR_PROPERTY_POOL
17.79 +
17.80 + Array of struct list, with each list item containing the index
17.81 + of a struct razor_property in the properties section. See the
17.82 + discussion of lists below.
17.83 +
17.84 +RAZOR_FILE_POOL
17.85 +
17.86 + Array of struct list, with each list item containing the index
17.87 + of a struct razor_entry in the files section. See the
17.88 + discussion of lists below.
17.89 +
17.90 +
17.91 +Data types
17.92 +----------
17.93 +Note that the exact layout of bits involves some historical accidents.
17.94 +(Particularly the fact that the "name" field in most structs loses its
17.95 +high bits to a flags field.)
17.96 +
17.97 +struct list_head
17.98 + uint list_ptr : 24;
17.99 + uint flags : 8;
17.100 +
17.101 +struct list
17.102 + uint data : 24;
17.103 + uint flags : 8;
17.104 +
17.105 + Used to store lists of package, property, or file IDs. "struct
17.106 + list_head" stores the head of the list, which points to one or
17.107 + more "struct list"s in the appropriate "pool" section.
17.108 + ("struct list" should probably be called "struct list_item".)
17.109 +
17.110 + "list_first(&head, &pool)" returns a "struct list *" pointing
17.111 + to the first element of the list (or NULL for an empty list),
17.112 + and "list_next(list)" will return successive elements, until
17.113 + NULL is returned. Each "list->data" contains the index of a
17.114 + package, property, or file in the corresponding section of the
17.115 + set.
17.116 +
17.117 + Peeking underneath the abstraction, a list_head's "flags" is
17.118 + 0xff if the list is empty, 0x80 if it contains a single
17.119 + element, or 0x00 if it contains more than one element. In the
17.120 + single-element case, that element is actually stored in the
17.121 + list_head directly rather than being stored in a pool (and so
17.122 + list_first() just casts the list_head* to a list* and returns
17.123 + it). For multi-element lists, list_ptr is the index in the
17.124 + pool of the first element of this list; the list continues
17.125 + through successive elements of the pool until one with
17.126 + non-zero flags is reached, indicating the end of the list.
17.127 +
17.128 +struct razor_package
17.129 + uint name : 24;
17.130 + uint flags : 8;
17.131 + uint version : 32;
17.132 + struct list_head properties;
17.133 + struct list_head files;
17.134 +
17.135 + name and version are indexes into string_pool. properties is a
17.136 + list of all of the package's properties, and files is a list
17.137 + of its files. flags is currently only used during razor_set
17.138 + merging, to keep track of which set a package came from.
17.139 +
17.140 +struct razor_property
17.141 + uint name : 24;
17.142 + uint flags : 6;
17.143 + uint type : 2;
17.144 + uint relation : 32;
17.145 + uint version : 32;
17.146 + struct list_head packages;
17.147 +
17.148 + name and version are indexes into string_pool. type is an enum
17.149 + razor_property_type (eg, RAZOR_PROPERTY_REQUIRES), and
17.150 + relation is an enum razor_version_relation (eg,
17.151 + RAZOR_VERSION_GREATER_OR_EQUAL). packages is a list of the
17.152 + packages that have this property. flags is currently unused.
17.153 +
17.154 +struct razor_entry
17.155 + uint name : 24;
17.156 + uint flags : 8;
17.157 + uint start : 32;
17.158 + struct list_head packages;
17.159 +
17.160 + name is an index into string_pool, giving the basename of the
17.161 + file. start is either 0, or an index pointing to another
17.162 + razor_entry that is the first child of this entry (for a
17.163 + non-empty directory). (Entry 0 is always the root of the tree,
17.164 + so no entry could have entry 0 as a child.) flags is 0x80
17.165 + (RAZOR_ENTRY_LAST) if an entry is the last entry in its
17.166 + directory. Otherwise it is 0.
17.167 +
17.168 + Note that given a pointer to a struct_razor_entry (eg, from a
17.169 + package's "files" list), there is no way to reconstruct its
17.170 + full name without walking the entire files array up to that
17.171 + point. Because of this and other problems (fix_file_map()), it
17.172 + seems like razor_entry should be modified to include a pointer
17.173 + to its parent. (Storing full paths instead of just basenames
17.174 + would also fix this problem, but that would use much more
17.175 + memory.)
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/librazor/.gitignore Fri Jun 20 19:04:47 2008 -0400
18.3 @@ -0,0 +1,5 @@
18.4 +.deps
18.5 +.libs
18.6 +*.lo
18.7 +*.la
18.8 +
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/librazor/Makefile.am Fri Jun 20 19:04:47 2008 -0400
19.3 @@ -0,0 +1,37 @@
19.4 +## Process this file with automake to produce Makefile.in
19.5 +
19.6 +INCLUDES = \
19.7 + -I$(top_builddir)/src -I$(top_srcdir)/src \
19.8 + -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
19.9 + -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
19.10 + -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
19.11 + -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
19.12 + -DPACKAGE_LOCALSTATE_DIR=\""$(localstatedir)"\" \
19.13 + -DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
19.14 + -DPACKAGE_LIB_DIR=\""$(libdir)"\"
19.15 +
19.16 +lib_LTLIBRARIES = librazor.la
19.17 +
19.18 +librazorincludedir = $(includedir)/razor
19.19 +
19.20 +librazorinclude_HEADERS = \
19.21 + razor.h
19.22 +
19.23 +librazor_la_SOURCES = \
19.24 + razor-internal.h \
19.25 + razor.h \
19.26 + razor.c \
19.27 + root.c \
19.28 + types.c \
19.29 + util.c \
19.30 + rpm.c \
19.31 + iterator.c \
19.32 + importer.c \
19.33 + merger.c \
19.34 + transaction.c
19.35 +
19.36 +librazor_la_LIBADD = $(ZLIB_LIBS)
19.37 +
19.38 +clean-local :
19.39 + rm -f *~
19.40 +
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/librazor/importer.c Fri Jun 20 19:04:47 2008 -0400
20.3 @@ -0,0 +1,505 @@
20.4 +/*
20.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
20.6 + * Copyright (C) 2008 Red Hat, Inc
20.7 + *
20.8 + * This program is free software; you can redistribute it and/or modify
20.9 + * it under the terms of the GNU General Public License as published by
20.10 + * the Free Software Foundation; either version 2 of the License, or
20.11 + * (at your option) any later version.
20.12 + *
20.13 + * This program is distributed in the hope that it will be useful,
20.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
20.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20.16 + * GNU General Public License for more details.
20.17 + *
20.18 + * You should have received a copy of the GNU General Public License along
20.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
20.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20.21 + */
20.22 +
20.23 +#define _GNU_SOURCE
20.24 +
20.25 +#include <string.h>
20.26 +#include "razor-internal.h"
20.27 +#include "razor.h"
20.28 +
20.29 +void
20.30 +razor_importer_begin_package(struct razor_importer *importer,
20.31 + const char *name,
20.32 + const char *version,
20.33 + const char *arch)
20.34 +{
20.35 + struct razor_package *p;
20.36 +
20.37 + p = array_add(&importer->set->packages, sizeof *p);
20.38 + p->name = hashtable_tokenize(&importer->table, name);
20.39 + p->flags = 0;
20.40 + p->version = hashtable_tokenize(&importer->table, version);
20.41 + p->arch = hashtable_tokenize(&importer->table, arch);
20.42 +
20.43 + importer->package = p;
20.44 + array_init(&importer->properties);
20.45 +}
20.46 +
20.47 +
20.48 +void
20.49 +razor_importer_finish_package(struct razor_importer *importer)
20.50 +{
20.51 + list_set_array(&importer->package->properties,
20.52 + &importer->set->property_pool,
20.53 + &importer->properties,
20.54 + 1);
20.55 +
20.56 + array_release(&importer->properties);
20.57 +}
20.58 +
20.59 +void
20.60 +razor_importer_add_details(struct razor_importer *importer,
20.61 + const char *summary,
20.62 + const char *description,
20.63 + const char *url,
20.64 + const char *license)
20.65 +{
20.66 + importer->package->summary = hashtable_tokenize(&importer->details_table, summary);
20.67 + importer->package->description = hashtable_tokenize(&importer->details_table, description);
20.68 + importer->package->url = hashtable_tokenize(&importer->details_table, url);
20.69 + importer->package->license = hashtable_tokenize(&importer->details_table, license);
20.70 +}
20.71 +
20.72 +void
20.73 +razor_importer_add_property(struct razor_importer *importer,
20.74 + const char *name,
20.75 + uint32_t flags,
20.76 + const char *version)
20.77 +{
20.78 + struct razor_property *p;
20.79 + uint32_t *r;
20.80 +
20.81 + p = array_add(&importer->set->properties, sizeof *p);
20.82 + p->name = hashtable_tokenize(&importer->table, name);
20.83 + p->flags = flags;
20.84 + p->version = hashtable_tokenize(&importer->table, version);
20.85 + list_set_ptr(&p->packages, importer->package -
20.86 + (struct razor_package *) importer->set->packages.data);
20.87 +
20.88 + r = array_add(&importer->properties, sizeof *r);
20.89 + *r = p - (struct razor_property *) importer->set->properties.data;
20.90 +
20.91 + if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) &&
20.92 + *name == '/') {
20.93 + r = array_add(&importer->file_requires, sizeof *r);
20.94 + *r = p->name;
20.95 + }
20.96 +}
20.97 +
20.98 +void
20.99 +razor_importer_add_file(struct razor_importer *importer, const char *name)
20.100 +{
20.101 + struct import_entry *e;
20.102 +
20.103 + e = array_add(&importer->files, sizeof *e);
20.104 +
20.105 + e->package = importer->package -
20.106 + (struct razor_package *) importer->set->packages.data;
20.107 + e->name = strdup(name);
20.108 +}
20.109 +
20.110 +struct razor_importer *
20.111 +razor_importer_new(void)
20.112 +{
20.113 + struct razor_importer *importer;
20.114 +
20.115 + importer = zalloc(sizeof *importer);
20.116 + importer->set = razor_set_create();
20.117 + hashtable_init(&importer->table, &importer->set->string_pool);
20.118 + hashtable_init(&importer->details_table,
20.119 + &importer->set->details_string_pool);
20.120 + hashtable_init(&importer->file_table,
20.121 + &importer->set->file_string_pool);
20.122 +
20.123 + return importer;
20.124 +}
20.125 +
20.126 +/* Destroy an importer without creating the set. */
20.127 +void
20.128 +razor_importer_destroy(struct razor_importer *importer)
20.129 +{
20.130 + /* FIXME: write this */
20.131 +}
20.132 +
20.133 +static int
20.134 +compare_packages(const void *p1, const void *p2, void *data)
20.135 +{
20.136 + const struct razor_package *pkg1 = p1, *pkg2 = p2;
20.137 + struct razor_set *set = data;
20.138 + char *pool = set->string_pool.data;
20.139 +
20.140 + /* FIXME: what if the flags are different? */
20.141 + if (pkg1->name == pkg2->name)
20.142 + return razor_versioncmp(&pool[pkg1->version], &pool[pkg2->version]);
20.143 + else
20.144 + return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
20.145 +}
20.146 +
20.147 +static int
20.148 +compare_properties(const void *p1, const void *p2, void *data)
20.149 +{
20.150 + const struct razor_property *prop1 = p1, *prop2 = p2;
20.151 + struct razor_set *set = data;
20.152 + char *pool = set->string_pool.data;
20.153 +
20.154 + if (prop1->name != prop2->name)
20.155 + return strcmp(&pool[prop1->name], &pool[prop2->name]);
20.156 + else if (prop1->flags != prop2->flags)
20.157 + return prop1->flags - prop2->flags;
20.158 + else
20.159 + return razor_versioncmp(&pool[prop1->version], &pool[prop2->version]);
20.160 +}
20.161 +
20.162 +static uint32_t *
20.163 +uniqueify_properties(struct razor_set *set)
20.164 +{
20.165 + struct razor_property *rp, *up, *rp_end;
20.166 + struct array *pkgs, *p;
20.167 + struct list_head *r;
20.168 + uint32_t *map, *rmap;
20.169 + int i, count, unique;
20.170 +
20.171 + count = set->properties.size / sizeof(struct razor_property);
20.172 + map = razor_qsort_with_data(set->properties.data,
20.173 + count,
20.174 + sizeof(struct razor_property),
20.175 + compare_properties,
20.176 + set);
20.177 +
20.178 + rp_end = set->properties.data + set->properties.size;
20.179 + rmap = malloc(count * sizeof *map);
20.180 + pkgs = zalloc(count * sizeof *pkgs);
20.181 + for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
20.182 + if (rp->name != up->name ||
20.183 + rp->flags != up->flags ||
20.184 + rp->version != up->version) {
20.185 + up++;
20.186 + up->name = rp->name;
20.187 + up->flags = rp->flags;
20.188 + up->version = rp->version;
20.189 + }
20.190 +
20.191 + unique = up - (struct razor_property *) set->properties.data;
20.192 + rmap[map[i]] = unique;
20.193 + r = array_add(&pkgs[unique], sizeof *r);
20.194 + *r = rp->packages;
20.195 + }
20.196 + free(map);
20.197 +
20.198 + if (up != rp)
20.199 + up++;
20.200 + set->properties.size = (void *) up - set->properties.data;
20.201 + rp_end = up;
20.202 + for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
20.203 + list_set_array(&rp->packages, &set->package_pool, p, 0);
20.204 + array_release(p);
20.205 + }
20.206 +
20.207 + free(pkgs);
20.208 +
20.209 + return rmap;
20.210 +}
20.211 +
20.212 +static int
20.213 +compare_filenames(const void *p1, const void *p2, void *data)
20.214 +{
20.215 + const struct import_entry *e1 = p1;
20.216 + const struct import_entry *e2 = p2;
20.217 + const char *n1 = e1->name;
20.218 + const char *n2 = e2->name;
20.219 +
20.220 + /* Need to make sure that the contents of a directory
20.221 + * are sorted immediately after it. So "foo/bar" has to
20.222 + * sort before "foo.conf"
20.223 + *
20.224 + * FIXME: this is about 60% slower than strcmp
20.225 + */
20.226 + while (*n1 && *n2) {
20.227 + if (*n1 < *n2)
20.228 + return *n2 == '/' ? 1 : -1;
20.229 + else if (*n1 > *n2)
20.230 + return *n1 == '/' ? -1 : 1;
20.231 + n1++;
20.232 + n2++;
20.233 + }
20.234 + if (*n1)
20.235 + return 1;
20.236 + else if (*n2)
20.237 + return -1;
20.238 + else
20.239 + return 0;
20.240 +}
20.241 +
20.242 +static void
20.243 +count_entries(struct import_directory *d)
20.244 +{
20.245 + struct import_directory *p, *end;
20.246 +
20.247 + p = d->files.data;
20.248 + end = d->files.data + d->files.size;
20.249 + d->count = 0;
20.250 + while (p < end) {
20.251 + count_entries(p);
20.252 + d->count += p->count + 1;
20.253 + p++;
20.254 + }
20.255 +}
20.256 +
20.257 +static void
20.258 +serialize_files(struct razor_set *set,
20.259 + struct import_directory *d, struct array *array)
20.260 +{
20.261 + struct import_directory *p, *end;
20.262 + struct razor_entry *e = NULL;
20.263 + uint32_t s;
20.264 +
20.265 + p = d->files.data;
20.266 + end = d->files.data + d->files.size;
20.267 + s = array->size / sizeof *e + d->files.size / sizeof *p;
20.268 + while (p < end) {
20.269 + e = array_add(array, sizeof *e);
20.270 + e->name = p->name;
20.271 + e->flags = 0;
20.272 + e->start = p->count > 0 ? s : 0;
20.273 + s += p->count;
20.274 +
20.275 + list_set_array(&e->packages, &set->package_pool, &p->packages, 0);
20.276 + array_release(&p->packages);
20.277 + p++;
20.278 + }
20.279 + if (e != NULL)
20.280 + e->flags |= RAZOR_ENTRY_LAST;
20.281 +
20.282 + p = d->files.data;
20.283 + end = d->files.data + d->files.size;
20.284 + while (p < end) {
20.285 + serialize_files(set, p, array);
20.286 + p++;
20.287 + }
20.288 +}
20.289 +
20.290 +static void
20.291 +remap_property_package_links(struct array *properties, uint32_t *rmap)
20.292 +{
20.293 + struct razor_property *p, *end;
20.294 +
20.295 + end = properties->data + properties->size;
20.296 + for (p = properties->data; p < end; p++)
20.297 + list_remap_head(&p->packages, rmap);
20.298 +}
20.299 +
20.300 +static void
20.301 +build_file_tree(struct razor_importer *importer)
20.302 +{
20.303 + int count, i, length;
20.304 + struct import_entry *filenames;
20.305 + char *f, *end;
20.306 + uint32_t name, *r;
20.307 + char dirname[256];
20.308 + struct import_directory *d, root;
20.309 + struct razor_entry *e;
20.310 +
20.311 + count = importer->files.size / sizeof (struct import_entry);
20.312 + razor_qsort_with_data(importer->files.data,
20.313 + count,
20.314 + sizeof (struct import_entry),
20.315 + compare_filenames,
20.316 + NULL);
20.317 +
20.318 + root.name = hashtable_tokenize(&importer->table, "");
20.319 + array_init(&root.files);
20.320 + array_init(&root.packages);
20.321 + root.last = NULL;
20.322 +
20.323 + filenames = importer->files.data;
20.324 + for (i = 0; i < count; i++) {
20.325 + f = filenames[i].name;
20.326 + if (*f != '/')
20.327 + continue;
20.328 + f++;
20.329 +
20.330 + d = &root;
20.331 + while (*f) {
20.332 + end = strchr(f, '/');
20.333 + if (end == NULL)
20.334 + end = f + strlen(f);
20.335 + length = end - f;
20.336 + memcpy(dirname, f, length);
20.337 + dirname[length] ='\0';
20.338 + name = hashtable_tokenize(&importer->table, dirname);
20.339 + if (d->last == NULL || d->last->name != name) {
20.340 + d->last = array_add(&d->files, sizeof *d);
20.341 + d->last->name = name;
20.342 + d->last->last = NULL;
20.343 + array_init(&d->last->files);
20.344 + array_init(&d->last->packages);
20.345 + }
20.346 + d = d->last;
20.347 + f = end + 1;
20.348 + if (*end == '\0')
20.349 + break;
20.350 + }
20.351 +
20.352 + r = array_add(&d->packages, sizeof *r);
20.353 + *r = filenames[i].package;
20.354 + free(filenames[i].name);
20.355 + }
20.356 +
20.357 + count_entries(&root);
20.358 + e = importer->set->files.data;
20.359 + e->name = root.name;
20.360 + e->flags = RAZOR_ENTRY_LAST;
20.361 + e->start = importer->files.size ? 1 : 0;
20.362 + list_set_empty(&e->packages);
20.363 +
20.364 + serialize_files(importer->set, &root, &importer->set->files);
20.365 +
20.366 + array_release(&importer->files);
20.367 +}
20.368 +
20.369 +static void
20.370 +list_to_array(struct list *list, struct array *array)
20.371 +{
20.372 + uint32_t *item;
20.373 +
20.374 + while (list) {
20.375 + item = array_add(array, sizeof *item);
20.376 + *item = list->data;
20.377 + list = list_next(list);
20.378 + }
20.379 +}
20.380 +
20.381 +static int
20.382 +compare_file_requires(const void *p1, const void *p2, void *data)
20.383 +{
20.384 + uint32_t *f1 = (void *)p1, *f2 = (void *)p2;
20.385 + const char *pool = data;
20.386 +
20.387 + return strcmp(&pool[*f1], &pool[*f2]);
20.388 +}
20.389 +
20.390 +static void
20.391 +find_file_provides(struct razor_importer *importer)
20.392 +{
20.393 + struct razor_property *prop;
20.394 + struct razor_entry *top, *entry;
20.395 + struct razor_package *packages;
20.396 + struct array pkgprops;
20.397 + struct list *pkg;
20.398 + uint32_t *req, *req_start, *req_end;
20.399 + uint32_t *map, *newprop;
20.400 + char *pool;
20.401 +
20.402 + pool = importer->set->string_pool.data;
20.403 + packages = importer->set->packages.data;
20.404 + top = importer->set->files.data;
20.405 +
20.406 + req = req_start = importer->file_requires.data;
20.407 + req_end = importer->file_requires.data + importer->file_requires.size;
20.408 + map = razor_qsort_with_data(req, req_end - req, sizeof *req,
20.409 + compare_file_requires, pool);
20.410 + free(map);
20.411 +
20.412 + for (req = req_start; req < req_end; req++) {
20.413 + if (req > req_start && req[0] == req[-1])
20.414 + continue;
20.415 + entry = razor_set_find_entry(importer->set, top, &pool[*req]);
20.416 + if (!entry)
20.417 + continue;
20.418 +
20.419 + for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
20.420 + prop = array_add(&importer->set->properties, sizeof *prop);
20.421 + prop->name = *req;
20.422 + prop->flags =
20.423 + RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL;
20.424 + prop->version = hashtable_tokenize(&importer->table, "");
20.425 + list_set_ptr(&prop->packages, pkg->data);
20.426 +
20.427 + /* Update property list of pkg */
20.428 + array_init(&pkgprops);
20.429 + list_to_array(list_first(&packages[pkg->data].properties, &importer->set->property_pool), &pkgprops);
20.430 + newprop = array_add(&pkgprops, sizeof *newprop);
20.431 + *newprop = prop - (struct razor_property *)importer->set->properties.data;
20.432 + list_set_array(&packages[pkg->data].properties, &importer->set->property_pool, &pkgprops, 1);
20.433 + array_release(&pkgprops);
20.434 + }
20.435 + }
20.436 +
20.437 + array_release(&importer->file_requires);
20.438 +}
20.439 +
20.440 +static void
20.441 +build_package_file_lists(struct razor_set *set, uint32_t *rmap)
20.442 +{
20.443 + struct razor_package *p, *packages;
20.444 + struct array *pkgs;
20.445 + struct razor_entry *e, *end;
20.446 + struct list *r;
20.447 + uint32_t *q;
20.448 + int i, count;
20.449 +
20.450 + count = set->packages.size / sizeof *p;
20.451 + pkgs = zalloc(count * sizeof *pkgs);
20.452 +
20.453 + end = set->files.data + set->files.size;
20.454 + for (e = set->files.data; e < end; e++) {
20.455 + list_remap_head(&e->packages, rmap);
20.456 + r = list_first(&e->packages, &set->package_pool);
20.457 + while (r) {
20.458 + q = array_add(&pkgs[r->data], sizeof *q);
20.459 + *q = e - (struct razor_entry *) set->files.data;
20.460 + r = list_next(r);
20.461 + }
20.462 + }
20.463 +
20.464 + packages = set->packages.data;
20.465 + for (i = 0; i < count; i++) {
20.466 + list_set_array(&packages[i].files, &set->file_pool, &pkgs[i], 0);
20.467 + array_release(&pkgs[i]);
20.468 + }
20.469 + free(pkgs);
20.470 +}
20.471 +
20.472 +struct razor_set *
20.473 +razor_importer_finish(struct razor_importer *importer)
20.474 +{
20.475 + struct razor_set *set;
20.476 + uint32_t *map, *rmap;
20.477 + int i, count;
20.478 +
20.479 + build_file_tree(importer);
20.480 + find_file_provides(importer);
20.481 +
20.482 + map = uniqueify_properties(importer->set);
20.483 + list_remap_pool(&importer->set->property_pool, map);
20.484 + free(map);
20.485 +
20.486 + count = importer->set->packages.size / sizeof(struct razor_package);
20.487 + map = razor_qsort_with_data(importer->set->packages.data,
20.488 + count,
20.489 + sizeof(struct razor_package),
20.490 + compare_packages,
20.491 + importer->set);
20.492 +
20.493 + rmap = malloc(count * sizeof *rmap);
20.494 + for (i = 0; i < count; i++)
20.495 + rmap[map[i]] = i;
20.496 + free(map);
20.497 +
20.498 + list_remap_pool(&importer->set->package_pool, rmap);
20.499 + build_package_file_lists(importer->set, rmap);
20.500 + remap_property_package_links(&importer->set->properties, rmap);
20.501 + free(rmap);
20.502 +
20.503 + set = importer->set;
20.504 + hashtable_release(&importer->table);
20.505 + free(importer);
20.506 +
20.507 + return set;
20.508 +}
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/librazor/iterator.c Fri Jun 20 19:04:47 2008 -0400
21.3 @@ -0,0 +1,265 @@
21.4 +/*
21.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
21.6 + * Copyright (C) 2008 Red Hat, Inc
21.7 + *
21.8 + * This program is free software; you can redistribute it and/or modify
21.9 + * it under the terms of the GNU General Public License as published by
21.10 + * the Free Software Foundation; either version 2 of the License, or
21.11 + * (at your option) any later version.
21.12 + *
21.13 + * This program is distributed in the hope that it will be useful,
21.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
21.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21.16 + * GNU General Public License for more details.
21.17 + *
21.18 + * You should have received a copy of the GNU General Public License along
21.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
21.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21.21 + */
21.22 +
21.23 +#define _GNU_SOURCE
21.24 +
21.25 +#include <string.h>
21.26 +#include "razor-internal.h"
21.27 +#include "razor.h"
21.28 +
21.29 +static struct razor_package_iterator *
21.30 +razor_package_iterator_create_with_index(struct razor_set *set,
21.31 + struct list *index)
21.32 +{
21.33 + struct razor_package_iterator *pi;
21.34 +
21.35 + pi = zalloc(sizeof *pi);
21.36 + pi->set = set;
21.37 + pi->index = index;
21.38 +
21.39 + return pi;
21.40 +}
21.41 +
21.42 +struct razor_package_iterator *
21.43 +razor_package_iterator_create(struct razor_set *set)
21.44 +{
21.45 + struct razor_package_iterator *pi;
21.46 +
21.47 + pi = zalloc(sizeof *pi);
21.48 + pi->set = set;
21.49 + pi->end = set->packages.data + set->packages.size;
21.50 + pi->package = set->packages.data;
21.51 +
21.52 + return pi;
21.53 +}
21.54 +
21.55 +void
21.56 +razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
21.57 + struct razor_set *set,
21.58 + struct razor_property *property)
21.59 +{
21.60 + memset(pi, 0, sizeof *pi);
21.61 + pi->set = set;
21.62 + pi->index = list_first(&property->packages, &set->package_pool);
21.63 +}
21.64 +
21.65 +struct razor_package_iterator *
21.66 +razor_package_iterator_create_for_property(struct razor_set *set,
21.67 + struct razor_property *property)
21.68 +{
21.69 + struct list *index;
21.70 +
21.71 + index = list_first(&property->packages, &set->package_pool);
21.72 + return razor_package_iterator_create_with_index(set, index);
21.73 +}
21.74 +
21.75 +struct razor_package_iterator *
21.76 +razor_package_iterator_create_for_file(struct razor_set *set,
21.77 + const char *filename)
21.78 +{
21.79 + struct razor_entry *entry;
21.80 + struct list *index;
21.81 +
21.82 + entry = razor_set_find_entry(set, set->files.data, filename);
21.83 + if (entry == NULL)
21.84 + return NULL;
21.85 +
21.86 + index = list_first(&entry->packages, &set->package_pool);
21.87 + return razor_package_iterator_create_with_index(set, index);
21.88 +}
21.89 +
21.90 +int
21.91 +razor_package_iterator_next(struct razor_package_iterator *pi,
21.92 + struct razor_package **package,
21.93 + const char **name,
21.94 + const char **version,
21.95 + const char **arch)
21.96 +{
21.97 + char *pool;
21.98 + int valid;
21.99 + struct razor_package *p, *packages;
21.100 +
21.101 + if (pi->package) {
21.102 + p = pi->package++;
21.103 + valid = p < pi->end;
21.104 + } else if (pi->index) {
21.105 + packages = pi->set->packages.data;
21.106 + p = &packages[pi->index->data];
21.107 + pi->index = list_next(pi->index);
21.108 + valid = 1;
21.109 + } else
21.110 + valid = 0;
21.111 +
21.112 + if (valid) {
21.113 + pool = pi->set->string_pool.data;
21.114 + *package = p;
21.115 + *name = &pool[p->name];
21.116 + *version = &pool[p->version];
21.117 + *arch = &pool[p->arch];
21.118 + } else {
21.119 + *package = NULL;
21.120 + }
21.121 +
21.122 + return valid;
21.123 +}
21.124 +
21.125 +void
21.126 +razor_package_iterator_destroy(struct razor_package_iterator *pi)
21.127 +{
21.128 + if (pi->free_index)
21.129 + free(pi->index);
21.130 +
21.131 + free(pi);
21.132 +}
21.133 +
21.134 +struct razor_property_iterator *
21.135 +razor_property_iterator_create(struct razor_set *set,
21.136 + struct razor_package *package)
21.137 +{
21.138 + struct razor_property_iterator *pi;
21.139 +
21.140 + pi = zalloc(sizeof *pi);
21.141 + pi->set = set;
21.142 +
21.143 + if (package) {
21.144 + pi->index = list_first(&package->properties,
21.145 + &set->property_pool);
21.146 + } else {
21.147 + pi->property = set->properties.data;
21.148 + pi->end = set->properties.data + set->properties.size;
21.149 + }
21.150 +
21.151 + return pi;
21.152 +}
21.153 +
21.154 +int
21.155 +razor_property_iterator_next(struct razor_property_iterator *pi,
21.156 + struct razor_property **property,
21.157 + const char **name,
21.158 + uint32_t *flags,
21.159 + const char **version)
21.160 +{
21.161 + char *pool;
21.162 + int valid;
21.163 + struct razor_property *p, *properties;
21.164 +
21.165 + if (pi->property) {
21.166 + p = pi->property++;
21.167 + valid = p < pi->end;
21.168 + } else if (pi->index) {
21.169 + properties = pi->set->properties.data;
21.170 + p = &properties[pi->index->data];
21.171 + pi->index = list_next(pi->index);
21.172 + valid = 1;
21.173 + } else
21.174 + valid = 0;
21.175 +
21.176 + if (valid) {
21.177 + pool = pi->set->string_pool.data;
21.178 + *property = p;
21.179 + *name = &pool[p->name];
21.180 + *flags = p->flags;
21.181 + *version = &pool[p->version];
21.182 + } else {
21.183 + *property = NULL;
21.184 + }
21.185 +
21.186 + return valid;
21.187 +}
21.188 +
21.189 +void
21.190 +razor_property_iterator_destroy(struct razor_property_iterator *pi)
21.191 +{
21.192 + free(pi);
21.193 +}
21.194 +
21.195 +struct razor_package_query {
21.196 + struct razor_set *set;
21.197 + char *vector;
21.198 + int count;
21.199 +};
21.200 +
21.201 +struct razor_package_query *
21.202 +razor_package_query_create(struct razor_set *set)
21.203 +{
21.204 + struct razor_package_query *pq;
21.205 + int count;
21.206 +
21.207 + pq = zalloc(sizeof *pq);
21.208 + pq->set = set;
21.209 + count = set->packages.size / sizeof(struct razor_package);
21.210 + pq->vector = zalloc(count * sizeof(char));
21.211 +
21.212 + return pq;
21.213 +}
21.214 +
21.215 +void
21.216 +razor_package_query_add_package(struct razor_package_query *pq,
21.217 + struct razor_package *p)
21.218 +{
21.219 + struct razor_package *packages;
21.220 +
21.221 + packages = pq->set->packages.data;
21.222 + pq->count += pq->vector[p - packages] ^ 1;
21.223 + pq->vector[p - packages] = 1;
21.224 +}
21.225 +
21.226 +void
21.227 +razor_package_query_add_iterator(struct razor_package_query *pq,
21.228 + struct razor_package_iterator *pi)
21.229 +{
21.230 + struct razor_package *packages, *p;
21.231 + const char *name, *version, *arch;
21.232 +
21.233 + packages = pq->set->packages.data;
21.234 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
21.235 + pq->count += pq->vector[p - packages] ^ 1;
21.236 + pq->vector[p - packages] = 1;
21.237 + }
21.238 +}
21.239 +
21.240 +struct razor_package_iterator *
21.241 +razor_package_query_finish(struct razor_package_query *pq)
21.242 +{
21.243 + struct razor_package_iterator *pi;
21.244 + struct razor_set *set;
21.245 + struct list *index;
21.246 + int i, j, count;
21.247 +
21.248 + set = pq->set;
21.249 + count = set->packages.size / sizeof(struct razor_package);
21.250 + index = zalloc(pq->count * sizeof *index);
21.251 +
21.252 + for (i = 0, j = 0; i < count; i++) {
21.253 + if (!pq->vector[i])
21.254 + continue;
21.255 +
21.256 + index[j].data = i;
21.257 + if (j == pq->count - 1)
21.258 + index[j].flags = 0x80;
21.259 + j++;
21.260 + }
21.261 +
21.262 + free(pq);
21.263 +
21.264 + pi = razor_package_iterator_create_with_index(set, index);
21.265 + pi->free_index = 1;
21.266 +
21.267 + return pi;
21.268 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/librazor/merger.c Fri Jun 20 19:04:47 2008 -0400
22.3 @@ -0,0 +1,525 @@
22.4 +/*
22.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
22.6 + * Copyright (C) 2008 Red Hat, Inc
22.7 + *
22.8 + * This program is free software; you can redistribute it and/or modify
22.9 + * it under the terms of the GNU General Public License as published by
22.10 + * the Free Software Foundation; either version 2 of the License, or
22.11 + * (at your option) any later version.
22.12 + *
22.13 + * This program is distributed in the hope that it will be useful,
22.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
22.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22.16 + * GNU General Public License for more details.
22.17 + *
22.18 + * You should have received a copy of the GNU General Public License along
22.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
22.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22.21 + */
22.22 +
22.23 +#include <string.h>
22.24 +#include "razor-internal.h"
22.25 +#include "razor.h"
22.26 +
22.27 +#define UPSTREAM_SOURCE 0x80
22.28 +
22.29 +struct source {
22.30 + struct razor_set *set;
22.31 + uint32_t *property_map;
22.32 + uint32_t *file_map;
22.33 +};
22.34 +
22.35 +struct razor_merger {
22.36 + struct razor_set *set;
22.37 + struct hashtable table;
22.38 + struct source source1;
22.39 + struct source source2;
22.40 +};
22.41 +
22.42 +struct razor_merger *
22.43 +razor_merger_create(struct razor_set *set1, struct razor_set *set2)
22.44 +{
22.45 + struct razor_merger *merger;
22.46 + int count;
22.47 + size_t size;
22.48 +
22.49 + merger = zalloc(sizeof *merger);
22.50 + merger->set = razor_set_create();
22.51 + hashtable_init(&merger->table, &merger->set->string_pool);
22.52 +
22.53 + merger->source1.set = set1;
22.54 + count = set1->properties.size / sizeof (struct razor_property);
22.55 + size = count * sizeof merger->source1.property_map[0];
22.56 + merger->source1.property_map = zalloc(size);
22.57 + count = set1->files.size / sizeof (struct razor_entry);
22.58 + size = count * sizeof merger->source1.file_map[0];
22.59 + merger->source1.file_map = zalloc(size);
22.60 +
22.61 + merger->source2.set = set2;
22.62 + count = set2->properties.size / sizeof (struct razor_property);
22.63 + size = count * sizeof merger->source2.property_map[0];
22.64 + merger->source2.property_map = zalloc(size);
22.65 + count = set2->files.size / sizeof (struct razor_entry);
22.66 + size = count * sizeof merger->source2.file_map[0];
22.67 + merger->source2.file_map = zalloc(size);
22.68 +
22.69 + return merger;
22.70 +}
22.71 +
22.72 +void
22.73 +razor_merger_add_package(struct razor_merger *merger,
22.74 + struct razor_package *package)
22.75 +{
22.76 + char *pool;
22.77 + struct list *r;
22.78 + struct razor_package *p;
22.79 + struct razor_set *set1;
22.80 + struct source *source;
22.81 + uint32_t flags;
22.82 +
22.83 + set1 = merger->source1.set;
22.84 + if (set1->packages.data <= (void *) package &&
22.85 + (void *) package < set1->packages.data + set1->packages.size) {
22.86 + source = &merger->source1;
22.87 + flags = 0;
22.88 + } else {
22.89 + source = &merger->source2;
22.90 + flags = UPSTREAM_SOURCE;
22.91 + }
22.92 +
22.93 + pool = source->set->string_pool.data;
22.94 + p = array_add(&merger->set->packages, sizeof *p);
22.95 + p->name = hashtable_tokenize(&merger->table, &pool[package->name]);
22.96 + p->flags = flags;
22.97 + p->version = hashtable_tokenize(&merger->table,
22.98 + &pool[package->version]);
22.99 + p->arch = hashtable_tokenize(&merger->table,
22.100 + &pool[package->arch]);
22.101 +
22.102 + p->properties = package->properties;
22.103 + r = list_first(&package->properties, &source->set->property_pool);
22.104 + while (r) {
22.105 + source->property_map[r->data] = 1;
22.106 + r = list_next(r);
22.107 + }
22.108 +
22.109 + p->files = package->files;
22.110 + r = list_first(&package->files, &source->set->file_pool);
22.111 + while (r) {
22.112 + source->file_map[r->data] = 1;
22.113 + r = list_next(r);
22.114 + }
22.115 +}
22.116 +
22.117 +static uint32_t
22.118 +add_property(struct razor_merger *merger,
22.119 + const char *name, uint32_t flags, const char *version)
22.120 +{
22.121 + struct razor_property *p;
22.122 +
22.123 + p = array_add(&merger->set->properties, sizeof *p);
22.124 + p->name = hashtable_tokenize(&merger->table, name);
22.125 + p->flags = flags;
22.126 + p->version = hashtable_tokenize(&merger->table, version);
22.127 +
22.128 + return p - (struct razor_property *) merger->set->properties.data;
22.129 +}
22.130 +
22.131 +static void
22.132 +merge_properties(struct razor_merger *merger)
22.133 +{
22.134 + struct razor_property *p1, *p2;
22.135 + struct razor_set *set1, *set2;
22.136 + uint32_t *map1, *map2;
22.137 + int i, j, cmp, count1, count2;
22.138 + char *pool1, *pool2;
22.139 +
22.140 + set1 = merger->source1.set;
22.141 + set2 = merger->source2.set;
22.142 + map1 = merger->source1.property_map;
22.143 + map2 = merger->source2.property_map;
22.144 +
22.145 + i = 0;
22.146 + j = 0;
22.147 + pool1 = set1->string_pool.data;
22.148 + pool2 = set2->string_pool.data;
22.149 +
22.150 + count1 = set1->properties.size / sizeof *p1;
22.151 + count2 = set2->properties.size / sizeof *p2;
22.152 + while (i < count1 || j < count2) {
22.153 + if (i < count1 && map1[i] == 0) {
22.154 + i++;
22.155 + continue;
22.156 + }
22.157 + if (j < count2 && map2[j] == 0) {
22.158 + j++;
22.159 + continue;
22.160 + }
22.161 + p1 = (struct razor_property *) set1->properties.data + i;
22.162 + p2 = (struct razor_property *) set2->properties.data + j;
22.163 + if (i < count1 && j < count2)
22.164 + cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
22.165 + else if (i < count1)
22.166 + cmp = -1;
22.167 + else
22.168 + cmp = 1;
22.169 + if (cmp == 0)
22.170 + cmp = p1->flags - p2->flags;
22.171 + if (cmp == 0)
22.172 + cmp = razor_versioncmp(&pool1[p1->version],
22.173 + &pool2[p2->version]);
22.174 + if (cmp < 0) {
22.175 + map1[i++] = add_property(merger,
22.176 + &pool1[p1->name],
22.177 + p1->flags,
22.178 + &pool1[p1->version]);
22.179 + } else if (cmp > 0) {
22.180 + map2[j++] = add_property(merger,
22.181 + &pool2[p2->name],
22.182 + p2->flags,
22.183 + &pool2[p2->version]);
22.184 + } else {
22.185 + map1[i++] = map2[j++] =
22.186 + add_property(merger,
22.187 + &pool1[p1->name],
22.188 + p1->flags,
22.189 + &pool1[p1->version]);
22.190 + }
22.191 + }
22.192 +}
22.193 +
22.194 +static void
22.195 +emit_properties(struct list_head *properties, struct array *source_pool,
22.196 + uint32_t *map, struct array *pool)
22.197 +{
22.198 + uint32_t r;
22.199 + struct list *p, *q;
22.200 +
22.201 + r = pool->size / sizeof *q;
22.202 + p = list_first(properties, source_pool);
22.203 + while (p) {
22.204 + q = array_add(pool, sizeof *q);
22.205 + q->data = map[p->data];
22.206 + q->flags = p->flags;
22.207 + p = list_next(p);
22.208 + }
22.209 +
22.210 + list_set_ptr(properties, r);
22.211 +}
22.212 +
22.213 +static uint32_t
22.214 +add_file(struct razor_merger *merger, const char *name)
22.215 +{
22.216 + struct razor_entry *e;
22.217 +
22.218 + e = array_add(&merger->set->files, sizeof *e);
22.219 + e->name = hashtable_tokenize(&merger->table, name);
22.220 + e->flags = 0;
22.221 + e->start = 0;
22.222 +
22.223 + return e - (struct razor_entry *)merger->set->files.data;
22.224 +}
22.225 +
22.226 +/* FIXME. Blah */
22.227 +static int
22.228 +fix_file_map(uint32_t *map,
22.229 + struct razor_entry *files,
22.230 + struct razor_entry *top)
22.231 +{
22.232 + uint32_t e;
22.233 + int found_file = 0;
22.234 +
22.235 + e = top->start;
22.236 + do {
22.237 + if (files[e].start)
22.238 + fix_file_map(map, files, &files[e]);
22.239 + if (map[e])
22.240 + found_file = 1;
22.241 + } while (!(files[e++].flags & RAZOR_ENTRY_LAST));
22.242 +
22.243 + if (found_file)
22.244 + map[top - files] = 1;
22.245 + return found_file;
22.246 +}
22.247 +
22.248 +struct merge_directory {
22.249 + uint32_t merged, dir1, dir2;
22.250 +};
22.251 +
22.252 +static void
22.253 +merge_one_directory(struct razor_merger *merger, struct merge_directory *md)
22.254 +{
22.255 + struct razor_entry *root1, *root2, *mroot, *e1, *e2;
22.256 + struct razor_set *set1, *set2;
22.257 + struct array merge_stack;
22.258 + struct merge_directory *child_md, *end_md;
22.259 + uint32_t *map1, *map2, start, last;
22.260 + int cmp;
22.261 + char *pool1, *pool2;
22.262 +
22.263 + set1 = merger->source1.set;
22.264 + set2 = merger->source2.set;
22.265 + map1 = merger->source1.file_map;
22.266 + map2 = merger->source2.file_map;
22.267 + pool1 = set1->string_pool.data;
22.268 + pool2 = set2->string_pool.data;
22.269 + root1 = (struct razor_entry *) set1->files.data;
22.270 + root2 = (struct razor_entry *) set2->files.data;
22.271 +
22.272 + array_init(&merge_stack);
22.273 +
22.274 + start = merger->set->files.size / sizeof (struct razor_entry);
22.275 + last = 0;
22.276 + e1 = md->dir1 ? root1 + md->dir1 : NULL;
22.277 + e2 = md->dir2 ? root2 + md->dir2 : NULL;
22.278 + while (e1 || e2) {
22.279 + if (!e2 && !map1[e1 - root1]) {
22.280 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
22.281 + e1 = NULL;
22.282 + continue;
22.283 + }
22.284 + if (!e1 && !map2[e2 - root2]) {
22.285 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
22.286 + e2 = NULL;
22.287 + continue;
22.288 + }
22.289 + if (e1 && !map1[e1 - root1] &&
22.290 + e2 && !map1[e2 - root2]) {
22.291 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
22.292 + e1 = NULL;
22.293 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
22.294 + e2 = NULL;
22.295 + continue;
22.296 + }
22.297 +
22.298 + if (!e1)
22.299 + cmp = 1;
22.300 + else if (!e2)
22.301 + cmp = -1;
22.302 + else {
22.303 + cmp = strcmp (&pool1[e1->name],
22.304 + &pool2[e2->name]);
22.305 + }
22.306 +
22.307 + if (cmp < 0) {
22.308 + if (map1[e1 - root1]) {
22.309 + map1[e1 - root1] = last =
22.310 + add_file(merger, &pool1[e1->name]);
22.311 + if (e1->start) {
22.312 + child_md = array_add(&merge_stack, sizeof (struct merge_directory));
22.313 + child_md->merged = last;
22.314 + child_md->dir1 = e1->start;
22.315 + child_md->dir2 = 0;
22.316 + }
22.317 + }
22.318 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
22.319 + e1 = NULL;
22.320 + } else if (cmp > 0) {
22.321 + if (map2[e2 - root2]) {
22.322 + map2[e2 - root2] = last =
22.323 + add_file(merger, &pool2[e2->name]);
22.324 + if (e2->start) {
22.325 + child_md = array_add(&merge_stack, sizeof (struct merge_directory));
22.326 + child_md->merged = last;
22.327 + child_md->dir1 = 0;
22.328 + child_md->dir2 = e2->start;
22.329 + }
22.330 + }
22.331 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
22.332 + e2 = NULL;
22.333 + } else {
22.334 + map1[e1 - root1] = map2[e2- root2] = last =
22.335 + add_file(merger, &pool1[e1->name]);
22.336 + if (e1->start || e2->start) {
22.337 + child_md = array_add(&merge_stack, sizeof (struct merge_directory));
22.338 + child_md->merged = last;
22.339 + child_md->dir1 = e1->start;
22.340 + child_md->dir2 = e2->start;
22.341 + }
22.342 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
22.343 + e1 = NULL;
22.344 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
22.345 + e2 = NULL;
22.346 + }
22.347 + }
22.348 +
22.349 + mroot = (struct razor_entry *)merger->set->files.data;
22.350 + if (last) {
22.351 + mroot[last].flags = RAZOR_ENTRY_LAST;
22.352 + mroot[md->merged].start = start;
22.353 + } else
22.354 + mroot[md->merged].start = 0;
22.355 +
22.356 + end_md = merge_stack.data + merge_stack.size;
22.357 + for (child_md = merge_stack.data; child_md < end_md; child_md++)
22.358 + merge_one_directory(merger, child_md);
22.359 + array_release(&merge_stack);
22.360 +}
22.361 +
22.362 +static void
22.363 +merge_files(struct razor_merger *merger)
22.364 +{
22.365 + struct razor_entry *root;
22.366 + struct merge_directory md;
22.367 + uint32_t *map1, *map2;
22.368 +
22.369 + map1 = merger->source1.file_map;
22.370 + map2 = merger->source2.file_map;
22.371 +
22.372 + md.merged = 0;
22.373 +
22.374 + if (merger->source1.set->files.size) {
22.375 + root = (struct razor_entry *) merger->source1.set->files.data;
22.376 + if (root->start)
22.377 + fix_file_map(map1, root, root);
22.378 + md.dir1 = root->start;
22.379 + } else
22.380 + md.dir1 = 0;
22.381 +
22.382 + if (merger->source2.set->files.size) {
22.383 + root = (struct razor_entry *) merger->source2.set->files.data;
22.384 + if (root->start)
22.385 + fix_file_map(map2, root, root);
22.386 + md.dir2 = root->start;
22.387 + } else
22.388 + md.dir2 = 0;
22.389 +
22.390 + merge_one_directory(merger, &md);
22.391 +}
22.392 +
22.393 +static void
22.394 +emit_files(struct list_head *files, struct array *source_pool,
22.395 + uint32_t *map, struct array *pool)
22.396 +{
22.397 + uint32_t r;
22.398 + struct list *p, *q;
22.399 +
22.400 + r = pool->size / sizeof *q;
22.401 + p = list_first(files, source_pool);
22.402 + while (p) {
22.403 + q = array_add(pool, sizeof *q);
22.404 + q->data = map[p->data];
22.405 + q->flags = p->flags;
22.406 + p = list_next(p);
22.407 + }
22.408 +
22.409 + list_set_ptr(files, r);
22.410 +}
22.411 +
22.412 +/* Rebuild property->packages maps. We can't just remap these, as a
22.413 + * property may have lost or gained a number of packages. Allocate an
22.414 + * array per property and loop through the packages and add them to
22.415 + * the arrays for their properties. */
22.416 +static void
22.417 +rebuild_property_package_lists(struct razor_set *set)
22.418 +{
22.419 + struct array *pkgs, *a;
22.420 + struct razor_package *pkg, *pkg_end;
22.421 + struct razor_property *prop, *prop_end;
22.422 + struct list *r;
22.423 + uint32_t *q;
22.424 + int count;
22.425 +
22.426 + count = set->properties.size / sizeof (struct razor_property);
22.427 + pkgs = zalloc(count * sizeof *pkgs);
22.428 + pkg_end = set->packages.data + set->packages.size;
22.429 +
22.430 + for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
22.431 + r = list_first(&pkg->properties, &set->property_pool);
22.432 + while (r) {
22.433 + q = array_add(&pkgs[r->data], sizeof *q);
22.434 + *q = pkg - (struct razor_package *) set->packages.data;
22.435 + r = list_next(r);
22.436 + }
22.437 + }
22.438 +
22.439 + prop_end = set->properties.data + set->properties.size;
22.440 + a = pkgs;
22.441 + for (prop = set->properties.data; prop < prop_end; prop++, a++) {
22.442 + list_set_array(&prop->packages, &set->package_pool, a, 0);
22.443 + array_release(a);
22.444 + }
22.445 + free(pkgs);
22.446 +}
22.447 +
22.448 +static void
22.449 +rebuild_file_package_lists(struct razor_set *set)
22.450 +{
22.451 + struct array *pkgs, *a;
22.452 + struct razor_package *pkg, *pkg_end;
22.453 + struct razor_entry *entry, *entry_end;
22.454 + struct list *r;
22.455 + uint32_t *q;
22.456 + int count;
22.457 +
22.458 + count = set->files.size / sizeof (struct razor_entry);
22.459 + pkgs = zalloc(count * sizeof *pkgs);
22.460 + pkg_end = set->packages.data + set->packages.size;
22.461 +
22.462 + for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
22.463 + r = list_first(&pkg->files, &set->file_pool);
22.464 + while (r) {
22.465 + q = array_add(&pkgs[r->data], sizeof *q);
22.466 + *q = pkg - (struct razor_package *) set->packages.data;
22.467 + r = list_next(r);
22.468 + }
22.469 + }
22.470 +
22.471 + entry_end = set->files.data + set->files.size;
22.472 + a = pkgs;
22.473 + for (entry = set->files.data; entry < entry_end; entry++, a++) {
22.474 + list_set_array(&entry->packages, &set->package_pool, a, 0);
22.475 + array_release(a);
22.476 + }
22.477 + free(pkgs);
22.478 +}
22.479 +
22.480 +struct razor_set *
22.481 +razor_merger_finish(struct razor_merger *merger)
22.482 +{
22.483 + struct razor_set *result;
22.484 + struct razor_package *p, *pend;
22.485 +
22.486 + /* As we built the package list, we filled out a bitvector of
22.487 + * the properties that are referenced by the packages in the
22.488 + * new set. Now we do a parallel loop through the properties
22.489 + * and emit those marked in the bit vector to the new set. In
22.490 + * the process, we update the bit vector to actually map from
22.491 + * indices in the old property list to indices in the new
22.492 + * property list for both sets. */
22.493 +
22.494 + merge_properties(merger);
22.495 + merge_files(merger);
22.496 +
22.497 + /* Now we loop through the packages again and emit the
22.498 + * property lists, remapped to point to the new properties. */
22.499 +
22.500 + pend = merger->set->packages.data + merger->set->packages.size;
22.501 + for (p = merger->set->packages.data; p < pend; p++) {
22.502 + struct source *src;
22.503 +
22.504 + if (p->flags & UPSTREAM_SOURCE)
22.505 + src = &merger->source2;
22.506 + else
22.507 + src = &merger->source1;
22.508 +
22.509 + emit_properties(&p->properties,
22.510 + &src->set->property_pool,
22.511 + src->property_map,
22.512 + &merger->set->property_pool);
22.513 + emit_files(&p->files,
22.514 + &src->set->file_pool,
22.515 + src->file_map,
22.516 + &merger->set->file_pool);
22.517 + p->flags &= ~UPSTREAM_SOURCE;
22.518 + }
22.519 +
22.520 + rebuild_property_package_lists(merger->set);
22.521 + rebuild_file_package_lists(merger->set);
22.522 +
22.523 + result = merger->set;
22.524 + hashtable_release(&merger->table);
22.525 + free(merger);
22.526 +
22.527 + return result;
22.528 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/librazor/razor-internal.h Fri Jun 20 19:04:47 2008 -0400
23.3 @@ -0,0 +1,194 @@
23.4 +#ifndef _RAZOR_INTERNAL_H_
23.5 +#define _RAZOR_INTERNAL_H_
23.6 +
23.7 +#include <stdlib.h>
23.8 +#include <stdint.h>
23.9 +
23.10 +void *zalloc(size_t size);
23.11 +
23.12 +struct array {
23.13 + void *data;
23.14 + int size, alloc;
23.15 +};
23.16 +
23.17 +void array_init(struct array *array);
23.18 +void array_release(struct array *array);
23.19 +void *array_add(struct array *array, int size);
23.20 +
23.21 +
23.22 +struct list_head {
23.23 + uint32_t list_ptr : 24;
23.24 + uint32_t flags : 8;
23.25 +};
23.26 +
23.27 +struct list {
23.28 + uint32_t data : 24;
23.29 + uint32_t flags : 8;
23.30 +};
23.31 +
23.32 +void list_set_empty(struct list_head *head);
23.33 +void list_set_ptr(struct list_head *head, uint32_t ptr);
23.34 +void list_set_array(struct list_head *head, struct array *pool, struct array *items, int force_indirect);
23.35 +
23.36 +struct list *list_first(struct list_head *head, struct array *pool);
23.37 +struct list *list_next(struct list *list);
23.38 +
23.39 +void list_remap_pool(struct array *pool, uint32_t *map);
23.40 +void list_remap_head(struct list_head *list, uint32_t *map);
23.41 +
23.42 +
23.43 +struct hashtable {
23.44 + struct array buckets;
23.45 + struct array *pool;
23.46 +};
23.47 +
23.48 +void hashtable_init(struct hashtable *table, struct array *pool);
23.49 +void hashtable_release(struct hashtable *table);
23.50 +uint32_t hashtable_insert(struct hashtable *table, const char *key);
23.51 +uint32_t hashtable_lookup(struct hashtable *table, const char *key);
23.52 +uint32_t hashtable_tokenize(struct hashtable *table, const char *string);
23.53 +
23.54 +
23.55 +struct razor_set_section {
23.56 + uint32_t type;
23.57 + uint32_t offset;
23.58 + uint32_t size;
23.59 +};
23.60 +
23.61 +struct razor_set_header {
23.62 + uint32_t magic;
23.63 + uint32_t version;
23.64 + struct razor_set_section sections[0];
23.65 +};
23.66 +
23.67 +#define RAZOR_MAGIC 0x7a7a7a7a
23.68 +#define RAZOR_DETAILS_MAGIC 0x7a7a7a7b
23.69 +#define RAZOR_FILES_MAGIC 0x7a7a7a7c
23.70 +#define RAZOR_VERSION 1
23.71 +
23.72 +#define RAZOR_STRING_POOL 0
23.73 +#define RAZOR_PACKAGES 1
23.74 +#define RAZOR_PROPERTIES 2
23.75 +#define RAZOR_PACKAGE_POOL 3
23.76 +#define RAZOR_PROPERTY_POOL 4
23.77 +
23.78 +#define RAZOR_DETAILS_STRING_POOL 0
23.79 +
23.80 +#define RAZOR_FILES 0
23.81 +#define RAZOR_FILE_POOL 1
23.82 +#define RAZOR_FILE_STRING_POOL 2
23.83 +
23.84 +struct razor_package {
23.85 + uint name : 24;
23.86 + uint flags : 8;
23.87 + uint32_t version;
23.88 + uint32_t arch;
23.89 + uint32_t summary;
23.90 + uint32_t description;
23.91 + uint32_t url;
23.92 + uint32_t license;
23.93 + struct list_head properties;
23.94 + struct list_head files;
23.95 +};
23.96 +
23.97 +
23.98 +struct razor_property {
23.99 + uint32_t name;
23.100 + uint32_t flags;
23.101 + uint32_t version;
23.102 + struct list_head packages;
23.103 +};
23.104 +
23.105 +struct razor_entry {
23.106 + uint32_t name : 24;
23.107 + uint32_t flags : 8;
23.108 + uint32_t start;
23.109 + struct list_head packages;
23.110 +};
23.111 +
23.112 +#define RAZOR_ENTRY_LAST 0x80
23.113 +
23.114 +struct razor_set {
23.115 + struct array string_pool;
23.116 + struct array packages;
23.117 + struct array properties;
23.118 + struct array files;
23.119 + struct array package_pool;
23.120 + struct array property_pool;
23.121 + struct array file_pool;
23.122 + struct array file_string_pool;
23.123 + struct array details_string_pool;
23.124 + struct razor_set_header *header;
23.125 + struct razor_set_header *details_header;
23.126 + struct razor_set_header *files_header;
23.127 +};
23.128 +
23.129 +struct import_entry {
23.130 + uint32_t package;
23.131 + char *name;
23.132 +};
23.133 +
23.134 +struct import_directory {
23.135 + uint32_t name, count;
23.136 + struct array files;
23.137 + struct array packages;
23.138 + struct import_directory *last;
23.139 +};
23.140 +
23.141 +struct razor_importer {
23.142 + struct razor_set *set;
23.143 + struct hashtable table;
23.144 + struct hashtable file_table;
23.145 + struct hashtable details_table;
23.146 + struct razor_package *package;
23.147 + struct array properties;
23.148 + struct array files;
23.149 + struct array file_requires;
23.150 +};
23.151 +
23.152 +struct razor_package_iterator {
23.153 + struct razor_set *set;
23.154 + struct razor_package *package, *end;
23.155 + struct list *index;
23.156 + int free_index;
23.157 +};
23.158 +
23.159 +void
23.160 +razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
23.161 + struct razor_set *set,
23.162 + struct razor_property *property);
23.163 +
23.164 +struct razor_property_iterator {
23.165 + struct razor_set *set;
23.166 + struct razor_property *property, *end;
23.167 + struct list *index;
23.168 +};
23.169 +
23.170 +#define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
23.171 +
23.172 +struct razor_entry *
23.173 +razor_set_find_entry(struct razor_set *set,
23.174 + struct razor_entry *dir, const char *pattern);
23.175 +
23.176 +struct razor_merger *
23.177 +razor_merger_create(struct razor_set *set1, struct razor_set *set2);
23.178 +void
23.179 +razor_merger_add_package(struct razor_merger *merger,
23.180 + struct razor_package *package);
23.181 +struct razor_set *
23.182 +razor_merger_finish(struct razor_merger *merger);
23.183 +
23.184 +/* Utility functions */
23.185 +
23.186 +int razor_create_dir(const char *root, const char *path);
23.187 +int razor_write(int fd, const void *data, size_t size);
23.188 +
23.189 +
23.190 +typedef int (*razor_compare_with_data_func_t)(const void *p1,
23.191 + const void *p,
23.192 + void *data);
23.193 +uint32_t *
23.194 +razor_qsort_with_data(void *base, size_t nelem, size_t size,
23.195 + razor_compare_with_data_func_t compare, void *data);
23.196 +
23.197 +#endif /* _RAZOR_INTERNAL_H_ */
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/librazor/razor.c Fri Jun 20 19:04:47 2008 -0400
24.3 @@ -0,0 +1,588 @@
24.4 +/*
24.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
24.6 + * Copyright (C) 2008 Red Hat, Inc
24.7 + *
24.8 + * This program is free software; you can redistribute it and/or modify
24.9 + * it under the terms of the GNU General Public License as published by
24.10 + * the Free Software Foundation; either version 2 of the License, or
24.11 + * (at your option) any later version.
24.12 + *
24.13 + * This program is distributed in the hope that it will be useful,
24.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
24.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24.16 + * GNU General Public License for more details.
24.17 + *
24.18 + * You should have received a copy of the GNU General Public License along
24.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
24.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24.21 + */
24.22 +
24.23 +#define _GNU_SOURCE
24.24 +
24.25 +#include <stdlib.h>
24.26 +#include <stddef.h>
24.27 +#include <stdint.h>
24.28 +#include <stdio.h>
24.29 +#include <string.h>
24.30 +#include <sys/types.h>
24.31 +#include <sys/stat.h>
24.32 +#include <sys/mman.h>
24.33 +#include <unistd.h>
24.34 +#include <fcntl.h>
24.35 +#include <errno.h>
24.36 +#include <ctype.h>
24.37 +#include <fnmatch.h>
24.38 +
24.39 +#include "razor.h"
24.40 +#include "razor-internal.h"
24.41 +
24.42 +void *
24.43 +zalloc(size_t size)
24.44 +{
24.45 + void *p;
24.46 +
24.47 + p = malloc(size);
24.48 + memset(p, 0, size);
24.49 +
24.50 + return p;
24.51 +}
24.52 +
24.53 +struct razor_set_section razor_sections[] = {
24.54 + { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
24.55 + { RAZOR_PACKAGES, offsetof(struct razor_set, packages) },
24.56 + { RAZOR_PROPERTIES, offsetof(struct razor_set, properties) },
24.57 + { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
24.58 + { RAZOR_PROPERTY_POOL, offsetof(struct razor_set, property_pool) },
24.59 +};
24.60 +
24.61 +struct razor_set_section razor_files_sections[] = {
24.62 + { RAZOR_FILES, offsetof(struct razor_set, files) },
24.63 + { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) },
24.64 + { RAZOR_FILE_STRING_POOL, offsetof(struct razor_set, file_string_pool) },
24.65 +};
24.66 +
24.67 +struct razor_set_section razor_details_sections[] = {
24.68 + { RAZOR_DETAILS_STRING_POOL, offsetof(struct razor_set, details_string_pool) },
24.69 +};
24.70 +struct razor_set *
24.71 +razor_set_create(void)
24.72 +{
24.73 + struct razor_set *set;
24.74 + struct razor_entry *e;
24.75 + char *empty;
24.76 +
24.77 + set = zalloc(sizeof *set);
24.78 +
24.79 + e = array_add(&set->files, sizeof *e);
24.80 + empty = array_add(&set->string_pool, 1);
24.81 + *empty = '\0';
24.82 + e->name = 0;
24.83 + e->flags = RAZOR_ENTRY_LAST;
24.84 + e->start = 0;
24.85 + list_set_empty(&e->packages);
24.86 +
24.87 + return set;
24.88 +}
24.89 +
24.90 +struct razor_set *
24.91 +razor_set_open(const char *filename)
24.92 +{
24.93 + struct razor_set *set;
24.94 + struct razor_set_section *s;
24.95 + struct stat stat;
24.96 + struct array *array;
24.97 + int fd;
24.98 +
24.99 + set = zalloc(sizeof *set);
24.100 + fd = open(filename, O_RDONLY);
24.101 + if (fstat(fd, &stat) < 0)
24.102 + return NULL;
24.103 + set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
24.104 + if (set->header == MAP_FAILED) {
24.105 + free(set);
24.106 + return NULL;
24.107 + }
24.108 +
24.109 + for (s = set->header->sections; ~s->type; s++) {
24.110 + if (s->type >= ARRAY_SIZE(razor_sections))
24.111 + continue;
24.112 + if (s->type != razor_sections[s->type].type)
24.113 + continue;
24.114 + array = (void *) set + razor_sections[s->type].offset;
24.115 + array->data = (void *) set->header + s->offset;
24.116 + array->size = s->size;
24.117 + array->alloc = s->size;
24.118 + }
24.119 + close(fd);
24.120 +
24.121 + return set;
24.122 +}
24.123 +
24.124 +void
24.125 +razor_set_open_details(struct razor_set *set, const char *filename)
24.126 +{
24.127 + struct razor_set_section *s;
24.128 + struct stat stat;
24.129 + struct array *array;
24.130 + int fd;
24.131 +
24.132 + fd = open(filename, O_RDONLY);
24.133 + if (fstat(fd, &stat) < 0)
24.134 + return;
24.135 + set->details_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
24.136 + if (set->details_header == MAP_FAILED)
24.137 + return;
24.138 +
24.139 + for (s = set->details_header->sections; ~s->type; s++) {
24.140 + if (s->type >= ARRAY_SIZE(razor_details_sections))
24.141 + continue;
24.142 + if (s->type != razor_details_sections[s->type].type)
24.143 + continue;
24.144 + array = (void *) set + razor_details_sections[s->type].offset;
24.145 + array->data = (void *) set->details_header + s->offset;
24.146 + array->size = s->size;
24.147 + array->alloc = s->size;
24.148 + }
24.149 + close(fd);
24.150 +}
24.151 +
24.152 +void
24.153 +razor_set_open_files(struct razor_set *set, const char *filename)
24.154 +{
24.155 + struct razor_set_section *s;
24.156 + struct stat stat;
24.157 + struct array *array;
24.158 + int fd;
24.159 +
24.160 + fd = open(filename, O_RDONLY);
24.161 + if (fstat(fd, &stat) < 0)
24.162 + return;
24.163 + set->files_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
24.164 + if (set->files_header == MAP_FAILED)
24.165 + return;
24.166 +
24.167 + for (s = set->files_header->sections; ~s->type; s++) {
24.168 + if (s->type >= ARRAY_SIZE(razor_files_sections))
24.169 + continue;
24.170 + if (s->type != razor_files_sections[s->type].type)
24.171 + continue;
24.172 + array = (void *) set + razor_files_sections[s->type].offset;
24.173 + array->data = (void *) set->files_header + s->offset;
24.174 + array->size = s->size;
24.175 + array->alloc = s->size;
24.176 + }
24.177 + close(fd);
24.178 +}
24.179 +
24.180 +void
24.181 +razor_set_destroy(struct razor_set *set)
24.182 +{
24.183 + unsigned int size;
24.184 + struct array *a;
24.185 + int i;
24.186 +
24.187 + if (set->header) {
24.188 + for (i = 0; set->header->sections[i].type; i++)
24.189 + ;
24.190 + size = set->header->sections[i].type;
24.191 + munmap(set->header, size);
24.192 + } else {
24.193 + for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
24.194 + a = (void *) set + razor_sections[i].offset;
24.195 + free(a->data);
24.196 + }
24.197 + }
24.198 +
24.199 + if (set->details_header) {
24.200 + for (i = 0; set->details_header->sections[i].type; i++)
24.201 + ;
24.202 + size = set->details_header->sections[i].type;
24.203 + munmap(set->details_header, size);
24.204 + } else {
24.205 + for (i = 0; i < ARRAY_SIZE(razor_details_sections); i++) {
24.206 + a = (void *) set + razor_details_sections[i].offset;
24.207 + free(a->data);
24.208 + }
24.209 + }
24.210 +
24.211 + if (set->files_header) {
24.212 + for (i = 0; set->files_header->sections[i].type; i++)
24.213 + ;
24.214 + size = set->files_header->sections[i].type;
24.215 + munmap(set->files_header, size);
24.216 + } else {
24.217 + for (i = 0; i < ARRAY_SIZE(razor_files_sections); i++) {
24.218 + a = (void *) set + razor_files_sections[i].offset;
24.219 + free(a->data);
24.220 + }
24.221 + }
24.222 +
24.223 + free(set);
24.224 +}
24.225 +
24.226 +static int
24.227 +razor_set_write_sections_to_fd(struct razor_set *set, int fd, int magic,
24.228 + struct razor_set_section *sections,
24.229 + size_t array_size)
24.230 +{
24.231 + char data[4096];
24.232 + struct razor_set_header *header = (struct razor_set_header *) data;
24.233 + struct array *a;
24.234 + uint32_t offset;
24.235 + int i;
24.236 +
24.237 + memset(data, 0, sizeof data);
24.238 + header->magic = magic;
24.239 + header->version = RAZOR_VERSION;
24.240 + offset = sizeof data;
24.241 +
24.242 + for (i = 0; i < array_size; i++) {
24.243 + if (sections[i].type != i)
24.244 + continue;
24.245 + a = (void *) set + sections[i].offset;
24.246 + header->sections[i].type = i;
24.247 + header->sections[i].offset = offset;
24.248 + header->sections[i].size = a->size;
24.249 + offset += ALIGN(a->size, 4096);
24.250 + }
24.251 +
24.252 + header->sections[i].type = ~0;
24.253 + header->sections[i].offset = 0;
24.254 + header->sections[i].size = 0;
24.255 +
24.256 + razor_write(fd, data, sizeof data);
24.257 + memset(data, 0, sizeof data);
24.258 + for (i = 0; i < array_size; i++) {
24.259 + if (sections[i].type != i)
24.260 + continue;
24.261 + a = (void *) set + sections[i].offset;
24.262 + razor_write(fd, a->data, a->size);
24.263 + razor_write(fd, data, ALIGN(a->size, 4096) - a->size);
24.264 + }
24.265 +
24.266 + return 0;
24.267 +}
24.268 +
24.269 +int
24.270 +razor_set_write_to_fd(struct razor_set *set, int fd,
24.271 + enum razor_repo_file_type type)
24.272 +{
24.273 + switch (type) {
24.274 + case RAZOR_REPO_FILE_MAIN:
24.275 + return razor_set_write_sections_to_fd(set, fd, RAZOR_MAGIC,
24.276 + razor_sections,
24.277 + ARRAY_SIZE(razor_sections));
24.278 +
24.279 + case RAZOR_REPO_FILE_DETAILS:
24.280 + return razor_set_write_sections_to_fd(set, fd, RAZOR_DETAILS_MAGIC,
24.281 + razor_details_sections,
24.282 + ARRAY_SIZE(razor_details_sections));
24.283 + case RAZOR_REPO_FILE_FILES:
24.284 + return razor_set_write_sections_to_fd(set, fd, RAZOR_FILES_MAGIC,
24.285 + razor_files_sections,
24.286 + ARRAY_SIZE(razor_files_sections));
24.287 + default:
24.288 + return -1;
24.289 + }
24.290 +}
24.291 +
24.292 +int
24.293 +razor_set_write(struct razor_set *set, const char *filename,
24.294 + enum razor_repo_file_type type)
24.295 +{
24.296 + int fd, status;
24.297 +
24.298 + fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
24.299 + if (fd < 0)
24.300 + return -1;
24.301 +
24.302 + status = razor_set_write_to_fd(set, fd, type);
24.303 + if (status) {
24.304 + close(fd);
24.305 + return status;
24.306 + }
24.307 +
24.308 + return close(fd);
24.309 +}
24.310 +void
24.311 +razor_build_evr(char *evr_buf, int size, const char *epoch,
24.312 + const char *version, const char *release)
24.313 +{
24.314 + int len;
24.315 +
24.316 + if (!version || !*version) {
24.317 + *evr_buf = '\0';
24.318 + return;
24.319 + }
24.320 +
24.321 + if (epoch && *epoch && strcmp(epoch, "0") != 0) {
24.322 + len = snprintf(evr_buf, size, "%s:", epoch);
24.323 + evr_buf += len;
24.324 + size -= len;
24.325 + }
24.326 + len = snprintf(evr_buf, size, "%s", version);
24.327 + evr_buf += len;
24.328 + size -= len;
24.329 + if (release && *release)
24.330 + snprintf(evr_buf, size, "-%s", release);
24.331 +}
24.332 +
24.333 +int
24.334 +razor_versioncmp(const char *s1, const char *s2)
24.335 +{
24.336 + const char *p1, *p2;
24.337 + long n1, n2;
24.338 + int res;
24.339 +
24.340 + n1 = strtol(s1, (char **) &p1, 10);
24.341 + n2 = strtol(s2, (char **) &p2, 10);
24.342 +
24.343 + /* Epoch; if one but not the other has an epoch set, default
24.344 + * the epoch-less version to 0. */
24.345 + res = (*p1 == ':') - (*p2 == ':');
24.346 + if (res < 0) {
24.347 + n1 = 0;
24.348 + p1 = s1;
24.349 + p2++;
24.350 + } else if (res > 0) {
24.351 + p1++;
24.352 + n2 = 0;
24.353 + p2 = s2;
24.354 + }
24.355 +
24.356 + if (n1 != n2)
24.357 + return n1 - n2;
24.358 + while (*p1 && *p2) {
24.359 + if (*p1 != *p2)
24.360 + return *p1 - *p2;
24.361 + p1++;
24.362 + p2++;
24.363 + if (isdigit(*p1) && isdigit(*p2))
24.364 + return razor_versioncmp(p1, p2);
24.365 + }
24.366 +
24.367 + return *p1 - *p2;
24.368 +}
24.369 +
24.370 +struct razor_package *
24.371 +razor_set_get_package(struct razor_set *set, const char *package)
24.372 +{
24.373 + struct razor_package_iterator *pi;
24.374 + struct razor_package *p;
24.375 + const char *name, *version, *arch;
24.376 +
24.377 + pi = razor_package_iterator_create(set);
24.378 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
24.379 + if (strcmp(package, name) == 0)
24.380 + break;
24.381 + }
24.382 + razor_package_iterator_destroy(pi);
24.383 +
24.384 + return p;
24.385 +}
24.386 +
24.387 +void
24.388 +razor_package_get_details(struct razor_set *set, struct razor_package *package,
24.389 + const char **summary, const char **description,
24.390 + const char **url, const char **license)
24.391 +{
24.392 + const char *pool = set->details_string_pool.data;
24.393 +
24.394 + *summary = &pool[package->summary];
24.395 + *description = &pool[package->description];
24.396 + *url = &pool[package->url];
24.397 + *license = &pool[package->license];
24.398 +}
24.399 +
24.400 +struct razor_entry *
24.401 +razor_set_find_entry(struct razor_set *set,
24.402 + struct razor_entry *dir, const char *pattern)
24.403 +{
24.404 + struct razor_entry *e;
24.405 + const char *n, *pool = set->string_pool.data;
24.406 + int len;
24.407 +
24.408 + e = (struct razor_entry *) set->files.data + dir->start;
24.409 + do {
24.410 + n = pool + e->name;
24.411 + if (strcmp(pattern + 1, n) == 0)
24.412 + return e;
24.413 + len = strlen(n);
24.414 + if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
24.415 + pattern[len + 1] == '/') {
24.416 + return razor_set_find_entry(set, e, pattern + len + 1);
24.417 + }
24.418 + } while (!((e++)->flags & RAZOR_ENTRY_LAST));
24.419 +
24.420 + return NULL;
24.421 +}
24.422 +
24.423 +static void
24.424 +list_dir(struct razor_set *set, struct razor_entry *dir,
24.425 + char *prefix, const char *pattern)
24.426 +{
24.427 + struct razor_entry *e;
24.428 + const char *n, *pool = set->string_pool.data;
24.429 +
24.430 + e = (struct razor_entry *) set->files.data + dir->start;
24.431 + do {
24.432 + n = pool + e->name;
24.433 + if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0)
24.434 + continue;
24.435 + printf("%s/%s\n", prefix, n);
24.436 + if (e->start) {
24.437 + char *sub = prefix + strlen (prefix);
24.438 + *sub = '/';
24.439 + strcpy (sub + 1, n);
24.440 + list_dir(set, e, prefix, pattern);
24.441 + *sub = '\0';
24.442 + }
24.443 + } while (!((e++)->flags & RAZOR_ENTRY_LAST));
24.444 +}
24.445 +
24.446 +void
24.447 +razor_set_list_files(struct razor_set *set, const char *pattern)
24.448 +{
24.449 + struct razor_entry *e;
24.450 + char buffer[512], *p, *base;
24.451 +
24.452 + if (pattern == NULL || !strcmp (pattern, "/")) {
24.453 + buffer[0] = '\0';
24.454 + list_dir(set, set->files.data, buffer, NULL);
24.455 + return;
24.456 + }
24.457 +
24.458 + strcpy(buffer, pattern);
24.459 + e = razor_set_find_entry(set, set->files.data, buffer);
24.460 + if (e && e->start > 0) {
24.461 + base = NULL;
24.462 + } else {
24.463 + p = strrchr(buffer, '/');
24.464 + if (p) {
24.465 + *p = '\0';
24.466 + base = p + 1;
24.467 + } else {
24.468 + base = NULL;
24.469 + }
24.470 + }
24.471 + e = razor_set_find_entry(set, set->files.data, buffer);
24.472 + if (e->start != 0)
24.473 + list_dir(set, e, buffer, base);
24.474 +}
24.475 +
24.476 +static struct list *
24.477 +list_package_files(struct razor_set *set, struct list *r,
24.478 + struct razor_entry *dir, uint32_t end,
24.479 + char *prefix)
24.480 +{
24.481 + struct razor_entry *e, *f, *entries;
24.482 + uint32_t next, file;
24.483 + char *pool;
24.484 + int len;
24.485 +
24.486 + entries = (struct razor_entry *) set->files.data;
24.487 + pool = set->string_pool.data;
24.488 +
24.489 + e = entries + dir->start;
24.490 + do {
24.491 + if (entries + r->data == e) {
24.492 + printf("%s/%s\n", prefix, pool + e->name);
24.493 + r = list_next(r);
24.494 + if (!r)
24.495 + return NULL;
24.496 + if (r->data >= end)
24.497 + return r;
24.498 + }
24.499 + } while (!((e++)->flags & RAZOR_ENTRY_LAST));
24.500 +
24.501 + e = entries + dir->start;
24.502 + do {
24.503 + if (e->start == 0)
24.504 + continue;
24.505 +
24.506 + if (e->flags & RAZOR_ENTRY_LAST)
24.507 + next = end;
24.508 + else {
24.509 + f = e + 1;
24.510 + while (f->start == 0 && !(f->flags & RAZOR_ENTRY_LAST))
24.511 + f++;
24.512 + if (f->start == 0)
24.513 + next = end;
24.514 + else
24.515 + next = f->start;
24.516 + }
24.517 +
24.518 + file = r->data;
24.519 + if (e->start <= file && file < next) {
24.520 + len = strlen(prefix);
24.521 + prefix[len] = '/';
24.522 + strcpy(prefix + len + 1, pool + e->name);
24.523 + r = list_package_files(set, r, e, next, prefix);
24.524 + prefix[len] = '\0';
24.525 + }
24.526 + } while (!((e++)->flags & RAZOR_ENTRY_LAST) && r != NULL);
24.527 +
24.528 + return r;
24.529 +}
24.530 +
24.531 +void
24.532 +razor_set_list_package_files(struct razor_set *set, const char *name)
24.533 +{
24.534 + struct razor_package *package;
24.535 + struct list *r;
24.536 + uint32_t end;
24.537 + char buffer[512];
24.538 +
24.539 + package = razor_set_get_package(set, name);
24.540 +
24.541 + r = list_first(&package->files, &set->file_pool);
24.542 + end = set->files.size / sizeof (struct razor_entry);
24.543 + buffer[0] = '\0';
24.544 + list_package_files(set, r, set->files.data, end, buffer);
24.545 +}
24.546 +
24.547 +/* The diff order matters. We should sort the packages so that a
24.548 + * REMOVE of a package comes before the INSTALL, and so that all
24.549 + * requires for a package have been installed before the package.
24.550 + **/
24.551 +
24.552 +void
24.553 +razor_set_diff(struct razor_set *set, struct razor_set *upstream,
24.554 + razor_package_callback_t callback, void *data)
24.555 +{
24.556 + struct razor_package_iterator *pi1, *pi2;
24.557 + struct razor_package *p1, *p2;
24.558 + const char *name1, *name2, *version1, *version2, *arch1, *arch2;
24.559 + int res;
24.560 +
24.561 + pi1 = razor_package_iterator_create(set);
24.562 + pi2 = razor_package_iterator_create(upstream);
24.563 +
24.564 + razor_package_iterator_next(pi1, &p1, &name1, &version1, &arch1);
24.565 + razor_package_iterator_next(pi2, &p2, &name2, &version2, &arch2);
24.566 +
24.567 + while (p1 || p2) {
24.568 + if (p1 && p2) {
24.569 + res = strcmp(name1, name2);
24.570 + if (res == 0)
24.571 + res = razor_versioncmp(version1, version2);
24.572 + } else {
24.573 + res = 0;
24.574 + }
24.575 +
24.576 + if (p2 == NULL || res < 0)
24.577 + callback(name1, version1, NULL, arch1, data);
24.578 + else if (p1 == NULL || res > 0)
24.579 + callback(name2, NULL, version2, arch2, data);
24.580 +
24.581 + if (p1 != NULL && res <= 0)
24.582 + razor_package_iterator_next(pi1, &p1,
24.583 + &name1, &version1, &arch1);
24.584 + if (p2 != NULL && res >= 0)
24.585 + razor_package_iterator_next(pi2, &p2,
24.586 + &name2, &version2, &arch2);
24.587 + }
24.588 +
24.589 + razor_package_iterator_destroy(pi1);
24.590 + razor_package_iterator_destroy(pi2);
24.591 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/librazor/razor.h Fri Jun 20 19:04:47 2008 -0400
25.3 @@ -0,0 +1,218 @@
25.4 +/*
25.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
25.6 + * Copyright (C) 2008 Red Hat, Inc
25.7 + *
25.8 + * This program is free software; you can redistribute it and/or modify
25.9 + * it under the terms of the GNU General Public License as published by
25.10 + * the Free Software Foundation; either version 2 of the License, or
25.11 + * (at your option) any later version.
25.12 + *
25.13 + * This program is distributed in the hope that it will be useful,
25.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
25.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25.16 + * GNU General Public License for more details.
25.17 + *
25.18 + * You should have received a copy of the GNU General Public License along
25.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
25.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25.21 + */
25.22 +
25.23 +#ifndef _RAZOR_H_
25.24 +#define _RAZOR_H_
25.25 +
25.26 +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
25.27 +
25.28 +struct razor_set;
25.29 +struct razor_package;
25.30 +struct razor_property;
25.31 +
25.32 +enum razor_repo_file_type {
25.33 + RAZOR_REPO_FILE_MAIN,
25.34 + RAZOR_REPO_FILE_DETAILS,
25.35 + RAZOR_REPO_FILE_FILES
25.36 +};
25.37 +
25.38 +enum razor_property_flags {
25.39 + RAZOR_PROPERTY_LESS = 1 << 0,
25.40 + RAZOR_PROPERTY_GREATER = 1 << 1,
25.41 + RAZOR_PROPERTY_EQUAL = 1 << 2,
25.42 + RAZOR_PROPERTY_RELATION_MASK =
25.43 + RAZOR_PROPERTY_LESS |
25.44 + RAZOR_PROPERTY_GREATER |
25.45 + RAZOR_PROPERTY_EQUAL,
25.46 +
25.47 + RAZOR_PROPERTY_REQUIRES = 0 << 3,
25.48 + RAZOR_PROPERTY_PROVIDES = 1 << 3,
25.49 + RAZOR_PROPERTY_CONFLICTS = 2 << 3,
25.50 + RAZOR_PROPERTY_OBSOLETES = 3 << 3,
25.51 + RAZOR_PROPERTY_TYPE_MASK = 3 << 3,
25.52 +
25.53 + RAZOR_PROPERTY_PRE = 1 << 5,
25.54 + RAZOR_PROPERTY_POST = 1 << 6,
25.55 + RAZOR_PROPERTY_PREUN = 1 << 7,
25.56 + RAZOR_PROPERTY_POSTUN = 1 << 8
25.57 +};
25.58 +
25.59 +const char *
25.60 +razor_property_relation_to_string(struct razor_property *p);
25.61 +const char *
25.62 +razor_property_type_to_string(struct razor_property *p);
25.63 +
25.64 +struct razor_set *razor_set_create(void);
25.65 +struct razor_set *razor_set_open(const char *filename);
25.66 +void razor_set_destroy(struct razor_set *set);
25.67 +int razor_set_write_to_fd(struct razor_set *set, int fd,
25.68 + enum razor_repo_file_type type);
25.69 +int razor_set_write(struct razor_set *set, const char *filename,
25.70 + enum razor_repo_file_type type);
25.71 +
25.72 +void razor_set_open_details(struct razor_set *set, const char *filename);
25.73 +void razor_set_open_files(struct razor_set *set, const char *filename);
25.74 +
25.75 +struct razor_package *
25.76 +razor_set_get_package(struct razor_set *set, const char *package);
25.77 +
25.78 +void
25.79 +razor_package_get_details(struct razor_set *set, struct razor_package *package,
25.80 + const char **summary, const char **description,
25.81 + const char **url, const char **license);
25.82 +
25.83 +struct razor_package_iterator;
25.84 +struct razor_package_iterator *
25.85 +razor_package_iterator_create(struct razor_set *set);
25.86 +struct razor_package_iterator *
25.87 +razor_package_iterator_create_for_property(struct razor_set *set,
25.88 + struct razor_property *property);
25.89 +struct razor_package_iterator *
25.90 +razor_package_iterator_create_for_file(struct razor_set *set,
25.91 + const char *filename);
25.92 +
25.93 +int razor_package_iterator_next(struct razor_package_iterator *pi,
25.94 + struct razor_package **package,
25.95 + const char **name,
25.96 + const char **version,
25.97 + const char **arch);
25.98 +void razor_package_iterator_destroy(struct razor_package_iterator *pi);
25.99 +
25.100 +struct razor_package_query *
25.101 +razor_package_query_create(struct razor_set *set);
25.102 +void
25.103 +razor_package_query_add_package(struct razor_package_query *pq,
25.104 + struct razor_package *p);
25.105 +void
25.106 +razor_package_query_add_iterator(struct razor_package_query *pq,
25.107 + struct razor_package_iterator *pi);
25.108 +struct razor_package_iterator *
25.109 +razor_package_query_finish(struct razor_package_query *pq);
25.110 +
25.111 +struct razor_property_iterator;
25.112 +struct razor_property_iterator *
25.113 +razor_property_iterator_create(struct razor_set *set,
25.114 + struct razor_package *package);
25.115 +int razor_property_iterator_next(struct razor_property_iterator *pi,
25.116 + struct razor_property **property,
25.117 + const char **name,
25.118 + uint32_t *flags,
25.119 + const char **version);
25.120 +void
25.121 +razor_property_iterator_destroy(struct razor_property_iterator *pi);
25.122 +
25.123 +void razor_set_list_files(struct razor_set *set, const char *prefix);
25.124 +void razor_set_list_package_files(struct razor_set *set, const char *name);
25.125 +
25.126 +void razor_set_list_unsatisfied(struct razor_set *set);
25.127 +
25.128 +typedef void (*razor_package_callback_t)(const char *name,
25.129 + const char *old_version,
25.130 + const char *new_version,
25.131 + const char *arch,
25.132 + void *data);
25.133 +void
25.134 +razor_set_diff(struct razor_set *set, struct razor_set *upstream,
25.135 + razor_package_callback_t callback, void *data);
25.136 +
25.137 +/* Package transactions */
25.138 +
25.139 +struct razor_transaction *
25.140 +razor_transaction_create(struct razor_set *system, struct razor_set *upstream);
25.141 +void razor_transaction_install_package(struct razor_transaction *transaction,
25.142 + struct razor_package *package);
25.143 +void razor_transaction_remove_package(struct razor_transaction *transaction,
25.144 + struct razor_package *package);
25.145 +void razor_transaction_update_package(struct razor_transaction *trans,
25.146 + struct razor_package *package);
25.147 +void razor_transaction_update_all(struct razor_transaction *transaction);
25.148 +int razor_transaction_resolve(struct razor_transaction *trans);
25.149 +int razor_transaction_describe(struct razor_transaction *trans);
25.150 +struct razor_set *razor_transaction_finish(struct razor_transaction *trans);
25.151 +void razor_transaction_destroy(struct razor_transaction *trans);
25.152 +
25.153 +/* Temporary helper for test suite. */
25.154 +int razor_transaction_unsatisfied_property(struct razor_transaction *trans,
25.155 + const char *name,
25.156 + uint32_t flags,
25.157 + const char *version);
25.158 +
25.159 +/* Importer interface; for building a razor set from external sources,
25.160 + * like yum, rpmdb or razor package files. */
25.161 +
25.162 +struct razor_importer;
25.163 +struct razor_rpm;
25.164 +
25.165 +struct razor_importer *razor_importer_new(void);
25.166 +void razor_importer_destroy(struct razor_importer *importer);
25.167 +void razor_importer_begin_package(struct razor_importer *importer,
25.168 + const char *name,
25.169 + const char *version,
25.170 + const char *arch);
25.171 +void razor_importer_add_details(struct razor_importer *importer,
25.172 + const char *summary,
25.173 + const char *description,
25.174 + const char *url,
25.175 + const char *license);
25.176 +void razor_importer_add_property(struct razor_importer *importer,
25.177 + const char *name,
25.178 + uint32_t flags,
25.179 + const char *version);
25.180 +void razor_importer_add_file(struct razor_importer *importer,
25.181 + const char *name);
25.182 +void razor_importer_finish_package(struct razor_importer *importer);
25.183 +
25.184 +int razor_importer_add_rpm(struct razor_importer *importer,
25.185 + struct razor_rpm *rpm);
25.186 +
25.187 +struct razor_set *razor_importer_finish(struct razor_importer *importer);
25.188 +
25.189 +void razor_build_evr(char *evr_buf, int size, const char *epoch,
25.190 + const char *version, const char *release);
25.191 +int razor_versioncmp(const char *s1, const char *s2);
25.192 +
25.193 +struct razor_set *razor_set_create_from_yum(void);
25.194 +struct razor_set *razor_set_create_from_rpmdb(void);
25.195 +
25.196 +/* RPM functions */
25.197 +
25.198 +struct razor_rpm *razor_rpm_open(const char *filename);
25.199 +int razor_rpm_install(struct razor_rpm *rpm, const char *root);
25.200 +int razor_rpm_close(struct razor_rpm *rpm);
25.201 +
25.202 +
25.203 +/* Razor root functions. The root data struct encapsulates filesystem
25.204 + * conventions and the locking protocol. */
25.205 +
25.206 +struct razor_root;
25.207 +#define RAZOR_ROOT_OPEN_WRITE 0x01
25.208 +
25.209 +int razor_root_create(const char *root);
25.210 +struct razor_root *razor_root_open(const char *root, int flags);
25.211 +struct razor_set *razor_root_open_read_only(const char *root);
25.212 +struct razor_transaction *
25.213 +razor_root_create_transaction(struct razor_root *image,
25.214 + struct razor_set *upstream);
25.215 +int razor_root_close(struct razor_root *image);
25.216 +void razor_root_update(struct razor_root *image, struct razor_set *next);
25.217 +int razor_root_commit(struct razor_root *image);
25.218 +void razor_root_diff(struct razor_root *root,
25.219 + razor_package_callback_t callback, void *data);
25.220 +
25.221 +#endif /* _RAZOR_H_ */
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/librazor/root.c Fri Jun 20 19:04:47 2008 -0400
26.3 @@ -0,0 +1,168 @@
26.4 +#include <stdlib.h>
26.5 +#include <stdint.h>
26.6 +#include <stdio.h>
26.7 +#include <sys/stat.h>
26.8 +#include <dirent.h>
26.9 +#include <unistd.h>
26.10 +#include <fcntl.h>
26.11 +#include "razor.h"
26.12 +#include "razor-internal.h"
26.13 +
26.14 +static const char system_repo_filename[] = "system.repo";
26.15 +static const char next_repo_filename[] = "system-next.repo";
26.16 +static const char razor_root_path[] = "/var/lib/razor";
26.17 +
26.18 +struct razor_root {
26.19 + struct razor_set *system;
26.20 + struct razor_set *next;
26.21 + int fd;
26.22 + char path[PATH_MAX];
26.23 + char new_path[PATH_MAX];
26.24 +};
26.25 +
26.26 +int
26.27 +razor_root_create(const char *root)
26.28 +{
26.29 + struct stat buf;
26.30 + struct razor_set *set;
26.31 + char path[PATH_MAX];
26.32 +
26.33 + if (stat(root, &buf) < 0) {
26.34 + if (mkdir(root, 0777) < 0) {
26.35 + fprintf(stderr,
26.36 + "could not create install root \"%s\"\n",
26.37 + root);
26.38 + return -1;
26.39 + }
26.40 + fprintf(stderr, "created install root \"%s\"\n", root);
26.41 + } else if (!S_ISDIR(buf.st_mode)) {
26.42 + fprintf(stderr,
26.43 + "install root \"%s\" exists, but is not a directory\n",
26.44 + root);
26.45 + return -1;
26.46 + }
26.47 +
26.48 + snprintf(path, sizeof path, "%s/%s",
26.49 + razor_root_path, system_repo_filename);
26.50 + if (razor_create_dir(root, path) < 0) {
26.51 + fprintf(stderr, "could not create %s%s\n",
26.52 + root, razor_root_path);
26.53 + return -1;
26.54 + }
26.55 +
26.56 + set = razor_set_create();
26.57 + snprintf(path, sizeof path, "%s%s/%s",
26.58 + root, razor_root_path, system_repo_filename);
26.59 + if (stat(path, &buf) == 0) {
26.60 + fprintf(stderr,
26.61 + "a razor install root is already initialized\n");
26.62 + return -1;
26.63 + }
26.64 + if (razor_set_write(set, path, RAZOR_REPO_FILE_MAIN) < 0) {
26.65 + fprintf(stderr, "could not write initial package set\n");
26.66 + return -1;
26.67 + }
26.68 + razor_set_destroy(set);
26.69 +
26.70 + return 0;
26.71 +}
26.72 +
26.73 +struct razor_root *
26.74 +razor_root_open(const char *root, int flags)
26.75 +{
26.76 + struct razor_root *image;
26.77 +
26.78 + image = malloc(sizeof *image);
26.79 + if (image == NULL)
26.80 + return NULL;
26.81 +
26.82 + /* Create the new next repo file up front to ensure exclusive
26.83 + * access. */
26.84 + snprintf(image->new_path, sizeof image->new_path,
26.85 + "%s%s/%s", root, razor_root_path, next_repo_filename);
26.86 + image->fd = open(image->new_path,
26.87 + O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
26.88 + if (image->fd < 0) {
26.89 + fprintf(stderr, "failed to get lock file, "
26.90 + "maybe previous operation crashed?\n");
26.91 +
26.92 + /* FIXME: Use fcntl advisory locking on the system
26.93 + * package set file to figure out whether previous
26.94 + * operation crashed or is still in progress. */
26.95 +
26.96 + free(image);
26.97 + return NULL;
26.98 + }
26.99 +
26.100 + snprintf(image->path, sizeof image->path,
26.101 + "%s%s/%s", root, razor_root_path, system_repo_filename);
26.102 + image->system = razor_set_open(image->path);
26.103 + if (image->system == NULL) {
26.104 + unlink(image->new_path);
26.105 + close(image->fd);
26.106 + free(image);
26.107 + return NULL;
26.108 + }
26.109 +
26.110 + return image;
26.111 +}
26.112 +
26.113 +struct razor_set *
26.114 +razor_root_open_read_only(const char *root)
26.115 +{
26.116 + char path[PATH_MAX];
26.117 +
26.118 + snprintf(path, sizeof path, "%s%s/%s",
26.119 + root, razor_root_path, system_repo_filename);
26.120 +
26.121 + return razor_set_open(path);
26.122 +}
26.123 +
26.124 +struct razor_transaction *
26.125 +razor_root_create_transaction(struct razor_root *image,
26.126 + struct razor_set *upstream)
26.127 +{
26.128 + /* FIXME: This should take a number of upstream repos. */
26.129 + return razor_transaction_create(image->system, upstream);
26.130 +}
26.131 +
26.132 +int
26.133 +razor_root_close(struct razor_root *image)
26.134 +{
26.135 + unlink(image->new_path);
26.136 + close(image->fd);
26.137 + free(image);
26.138 +
26.139 + return 0;
26.140 +}
26.141 +
26.142 +void
26.143 +razor_root_update(struct razor_root *root, struct razor_set *next)
26.144 +{
26.145 + razor_set_write_to_fd(next, root->fd, RAZOR_REPO_FILE_MAIN);
26.146 + root->next = next;
26.147 +
26.148 + /* Sync the new repo file so the new package set is on disk
26.149 + * before we start upgrading. */
26.150 + fsync(root->fd);
26.151 + printf("wrote %s\n", root->new_path);
26.152 +}
26.153 +
26.154 +int
26.155 +razor_root_commit(struct razor_root *image)
26.156 +{
26.157 + /* Make it so. */
26.158 + rename(image->new_path, image->path);
26.159 + printf("renamed %s to %s\n", image->new_path, image->path);
26.160 + close(image->fd);
26.161 + free(image);
26.162 +
26.163 + return 0;
26.164 +}
26.165 +
26.166 +void
26.167 +razor_root_diff(struct razor_root *root,
26.168 + razor_package_callback_t callback, void *data)
26.169 +{
26.170 + return razor_set_diff(root->system, root->next, callback, data);
26.171 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/librazor/rpm.c Fri Jun 20 19:04:47 2008 -0400
27.3 @@ -0,0 +1,828 @@
27.4 +/*
27.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
27.6 + * Copyright (C) 2008 Red Hat, Inc
27.7 + *
27.8 + * This program is free software; you can redistribute it and/or modify
27.9 + * it under the terms of the GNU General Public License as published by
27.10 + * the Free Software Foundation; either version 2 of the License, or
27.11 + * (at your option) any later version.
27.12 + *
27.13 + * This program is distributed in the hope that it will be useful,
27.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
27.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27.16 + * GNU General Public License for more details.
27.17 + *
27.18 + * You should have received a copy of the GNU General Public License along
27.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
27.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27.21 + */
27.22 +
27.23 +#include <stdio.h>
27.24 +#include <stddef.h>
27.25 +#include <stdlib.h>
27.26 +#include <string.h>
27.27 +#include <errno.h>
27.28 +#include <sys/stat.h>
27.29 +#include <sys/mman.h>
27.30 +#include <sys/types.h>
27.31 +#include <sys/wait.h>
27.32 +#include <fcntl.h>
27.33 +#include <dirent.h>
27.34 +#include <unistd.h>
27.35 +#include <arpa/inet.h>
27.36 +#include <zlib.h>
27.37 +
27.38 +#include "razor.h"
27.39 +#include "razor-internal.h"
27.40 +
27.41 +#define RPM_LEAD_SIZE 96
27.42 +
27.43 +enum {
27.44 + PIPE = 1, /*!< pipe/fifo */
27.45 + CDEV = 2, /*!< character device */
27.46 + XDIR = 4, /*!< directory */
27.47 + BDEV = 6, /*!< block device */
27.48 + REG = 8, /*!< regular file */
27.49 + LINK = 10, /*!< hard link */
27.50 + SOCK = 12 /*!< socket */
27.51 +};
27.52 +
27.53 +enum {
27.54 + RPMSENSE_LESS = 1 << 1,
27.55 + RPMSENSE_GREATER = 1 << 2,
27.56 + RPMSENSE_EQUAL = 1 << 3,
27.57 + RPMSENSE_PREREQ = 1 << 6,
27.58 + RPMSENSE_SCRIPT_PRE = 1 << 9,
27.59 + RPMSENSE_SCRIPT_POST = 1 << 10,
27.60 + RPMSENSE_SCRIPT_PREUN = 1 << 11,
27.61 + RPMSENSE_SCRIPT_POSTUN = 1 << 12,
27.62 +};
27.63 +
27.64 +enum {
27.65 + RPMTAG_NAME = 1000, /* s */
27.66 + RPMTAG_VERSION = 1001, /* s */
27.67 + RPMTAG_RELEASE = 1002, /* s */
27.68 + RPMTAG_EPOCH = 1003, /* i */
27.69 + RPMTAG_SUMMARY = 1004, /* s{} */
27.70 + RPMTAG_DESCRIPTION = 1005, /* s{} */
27.71 + RPMTAG_BUILDTIME = 1006, /* i */
27.72 + RPMTAG_BUILDHOST = 1007, /* s */
27.73 + RPMTAG_INSTALLTIME = 1008, /* i */
27.74 + RPMTAG_SIZE = 1009, /* i */
27.75 + RPMTAG_DISTRIBUTION = 1010, /* s */
27.76 + RPMTAG_VENDOR = 1011, /* s */
27.77 + RPMTAG_GIF = 1012, /* x */
27.78 + RPMTAG_XPM = 1013, /* x */
27.79 + RPMTAG_LICENSE = 1014, /* s */
27.80 + RPMTAG_PACKAGER = 1015, /* s */
27.81 + RPMTAG_GROUP = 1016, /* s{} */
27.82 + RPMTAG_CHANGELOG = 1017, /*!< s[] internal */
27.83 + RPMTAG_SOURCE = 1018, /* s[] */
27.84 + RPMTAG_PATCH = 1019, /* s[] */
27.85 + RPMTAG_URL = 1020, /* s */
27.86 + RPMTAG_OS = 1021, /* s legacy used int */
27.87 + RPMTAG_ARCH = 1022, /* s legacy used int */
27.88 + RPMTAG_PREIN = 1023, /* s */
27.89 + RPMTAG_POSTIN = 1024, /* s */
27.90 + RPMTAG_PREUN = 1025, /* s */
27.91 + RPMTAG_POSTUN = 1026, /* s */
27.92 + RPMTAG_OLDFILENAMES = 1027, /* s[] obsolete */
27.93 + RPMTAG_FILESIZES = 1028, /* i */
27.94 + RPMTAG_FILESTATES = 1029, /* c */
27.95 + RPMTAG_FILEMODES = 1030, /* h */
27.96 + RPMTAG_FILEUIDS = 1031, /*!< internal */
27.97 + RPMTAG_FILEGIDS = 1032, /*!< internal */
27.98 + RPMTAG_FILERDEVS = 1033, /* h */
27.99 + RPMTAG_FILEMTIMES = 1034, /* i */
27.100 + RPMTAG_FILEMD5S = 1035, /* s[] */
27.101 + RPMTAG_FILELINKTOS = 1036, /* s[] */
27.102 + RPMTAG_FILEFLAGS = 1037, /* i */
27.103 + RPMTAG_ROOT = 1038, /*!< internal - obsolete */
27.104 + RPMTAG_FILEUSERNAME = 1039, /* s[] */
27.105 + RPMTAG_FILEGROUPNAME = 1040, /* s[] */
27.106 + RPMTAG_EXCLUDE = 1041, /*!< internal - obsolete */
27.107 + RPMTAG_EXCLUSIVE = 1042, /*!< internal - obsolete */
27.108 + RPMTAG_ICON = 1043,
27.109 + RPMTAG_SOURCERPM = 1044, /* s */
27.110 + RPMTAG_FILEVERIFYFLAGS = 1045, /* i */
27.111 + RPMTAG_ARCHIVESIZE = 1046, /* i */
27.112 + RPMTAG_PROVIDENAME = 1047, /* s[] */
27.113 + RPMTAG_REQUIREFLAGS = 1048, /* i */
27.114 + RPMTAG_REQUIRENAME = 1049, /* s[] */
27.115 + RPMTAG_REQUIREVERSION = 1050, /* s[] */
27.116 + RPMTAG_NOSOURCE = 1051, /*!< internal */
27.117 + RPMTAG_NOPATCH = 1052, /*!< internal */
27.118 + RPMTAG_CONFLICTFLAGS = 1053, /* i */
27.119 + RPMTAG_CONFLICTNAME = 1054, /* s[] */
27.120 + RPMTAG_CONFLICTVERSION = 1055, /* s[] */
27.121 + RPMTAG_DEFAULTPREFIX = 1056, /*!< internal - deprecated */
27.122 + RPMTAG_BUILDROOT = 1057, /*!< internal */
27.123 + RPMTAG_INSTALLPREFIX = 1058, /*!< internal - deprecated */
27.124 + RPMTAG_EXCLUDEARCH = 1059,
27.125 + RPMTAG_EXCLUDEOS = 1060,
27.126 + RPMTAG_EXCLUSIVEARCH = 1061,
27.127 + RPMTAG_EXCLUSIVEOS = 1062,
27.128 + RPMTAG_AUTOREQPROV = 1063, /*!< internal */
27.129 + RPMTAG_RPMVERSION = 1064, /* s */
27.130 + RPMTAG_TRIGGERSCRIPTS = 1065, /* s[] */
27.131 + RPMTAG_TRIGGERNAME = 1066, /* s[] */
27.132 + RPMTAG_TRIGGERVERSION = 1067, /* s[] */
27.133 + RPMTAG_TRIGGERFLAGS = 1068, /* i */
27.134 + RPMTAG_TRIGGERINDEX = 1069, /* i */
27.135 + RPMTAG_VERIFYSCRIPT = 1079, /* s */
27.136 + RPMTAG_CHANGELOGTIME = 1080, /* i */
27.137 + RPMTAG_CHANGELOGNAME = 1081, /* s[] */
27.138 + RPMTAG_CHANGELOGTEXT = 1082, /* s[] */
27.139 + RPMTAG_BROKENMD5 = 1083, /*!< internal - obsolete */
27.140 + RPMTAG_PREREQ = 1084, /*!< internal */
27.141 + RPMTAG_PREINPROG = 1085, /* s */
27.142 + RPMTAG_POSTINPROG = 1086, /* s */
27.143 + RPMTAG_PREUNPROG = 1087, /* s */
27.144 + RPMTAG_POSTUNPROG = 1088, /* s */
27.145 + RPMTAG_BUILDARCHS = 1089,
27.146 + RPMTAG_OBSOLETENAME = 1090, /* s[] */
27.147 + RPMTAG_VERIFYSCRIPTPROG = 1091, /* s */
27.148 + RPMTAG_TRIGGERSCRIPTPROG = 1092, /* s */
27.149 + RPMTAG_DOCDIR = 1093, /*!< internal */
27.150 + RPMTAG_COOKIE = 1094, /* s */
27.151 + RPMTAG_FILEDEVICES = 1095, /* i */
27.152 + RPMTAG_FILEINODES = 1096, /* i */
27.153 + RPMTAG_FILELANGS = 1097, /* s[] */
27.154 + RPMTAG_PREFIXES = 1098, /* s[] */
27.155 + RPMTAG_INSTPREFIXES = 1099, /* s[] */
27.156 + RPMTAG_TRIGGERIN = 1100, /*!< internal */
27.157 + RPMTAG_TRIGGERUN = 1101, /*!< internal */
27.158 + RPMTAG_TRIGGERPOSTUN = 1102, /*!< internal */
27.159 + RPMTAG_AUTOREQ = 1103, /*!< internal */
27.160 + RPMTAG_AUTOPROV = 1104, /*!< internal */
27.161 + RPMTAG_CAPABILITY = 1105, /*!< internal - obsolete */
27.162 + RPMTAG_SOURCEPACKAGE = 1106, /*!< i src.rpm header marker */
27.163 + RPMTAG_OLDORIGFILENAMES = 1107, /*!< internal - obsolete */
27.164 + RPMTAG_BUILDPREREQ = 1108, /*!< internal */
27.165 + RPMTAG_BUILDREQUIRES = 1109, /*!< internal */
27.166 + RPMTAG_BUILDCONFLICTS = 1110, /*!< internal */
27.167 + RPMTAG_BUILDMACROS = 1111, /*!< internal - unused */
27.168 + RPMTAG_PROVIDEFLAGS = 1112, /* i */
27.169 + RPMTAG_PROVIDEVERSION = 1113, /* s[] */
27.170 + RPMTAG_OBSOLETEFLAGS = 1114, /* i */
27.171 + RPMTAG_OBSOLETEVERSION = 1115, /* s[] */
27.172 + RPMTAG_DIRINDEXES = 1116, /* i */
27.173 + RPMTAG_BASENAMES = 1117, /* s[] */
27.174 + RPMTAG_DIRNAMES = 1118, /* s[] */
27.175 + RPMTAG_ORIGDIRINDEXES = 1119, /*!< internal */
27.176 + RPMTAG_ORIGBASENAMES = 1120, /*!< internal */
27.177 + RPMTAG_ORIGDIRNAMES = 1121, /*!< internal */
27.178 + RPMTAG_OPTFLAGS = 1122, /* s */
27.179 + RPMTAG_DISTURL = 1123, /* s */
27.180 + RPMTAG_PAYLOADFORMAT = 1124, /* s */
27.181 + RPMTAG_PAYLOADCOMPRESSOR = 1125, /* s */
27.182 + RPMTAG_PAYLOADFLAGS = 1126, /* s */
27.183 + RPMTAG_INSTALLCOLOR = 1127, /*!< i transaction color when installed */
27.184 + RPMTAG_INSTALLTID = 1128, /* i */
27.185 + RPMTAG_REMOVETID = 1129, /* i */
27.186 + RPMTAG_SHA1RHN = 1130, /*!< internal - obsolete */
27.187 + RPMTAG_RHNPLATFORM = 1131, /* s */
27.188 + RPMTAG_PLATFORM = 1132, /* s */
27.189 + RPMTAG_PATCHESNAME = 1133, /*!< placeholder (SuSE) */
27.190 + RPMTAG_PATCHESFLAGS = 1134, /*!< placeholder (SuSE) */
27.191 + RPMTAG_PATCHESVERSION = 1135, /*!< placeholder (SuSE) */
27.192 + RPMTAG_CACHECTIME = 1136, /* i */
27.193 + RPMTAG_CACHEPKGPATH = 1137, /* s */
27.194 + RPMTAG_CACHEPKGSIZE = 1138, /* i */
27.195 + RPMTAG_CACHEPKGMTIME = 1139, /* i */
27.196 + RPMTAG_FILECOLORS = 1140, /* i */
27.197 + RPMTAG_FILECLASS = 1141, /* i */
27.198 + RPMTAG_CLASSDICT = 1142, /* s[] */
27.199 + RPMTAG_FILEDEPENDSX = 1143, /* i */
27.200 + RPMTAG_FILEDEPENDSN = 1144, /* i */
27.201 + RPMTAG_DEPENDSDICT = 1145, /* i */
27.202 + RPMTAG_SOURCEPKGID = 1146, /* x */
27.203 + RPMTAG_FILECONTEXTS = 1147, /* s[] */
27.204 + RPMTAG_FSCONTEXTS = 1148, /*!< s[] extension */
27.205 + RPMTAG_RECONTEXTS = 1149, /*!< s[] extension */
27.206 + RPMTAG_POLICIES = 1150, /*!< s[] selinux *.te policy file. */
27.207 + RPMTAG_PRETRANS = 1151, /* s */
27.208 + RPMTAG_POSTTRANS = 1152, /* s */
27.209 + RPMTAG_PRETRANSPROG = 1153, /* s */
27.210 + RPMTAG_POSTTRANSPROG = 1154, /* s */
27.211 + RPMTAG_DISTTAG = 1155, /* s */
27.212 + RPMTAG_SUGGESTSNAME = 1156, /* s[] extension placeholder */
27.213 + RPMTAG_SUGGESTSVERSION = 1157, /* s[] extension placeholder */
27.214 + RPMTAG_SUGGESTSFLAGS = 1158, /* i extension placeholder */
27.215 + RPMTAG_ENHANCESNAME = 1159, /* s[] extension placeholder */
27.216 + RPMTAG_ENHANCESVERSION = 1160, /* s[] extension placeholder */
27.217 + RPMTAG_ENHANCESFLAGS = 1161, /* i extension placeholder */
27.218 + RPMTAG_PRIORITY = 1162, /* i extension placeholder */
27.219 + RPMTAG_CVSID = 1163, /* s */
27.220 + RPMTAG_TRIGGERPREIN = 1171, /*!< internal */
27.221 +};
27.222 +
27.223 +struct rpm_header {
27.224 + unsigned char magic[4];
27.225 + unsigned char reserved[4];
27.226 + int nindex;
27.227 + int hsize;
27.228 +};
27.229 +
27.230 +struct rpm_header_index {
27.231 + int tag;
27.232 + int type;
27.233 + int offset;
27.234 + int count;
27.235 +};
27.236 +
27.237 +struct razor_rpm {
27.238 + struct rpm_header *signature;
27.239 + struct rpm_header *header;
27.240 + const char **dirs;
27.241 + const char *pool;
27.242 + void *map;
27.243 + size_t size;
27.244 + void *payload;
27.245 +};
27.246 +
27.247 +static struct rpm_header_index *
27.248 +razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
27.249 +{
27.250 + struct rpm_header_index *index, *end;
27.251 +
27.252 + index = (struct rpm_header_index *) (rpm->header + 1);
27.253 + end = index + ntohl(rpm->header->nindex);
27.254 + while (index < end) {
27.255 + if (ntohl(index->tag) == tag)
27.256 + return index;
27.257 + index++;
27.258 + }
27.259 +
27.260 + return NULL;
27.261 +}
27.262 +
27.263 +static const void *
27.264 +razor_rpm_get_indirect(struct razor_rpm *rpm,
27.265 + unsigned int tag, unsigned int *count)
27.266 +{
27.267 + struct rpm_header_index *index;
27.268 +
27.269 + index = razor_rpm_get_header(rpm, tag);
27.270 + if (index != NULL) {
27.271 + if (count)
27.272 + *count = ntohl(index->count);
27.273 +
27.274 + return rpm->pool + ntohl(index->offset);
27.275 + }
27.276 +
27.277 + return NULL;
27.278 +}
27.279 +
27.280 +static uint32_t
27.281 +rpm_to_razor_flags(uint32_t flags)
27.282 +{
27.283 + uint32_t razor_flags;
27.284 +
27.285 + razor_flags = 0;
27.286 + if (flags & RPMSENSE_LESS)
27.287 + razor_flags |= RAZOR_PROPERTY_LESS;
27.288 + if (flags & RPMSENSE_EQUAL)
27.289 + razor_flags |= RAZOR_PROPERTY_EQUAL;
27.290 + if (flags & RPMSENSE_GREATER)
27.291 + razor_flags |= RAZOR_PROPERTY_GREATER;
27.292 +
27.293 + if (flags & RPMSENSE_SCRIPT_PRE)
27.294 + razor_flags |= RAZOR_PROPERTY_PRE;
27.295 + if (flags & RPMSENSE_SCRIPT_POST)
27.296 + razor_flags |= RAZOR_PROPERTY_POST;
27.297 + if (flags & RPMSENSE_SCRIPT_PREUN)
27.298 + razor_flags |= RAZOR_PROPERTY_PREUN;
27.299 + if (flags & RPMSENSE_SCRIPT_POSTUN)
27.300 + razor_flags |= RAZOR_PROPERTY_POSTUN;
27.301 +
27.302 + return razor_flags;
27.303 +}
27.304 +
27.305 +static void
27.306 +import_properties(struct razor_importer *importer, uint32_t type,
27.307 + struct razor_rpm *rpm,
27.308 + int name_tag, int version_tag, int flags_tag)
27.309 +{
27.310 + const char *name, *version;
27.311 + const uint32_t *flags;
27.312 + uint32_t f;
27.313 + unsigned int i, count;
27.314 +
27.315 + name = razor_rpm_get_indirect(rpm, name_tag, &count);
27.316 + if (name == NULL)
27.317 + return;
27.318 +
27.319 + flags = razor_rpm_get_indirect(rpm, flags_tag, &count);
27.320 +
27.321 + version = razor_rpm_get_indirect(rpm, version_tag, &count);
27.322 + for (i = 0; i < count; i++) {
27.323 + f = rpm_to_razor_flags(ntohl(flags[i]));
27.324 + razor_importer_add_property(importer, name, f | type, version);
27.325 + name += strlen(name) + 1;
27.326 + version += strlen(version) + 1;
27.327 + }
27.328 +}
27.329 +
27.330 +static void
27.331 +import_files(struct razor_importer *importer, struct razor_rpm *rpm)
27.332 +{
27.333 + const char *name;
27.334 + const uint32_t *index;
27.335 + unsigned int i, count;
27.336 + char buffer[256];
27.337 +
27.338 + if (rpm->dirs == NULL)
27.339 + return;
27.340 +
27.341 + /* assert: count is the same for all arrays */
27.342 + index = razor_rpm_get_indirect(rpm, RPMTAG_DIRINDEXES, &count);
27.343 + name = razor_rpm_get_indirect(rpm, RPMTAG_BASENAMES, &count);
27.344 + for (i = 0; i < count; i++) {
27.345 + snprintf(buffer, sizeof buffer,
27.346 + "%s%s", rpm->dirs[ntohl(*index)], name);
27.347 + razor_importer_add_file(importer, buffer);
27.348 + name += strlen(name) + 1;
27.349 + index++;
27.350 + }
27.351 +}
27.352 +
27.353 +struct razor_rpm *
27.354 +razor_rpm_open(const char *filename)
27.355 +{
27.356 + struct razor_rpm *rpm;
27.357 + struct rpm_header_index *base, *index;
27.358 + struct stat buf;
27.359 + unsigned int count, i, nindex, hsize;
27.360 + const char *name;
27.361 + int fd;
27.362 +
27.363 + rpm = malloc(sizeof *rpm);
27.364 + if (rpm == NULL)
27.365 + return NULL;
27.366 + memset(rpm, 0, sizeof *rpm);
27.367 +
27.368 + fd = open(filename, O_RDONLY);
27.369 + if (fd < 0) {
27.370 + fprintf(stderr, "couldn't open %s\n", filename);
27.371 + return NULL;
27.372 + }
27.373 +
27.374 + if (fstat(fd, &buf) < 0) {
27.375 + fprintf(stderr, "failed to stat %s (%m)\n", filename);
27.376 + return NULL;
27.377 + }
27.378 +
27.379 + rpm->size = buf.st_size;
27.380 + rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
27.381 + if (rpm->map == MAP_FAILED) {
27.382 + fprintf(stderr, "couldn't mmap %s\n", filename);
27.383 + return NULL;
27.384 + }
27.385 + close(fd);
27.386 +
27.387 + rpm->signature = rpm->map + RPM_LEAD_SIZE;
27.388 + nindex = ntohl(rpm->signature->nindex);
27.389 + hsize = ntohl(rpm->signature->hsize);
27.390 + rpm->header = (void *) (rpm->signature + 1) +
27.391 + ALIGN(nindex * sizeof *index + hsize, 8);
27.392 + nindex = ntohl(rpm->header->nindex);
27.393 + hsize = ntohl(rpm->header->hsize);
27.394 + rpm->payload = (void *) (rpm->header + 1) +
27.395 + nindex * sizeof *index + hsize;
27.396 +
27.397 + base = (struct rpm_header_index *) (rpm->header + 1);
27.398 + rpm->pool = (void *) base + nindex * sizeof *index;
27.399 +
27.400 + /* Look up dir names now so we can index them directly. */
27.401 + name = razor_rpm_get_indirect(rpm, RPMTAG_DIRNAMES, &count);
27.402 + if (name) {
27.403 + rpm->dirs = calloc(count, sizeof *rpm->dirs);
27.404 + for (i = 0; i < count; i++) {
27.405 + rpm->dirs[i] = name;
27.406 + name += strlen(name) + 1;
27.407 + }
27.408 + } else {
27.409 + name = razor_rpm_get_indirect(rpm, RPMTAG_OLDFILENAMES,
27.410 + &count);
27.411 + if (name) {
27.412 + fprintf(stderr, "old filenames not supported\n");
27.413 + return NULL;
27.414 + }
27.415 + }
27.416 +
27.417 + return rpm;
27.418 +}
27.419 +
27.420 +struct cpio_file_header {
27.421 + char magic[6];
27.422 + char inode[8];
27.423 + char mode[8];
27.424 + char uid[8];
27.425 + char gid[8];
27.426 + char nlink[8];
27.427 + char mtime[8];
27.428 + char filesize[8];
27.429 + char devmajor[8];
27.430 + char devminor[8];
27.431 + char rdevmajor[8];
27.432 + char rdevminor[8];
27.433 + char namesize[8];
27.434 + char checksum[8];
27.435 + char filename[0];
27.436 +};
27.437 +
27.438 +/* gzip flags */
27.439 +#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
27.440 +#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
27.441 +#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
27.442 +#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
27.443 +#define COMMENT 0x10 /* bit 4 set: file comment present */
27.444 +#define RESERVED 0xE0 /* bits 5..7: reserved */
27.445 +
27.446 +struct installer {
27.447 + const char *root;
27.448 + struct razor_rpm *rpm;
27.449 + z_stream stream;
27.450 + unsigned char buffer[32768];
27.451 + size_t rest, length;
27.452 +};
27.453 +
27.454 +static int
27.455 +installer_inflate(struct installer *installer)
27.456 +{
27.457 + size_t length;
27.458 + int err;
27.459 +
27.460 + if (installer->rest > sizeof installer->buffer)
27.461 + length = sizeof installer->buffer;
27.462 + else
27.463 + length = installer->rest;
27.464 +
27.465 + installer->stream.next_out = installer->buffer;
27.466 + installer->stream.avail_out = length;
27.467 + err = inflate(&installer->stream, Z_SYNC_FLUSH);
27.468 + if (err != Z_OK && err != Z_STREAM_END) {
27.469 + fprintf(stderr, "inflate error: %d (%m)\n", err);
27.470 + return -1;
27.471 + }
27.472 +
27.473 + installer->rest -= length;
27.474 + installer->length = length;
27.475 +
27.476 + return 0;
27.477 +}
27.478 +
27.479 +static int
27.480 +installer_align(struct installer *installer, size_t size)
27.481 +{
27.482 + unsigned char buffer[4];
27.483 + int err;
27.484 +
27.485 + installer->stream.next_out = buffer;
27.486 + installer->stream.avail_out =
27.487 + (size - installer->stream.total_out) & (size - 1);
27.488 +
27.489 + if (installer->stream.avail_out == 0)
27.490 + return 0;
27.491 +
27.492 + err = inflate(&installer->stream, Z_SYNC_FLUSH);
27.493 + if (err != Z_OK && err != Z_STREAM_END) {
27.494 + fprintf(stderr, "inflate error: %d (%m)\n", err);
27.495 + return -1;
27.496 + }
27.497 +
27.498 + return 0;
27.499 +}
27.500 +
27.501 +static int
27.502 +create_path(struct installer *installer, const char *path, unsigned int mode)
27.503 +{
27.504 + char buffer[PATH_MAX];
27.505 + struct stat buf;
27.506 + int fd, ret;
27.507 +
27.508 + if (razor_create_dir(installer->root, path) < 0)
27.509 + return -1;
27.510 +
27.511 + snprintf(buffer, sizeof buffer, "%s%s", installer->root, path);
27.512 +
27.513 + switch (mode >> 12) {
27.514 + case REG:
27.515 + /* FIXME: handle the case where a file is already there. */
27.516 + fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, mode & 0x1ff);
27.517 + if (fd < 0){
27.518 + fprintf(stderr, "failed to create file %s\n", buffer);
27.519 + return -1;
27.520 + }
27.521 + while (installer->rest > 0) {
27.522 + if (installer_inflate(installer)) {
27.523 + fprintf(stderr, "failed to inflate\n");
27.524 + return -1;
27.525 + }
27.526 + if (razor_write(fd, installer->buffer,
27.527 + installer->length)) {
27.528 + fprintf(stderr, "failed to write payload\n");
27.529 + return -1;
27.530 + }
27.531 + }
27.532 + if (close(fd) < 0) {
27.533 + fprintf(stderr, "failed to close %s: %m\n", buffer);
27.534 + return -1;
27.535 + }
27.536 + return 0;
27.537 + case XDIR:
27.538 + ret = mkdir(buffer, mode & 0x1ff);
27.539 + if (ret == 0 || errno != EEXIST)
27.540 + return ret;
27.541 + if (stat(buffer, &buf) || !S_ISDIR(buf.st_mode)) {
27.542 + /* FIXME: also check that mode match. */
27.543 + fprintf(stderr,
27.544 + "%s exists but is not a directory\n", buffer);
27.545 + return -1;
27.546 + }
27.547 + return 0;
27.548 + case PIPE:
27.549 + case CDEV:
27.550 + case BDEV:
27.551 + case SOCK:
27.552 + printf("%s: unhandled file type %d\n", buffer, mode >> 12);
27.553 + return 0;
27.554 + case LINK:
27.555 + if (installer_inflate(installer)) {
27.556 + fprintf(stderr, "failed to inflate\n");
27.557 + return -1;
27.558 + }
27.559 + if (installer->length >= sizeof installer->buffer) {
27.560 + fprintf(stderr, "link name too long\n");
27.561 + return -1;
27.562 + }
27.563 + installer->buffer[installer->length] = '\0';
27.564 + if (symlink((const char *) installer->buffer, buffer)) {
27.565 + fprintf(stderr, "failed to create symlink, %m\n");
27.566 + return -1;
27.567 + }
27.568 + return 0;
27.569 + default:
27.570 + printf("%s: unknown file type %d\n", buffer, mode >> 12);
27.571 + return 0;
27.572 + }
27.573 +}
27.574 +
27.575 +static int
27.576 +run_script(struct installer *installer,
27.577 + unsigned int program_tag, unsigned int script_tag)
27.578 +{
27.579 + int pid, status, fd[2];
27.580 + const char *script = NULL, *program = NULL;
27.581 +
27.582 + program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
27.583 + script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
27.584 + if (program == NULL && script == NULL) {
27.585 + return 0;
27.586 + } else if (program == NULL) {
27.587 + program = "/bin/sh";
27.588 + }
27.589 +
27.590 + if (pipe(fd) < 0) {
27.591 + fprintf(stderr, "failed to create pipe\n");
27.592 + return -1;
27.593 + }
27.594 + pid = fork();
27.595 + if (pid < 0) {
27.596 + fprintf(stderr, "failed to fork, %m\n");
27.597 + } else if (pid == 0) {
27.598 + if (dup2(fd[0], STDIN_FILENO) < 0) {
27.599 + fprintf(stderr, "failed redirect stdin, %m\n");
27.600 + return -1;
27.601 + }
27.602 + if (close(fd[0]) < 0 || close(fd[1]) < 0) {
27.603 + fprintf(stderr, "failed to close pipe, %m\n");
27.604 + return -1;
27.605 + }
27.606 + if (chroot(installer->root) < 0) {
27.607 + fprintf(stderr, "failed to chroot to %s, %m\n",
27.608 + installer->root);
27.609 + return -1;
27.610 + }
27.611 + printf("executing program %s in chroot %s\n",
27.612 + program, installer->root);
27.613 + if (execl(program, program, NULL)) {
27.614 + fprintf(stderr, "failed to exec %s, %m\n", program);
27.615 + exit(-1);
27.616 + }
27.617 + } else {
27.618 + if (script && razor_write(fd[1], script, strlen(script)) < 0) {
27.619 + fprintf(stderr, "failed to pipe script, %m\n");
27.620 + return -1;
27.621 + }
27.622 + if (close(fd[0]) || close(fd[1])) {
27.623 + fprintf(stderr, "failed to close pipe, %m\n");
27.624 + return -1;
27.625 + }
27.626 + if (wait(&status) < 0) {
27.627 + fprintf(stderr, "wait for child failed, %m");
27.628 + return -1;
27.629 + }
27.630 + if (status)
27.631 + printf("script exited with status %d\n", status);
27.632 + }
27.633 +
27.634 + return 0;
27.635 +}
27.636 +
27.637 +static int
27.638 +installer_init(struct installer *installer)
27.639 +{
27.640 + unsigned char *gz_header;
27.641 + int method, flags, err;
27.642 +
27.643 + gz_header = installer->rpm->payload;
27.644 + if (gz_header[0] != 0x1f || gz_header[1] != 0x8b) {
27.645 + fprintf(stderr, "payload section doesn't have gz header\n");
27.646 + return -1;
27.647 + }
27.648 +
27.649 + method = gz_header[2];
27.650 + flags = gz_header[3];
27.651 +
27.652 + if (method != Z_DEFLATED || flags != 0) {
27.653 + fprintf(stderr,
27.654 + "unknown payload compression method or flags set\n");
27.655 + return -1;
27.656 + }
27.657 +
27.658 + installer->stream.zalloc = NULL;
27.659 + installer->stream.zfree = NULL;
27.660 + installer->stream.opaque = NULL;
27.661 +
27.662 + installer->stream.next_in = gz_header + 10;
27.663 + installer->stream.avail_in =
27.664 + (installer->rpm->map + installer->rpm->size) -
27.665 + (void *) installer->stream.next_in;
27.666 + installer->stream.next_out = NULL;
27.667 + installer->stream.avail_out = 0;
27.668 +
27.669 + err = inflateInit2(&installer->stream, -MAX_WBITS);
27.670 + if (err != Z_OK) {
27.671 + fprintf(stderr, "inflateInit error: %d\n", err);
27.672 + return -1;
27.673 + }
27.674 +
27.675 + return 0;
27.676 +}
27.677 +
27.678 +static int
27.679 +installer_finish(struct installer *installer)
27.680 +{
27.681 + int err;
27.682 +
27.683 + err = inflateEnd(&installer->stream);
27.684 +
27.685 + if (err != Z_OK) {
27.686 + fprintf(stderr, "inflateEnd error: %d\n", err);
27.687 + return -1;
27.688 + }
27.689 +
27.690 + return 0;
27.691 +}
27.692 +
27.693 +static unsigned long
27.694 +fixed_hex_to_ulong(const char *hex, int length)
27.695 +{
27.696 + long l;
27.697 + int i;
27.698 +
27.699 + for (i = 0, l = 0; i < length; i++) {
27.700 + if (hex[i] < 'a')
27.701 + l = l * 16 + hex[i] - '0';
27.702 + else
27.703 + l = l * 16 + hex[i] - 'a' + 10;
27.704 + }
27.705 +
27.706 + return l;
27.707 +}
27.708 +
27.709 +int
27.710 +razor_rpm_install(struct razor_rpm *rpm, const char *root)
27.711 +{
27.712 + struct installer installer;
27.713 + struct cpio_file_header *header;
27.714 + struct stat buf;
27.715 + unsigned int mode;
27.716 + char *path;
27.717 + size_t filesize;
27.718 +
27.719 + installer.rpm = rpm;
27.720 + installer.root = root;
27.721 +
27.722 + /* FIXME: Only do this before a transaction, not per rpm. */
27.723 + if (stat(root, &buf) < 0 || !S_ISDIR(buf.st_mode)) {
27.724 + fprintf(stderr,
27.725 + "root installation directory \"%s\" does not exist\n",
27.726 + root);
27.727 + return -1;
27.728 + }
27.729 +
27.730 + if (installer_init(&installer))
27.731 + return -1;
27.732 +
27.733 + run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN);
27.734 +
27.735 + while (installer.stream.avail_in > 0) {
27.736 + installer.rest = sizeof *header;
27.737 + if (installer_inflate(&installer))
27.738 + return -1;
27.739 +
27.740 + header = (struct cpio_file_header *) installer.buffer;
27.741 + mode = fixed_hex_to_ulong(header->mode, sizeof header->mode);
27.742 + filesize = fixed_hex_to_ulong(header->filesize,
27.743 + sizeof header->filesize);
27.744 +
27.745 + installer.rest = fixed_hex_to_ulong(header->namesize,
27.746 + sizeof header->namesize);
27.747 +
27.748 + if (installer_inflate(&installer) ||
27.749 + installer_align(&installer, 4))
27.750 + return -1;
27.751 +
27.752 + path = (char *) installer.buffer;
27.753 + /* This convention is so lame... */
27.754 + if (strcmp(path, "TRAILER!!!") == 0)
27.755 + break;
27.756 +
27.757 + installer.rest = filesize;
27.758 + if (create_path(&installer, path + 1, mode) < 0)
27.759 + return -1;
27.760 + if (installer_align(&installer, 4))
27.761 + return -1;
27.762 + }
27.763 +
27.764 + if (installer_finish(&installer))
27.765 + return -1;
27.766 +
27.767 + run_script(&installer, RPMTAG_POSTINPROG, RPMTAG_POSTIN);
27.768 +
27.769 + return 0;
27.770 +}
27.771 +
27.772 +int
27.773 +razor_rpm_close(struct razor_rpm *rpm)
27.774 +{
27.775 + int err;
27.776 +
27.777 + free(rpm->dirs);
27.778 + err = munmap(rpm->map, rpm->size);
27.779 + free(rpm);
27.780 +
27.781 + return err;
27.782 +}
27.783 +
27.784 +int
27.785 +razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm)
27.786 +{
27.787 + const char *name, *version, *release, *arch, *summary;
27.788 + const uint32_t *epoch;
27.789 + char evr[128], buf[16];
27.790 +
27.791 + name = razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL);
27.792 + epoch = razor_rpm_get_indirect(rpm, RPMTAG_EPOCH, NULL);
27.793 + version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL);
27.794 + release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL);
27.795 + arch = razor_rpm_get_indirect(rpm, RPMTAG_ARCH, NULL);
27.796 + summary = razor_rpm_get_indirect(rpm, RPMTAG_SUMMARY, NULL);
27.797 +
27.798 + if (epoch) {
27.799 + snprintf(buf, sizeof buf, "%u", ntohl(*epoch));
27.800 + razor_build_evr(evr, sizeof evr, buf, version, release);
27.801 + } else {
27.802 + razor_build_evr(evr, sizeof evr, NULL, version, release);
27.803 + }
27.804 + razor_importer_begin_package(importer, name, evr, arch);
27.805 +
27.806 + import_properties(importer, RAZOR_PROPERTY_REQUIRES, rpm,
27.807 + RPMTAG_REQUIRENAME,
27.808 + RPMTAG_REQUIREVERSION,
27.809 + RPMTAG_REQUIREFLAGS);
27.810 +
27.811 + import_properties(importer, RAZOR_PROPERTY_PROVIDES, rpm,
27.812 + RPMTAG_PROVIDENAME,
27.813 + RPMTAG_PROVIDEVERSION,
27.814 + RPMTAG_PROVIDEFLAGS);
27.815 +
27.816 + import_properties(importer, RAZOR_PROPERTY_OBSOLETES, rpm,
27.817 + RPMTAG_OBSOLETENAME,
27.818 + RPMTAG_OBSOLETEVERSION,
27.819 + RPMTAG_OBSOLETEFLAGS);
27.820 +
27.821 + import_properties(importer, RAZOR_PROPERTY_CONFLICTS, rpm,
27.822 + RPMTAG_CONFLICTNAME,
27.823 + RPMTAG_CONFLICTVERSION,
27.824 + RPMTAG_CONFLICTFLAGS);
27.825 +
27.826 + import_files(importer, rpm);
27.827 +
27.828 + razor_importer_finish_package(importer);
27.829 +
27.830 + return 0;
27.831 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/librazor/transaction.c Fri Jun 20 19:04:47 2008 -0400
28.3 @@ -0,0 +1,912 @@
28.4 +/*
28.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
28.6 + * Copyright (C) 2008 Red Hat, Inc
28.7 + *
28.8 + * This program is free software; you can redistribute it and/or modify
28.9 + * it under the terms of the GNU General Public License as published by
28.10 + * the Free Software Foundation; either version 2 of the License, or
28.11 + * (at your option) any later version.
28.12 + *
28.13 + * This program is distributed in the hope that it will be useful,
28.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
28.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28.16 + * GNU General Public License for more details.
28.17 + *
28.18 + * You should have received a copy of the GNU General Public License along
28.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
28.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28.21 + */
28.22 +
28.23 +#define _GNU_SOURCE
28.24 +
28.25 +#include <stdlib.h>
28.26 +#include <stddef.h>
28.27 +#include <stdint.h>
28.28 +#include <stdio.h>
28.29 +#include <string.h>
28.30 +#include <sys/types.h>
28.31 +#include <sys/stat.h>
28.32 +#include <sys/mman.h>
28.33 +#include <unistd.h>
28.34 +#include <fcntl.h>
28.35 +#include <errno.h>
28.36 +#include <ctype.h>
28.37 +#include <fnmatch.h>
28.38 +
28.39 +#include "razor-internal.h"
28.40 +#include "razor.h"
28.41 +
28.42 +static int
28.43 +provider_satisfies_requirement(struct razor_property *provider,
28.44 + const char *provider_strings,
28.45 + uint32_t flags,
28.46 + const char *required)
28.47 +{
28.48 + int cmp, len;
28.49 + const char *provided = &provider_strings[provider->version];
28.50 +
28.51 + if (!*required)
28.52 + return 1;
28.53 + if (!*provided) {
28.54 + if (flags & RAZOR_PROPERTY_LESS)
28.55 + return 0;
28.56 + else
28.57 + return 1;
28.58 + }
28.59 +
28.60 + cmp = razor_versioncmp(provided, required);
28.61 +
28.62 + switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
28.63 + case RAZOR_PROPERTY_LESS:
28.64 + return cmp < 0;
28.65 +
28.66 + case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
28.67 + if (cmp <= 0)
28.68 + return 1;
28.69 + /* fall through: FIXME, make sure this is correct */
28.70 +
28.71 + case RAZOR_PROPERTY_EQUAL:
28.72 + if (cmp == 0)
28.73 + return 1;
28.74 +
28.75 + /* "foo == 1.1" is satisfied by "foo 1.1-2" */
28.76 + len = strlen(required);
28.77 + if (!strncmp(required, provided, len) && provided[len] == '-')
28.78 + return 1;
28.79 + return 0;
28.80 +
28.81 + case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
28.82 + return cmp >= 0;
28.83 +
28.84 + case RAZOR_PROPERTY_GREATER:
28.85 + return cmp > 0;
28.86 + }
28.87 +
28.88 + /* shouldn't happen */
28.89 + return 0;
28.90 +}
28.91 +
28.92 +#define TRANS_PACKAGE_PRESENT 1
28.93 +#define TRANS_PACKAGE_UPDATE 2
28.94 +#define TRANS_PROPERTY_SATISFIED 0x80000000
28.95 +
28.96 +struct transaction_set {
28.97 + struct razor_set *set;
28.98 + uint32_t *packages;
28.99 + uint32_t *properties;
28.100 +};
28.101 +
28.102 +struct razor_transaction {
28.103 + int package_count, errors;
28.104 + struct transaction_set system, upstream;
28.105 + int changes;
28.106 +};
28.107 +
28.108 +static void
28.109 +transaction_set_init(struct transaction_set *ts, struct razor_set *set)
28.110 +{
28.111 + int count;
28.112 +
28.113 + ts->set = set;
28.114 + count = set->packages.size / sizeof (struct razor_package);
28.115 + ts->packages = zalloc(count * sizeof *ts->packages);
28.116 + count = set->properties.size / sizeof (struct razor_property);
28.117 + ts->properties = zalloc(count * sizeof *ts->properties);
28.118 +}
28.119 +
28.120 +static void
28.121 +transaction_set_release(struct transaction_set *ts)
28.122 +{
28.123 + free(ts->packages);
28.124 + free(ts->properties);
28.125 +}
28.126 +
28.127 +static void
28.128 +transaction_set_install_package(struct transaction_set *ts,
28.129 + struct razor_package *package)
28.130 +{
28.131 + struct razor_package *pkgs;
28.132 + struct list *prop;
28.133 + int i;
28.134 +
28.135 + pkgs = ts->set->packages.data;
28.136 + i = package - pkgs;
28.137 + if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
28.138 + return;
28.139 +
28.140 + ts->packages[i] = TRANS_PACKAGE_PRESENT;
28.141 +
28.142 + prop = list_first(&package->properties, &ts->set->property_pool);
28.143 + while (prop) {
28.144 + ts->properties[prop->data]++;
28.145 + prop = list_next(prop);
28.146 + }
28.147 +}
28.148 +
28.149 +static void
28.150 +transaction_set_remove_package(struct transaction_set *ts,
28.151 + struct razor_package *package)
28.152 +{
28.153 + struct razor_package *pkgs;
28.154 + struct list *prop;
28.155 + int i;
28.156 +
28.157 + pkgs = ts->set->packages.data;
28.158 + i = package - pkgs;
28.159 + if (ts->packages[i] == 0)
28.160 + return;
28.161 +
28.162 + ts->packages[i] = 0;
28.163 +
28.164 + prop = list_first(&package->properties, &ts->set->property_pool);
28.165 + while (prop) {
28.166 + ts->properties[prop->data]--;
28.167 + prop = list_next(prop);
28.168 + }
28.169 +}
28.170 +
28.171 +struct razor_transaction *
28.172 +razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
28.173 +{
28.174 + struct razor_transaction *trans;
28.175 + struct razor_package *p, *spkgs, *pend;
28.176 +
28.177 + trans = zalloc(sizeof *trans);
28.178 + transaction_set_init(&trans->system, system);
28.179 + transaction_set_init(&trans->upstream, upstream);
28.180 +
28.181 + spkgs = trans->system.set->packages.data;
28.182 + pend = trans->system.set->packages.data +
28.183 + trans->system.set->packages.size;
28.184 + for (p = spkgs; p < pend; p++)
28.185 + transaction_set_install_package(&trans->system, p);
28.186 +
28.187 + return trans;
28.188 +}
28.189 +
28.190 +void
28.191 +razor_transaction_install_package(struct razor_transaction *trans,
28.192 + struct razor_package *package)
28.193 +{
28.194 + transaction_set_install_package(&trans->upstream, package);
28.195 + trans->changes++;
28.196 +}
28.197 +
28.198 +void
28.199 +razor_transaction_remove_package(struct razor_transaction *trans,
28.200 + struct razor_package *package)
28.201 +{
28.202 + transaction_set_remove_package(&trans->system, package);
28.203 + trans->changes++;
28.204 +}
28.205 +
28.206 +void
28.207 +razor_transaction_update_package(struct razor_transaction *trans,
28.208 + struct razor_package *package)
28.209 +{
28.210 + struct razor_package *spkgs, *upkgs, *end;
28.211 +
28.212 + spkgs = trans->system.set->packages.data;
28.213 + upkgs = trans->upstream.set->packages.data;
28.214 + end = trans->system.set->packages.data +
28.215 + trans->system.set->packages.size;
28.216 + if (spkgs <= package && package < end)
28.217 + trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
28.218 + else
28.219 + trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
28.220 +}
28.221 +
28.222 +struct prop_iter {
28.223 + struct razor_property *p, *start, *end;
28.224 + const char *pool;
28.225 + uint32_t *present;
28.226 +};
28.227 +
28.228 +static void
28.229 +prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
28.230 +{
28.231 + pi->p = ts->set->properties.data;
28.232 + pi->start = ts->set->properties.data;
28.233 + pi->end = ts->set->properties.data + ts->set->properties.size;
28.234 + pi->pool = ts->set->string_pool.data;
28.235 + pi->present = ts->properties;
28.236 +}
28.237 +
28.238 +static int
28.239 +prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
28.240 +{
28.241 + while (pi->p < pi->end) {
28.242 + if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
28.243 + (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
28.244 + *p = pi->p++;
28.245 + return 1;
28.246 + }
28.247 + pi->p++;
28.248 + }
28.249 +
28.250 + return 0;
28.251 +}
28.252 +
28.253 +static struct razor_property *
28.254 +prop_iter_seek_to(struct prop_iter *pi,
28.255 + uint32_t flags, const char *match)
28.256 +{
28.257 + uint32_t name;
28.258 +
28.259 + while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
28.260 + pi->p++;
28.261 +
28.262 + if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
28.263 + return NULL;
28.264 +
28.265 + name = pi->p->name;
28.266 + while (pi->p < pi->end &&
28.267 + pi->p->name == name &&
28.268 + (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
28.269 + pi->p++;
28.270 +
28.271 + if (pi->p == pi->end || pi->p->name != name)
28.272 + return NULL;
28.273 +
28.274 + return pi->p;
28.275 +}
28.276 +
28.277 +/* Remove packages from set that provide any of the matching (same
28.278 + * name and type) providers from ppi onwards that match the
28.279 + * requirement that rpi points to. */
28.280 +static void
28.281 +remove_matching_providers(struct razor_transaction *trans,
28.282 + struct prop_iter *ppi,
28.283 + uint32_t flags,
28.284 + const char *version)
28.285 +{
28.286 + struct razor_property *p;
28.287 + struct razor_package *pkg, *pkgs;
28.288 + struct razor_package_iterator pkg_iter;
28.289 + struct razor_set *set;
28.290 + const char *n, *v, *a;
28.291 + uint32_t type;
28.292 +
28.293 + if (ppi->present == trans->system.properties)
28.294 + set = trans->system.set;
28.295 + else
28.296 + set = trans->upstream.set;
28.297 +
28.298 + pkgs = (struct razor_package *) set->packages.data;
28.299 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
28.300 + for (p = ppi->p;
28.301 + p < ppi->end &&
28.302 + p->name == ppi->p->name &&
28.303 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
28.304 + p++) {
28.305 + if (!ppi->present[p - ppi->start])
28.306 + continue;
28.307 + if (!provider_satisfies_requirement(p, ppi->pool,
28.308 + flags, version))
28.309 + continue;
28.310 +
28.311 + razor_package_iterator_init_for_property(&pkg_iter, set, p);
28.312 + while (razor_package_iterator_next(&pkg_iter,
28.313 + &pkg, &n, &v, &a)) {
28.314 + fprintf(stderr, "removing %s-%s\n", n, v);
28.315 + razor_transaction_remove_package(trans, pkg);
28.316 + }
28.317 + }
28.318 +}
28.319 +
28.320 +static void
28.321 +flag_matching_providers(struct razor_transaction *trans,
28.322 + struct prop_iter *ppi,
28.323 + struct razor_property *r,
28.324 + struct prop_iter *rpi,
28.325 + unsigned int flag)
28.326 +{
28.327 + struct razor_property *p;
28.328 + struct razor_package *pkg, *pkgs;
28.329 + struct razor_package_iterator pkg_iter;
28.330 + struct razor_set *set;
28.331 + const char *name, *version, *arch;
28.332 + uint32_t *flags, type;
28.333 +
28.334 + if (ppi->present == trans->system.properties) {
28.335 + set = trans->system.set;
28.336 + flags = trans->system.packages;
28.337 + } else {
28.338 + set = trans->upstream.set;
28.339 + flags = trans->upstream.packages;
28.340 + }
28.341 +
28.342 + pkgs = (struct razor_package *) set->packages.data;
28.343 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
28.344 + for (p = ppi->p;
28.345 + p < ppi->end &&
28.346 + p->name == ppi->p->name &&
28.347 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
28.348 + p++) {
28.349 + if (!ppi->present[p - ppi->start])
28.350 + continue;
28.351 + if (!provider_satisfies_requirement(p, ppi->pool,
28.352 + r->flags,
28.353 + &rpi->pool[r->version]))
28.354 + continue;
28.355 +
28.356 + razor_package_iterator_init_for_property(&pkg_iter, set, p);
28.357 + while (razor_package_iterator_next(&pkg_iter, &pkg,
28.358 + &name, &version, &arch)) {
28.359 +
28.360 + fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
28.361 + name, version,
28.362 + ppi->pool + p->name,
28.363 + rpi->pool + r->name,
28.364 + rpi->pool + r->version);
28.365 + flags[pkg - pkgs] |= flag;
28.366 + }
28.367 + }
28.368 +}
28.369 +
28.370 +static struct razor_package *
28.371 +pick_matching_provider(struct razor_set *set,
28.372 + struct prop_iter *ppi,
28.373 + uint32_t flags,
28.374 + const char *version)
28.375 +{
28.376 + struct razor_property *p;
28.377 + struct razor_package *pkgs;
28.378 + struct list *i;
28.379 + uint32_t type;
28.380 +
28.381 + /* This is where we decide which pkgs to pull in to satisfy a
28.382 + * requirement. There may be several different providers
28.383 + * (different versions) and each version of a provider may
28.384 + * come from a number of packages. We pick the first package
28.385 + * from the first provider that matches. */
28.386 +
28.387 + pkgs = set->packages.data;
28.388 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
28.389 + for (p = ppi->p;
28.390 + p < ppi->end &&
28.391 + p->name == ppi->p->name &&
28.392 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
28.393 + ppi->present[p - ppi->start] == 0;
28.394 + p++) {
28.395 + if (!provider_satisfies_requirement(p, ppi->pool,
28.396 + flags, version))
28.397 + continue;
28.398 +
28.399 + i = list_first(&p->packages, &set->package_pool);
28.400 +
28.401 + return &pkgs[i->data];
28.402 + }
28.403 +
28.404 + return NULL;
28.405 +}
28.406 +
28.407 +static void
28.408 +remove_obsoleted_packages(struct razor_transaction *trans)
28.409 +{
28.410 + struct razor_property *up;
28.411 + struct razor_package *spkgs;
28.412 + struct prop_iter spi, upi;
28.413 +
28.414 + spkgs = trans->system.set->packages.data;
28.415 + prop_iter_init(&spi, &trans->system);
28.416 + prop_iter_init(&upi, &trans->upstream);
28.417 +
28.418 + while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
28.419 + if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
28.420 + &upi.pool[up->name]))
28.421 + continue;
28.422 + remove_matching_providers(trans, &spi, up->flags,
28.423 + &upi.pool[up->version]);
28.424 + }
28.425 +}
28.426 +
28.427 +static int
28.428 +any_provider_satisfies_requirement(struct prop_iter *ppi,
28.429 + uint32_t flags,
28.430 + const char *version)
28.431 +{
28.432 + struct razor_property *p;
28.433 + uint32_t type;
28.434 +
28.435 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
28.436 + for (p = ppi->p;
28.437 + p < ppi->end &&
28.438 + p->name == ppi->p->name &&
28.439 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
28.440 + p++) {
28.441 + if (ppi->present[p - ppi->start] > 0 &&
28.442 + provider_satisfies_requirement(p, ppi->pool,
28.443 + flags, version))
28.444 + return 1;
28.445 + }
28.446 +
28.447 + return 0;
28.448 +}
28.449 +
28.450 +static void
28.451 +clear_requires_flags(struct transaction_set *ts)
28.452 +{
28.453 + struct razor_property *p;
28.454 + const char *pool;
28.455 + int i, count;
28.456 +
28.457 + count = ts->set->properties.size / sizeof *p;
28.458 + p = ts->set->properties.data;
28.459 + pool = ts->set->string_pool.data;
28.460 + for (i = 0; i < count; i++) {
28.461 + ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
28.462 + if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
28.463 + ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
28.464 + }
28.465 +}
28.466 +
28.467 +const char *
28.468 +razor_property_relation_to_string(struct razor_property *p)
28.469 +{
28.470 + switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
28.471 + case RAZOR_PROPERTY_LESS:
28.472 + return "<";
28.473 +
28.474 + case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
28.475 + return "<=";
28.476 +
28.477 + case RAZOR_PROPERTY_EQUAL:
28.478 + return "=";
28.479 +
28.480 + case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
28.481 + return ">=";
28.482 +
28.483 + case RAZOR_PROPERTY_GREATER:
28.484 + return ">";
28.485 +
28.486 + default:
28.487 + return "?";
28.488 + }
28.489 +}
28.490 +
28.491 +const char *
28.492 +razor_property_type_to_string(struct razor_property *p)
28.493 +{
28.494 + switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
28.495 + case RAZOR_PROPERTY_REQUIRES:
28.496 + return "requires";
28.497 + case RAZOR_PROPERTY_PROVIDES:
28.498 + return "provides";
28.499 + case RAZOR_PROPERTY_CONFLICTS:
28.500 + return "conflicts";
28.501 + case RAZOR_PROPERTY_OBSOLETES:
28.502 + return "obsoletes";
28.503 + default:
28.504 + return NULL;
28.505 + }
28.506 +}
28.507 +
28.508 +static void
28.509 +mark_satisfied_requires(struct razor_transaction *trans,
28.510 + struct transaction_set *rts,
28.511 + struct transaction_set *pts)
28.512 +{
28.513 + struct prop_iter rpi, ppi;
28.514 + struct razor_property *rp;
28.515 +
28.516 + prop_iter_init(&rpi, rts);
28.517 + prop_iter_init(&ppi, pts);
28.518 +
28.519 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
28.520 + if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
28.521 + &rpi.pool[rp->name]))
28.522 + continue;
28.523 +
28.524 + if (any_provider_satisfies_requirement(&ppi, rp->flags,
28.525 + &rpi.pool[rp->version]))
28.526 + rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
28.527 + }
28.528 +}
28.529 +
28.530 +static void
28.531 +mark_all_satisfied_requires(struct razor_transaction *trans)
28.532 +{
28.533 + clear_requires_flags(&trans->system);
28.534 + clear_requires_flags(&trans->upstream);
28.535 + mark_satisfied_requires(trans, &trans->system, &trans->system);
28.536 + mark_satisfied_requires(trans, &trans->system, &trans->upstream);
28.537 + mark_satisfied_requires(trans, &trans->upstream, &trans->system);
28.538 + mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
28.539 +}
28.540 +
28.541 +static void
28.542 +update_unsatisfied_packages(struct razor_transaction *trans)
28.543 +{
28.544 + struct razor_package *spkgs, *pkg;
28.545 + struct razor_property *sp;
28.546 + struct prop_iter spi;
28.547 + struct razor_package_iterator pkg_iter;
28.548 + const char *name, *version, *arch;
28.549 +
28.550 + spkgs = trans->system.set->packages.data;
28.551 + prop_iter_init(&spi, &trans->system);
28.552 +
28.553 + while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
28.554 + if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
28.555 + continue;
28.556 +
28.557 + razor_package_iterator_init_for_property(&pkg_iter,
28.558 + trans->system.set,
28.559 + sp);
28.560 + while (razor_package_iterator_next(&pkg_iter, &pkg,
28.561 + &name, &version, &arch)) {
28.562 + fprintf(stderr, "updating %s because %s %s %s "
28.563 + "isn't satisfied\n",
28.564 + name, spi.pool + sp->name,
28.565 + razor_property_relation_to_string(sp),
28.566 + spi.pool + sp->version);
28.567 + trans->system.packages[pkg - spkgs] |=
28.568 + TRANS_PACKAGE_UPDATE;
28.569 + }
28.570 + }
28.571 +}
28.572 +
28.573 +void
28.574 +razor_transaction_update_all(struct razor_transaction *trans)
28.575 +{
28.576 + struct razor_package *p;
28.577 + int i, count;
28.578 +
28.579 + count = trans->system.set->packages.size / sizeof *p;
28.580 + for (i = 0; i < count; i++)
28.581 + trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
28.582 +}
28.583 +
28.584 +static void
28.585 +update_conflicted_packages(struct razor_transaction *trans)
28.586 +{
28.587 + struct razor_package *pkg, *spkgs;
28.588 + struct razor_property *up, *sp;
28.589 + struct prop_iter spi, upi;
28.590 + struct razor_package_iterator pkg_iter;
28.591 + const char *name, *version, *arch;
28.592 +
28.593 + spkgs = trans->system.set->packages.data;
28.594 + prop_iter_init(&spi, &trans->system);
28.595 + prop_iter_init(&upi, &trans->upstream);
28.596 +
28.597 + while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
28.598 + if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
28.599 + &spi.pool[sp->name]))
28.600 + continue;
28.601 +
28.602 + if (!any_provider_satisfies_requirement(&upi, sp->flags,
28.603 + &spi.pool[sp->version]))
28.604 + continue;
28.605 +
28.606 + razor_package_iterator_init_for_property(&pkg_iter,
28.607 + trans->system.set,
28.608 + sp);
28.609 + while (razor_package_iterator_next(&pkg_iter, &pkg,
28.610 + &name, &version, &arch)) {
28.611 + fprintf(stderr, "updating %s %s because it conflicts with %s",
28.612 + name, version, spi.pool + sp->name);
28.613 + trans->system.packages[pkg - spkgs] |=
28.614 + TRANS_PACKAGE_UPDATE;
28.615 + }
28.616 + }
28.617 +
28.618 + prop_iter_init(&spi, &trans->system);
28.619 + prop_iter_init(&upi, &trans->upstream);
28.620 +
28.621 + while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
28.622 + sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
28.623 + &upi.pool[upi.p->name]);
28.624 +
28.625 + if (sp)
28.626 + flag_matching_providers(trans, &spi, up, &upi,
28.627 + TRANS_PACKAGE_UPDATE);
28.628 + }
28.629 +}
28.630 +
28.631 +static void
28.632 +pull_in_requirements(struct razor_transaction *trans,
28.633 + struct prop_iter *rpi, struct prop_iter *ppi)
28.634 +{
28.635 + struct razor_property *rp, *pp;
28.636 + struct razor_package *pkg, *upkgs;
28.637 +
28.638 + upkgs = trans->upstream.set->packages.data;
28.639 + while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
28.640 + if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
28.641 + continue;
28.642 +
28.643 + pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
28.644 + &rpi->pool[rp->name]);
28.645 + if (pp == NULL)
28.646 + continue;
28.647 + pkg = pick_matching_provider(trans->upstream.set,
28.648 + ppi, rp->flags,
28.649 + &rpi->pool[rp->version]);
28.650 + if (pkg == NULL)
28.651 + continue;
28.652 +
28.653 + rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
28.654 +
28.655 + fprintf(stderr, "pulling in %s which provides %s %s %s "
28.656 + "to satisfy %s %s %s\n",
28.657 + ppi->pool + pkg->name,
28.658 + ppi->pool + pp->name,
28.659 + razor_property_relation_to_string(pp),
28.660 + ppi->pool + pp->version,
28.661 + &rpi->pool[rp->name],
28.662 + razor_property_relation_to_string(rp),
28.663 + &rpi->pool[rp->version]);
28.664 +
28.665 + trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
28.666 + }
28.667 +}
28.668 +
28.669 +static void
28.670 +pull_in_all_requirements(struct razor_transaction *trans)
28.671 +{
28.672 + struct prop_iter rpi, ppi;
28.673 +
28.674 + prop_iter_init(&rpi, &trans->system);
28.675 + prop_iter_init(&ppi, &trans->upstream);
28.676 + pull_in_requirements(trans, &rpi, &ppi);
28.677 +
28.678 + prop_iter_init(&rpi, &trans->upstream);
28.679 + prop_iter_init(&ppi, &trans->upstream);
28.680 + pull_in_requirements(trans, &rpi, &ppi);
28.681 +}
28.682 +
28.683 +static void
28.684 +flush_scheduled_system_updates(struct razor_transaction *trans)
28.685 +{
28.686 + struct razor_package_iterator *pi;
28.687 + struct razor_package *p, *pkg, *spkgs;
28.688 + struct prop_iter ppi;
28.689 + const char *name, *version, *arch;
28.690 +
28.691 + spkgs = trans->system.set->packages.data;
28.692 + pi = razor_package_iterator_create(trans->system.set);
28.693 + prop_iter_init(&ppi, &trans->upstream);
28.694 +
28.695 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
28.696 + if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
28.697 + continue;
28.698 +
28.699 + if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
28.700 + continue;
28.701 +
28.702 + pkg = pick_matching_provider(trans->upstream.set, &ppi,
28.703 + RAZOR_PROPERTY_GREATER, version);
28.704 + if (pkg == NULL)
28.705 + continue;
28.706 +
28.707 + fprintf(stderr, "updating %s-%s to %s-%s\n",
28.708 + name, version,
28.709 + &ppi.pool[pkg->name], &ppi.pool[pkg->version]);
28.710 +
28.711 + razor_transaction_remove_package(trans, p);
28.712 + razor_transaction_install_package(trans, pkg);
28.713 + }
28.714 +
28.715 + razor_package_iterator_destroy(pi);
28.716 +}
28.717 +
28.718 +static void
28.719 +flush_scheduled_upstream_updates(struct razor_transaction *trans)
28.720 +{
28.721 + struct razor_package_iterator *pi;
28.722 + struct razor_package *p, *upkgs;
28.723 + struct prop_iter spi;
28.724 + const char *name, *version, *arch;
28.725 +
28.726 + upkgs = trans->upstream.set->packages.data;
28.727 + pi = razor_package_iterator_create(trans->upstream.set);
28.728 + prop_iter_init(&spi, &trans->system);
28.729 +
28.730 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
28.731 + if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
28.732 + continue;
28.733 +
28.734 + if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
28.735 + remove_matching_providers(trans,
28.736 + &spi,
28.737 + RAZOR_PROPERTY_LESS,
28.738 + version);
28.739 + razor_transaction_install_package(trans, p);
28.740 + fprintf(stderr, "installing %s-%s\n", name, version);
28.741 + }
28.742 +}
28.743 +
28.744 +int
28.745 +razor_transaction_resolve(struct razor_transaction *trans)
28.746 +{
28.747 + int last = 0;
28.748 +
28.749 + flush_scheduled_system_updates(trans);
28.750 + flush_scheduled_upstream_updates(trans);
28.751 +
28.752 + while (last < trans->changes) {
28.753 + last = trans->changes;
28.754 + remove_obsoleted_packages(trans);
28.755 + mark_all_satisfied_requires(trans);
28.756 + update_unsatisfied_packages(trans);
28.757 + update_conflicted_packages(trans);
28.758 + pull_in_all_requirements(trans);
28.759 + flush_scheduled_system_updates(trans);
28.760 + flush_scheduled_upstream_updates(trans);
28.761 + }
28.762 +
28.763 + return trans->changes;
28.764 +}
28.765 +
28.766 +static void
28.767 +describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
28.768 +{
28.769 + struct razor_package_iterator pi;
28.770 + struct razor_package *pkg;
28.771 + const char *name, *version, *arch, *pool;
28.772 +
28.773 + pool = set->string_pool.data;
28.774 + if (pool[rp->version] == '\0') {
28.775 + razor_package_iterator_init_for_property(&pi, set, rp);
28.776 + while (razor_package_iterator_next(&pi, &pkg,
28.777 + &name, &version, &arch))
28.778 + fprintf(stderr, "%s is needed by %s-%s.%s\n",
28.779 + &pool[rp->name],
28.780 + name, version, arch);
28.781 + } else {
28.782 + razor_package_iterator_init_for_property(&pi, set, rp);
28.783 + while (razor_package_iterator_next(&pi, &pkg,
28.784 + &name, &version, &arch))
28.785 + fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
28.786 + &pool[rp->name],
28.787 + razor_property_relation_to_string(rp),
28.788 + &pool[rp->version],
28.789 + name, version, arch);
28.790 + }
28.791 +}
28.792 +
28.793 +int
28.794 +razor_transaction_describe(struct razor_transaction *trans)
28.795 +{
28.796 + struct prop_iter rpi;
28.797 + struct razor_property *rp;
28.798 + int unsatisfied;
28.799 +
28.800 + flush_scheduled_system_updates(trans);
28.801 + flush_scheduled_upstream_updates(trans);
28.802 + mark_all_satisfied_requires(trans);
28.803 +
28.804 + unsatisfied = 0;
28.805 + prop_iter_init(&rpi, &trans->system);
28.806 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
28.807 + if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
28.808 + describe_unsatisfied(trans->system.set, rp);
28.809 + unsatisfied++;
28.810 + }
28.811 + }
28.812 +
28.813 + prop_iter_init(&rpi, &trans->upstream);
28.814 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
28.815 + if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
28.816 + describe_unsatisfied(trans->upstream.set, rp);
28.817 + unsatisfied++;
28.818 + }
28.819 + }
28.820 +
28.821 + return unsatisfied;
28.822 +}
28.823 +
28.824 +int
28.825 +razor_transaction_unsatisfied_property(struct razor_transaction *trans,
28.826 + const char *name,
28.827 + uint32_t flags,
28.828 + const char *version)
28.829 +{
28.830 + struct prop_iter pi;
28.831 + struct razor_property *p;
28.832 +
28.833 + prop_iter_init(&pi, &trans->system);
28.834 + while (prop_iter_next(&pi, flags, &p)) {
28.835 + if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
28.836 + p->flags == flags &&
28.837 + strcmp(&pi.pool[p->name], name) == 0 &&
28.838 + strcmp(&pi.pool[p->version], version) == 0)
28.839 +
28.840 + return 1;
28.841 + }
28.842 +
28.843 + prop_iter_init(&pi, &trans->upstream);
28.844 + while (prop_iter_next(&pi, flags, &p)) {
28.845 + if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
28.846 + p->flags == flags &&
28.847 + strcmp(&pi.pool[p->name], name) == 0 &&
28.848 + strcmp(&pi.pool[p->version], version) == 0)
28.849 +
28.850 + return 1;
28.851 + }
28.852 +
28.853 + return 0;
28.854 +}
28.855 +
28.856 +struct razor_set *
28.857 +razor_transaction_finish(struct razor_transaction *trans)
28.858 +{
28.859 + struct razor_merger *merger;
28.860 + struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
28.861 + char *upool, *spool;
28.862 + int cmp;
28.863 +
28.864 + s = trans->system.set->packages.data;
28.865 + spkgs = trans->system.set->packages.data;
28.866 + send = trans->system.set->packages.data +
28.867 + trans->system.set->packages.size;
28.868 + spool = trans->system.set->string_pool.data;
28.869 +
28.870 + u = trans->upstream.set->packages.data;
28.871 + upkgs = trans->upstream.set->packages.data;
28.872 + uend = trans->upstream.set->packages.data +
28.873 + trans->upstream.set->packages.size;
28.874 + upool = trans->upstream.set->string_pool.data;
28.875 +
28.876 + merger = razor_merger_create(trans->system.set, trans->upstream.set);
28.877 + while (s < send || u < uend) {
28.878 + if (s < send && u < uend)
28.879 + cmp = strcmp(&spool[s->name], &upool[u->name]);
28.880 + else if (s < send)
28.881 + cmp = -1;
28.882 + else
28.883 + cmp = 1;
28.884 +
28.885 + if (cmp < 0) {
28.886 + if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
28.887 + razor_merger_add_package(merger, s);
28.888 + s++;
28.889 + } else if (cmp == 0) {
28.890 + if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
28.891 + razor_merger_add_package(merger, s);
28.892 + if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
28.893 + razor_merger_add_package(merger, u);
28.894 +
28.895 + s++;
28.896 + u++;
28.897 + } else {
28.898 + if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
28.899 + razor_merger_add_package(merger, u);
28.900 + u++;
28.901 + }
28.902 + }
28.903 +
28.904 + razor_transaction_destroy(trans);
28.905 +
28.906 + return razor_merger_finish(merger);
28.907 +}
28.908 +
28.909 +void
28.910 +razor_transaction_destroy(struct razor_transaction *trans)
28.911 +{
28.912 + transaction_set_release(&trans->system);
28.913 + transaction_set_release(&trans->upstream);
28.914 + free(trans);
28.915 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/librazor/types.c Fri Jun 20 19:04:47 2008 -0400
29.3 @@ -0,0 +1,246 @@
29.4 +#include <stdlib.h>
29.5 +#include <string.h>
29.6 +
29.7 +#include "razor-internal.h"
29.8 +
29.9 +void
29.10 +array_init(struct array *array)
29.11 +{
29.12 + memset(array, 0, sizeof *array);
29.13 +}
29.14 +
29.15 +void
29.16 +array_release(struct array *array)
29.17 +{
29.18 + free(array->data);
29.19 +}
29.20 +
29.21 +void *
29.22 +array_add(struct array *array, int size)
29.23 +{
29.24 + int alloc;
29.25 + void *data, *p;
29.26 +
29.27 + if (array->alloc > 0)
29.28 + alloc = array->alloc;
29.29 + else
29.30 + alloc = 16;
29.31 +
29.32 + while (alloc < array->size + size)
29.33 + alloc *= 2;
29.34 +
29.35 + if (array->alloc < alloc) {
29.36 + data = realloc(array->data, alloc);
29.37 + if (data == NULL)
29.38 + return 0;
29.39 + array->data = data;
29.40 + array->alloc = alloc;
29.41 + }
29.42 +
29.43 + p = array->data + array->size;
29.44 + array->size += size;
29.45 +
29.46 + return p;
29.47 +}
29.48 +
29.49 +/* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */
29.50 +#define RAZOR_ENTRY_LAST 0x80
29.51 +#define RAZOR_IMMEDIATE 0x80
29.52 +#define RAZOR_EMPTY_LIST 0xff
29.53 +
29.54 +void
29.55 +list_set_empty(struct list_head *head)
29.56 +{
29.57 + head->list_ptr = ~0;
29.58 + head->flags = RAZOR_EMPTY_LIST;
29.59 +}
29.60 +
29.61 +void
29.62 +list_set_ptr(struct list_head *head, uint32_t ptr)
29.63 +{
29.64 + head->list_ptr = ptr;
29.65 + head->flags = 0;
29.66 +}
29.67 +
29.68 +void
29.69 +list_set_array(struct list_head *head, struct array *pool,
29.70 + struct array *items, int force_indirect)
29.71 +{
29.72 + struct list *p;
29.73 +
29.74 + if (!force_indirect) {
29.75 + if (items->size == 0) {
29.76 + list_set_empty(head);
29.77 + return;
29.78 + } else if (items->size == sizeof (uint32_t)) {
29.79 + head->list_ptr = *(uint32_t *) items->data;
29.80 + head->flags = RAZOR_IMMEDIATE;
29.81 + return;
29.82 + }
29.83 + }
29.84 +
29.85 + p = array_add(pool, items->size);
29.86 + memcpy(p, items->data, items->size);
29.87 + p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST;
29.88 + list_set_ptr(head, p - (struct list *) pool->data);
29.89 +}
29.90 +
29.91 +struct list *
29.92 +list_first(struct list_head *head, struct array *pool)
29.93 +{
29.94 + if (head->flags == RAZOR_EMPTY_LIST)
29.95 + return NULL;
29.96 + else if (head->flags == RAZOR_IMMEDIATE)
29.97 + return (struct list *) head;
29.98 + else
29.99 + return (struct list *) pool->data + head->list_ptr;
29.100 +}
29.101 +
29.102 +struct list *
29.103 +list_next(struct list *list)
29.104 +{
29.105 + if (list->flags)
29.106 + return NULL;
29.107 + return ++list;
29.108 +}
29.109 +
29.110 +void
29.111 +list_remap_pool(struct array *pool, uint32_t *map)
29.112 +{
29.113 + struct list *p, *end;
29.114 +
29.115 + end = pool->data + pool->size;
29.116 + for (p = pool->data; p < end; p++)
29.117 + p->data = map[p->data];
29.118 +}
29.119 +
29.120 +void
29.121 +list_remap_head(struct list_head *head, uint32_t *map)
29.122 +{
29.123 + if (head->flags == RAZOR_IMMEDIATE)
29.124 + head->list_ptr = map[head->list_ptr];
29.125 +}
29.126 +
29.127 +
29.128 +void
29.129 +hashtable_init(struct hashtable *table, struct array *pool)
29.130 +{
29.131 + array_init(&table->buckets);
29.132 + table->pool = pool;
29.133 +}
29.134 +
29.135 +void
29.136 +hashtable_release(struct hashtable *table)
29.137 +{
29.138 + array_release(&table->buckets);
29.139 +}
29.140 +
29.141 +static unsigned int
29.142 +hash_string(const char *key)
29.143 +{
29.144 + const char *p;
29.145 + unsigned int hash = 0;
29.146 +
29.147 + for (p = key; *p; p++)
29.148 + hash = (hash * 617) ^ *p;
29.149 +
29.150 + return hash;
29.151 +}
29.152 +
29.153 +uint32_t
29.154 +hashtable_lookup(struct hashtable *table, const char *key)
29.155 +{
29.156 + unsigned int mask, start, i;
29.157 + uint32_t *b;
29.158 + char *pool;
29.159 +
29.160 + pool = table->pool->data;
29.161 + mask = table->buckets.alloc - 1;
29.162 + start = hash_string(key) * sizeof(uint32_t);
29.163 +
29.164 + for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
29.165 + b = table->buckets.data + ((start + i) & mask);
29.166 +
29.167 + if (*b == 0)
29.168 + return 0;
29.169 +
29.170 + if (strcmp(key, &pool[*b]) == 0)
29.171 + return *b;
29.172 + }
29.173 +
29.174 + return 0;
29.175 +}
29.176 +
29.177 +static void
29.178 +do_insert(struct hashtable *table, uint32_t value)
29.179 +{
29.180 + unsigned int mask, start, i;
29.181 + uint32_t *b;
29.182 + const char *key;
29.183 +
29.184 + key = (char *) table->pool->data + value;
29.185 + mask = table->buckets.alloc - 1;
29.186 + start = hash_string(key) * sizeof(uint32_t);
29.187 +
29.188 + for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
29.189 + b = table->buckets.data + ((start + i) & mask);
29.190 + if (*b == 0) {
29.191 + *b = value;
29.192 + break;
29.193 + }
29.194 + }
29.195 +}
29.196 +
29.197 +static uint32_t
29.198 +add_to_string_pool(struct hashtable *table, const char *key)
29.199 +{
29.200 + int len;
29.201 + char *p;
29.202 +
29.203 + len = strlen(key) + 1;
29.204 + p = array_add(table->pool, len);
29.205 + memcpy(p, key, len);
29.206 +
29.207 + return p - (char *) table->pool->data;
29.208 +}
29.209 +
29.210 +uint32_t
29.211 +hashtable_insert(struct hashtable *table, const char *key)
29.212 +{
29.213 + uint32_t value, *buckets, *b, *end;
29.214 + int alloc;
29.215 +
29.216 + alloc = table->buckets.alloc;
29.217 + array_add(&table->buckets, 4 * sizeof *buckets);
29.218 + if (alloc != table->buckets.alloc) {
29.219 + end = table->buckets.data + alloc;
29.220 + memset(end, 0, table->buckets.alloc - alloc);
29.221 + for (b = table->buckets.data; b < end; b++) {
29.222 + value = *b;
29.223 + if (value != 0) {
29.224 + *b = 0;
29.225 + do_insert(table, value);
29.226 + }
29.227 + }
29.228 + }
29.229 +
29.230 + value = add_to_string_pool(table, key);
29.231 + do_insert (table, value);
29.232 +
29.233 + return value;
29.234 +}
29.235 +
29.236 +uint32_t
29.237 +hashtable_tokenize(struct hashtable *table, const char *string)
29.238 +{
29.239 + uint32_t token;
29.240 +
29.241 + if (string == NULL)
29.242 + string = "";
29.243 +
29.244 + token = hashtable_lookup(table, string);
29.245 + if (token != 0)
29.246 + return token;
29.247 +
29.248 + return hashtable_insert(table, string);
29.249 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/librazor/util.c Fri Jun 20 19:04:47 2008 -0400
30.3 @@ -0,0 +1,167 @@
30.4 +#include <limits.h>
30.5 +#include <string.h>
30.6 +#include <sys/stat.h>
30.7 +#include <stdlib.h>
30.8 +#include <stdio.h>
30.9 +#include <stdint.h>
30.10 +#include <unistd.h>
30.11 +
30.12 +#include "razor-internal.h"
30.13 +
30.14 +int
30.15 +razor_create_dir(const char *root, const char *path)
30.16 +{
30.17 + char buffer[PATH_MAX], *p;
30.18 + const char *slash, *next;
30.19 + struct stat buf;
30.20 +
30.21 + /* Create all sub-directories in dir. We know root exists and
30.22 + * is a dir, root does not end in a '/', and path has a
30.23 + * leading '/'. */
30.24 +
30.25 + strcpy(buffer, root);
30.26 + p = buffer + strlen(buffer);
30.27 + slash = path;
30.28 + for (slash = path; *slash != '\0'; slash = next) {
30.29 + next = strchr(slash + 1, '/');
30.30 + if (next == NULL)
30.31 + break;
30.32 +
30.33 + memcpy(p, slash, next - slash);
30.34 + p += next - slash;
30.35 + *p = '\0';
30.36 +
30.37 + if (stat(buffer, &buf) == 0) {
30.38 + if (!S_ISDIR(buf.st_mode)) {
30.39 + fprintf(stderr,
30.40 + "%s exists but is not a directory\n",
30.41 + buffer);
30.42 + return -1;
30.43 + }
30.44 + } else if (mkdir(buffer, 0777) < 0) {
30.45 + fprintf(stderr, "failed to make directory %s: %m\n",
30.46 + buffer);
30.47 + return -1;
30.48 + }
30.49 +
30.50 + /* FIXME: What to do about permissions for dirs we
30.51 + * have to create but are not in the cpio archive? */
30.52 + }
30.53 +
30.54 + return 0;
30.55 +}
30.56 +
30.57 +int
30.58 +razor_write(int fd, const void *data, size_t size)
30.59 +{
30.60 + size_t rest;
30.61 + ssize_t written;
30.62 + const unsigned char *p;
30.63 +
30.64 + rest = size;
30.65 + p = data;
30.66 + while (rest > 0) {
30.67 + written = write(fd, p, rest);
30.68 + if (written < 0) {
30.69 + fprintf(stderr, "write error: %m\n");
30.70 + return -1;
30.71 + }
30.72 + rest -= written;
30.73 + p += written;
30.74 + }
30.75 +
30.76 + return 0;
30.77 +}
30.78 +
30.79 +struct qsort_context {
30.80 + size_t size;
30.81 + razor_compare_with_data_func_t compare;
30.82 + void *data;
30.83 +};
30.84 +
30.85 +static void
30.86 +qsort_swap(void *p1, void *p2, size_t size)
30.87 +{
30.88 + char buffer[size];
30.89 +
30.90 + memcpy(buffer, p1, size);
30.91 + memcpy(p1, p2, size);
30.92 + memcpy(p2, buffer, size);
30.93 +}
30.94 +
30.95 +static void
30.96 +__qsort_with_data(void *base, size_t nelem, uint32_t *map,
30.97 + struct qsort_context *ctx)
30.98 +{
30.99 + void *p, *start, *end, *pivot;
30.100 + uint32_t *mp, *mstart, *mend, tmp;
30.101 + int left, right, result;
30.102 + size_t size = ctx->size;
30.103 +
30.104 + p = base;
30.105 + start = base;
30.106 + end = base + nelem * size;
30.107 + mp = map;
30.108 + mstart = map;
30.109 + mend = map + nelem;
30.110 + pivot = base + (random() % nelem) * size;
30.111 +
30.112 + while (p < end) {
30.113 + result = ctx->compare(p, pivot, ctx->data);
30.114 + if (result < 0) {
30.115 + qsort_swap(p, start, size);
30.116 + tmp = *mp;
30.117 + *mp = *mstart;
30.118 + *mstart = tmp;
30.119 + if (start == pivot)
30.120 + pivot = p;
30.121 + start += size;
30.122 + mstart++;
30.123 + p += size;
30.124 + mp++;
30.125 + } else if (result == 0) {
30.126 + p += size;
30.127 + mp++;
30.128 + } else {
30.129 + end -= size;
30.130 + mend--;
30.131 + qsort_swap(p, end, size);
30.132 + tmp = *mp;
30.133 + *mp = *mend;
30.134 + *mend = tmp;
30.135 + if (end == pivot)
30.136 + pivot = p;
30.137 + }
30.138 + }
30.139 +
30.140 + left = (start - base) / size;
30.141 + right = (base + nelem * size - end) / size;
30.142 + if (left > 1)
30.143 + __qsort_with_data(base, left, map, ctx);
30.144 + if (right > 1)
30.145 + __qsort_with_data(end, right, mend, ctx);
30.146 +}
30.147 +
30.148 +uint32_t *
30.149 +razor_qsort_with_data(void *base, size_t nelem, size_t size,
30.150 + razor_compare_with_data_func_t compare, void *data)
30.151 +{
30.152 + struct qsort_context ctx;
30.153 + uint32_t *map;
30.154 + int i;
30.155 +
30.156 + if (nelem == 0)
30.157 + return NULL;
30.158 +
30.159 + ctx.size = size;
30.160 + ctx.compare = compare;
30.161 + ctx.data = data;
30.162 +
30.163 + map = malloc(nelem * sizeof (uint32_t));
30.164 + for (i = 0; i < nelem; i++)
30.165 + map[i] = i;
30.166 +
30.167 + __qsort_with_data(base, nelem, map, &ctx);
30.168 +
30.169 + return map;
30.170 +}
31.1 --- a/main.c Sun Jun 15 18:16:20 2008 -0400
31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
31.3 @@ -1,915 +0,0 @@
31.4 -/*
31.5 - * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
31.6 - * Copyright (C) 2008 Red Hat, Inc
31.7 - *
31.8 - * This program is free software; you can redistribute it and/or modify
31.9 - * it under the terms of the GNU General Public License as published by
31.10 - * the Free Software Foundation; either version 2 of the License, or
31.11 - * (at your option) any later version.
31.12 - *
31.13 - * This program is distributed in the hope that it will be useful,
31.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
31.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31.16 - * GNU General Public License for more details.
31.17 - *
31.18 - * You should have received a copy of the GNU General Public License along
31.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
31.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31.21 - */
31.22 -
31.23 -#include <stdlib.h>
31.24 -#include <stddef.h>
31.25 -#include <stdio.h>
31.26 -#include <stdint.h>
31.27 -#include <string.h>
31.28 -#include <sys/stat.h>
31.29 -#include <unistd.h>
31.30 -#include <fcntl.h>
31.31 -#include <dirent.h>
31.32 -#include <curl/curl.h>
31.33 -#include <fnmatch.h>
31.34 -#include <errno.h>
31.35 -#include "razor.h"
31.36 -#include "razor-internal.h"
31.37 -
31.38 -static const char system_repo_filename[] = "system.repo";
31.39 -static const char next_repo_filename[] = "system-next.repo";
31.40 -static const char rawhide_repo_filename[] = "rawhide.repo";
31.41 -static const char updated_repo_filename[] = "system-updated.repo";
31.42 -static const char razor_root_path[] = "/var/lib/razor";
31.43 -static const char root[] = "install";
31.44 -static const char *repo_filename = system_repo_filename;
31.45 -
31.46 -static int
31.47 -command_list(int argc, const char *argv[])
31.48 -{
31.49 - struct razor_set *set;
31.50 - struct razor_package_iterator *pi;
31.51 - struct razor_package *package;
31.52 - const char *pattern, *name, *version, *arch;
31.53 - int only_names = 0, i = 0;
31.54 -
31.55 - if (i < argc && strcmp(argv[i], "--only-names") == 0) {
31.56 - only_names = 1;
31.57 - i++;
31.58 - }
31.59 -
31.60 - pattern = argv[i];
31.61 - set = razor_set_open(repo_filename);
31.62 - pi = razor_package_iterator_create(set);
31.63 - while (razor_package_iterator_next(pi, &package,
31.64 - &name, &version, &arch)) {
31.65 - if (pattern && fnmatch(pattern, name, 0) != 0)
31.66 - continue;
31.67 -
31.68 - if (only_names)
31.69 - printf("%s\n", name);
31.70 - else
31.71 - printf("%s-%s.%s\n", name, version, arch);
31.72 - }
31.73 - razor_package_iterator_destroy(pi);
31.74 - razor_set_destroy(set);
31.75 -
31.76 - return 0;
31.77 -}
31.78 -
31.79 -static int
31.80 -list_properties(const char *package_name,
31.81 - enum razor_property_type required_type)
31.82 -{
31.83 - struct razor_set *set;
31.84 - struct razor_property *property;
31.85 - struct razor_package *package;
31.86 - struct razor_property_iterator *pi;
31.87 - const char *name, *version;
31.88 - enum razor_property_type type;
31.89 - enum razor_version_relation relation;
31.90 -
31.91 - set = razor_set_open(repo_filename);
31.92 - if (package_name)
31.93 - package = razor_set_get_package(set, package_name);
31.94 - else
31.95 - package = NULL;
31.96 -
31.97 - pi = razor_property_iterator_create(set, package);
31.98 - while (razor_property_iterator_next(pi, &property,
31.99 - &name, &relation, &version,
31.100 - &type)) {
31.101 - if (type != required_type)
31.102 - continue;
31.103 - if (version[0] == '\0')
31.104 - printf("%s\n", name);
31.105 - else
31.106 - printf("%s %s %s\n", name,
31.107 - razor_version_relations[relation], version);
31.108 - }
31.109 - razor_property_iterator_destroy(pi);
31.110 -
31.111 - razor_set_destroy(set);
31.112 -
31.113 - return 0;
31.114 -}
31.115 -
31.116 -static int
31.117 -command_list_requires(int argc, const char *argv[])
31.118 -{
31.119 - return list_properties(argv[0], RAZOR_PROPERTY_REQUIRES);
31.120 -}
31.121 -
31.122 -static int
31.123 -command_list_provides(int argc, const char *argv[])
31.124 -{
31.125 - return list_properties(argv[0], RAZOR_PROPERTY_PROVIDES);
31.126 -}
31.127 -
31.128 -static int
31.129 -command_list_obsoletes(int argc, const char *argv[])
31.130 -{
31.131 - return list_properties(argv[0], RAZOR_PROPERTY_OBSOLETES);
31.132 -}
31.133 -
31.134 -static int
31.135 -command_list_conflicts(int argc, const char *argv[])
31.136 -{
31.137 - return list_properties(argv[0], RAZOR_PROPERTY_CONFLICTS);
31.138 -}
31.139 -
31.140 -static int
31.141 -command_list_files(int argc, const char *argv[])
31.142 -{
31.143 - struct razor_set *set;
31.144 -
31.145 - set = razor_set_open(repo_filename);
31.146 - razor_set_open_files(set, "system-files.repo");
31.147 - if (set == NULL)
31.148 - return 1;
31.149 - razor_set_list_files(set, argv[0]);
31.150 - razor_set_destroy(set);
31.151 -
31.152 - return 0;
31.153 -}
31.154 -
31.155 -static int
31.156 -command_list_file_packages(int argc, const char *argv[])
31.157 -{
31.158 - struct razor_set *set;
31.159 - struct razor_package_iterator *pi;
31.160 - struct razor_package *package;
31.161 - const char *name, *version, *arch;
31.162 -
31.163 - set = razor_set_open(repo_filename);
31.164 - razor_set_open_files(set, "system-files.repo");
31.165 - if (set == NULL)
31.166 - return 1;
31.167 -
31.168 - pi = razor_package_iterator_create_for_file(set, argv[0]);
31.169 - while (razor_package_iterator_next(pi, &package,
31.170 - &name, &version, &arch))
31.171 - printf("%s-%s\n", name, version);
31.172 - razor_package_iterator_destroy(pi);
31.173 -
31.174 - razor_set_destroy(set);
31.175 -
31.176 - return 0;
31.177 -}
31.178 -
31.179 -static int
31.180 -command_list_package_files(int argc, const char *argv[])
31.181 -{
31.182 - struct razor_set *set;
31.183 -
31.184 - set = razor_set_open(repo_filename);
31.185 - razor_set_open_files(set, "system-files.repo");
31.186 - if (set == NULL)
31.187 - return 1;
31.188 - razor_set_list_package_files(set, argv[0]);
31.189 - razor_set_destroy(set);
31.190 -
31.191 - return 0;
31.192 -}
31.193 -
31.194 -static void
31.195 -list_packages_for_property(struct razor_set *set,
31.196 - struct razor_property *property)
31.197 -{
31.198 - struct razor_package_iterator *pi;
31.199 - struct razor_package *package;
31.200 - const char *name, *version, *arch;
31.201 -
31.202 - pi = razor_package_iterator_create_for_property(set, property);
31.203 - while (razor_package_iterator_next(pi, &package,
31.204 - &name, &version, &arch))
31.205 - printf("%s-%s.%s\n", name, version, arch);
31.206 - razor_package_iterator_destroy(pi);
31.207 -}
31.208 -
31.209 -static int
31.210 -list_property_packages(const char *ref_name,
31.211 - const char *ref_version,
31.212 - enum razor_property_type ref_type)
31.213 -{
31.214 - struct razor_set *set;
31.215 - struct razor_property *property;
31.216 - struct razor_property_iterator *pi;
31.217 - const char *name, *version;
31.218 - enum razor_property_type type;
31.219 - enum razor_version_relation relation;
31.220 -
31.221 - if (ref_name == NULL)
31.222 - return 0;
31.223 -
31.224 - set = razor_set_open(repo_filename);
31.225 - if (set == NULL)
31.226 - return 1;
31.227 -
31.228 - pi = razor_property_iterator_create(set, NULL);
31.229 - while (razor_property_iterator_next(pi, &property,
31.230 - &name, &relation, &version,
31.231 - &type)) {
31.232 - if (strcmp(ref_name, name) != 0)
31.233 - continue;
31.234 - if (ref_version && relation == RAZOR_VERSION_EQUAL &&
31.235 - strcmp(ref_version, version) != 0)
31.236 - continue;
31.237 - if (ref_type != type)
31.238 - continue;
31.239 -
31.240 - list_packages_for_property(set, property);
31.241 - }
31.242 - razor_property_iterator_destroy(pi);
31.243 -
31.244 - return 0;
31.245 -}
31.246 -
31.247 -static int
31.248 -command_what_requires(int argc, const char *argv[])
31.249 -{
31.250 - return list_property_packages(argv[0], argv[1],
31.251 - RAZOR_PROPERTY_REQUIRES);
31.252 -}
31.253 -
31.254 -static int
31.255 -command_what_provides(int argc, const char *argv[])
31.256 -{
31.257 - return list_property_packages(argv[0], argv[1],
31.258 - RAZOR_PROPERTY_PROVIDES);
31.259 -}
31.260 -
31.261 -static int
31.262 -show_progress(void *clientp,
31.263 - double dltotal, double dlnow, double ultotal, double ulnow)
31.264 -{
31.265 - const char *file = clientp;
31.266 -
31.267 - if (!dlnow < dltotal)
31.268 - fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
31.269 - file, (int) dlnow / 1024, (int) dltotal / 1024);
31.270 -
31.271 - return 0;
31.272 -}
31.273 -
31.274 -static int
31.275 -download_if_missing(const char *url, const char *file)
31.276 -{
31.277 - CURL *curl;
31.278 - struct stat buf;
31.279 - char error[256];
31.280 - FILE *fp;
31.281 - CURLcode res;
31.282 - long response;
31.283 -
31.284 - curl = curl_easy_init();
31.285 - if (curl == NULL)
31.286 - return 1;
31.287 -
31.288 - curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
31.289 - curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
31.290 - curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
31.291 - curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
31.292 -
31.293 - if (stat(file, &buf) < 0) {
31.294 - fp = fopen(file, "w");
31.295 - if (fp == NULL) {
31.296 - fprintf(stderr,
31.297 - "failed to open %s for writing\n", file);
31.298 - return -1;
31.299 - }
31.300 - curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
31.301 - curl_easy_setopt(curl, CURLOPT_URL, url);
31.302 - res = curl_easy_perform(curl);
31.303 - fclose(fp);
31.304 - if (res != CURLE_OK) {
31.305 - fprintf(stderr, "curl error: %s\n", error);
31.306 - unlink(file);
31.307 - return -1;
31.308 - }
31.309 - res = curl_easy_getinfo(curl,
31.310 - CURLINFO_RESPONSE_CODE, &response);
31.311 - if (res != CURLE_OK) {
31.312 - fprintf(stderr, "curl error: %s\n", error);
31.313 - unlink(file);
31.314 - return -1;
31.315 - }
31.316 - if (response != 200) {
31.317 - fprintf(stderr, " - failed %ld\n", response);
31.318 - unlink(file);
31.319 - return -1;
31.320 - }
31.321 - fprintf(stderr, "\n");
31.322 - }
31.323 -
31.324 - curl_easy_cleanup(curl);
31.325 -
31.326 - return 0;
31.327 -}
31.328 -
31.329 -#define REPO_URL "http://download.fedora.redhat.com" \
31.330 - "/pub/fedora/linux/development/i386/os"
31.331 -
31.332 -static int
31.333 -command_import_yum(int argc, const char *argv[])
31.334 -{
31.335 - struct razor_set *set;
31.336 -
31.337 - if (download_if_missing(REPO_URL "/repodata/primary.xml.gz",
31.338 - "primary.xml.gz") < 0)
31.339 - return -1;
31.340 - if (download_if_missing(REPO_URL "/repodata/filelists.xml.gz",
31.341 - "filelists.xml.gz") < 0)
31.342 - return -1;
31.343 -
31.344 - set = razor_set_create_from_yum();
31.345 - if (set == NULL)
31.346 - return 1;
31.347 - razor_set_write(set, rawhide_repo_filename, RAZOR_REPO_FILE_MAIN);
31.348 - razor_set_write(set, "rawhide-details.repo", RAZOR_REPO_FILE_DETAILS);
31.349 - razor_set_write(set, "rawhide-files.repo", RAZOR_REPO_FILE_FILES);
31.350 - razor_set_destroy(set);
31.351 - printf("wrote %s\n", rawhide_repo_filename);
31.352 -
31.353 - return 0;
31.354 -}
31.355 -
31.356 -static int
31.357 -command_import_rpmdb(int argc, const char *argv[])
31.358 -{
31.359 - struct razor_set *set;
31.360 -
31.361 - set = razor_set_create_from_rpmdb();
31.362 - if (set == NULL)
31.363 - return 1;
31.364 - razor_set_write(set, repo_filename, RAZOR_REPO_FILE_MAIN);
31.365 - razor_set_write(set, "system-details.repo", RAZOR_REPO_FILE_DETAILS);
31.366 - razor_set_write(set, "system-files.repo", RAZOR_REPO_FILE_FILES);
31.367 - razor_set_destroy(set);
31.368 - printf("wrote %s\n", repo_filename);
31.369 -
31.370 - return 0;
31.371 -}
31.372 -
31.373 -static int
31.374 -command_validate(int argc, const char *argv[])
31.375 -{
31.376 - struct razor_set *set;
31.377 -
31.378 - set = razor_set_open(repo_filename);
31.379 - if (set == NULL)
31.380 - return 1;
31.381 - razor_set_list_unsatisfied(set);
31.382 - razor_set_destroy(set);
31.383 -
31.384 - return 0;
31.385 -}
31.386 -
31.387 -static int
31.388 -mark_packages_for_update(struct razor_transaction *trans,
31.389 - struct razor_set *set, const char *pattern)
31.390 -{
31.391 - struct razor_package_iterator *pi;
31.392 - struct razor_package *package;
31.393 - const char *name, *version, *arch;
31.394 - int matches = 0;
31.395 -
31.396 - pi = razor_package_iterator_create(set);
31.397 - while (razor_package_iterator_next(pi, &package,
31.398 - &name, &version, &arch)) {
31.399 - if (pattern && fnmatch(pattern, name, 0) == 0) {
31.400 - razor_transaction_install_package(trans, package);
31.401 - matches++;
31.402 - }
31.403 - }
31.404 - razor_package_iterator_destroy(pi);
31.405 -
31.406 - return matches;
31.407 -}
31.408 -
31.409 -static int
31.410 -mark_packages_for_removal(struct razor_transaction *trans,
31.411 - struct razor_set *set, const char *pattern)
31.412 -{
31.413 - struct razor_package_iterator *pi;
31.414 - struct razor_package *package;
31.415 - const char *name, *version, *arch;
31.416 - int matches = 0;
31.417 -
31.418 - pi = razor_package_iterator_create(set);
31.419 - while (razor_package_iterator_next(pi, &package,
31.420 - &name, &version, &arch)) {
31.421 - if (pattern && fnmatch(pattern, name, 0) == 0) {
31.422 - razor_transaction_remove_package(trans, package);
31.423 - matches++;
31.424 - }
31.425 - }
31.426 - razor_package_iterator_destroy(pi);
31.427 -
31.428 - return matches;
31.429 -}
31.430 -
31.431 -static int
31.432 -command_update(int argc, const char *argv[])
31.433 -{
31.434 - struct razor_set *set, *upstream;
31.435 - struct razor_transaction *trans;
31.436 - int i, errors;
31.437 -
31.438 - set = razor_set_open(repo_filename);
31.439 - upstream = razor_set_open(rawhide_repo_filename);
31.440 - if (set == NULL || upstream == NULL)
31.441 - return 1;
31.442 -
31.443 - trans = razor_transaction_create(set, upstream);
31.444 - if (argc == 0)
31.445 - razor_transaction_update_all(trans);
31.446 - for (i = 0; i < argc; i++) {
31.447 - if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
31.448 - fprintf(stderr, "no match for %s\n", argv[i]);
31.449 - return 1;
31.450 - }
31.451 - }
31.452 -
31.453 - errors = razor_transaction_resolve(trans);
31.454 - if (errors)
31.455 - return 1;
31.456 -
31.457 - set = razor_transaction_finish(trans);
31.458 - razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
31.459 - razor_set_destroy(set);
31.460 - razor_set_destroy(upstream);
31.461 - printf("wrote system-updated.repo\n");
31.462 -
31.463 - return 0;
31.464 -}
31.465 -
31.466 -static int
31.467 -command_remove(int argc, const char *argv[])
31.468 -{
31.469 - struct razor_set *set;
31.470 - struct razor_transaction *trans;
31.471 - int i, errors;
31.472 -
31.473 - set = razor_set_open(repo_filename);
31.474 - if (set == NULL)
31.475 - return 1;
31.476 -
31.477 - trans = razor_transaction_create(set, NULL);
31.478 - for (i = 0; i < argc; i++) {
31.479 - if (mark_packages_for_removal(trans, set, argv[i]) == 0) {
31.480 - fprintf(stderr, "no match for %s\n", argv[i]);
31.481 - return 1;
31.482 - }
31.483 - }
31.484 -
31.485 - errors = razor_transaction_resolve(trans);
31.486 - if (errors)
31.487 - return 1;
31.488 -
31.489 - set = razor_transaction_finish(trans);
31.490 - razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
31.491 - razor_set_destroy(set);
31.492 - printf("wrote system-updated.repo\n");
31.493 -
31.494 - return 0;
31.495 -}
31.496 -
31.497 -static void
31.498 -print_diff(const char *name,
31.499 - const char *old_version, const char *new_version, const char *arch,
31.500 - void *data)
31.501 -{
31.502 - if (old_version)
31.503 - printf("removing %s %s\n", name, old_version);
31.504 - else
31.505 - printf("install %s %s\n", name, new_version);
31.506 -}
31.507 -
31.508 -static int
31.509 -command_diff(int argc, const char *argv[])
31.510 -{
31.511 - struct razor_set *set, *updated;
31.512 -
31.513 - set = razor_set_open(repo_filename);
31.514 - updated = razor_set_open(updated_repo_filename);
31.515 - if (set == NULL || updated == NULL)
31.516 - return 1;
31.517 -
31.518 - razor_set_diff(set, updated, print_diff, NULL);
31.519 -
31.520 - razor_set_destroy(set);
31.521 - razor_set_destroy(updated);
31.522 -
31.523 - return 0;
31.524 -}
31.525 -
31.526 -static int
31.527 -command_import_rpms(int argc, const char *argv[])
31.528 -{
31.529 - DIR *dir;
31.530 - struct dirent *de;
31.531 - struct razor_importer *importer;
31.532 - struct razor_set *set;
31.533 - struct razor_rpm *rpm;
31.534 - int len;
31.535 - char filename[256];
31.536 - const char *dirname = argv[0];
31.537 -
31.538 - if (dirname == NULL) {
31.539 - fprintf(stderr, "usage: razor import-rpms DIR\n");
31.540 - return -1;
31.541 - }
31.542 -
31.543 - dir = opendir(dirname);
31.544 - if (dir == NULL) {
31.545 - fprintf(stderr, "couldn't read dir %s\n", dirname);
31.546 - return -1;
31.547 - }
31.548 -
31.549 - importer = razor_importer_new();
31.550 -
31.551 - while (de = readdir(dir), de != NULL) {
31.552 - len = strlen(de->d_name);
31.553 - if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
31.554 - continue;
31.555 - snprintf(filename, sizeof filename,
31.556 - "%s/%s", dirname, de->d_name);
31.557 - rpm = razor_rpm_open(filename);
31.558 - if (rpm == NULL) {
31.559 - fprintf(stderr,
31.560 - "failed to open rpm \"%s\"\n", filename);
31.561 - continue;
31.562 - }
31.563 - if (razor_importer_add_rpm(importer, rpm)) {
31.564 - fprintf(stderr, "couldn't import %s\n", filename);
31.565 - break;
31.566 - }
31.567 - razor_rpm_close(rpm);
31.568 - }
31.569 -
31.570 - if (de != NULL) {
31.571 - razor_importer_destroy(importer);
31.572 - return -1;
31.573 - }
31.574 -
31.575 - set = razor_importer_finish(importer);
31.576 -
31.577 - razor_set_write(set, repo_filename, RAZOR_REPO_FILE_MAIN);
31.578 - razor_set_destroy(set);
31.579 - printf("wrote %s\n", repo_filename);
31.580 -
31.581 - return 0;
31.582 -}
31.583 -
31.584 -static void
31.585 -download_package(const char *name,
31.586 - const char *old_version,
31.587 - const char *new_version,
31.588 - const char *arch,
31.589 - void *data)
31.590 -{
31.591 - char file[PATH_MAX], url[256];
31.592 - const char *v;
31.593 - int *errors = data;
31.594 -
31.595 - if (old_version)
31.596 - return;
31.597 -
31.598 - /* Skip epoch */
31.599 - v = strchr(new_version, ':');
31.600 - if (v != NULL)
31.601 - v = v + 1;
31.602 - else
31.603 - v = new_version;
31.604 -
31.605 - snprintf(url, sizeof url,
31.606 - REPO_URL "/Packages/%s-%s.%s.rpm", name, v, arch);
31.607 - snprintf(file, sizeof file,
31.608 - "rpms/%s-%s.%s.rpm", name, v, arch);
31.609 - if (download_if_missing(url, file) < 0)
31.610 - (*errors)++;
31.611 -}
31.612 -
31.613 -static void
31.614 -install_package(const char *name,
31.615 - const char *old_version,
31.616 - const char *new_version,
31.617 - const char *arch,
31.618 - void *data)
31.619 -{
31.620 - const char *v, *root = data;
31.621 - char file[PATH_MAX];
31.622 - struct razor_rpm *rpm;
31.623 -
31.624 - if (old_version) {
31.625 - printf("removing %s %s not handled\n", name, old_version);
31.626 - return;
31.627 - }
31.628 -
31.629 - /* Skip epoch */
31.630 - v = strchr(new_version, ':');
31.631 - if (v != NULL)
31.632 - v = v + 1;
31.633 - else
31.634 - v = new_version;
31.635 -
31.636 - printf("install %s %s\n", name, v);
31.637 - snprintf(file, sizeof file, "rpms/%s-%s.%s.rpm", name, v, arch);
31.638 -
31.639 - rpm = razor_rpm_open(file);
31.640 - if (rpm == NULL) {
31.641 - fprintf(stderr, "failed to open rpm %s\n", file);
31.642 - return;
31.643 - }
31.644 - if (razor_rpm_install(rpm, root) < 0) {
31.645 - fprintf(stderr,
31.646 - "failed to install rpm %s\n", file);
31.647 - return;
31.648 - }
31.649 - razor_rpm_close(rpm);
31.650 -}
31.651 -
31.652 -static int
31.653 -command_install(int argc, const char *argv[])
31.654 -{
31.655 - struct razor_set *system, *upstream, *next;
31.656 - struct razor_transaction *trans;
31.657 - char path[PATH_MAX], new_path[PATH_MAX];
31.658 - int i = 0, errors, fd, dependencies = 1;
31.659 -
31.660 - if (i < argc && strcmp(argv[i], "--no-dependencies") == 0) {
31.661 - dependencies = 0;
31.662 - i++;
31.663 - }
31.664 -
31.665 - /* Create the new next repo file up front to ensure exclusive
31.666 - * access. */
31.667 - snprintf(new_path, sizeof new_path,
31.668 - "%s%s/%s", root, razor_root_path, next_repo_filename);
31.669 - fd = open(new_path, O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
31.670 - if (fd < 0) {
31.671 - fprintf(stderr, "failed to get lock file, "
31.672 - "maybe previous operation crashed?\n");
31.673 -
31.674 - /* FIXME: Use fcntl advisory locking to figure out
31.675 - * whether previous operation crashed or is still in
31.676 - * progress. */
31.677 -
31.678 - return -1;
31.679 - }
31.680 -
31.681 - upstream = razor_set_open(rawhide_repo_filename);
31.682 - snprintf(path, sizeof path,
31.683 - "%s%s/%s", root, razor_root_path, system_repo_filename);
31.684 - system = razor_set_open(path);
31.685 - if (system == NULL || upstream == NULL) {
31.686 - unlink(new_path);
31.687 - return 1;
31.688 - }
31.689 - trans = razor_transaction_create(system, upstream);
31.690 - for (; i < argc; i++) {
31.691 - if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
31.692 - fprintf(stderr, "no package matched %s\n", argv[i]);
31.693 - unlink(new_path);
31.694 - return 1;
31.695 - }
31.696 - }
31.697 -
31.698 - if (dependencies) {
31.699 - errors = razor_transaction_resolve(trans);
31.700 - if (errors) {
31.701 - unlink(new_path);
31.702 - return 1;
31.703 - }
31.704 - }
31.705 -
31.706 - next = razor_transaction_finish(trans);
31.707 -
31.708 - razor_set_write_to_fd(next, fd, RAZOR_REPO_FILE_MAIN);
31.709 - printf("wrote %s\n", new_path);
31.710 -
31.711 - if (mkdir("rpms", 0777) && errno != EEXIST) {
31.712 - fprintf(stderr, "failed to create rpms directory.\n");
31.713 - return 1;
31.714 - }
31.715 -
31.716 - razor_set_diff(system, next, download_package, &errors);
31.717 - if (errors > 0) {
31.718 - fprintf(stderr, "failed to download %d packages\n", errors);
31.719 - unlink(new_path);
31.720 - return 1;
31.721 - }
31.722 -
31.723 - /* FIXME: We need to figure out the right install order here,
31.724 - * so the post and pre scripts can run. */
31.725 - razor_set_diff(system, next, install_package, (void *) root);
31.726 -
31.727 - razor_set_destroy(next);
31.728 - razor_set_destroy(system);
31.729 - razor_set_destroy(upstream);
31.730 -
31.731 - /* Make it so. */
31.732 - rename(new_path, path);
31.733 - printf("renamed %s to %s\n", new_path, path);
31.734 -
31.735 - return 0;
31.736 -}
31.737 -
31.738 -static int
31.739 -command_init(int argc, const char *argv[])
31.740 -{
31.741 - struct stat buf;
31.742 - struct razor_set *set;
31.743 - char path[PATH_MAX];
31.744 -
31.745 - if (stat(root, &buf) < 0) {
31.746 - if (mkdir(root, 0777) < 0) {
31.747 - fprintf(stderr,
31.748 - "could not create install root \"%s\"\n",
31.749 - root);
31.750 - return -1;
31.751 - }
31.752 - fprintf(stderr, "created install root \"%s\"\n", root);
31.753 - } else if (!S_ISDIR(buf.st_mode)) {
31.754 - fprintf(stderr,
31.755 - "install root \"%s\" exists, but is not a directory\n",
31.756 - root);
31.757 - return -1;
31.758 - }
31.759 -
31.760 - snprintf(path, sizeof path, "%s/%s",
31.761 - razor_root_path, system_repo_filename);
31.762 - if (razor_create_dir(root, path) < 0) {
31.763 - fprintf(stderr, "could not create %s%s\n",
31.764 - root, razor_root_path);
31.765 - return -1;
31.766 - }
31.767 -
31.768 - set = razor_set_create();
31.769 - snprintf(path, sizeof path, "%s%s/%s",
31.770 - root, razor_root_path, system_repo_filename);
31.771 - if (razor_set_write(set, path, RAZOR_REPO_FILE_MAIN) < 0) {
31.772 - fprintf(stderr, "could not write initial package set\n");
31.773 - return -1;
31.774 - }
31.775 - razor_set_destroy(set);
31.776 -
31.777 - return 0;
31.778 -}
31.779 -
31.780 -static int
31.781 -command_download(int argc, const char *argv[])
31.782 -{
31.783 - struct razor_set *set;
31.784 - struct razor_package_iterator *pi;
31.785 - struct razor_package *package;
31.786 - const char *pattern = argv[0], *name, *version, *arch;
31.787 - char url[256], file[256];
31.788 - int matches = 0;
31.789 -
31.790 - if (mkdir("rpms", 0777) && errno != EEXIST) {
31.791 - fprintf(stderr, "failed to create rpms directory.\n");
31.792 - return 1;
31.793 - }
31.794 -
31.795 - set = razor_set_open(rawhide_repo_filename);
31.796 - pi = razor_package_iterator_create(set);
31.797 - while (razor_package_iterator_next(pi, &package,
31.798 - &name, &version, &arch)) {
31.799 - if (pattern && fnmatch(pattern, name, 0) != 0)
31.800 - continue;
31.801 -
31.802 - matches++;
31.803 - snprintf(url, sizeof url,
31.804 - REPO_URL "/Packages/%s-%s.%s.rpm",
31.805 - name, version, arch);
31.806 - snprintf(file, sizeof file,
31.807 - "rpms/%s-%s.%s.rpm", name, version, arch);
31.808 - download_if_missing(url, file);
31.809 - }
31.810 - razor_package_iterator_destroy(pi);
31.811 - razor_set_destroy(set);
31.812 -
31.813 - if (matches == 0)
31.814 - fprintf(stderr, "no packages matched \"%s\"\n", pattern);
31.815 - else if (matches == 1)
31.816 - fprintf(stderr, "downloaded 1 package\n");
31.817 - else
31.818 - fprintf(stderr, "downloaded %d packages\n", matches);
31.819 -
31.820 - return 0;
31.821 -}
31.822 -
31.823 -static int
31.824 -command_info(int argc, const char *argv[])
31.825 -{
31.826 - struct razor_set *set;
31.827 - struct razor_package_iterator *pi;
31.828 - struct razor_package *package;
31.829 - const char *pattern = argv[0], *name, *version, *arch;
31.830 - const char *summary, *description, *url, *license;
31.831 -
31.832 - set = razor_set_open(repo_filename);
31.833 - razor_set_open_details(set, "system-details.repo");
31.834 - pi = razor_package_iterator_create(set);
31.835 - while (razor_package_iterator_next(pi, &package,
31.836 - &name, &version, &arch)) {
31.837 - if (pattern && fnmatch(pattern, name, 0) != 0)
31.838 - continue;
31.839 -
31.840 - razor_package_get_details (set, package, &summary, &description,
31.841 - &url, &license);
31.842 -
31.843 - printf ("Name: %s\n", name);
31.844 - printf ("Arch: %s\n", arch);
31.845 - printf ("Version: %s\n", version);
31.846 - printf ("URL: %s\n", url);
31.847 - printf ("License: %s\n", license);
31.848 - printf ("Summary: %s\n", summary);
31.849 - printf ("Description:\n");
31.850 - printf ("%s\n", description);
31.851 - printf ("\n");
31.852 - }
31.853 - razor_package_iterator_destroy(pi);
31.854 - razor_set_destroy(set);
31.855 -
31.856 - return 0;
31.857 -}
31.858 -
31.859 -static struct {
31.860 - const char *name;
31.861 - const char *description;
31.862 - int (*func)(int argc, const char *argv[]);
31.863 -} razor_commands[] = {
31.864 - { "list", "list all packages", command_list },
31.865 - { "list-requires", "list all requires for the given package", command_list_requires },
31.866 - { "list-provides", "list all provides for the given package", command_list_provides },
31.867 - { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
31.868 - { "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
31.869 - { "list-files", "list files for package set", command_list_files },
31.870 - { "list-file-packages", "list packages owning file", command_list_file_packages },
31.871 - { "list-package-files", "list files in package", command_list_package_files },
31.872 - { "what-requires", "list the packages that have the given requires", command_what_requires },
31.873 - { "what-provides", "list the packages that have the given provides", command_what_provides },
31.874 - { "import-yum", "import yum metadata files", command_import_yum },
31.875 - { "import-rpmdb", "import the system rpm database", command_import_rpmdb },
31.876 - { "import-rpms", "import rpms from the given directory", command_import_rpms },
31.877 - { "validate", "validate a package set", command_validate },
31.878 - { "update", "update all or specified packages", command_update },
31.879 - { "remove", "remove specified packages", command_remove },
31.880 - { "diff", "show diff between two package sets", command_diff },
31.881 - { "install", "install rpm", command_install },
31.882 - { "init", "init razor root", command_init },
31.883 - { "download", "download packages", command_download },
31.884 - { "info", "display package details", command_info }
31.885 -};
31.886 -
31.887 -static int
31.888 -usage(void)
31.889 -{
31.890 - int i;
31.891 -
31.892 - printf("usage:\n");
31.893 - for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
31.894 - printf(" %-20s%s\n",
31.895 - razor_commands[i].name, razor_commands[i].description);
31.896 -
31.897 - return 1;
31.898 -}
31.899 -
31.900 -int
31.901 -main(int argc, const char *argv[])
31.902 -{
31.903 - char *repo;
31.904 - int i;
31.905 -
31.906 - repo = getenv("RAZOR_REPO");
31.907 - if (repo != NULL)
31.908 - repo_filename = repo;
31.909 -
31.910 - if (argc < 2)
31.911 - return usage();
31.912 -
31.913 - for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
31.914 - if (strcmp(razor_commands[i].name, argv[1]) == 0)
31.915 - return razor_commands[i].func(argc - 2, argv + 2);
31.916 -
31.917 - return usage();
31.918 -}
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
32.2 +++ b/po/.gitignore Fri Jun 20 19:04:47 2008 -0400
32.3 @@ -0,0 +1,4 @@
32.4 +POTFILES
32.5 +Makefile.in.in
32.6 +stamp-it
32.7 +
33.1 --- a/razor-internal.h Sun Jun 15 18:16:20 2008 -0400
33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
33.3 @@ -1,19 +0,0 @@
33.4 -#ifndef _RAZOR_INTERNAL_H_
33.5 -#define _RAZOR_INTERNAL_H_
33.6 -
33.7 -#define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
33.8 -
33.9 -/* Utility functions */
33.10 -
33.11 -int razor_create_dir(const char *root, const char *path);
33.12 -int razor_write(int fd, const void *data, size_t size);
33.13 -
33.14 -
33.15 -typedef int (*razor_compare_with_data_func_t)(const void *p1,
33.16 - const void *p,
33.17 - void *data);
33.18 -uint32_t *
33.19 -razor_qsort_with_data(void *base, size_t nelem, size_t size,
33.20 - razor_compare_with_data_func_t compare, void *data);
33.21 -
33.22 -#endif /* _RAZOR_INTERNAL_H_ */
34.1 --- a/razor.c Sun Jun 15 18:16:20 2008 -0400
34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
34.3 @@ -1,3244 +0,0 @@
34.4 -/*
34.5 - * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
34.6 - * Copyright (C) 2008 Red Hat, Inc
34.7 - *
34.8 - * This program is free software; you can redistribute it and/or modify
34.9 - * it under the terms of the GNU General Public License as published by
34.10 - * the Free Software Foundation; either version 2 of the License, or
34.11 - * (at your option) any later version.
34.12 - *
34.13 - * This program is distributed in the hope that it will be useful,
34.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
34.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
34.16 - * GNU General Public License for more details.
34.17 - *
34.18 - * You should have received a copy of the GNU General Public License along
34.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
34.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
34.21 - */
34.22 -
34.23 -#define _GNU_SOURCE
34.24 -
34.25 -#include <stdlib.h>
34.26 -#include <stddef.h>
34.27 -#include <stdint.h>
34.28 -#include <stdio.h>
34.29 -#include <string.h>
34.30 -#include <sys/types.h>
34.31 -#include <sys/stat.h>
34.32 -#include <sys/mman.h>
34.33 -#include <unistd.h>
34.34 -#include <fcntl.h>
34.35 -#include <errno.h>
34.36 -#include <ctype.h>
34.37 -#include <fnmatch.h>
34.38 -
34.39 -#include "razor.h"
34.40 -#include "razor-internal.h"
34.41 -#include "types.h"
34.42 -
34.43 -struct razor_set_section {
34.44 - uint32_t type;
34.45 - uint32_t offset;
34.46 - uint32_t size;
34.47 -};
34.48 -
34.49 -struct razor_set_header {
34.50 - uint32_t magic;
34.51 - uint32_t version;
34.52 - struct razor_set_section sections[0];
34.53 -};
34.54 -
34.55 -#define RAZOR_MAGIC 0x7a7a7a7a
34.56 -#define RAZOR_DETAILS_MAGIC 0x7a7a7a7b
34.57 -#define RAZOR_FILES_MAGIC 0x7a7a7a7c
34.58 -#define RAZOR_VERSION 1
34.59 -
34.60 -#define RAZOR_STRING_POOL 0
34.61 -#define RAZOR_PACKAGES 1
34.62 -#define RAZOR_PROPERTIES 2
34.63 -#define RAZOR_PACKAGE_POOL 3
34.64 -#define RAZOR_PROPERTY_POOL 4
34.65 -
34.66 -#define RAZOR_DETAILS_STRING_POOL 0
34.67 -
34.68 -#define RAZOR_FILES 0
34.69 -#define RAZOR_FILE_POOL 1
34.70 -#define RAZOR_FILE_STRING_POOL 2
34.71 -
34.72 -struct razor_package {
34.73 - uint name : 24;
34.74 - uint flags : 8;
34.75 - uint32_t version;
34.76 - uint32_t arch;
34.77 - uint32_t summary;
34.78 - uint32_t description;
34.79 - uint32_t url;
34.80 - uint32_t license;
34.81 - struct list_head properties;
34.82 - struct list_head files;
34.83 -};
34.84 -
34.85 -struct razor_property {
34.86 - uint name : 24;
34.87 - uint flags : 6;
34.88 - enum razor_property_type type : 2;
34.89 - enum razor_version_relation relation : 32;
34.90 - uint32_t version;
34.91 - struct list_head packages;
34.92 -};
34.93 -
34.94 -struct razor_entry {
34.95 - uint name : 24;
34.96 - uint flags : 8;
34.97 - uint32_t start;
34.98 - struct list_head packages;
34.99 -};
34.100 -
34.101 -#define RAZOR_ENTRY_LAST 0x80
34.102 -
34.103 -struct razor_set {
34.104 - struct array string_pool;
34.105 - struct array packages;
34.106 - struct array properties;
34.107 - struct array files;
34.108 - struct array package_pool;
34.109 - struct array property_pool;
34.110 - struct array file_pool;
34.111 - struct array file_string_pool;
34.112 - struct array details_string_pool;
34.113 - struct razor_set_header *header;
34.114 - struct razor_set_header *details_header;
34.115 - struct razor_set_header *files_header;
34.116 -};
34.117 -
34.118 -struct import_entry {
34.119 - uint32_t package;
34.120 - char *name;
34.121 -};
34.122 -
34.123 -struct import_directory {
34.124 - uint32_t name, count;
34.125 - struct array files;
34.126 - struct array packages;
34.127 - struct import_directory *last;
34.128 -};
34.129 -
34.130 -struct razor_importer {
34.131 - struct razor_set *set;
34.132 - struct hashtable table;
34.133 - struct hashtable file_table;
34.134 - struct hashtable details_table;
34.135 - struct razor_package *package;
34.136 - struct array properties;
34.137 - struct array files;
34.138 - struct array file_requires;
34.139 -};
34.140 -
34.141 -static void *
34.142 -zalloc(size_t size)
34.143 -{
34.144 - void *p;
34.145 -
34.146 - p = malloc(size);
34.147 - memset(p, 0, size);
34.148 -
34.149 - return p;
34.150 -}
34.151 -
34.152 -struct razor_set_section razor_sections[] = {
34.153 - { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) },
34.154 - { RAZOR_PACKAGES, offsetof(struct razor_set, packages) },
34.155 - { RAZOR_PROPERTIES, offsetof(struct razor_set, properties) },
34.156 - { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) },
34.157 - { RAZOR_PROPERTY_POOL, offsetof(struct razor_set, property_pool) },
34.158 -};
34.159 -
34.160 -struct razor_set_section razor_files_sections[] = {
34.161 - { RAZOR_FILES, offsetof(struct razor_set, files) },
34.162 - { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) },
34.163 - { RAZOR_FILE_STRING_POOL, offsetof(struct razor_set, file_string_pool) },
34.164 -};
34.165 -
34.166 -struct razor_set_section razor_details_sections[] = {
34.167 - { RAZOR_DETAILS_STRING_POOL, offsetof(struct razor_set, details_string_pool) },
34.168 -};
34.169 -
34.170 -struct razor_set *
34.171 -razor_set_create(void)
34.172 -{
34.173 - struct razor_set *set;
34.174 - struct razor_entry *e;
34.175 - char *empty;
34.176 -
34.177 - set = zalloc(sizeof *set);
34.178 -
34.179 - e = array_add(&set->files, sizeof *e);
34.180 - empty = array_add(&set->string_pool, 1);
34.181 - *empty = '\0';
34.182 - empty = array_add(&set->file_string_pool, 1);
34.183 - *empty = '\0';
34.184 - empty = array_add(&set->details_string_pool, 1);
34.185 - *empty = '\0';
34.186 - e->name = 0;
34.187 - e->flags = RAZOR_ENTRY_LAST;
34.188 - e->start = 0;
34.189 - list_set_empty(&e->packages);
34.190 -
34.191 - return set;
34.192 -}
34.193 -
34.194 -struct razor_set *
34.195 -razor_set_open(const char *filename)
34.196 -{
34.197 - struct razor_set *set;
34.198 - struct razor_set_section *s;
34.199 - struct stat stat;
34.200 - struct array *array;
34.201 - int fd;
34.202 -
34.203 - set = zalloc(sizeof *set);
34.204 - fd = open(filename, O_RDONLY);
34.205 - if (fstat(fd, &stat) < 0)
34.206 - return NULL;
34.207 - set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
34.208 - if (set->header == MAP_FAILED) {
34.209 - free(set);
34.210 - return NULL;
34.211 - }
34.212 -
34.213 - for (s = set->header->sections; ~s->type; s++) {
34.214 - if (s->type >= ARRAY_SIZE(razor_sections))
34.215 - continue;
34.216 - if (s->type != razor_sections[s->type].type)
34.217 - continue;
34.218 - array = (void *) set + razor_sections[s->type].offset;
34.219 - array->data = (void *) set->header + s->offset;
34.220 - array->size = s->size;
34.221 - array->alloc = s->size;
34.222 - }
34.223 - close(fd);
34.224 -
34.225 - return set;
34.226 -}
34.227 -
34.228 -void
34.229 -razor_set_destroy(struct razor_set *set)
34.230 -{
34.231 - unsigned int size;
34.232 - struct array *a;
34.233 - int i;
34.234 -
34.235 - if (set->header) {
34.236 - for (i = 0; set->header->sections[i].type; i++)
34.237 - ;
34.238 - size = set->header->sections[i].type;
34.239 - munmap(set->header, size);
34.240 - } else {
34.241 - for (i = 0; i < ARRAY_SIZE(razor_sections); i++) {
34.242 - a = (void *) set + razor_sections[i].offset;
34.243 - free(a->data);
34.244 - }
34.245 - }
34.246 -
34.247 - if (set->details_header) {
34.248 - for (i = 0; set->details_header->sections[i].type; i++)
34.249 - ;
34.250 - size = set->details_header->sections[i].type;
34.251 - munmap(set->details_header, size);
34.252 - } else {
34.253 - for (i = 0; i < ARRAY_SIZE(razor_details_sections); i++) {
34.254 - a = (void *) set + razor_details_sections[i].offset;
34.255 - free(a->data);
34.256 - }
34.257 - }
34.258 -
34.259 - if (set->files_header) {
34.260 - for (i = 0; set->files_header->sections[i].type; i++)
34.261 - ;
34.262 - size = set->files_header->sections[i].type;
34.263 - munmap(set->files_header, size);
34.264 - } else {
34.265 - for (i = 0; i < ARRAY_SIZE(razor_files_sections); i++) {
34.266 - a = (void *) set + razor_files_sections[i].offset;
34.267 - free(a->data);
34.268 - }
34.269 - }
34.270 -
34.271 - free(set);
34.272 -}
34.273 -
34.274 -void
34.275 -razor_set_open_details(struct razor_set *set, const char *filename)
34.276 -{
34.277 - struct razor_set_section *s;
34.278 - struct stat stat;
34.279 - struct array *array;
34.280 - int fd;
34.281 -
34.282 - fd = open(filename, O_RDONLY);
34.283 - if (fstat(fd, &stat) < 0)
34.284 - return;
34.285 - set->details_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
34.286 - if (set->details_header == MAP_FAILED)
34.287 - return;
34.288 -
34.289 - for (s = set->details_header->sections; ~s->type; s++) {
34.290 - if (s->type >= ARRAY_SIZE(razor_details_sections))
34.291 - continue;
34.292 - if (s->type != razor_details_sections[s->type].type)
34.293 - continue;
34.294 - array = (void *) set + razor_details_sections[s->type].offset;
34.295 - array->data = (void *) set->details_header + s->offset;
34.296 - array->size = s->size;
34.297 - array->alloc = s->size;
34.298 - }
34.299 - close(fd);
34.300 -}
34.301 -
34.302 -void
34.303 -razor_set_open_files(struct razor_set *set, const char *filename)
34.304 -{
34.305 - struct razor_set_section *s;
34.306 - struct stat stat;
34.307 - struct array *array;
34.308 - int fd;
34.309 -
34.310 - fd = open(filename, O_RDONLY);
34.311 - if (fstat(fd, &stat) < 0)
34.312 - return;
34.313 - set->files_header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
34.314 - if (set->files_header == MAP_FAILED)
34.315 - return;
34.316 -
34.317 - for (s = set->files_header->sections; ~s->type; s++) {
34.318 - if (s->type >= ARRAY_SIZE(razor_files_sections))
34.319 - continue;
34.320 - if (s->type != razor_files_sections[s->type].type)
34.321 - continue;
34.322 - array = (void *) set + razor_files_sections[s->type].offset;
34.323 - array->data = (void *) set->files_header + s->offset;
34.324 - array->size = s->size;
34.325 - array->alloc = s->size;
34.326 - }
34.327 - close(fd);
34.328 -}
34.329 -
34.330 -static int
34.331 -razor_set_write_sections_to_fd(struct razor_set *set, int fd, int magic,
34.332 - struct razor_set_section *sections,
34.333 - size_t array_size)
34.334 -{
34.335 - char data[4096];
34.336 - struct razor_set_header *header = (struct razor_set_header *) data;
34.337 - struct array *a;
34.338 - uint32_t offset;
34.339 - int i;
34.340 -
34.341 - memset(data, 0, sizeof data);
34.342 - header->magic = magic;
34.343 - header->version = RAZOR_VERSION;
34.344 - offset = sizeof data;
34.345 -
34.346 - for (i = 0; i < array_size; i++) {
34.347 - if (sections[i].type != i)
34.348 - continue;
34.349 - a = (void *) set + sections[i].offset;
34.350 - header->sections[i].type = i;
34.351 - header->sections[i].offset = offset;
34.352 - header->sections[i].size = a->size;
34.353 - offset += ALIGN(a->size, 4096);
34.354 - }
34.355 -
34.356 - header->sections[i].type = ~0;
34.357 - header->sections[i].offset = 0;
34.358 - header->sections[i].size = 0;
34.359 -
34.360 - razor_write(fd, data, sizeof data);
34.361 - memset(data, 0, sizeof data);
34.362 - for (i = 0; i < array_size; i++) {
34.363 - if (sections[i].type != i)
34.364 - continue;
34.365 - a = (void *) set + sections[i].offset;
34.366 - razor_write(fd, a->data, a->size);
34.367 - razor_write(fd, data, ALIGN(a->size, 4096) - a->size);
34.368 - }
34.369 -
34.370 - return 0;
34.371 -}
34.372 -
34.373 -int
34.374 -razor_set_write_to_fd(struct razor_set *set, int fd,
34.375 - enum razor_repo_file_type type)
34.376 -{
34.377 - switch (type) {
34.378 - case RAZOR_REPO_FILE_MAIN:
34.379 - return razor_set_write_sections_to_fd(set, fd, RAZOR_MAGIC,
34.380 - razor_sections,
34.381 - ARRAY_SIZE(razor_sections));
34.382 -
34.383 - case RAZOR_REPO_FILE_DETAILS:
34.384 - return razor_set_write_sections_to_fd(set, fd, RAZOR_DETAILS_MAGIC,
34.385 - razor_details_sections,
34.386 - ARRAY_SIZE(razor_details_sections));
34.387 - case RAZOR_REPO_FILE_FILES:
34.388 - return razor_set_write_sections_to_fd(set, fd, RAZOR_FILES_MAGIC,
34.389 - razor_files_sections,
34.390 - ARRAY_SIZE(razor_files_sections));
34.391 - default:
34.392 - return -1;
34.393 - }
34.394 -}
34.395 -
34.396 -int
34.397 -razor_set_write(struct razor_set *set, const char *filename,
34.398 - enum razor_repo_file_type type)
34.399 -{
34.400 - int fd, status;
34.401 -
34.402 - fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
34.403 - if (fd < 0)
34.404 - return -1;
34.405 -
34.406 - status = razor_set_write_to_fd(set, fd, type);
34.407 - if (status) {
34.408 - close(fd);
34.409 - return status;
34.410 - }
34.411 -
34.412 - return close(fd);
34.413 -}
34.414 -
34.415 -void
34.416 -razor_build_evr(char *evr_buf, int size, const char *epoch,
34.417 - const char *version, const char *release)
34.418 -{
34.419 - int len;
34.420 -
34.421 - if (!version || !*version) {
34.422 - *evr_buf = '\0';
34.423 - return;
34.424 - }
34.425 -
34.426 - if (epoch && *epoch && strcmp(epoch, "0") != 0) {
34.427 - len = snprintf(evr_buf, size, "%s:", epoch);
34.428 - evr_buf += len;
34.429 - size -= len;
34.430 - }
34.431 - len = snprintf(evr_buf, size, "%s", version);
34.432 - evr_buf += len;
34.433 - size -= len;
34.434 - if (release && *release)
34.435 - snprintf(evr_buf, size, "-%s", release);
34.436 -}
34.437 -
34.438 -void
34.439 -razor_importer_begin_package(struct razor_importer *importer,
34.440 - const char *name,
34.441 - const char *version,
34.442 - const char *arch)
34.443 -{
34.444 - struct razor_package *p;
34.445 -
34.446 - p = array_add(&importer->set->packages, sizeof *p);
34.447 - p->name = hashtable_tokenize(&importer->table, name);
34.448 - p->flags = 0;
34.449 - p->version = hashtable_tokenize(&importer->table, version);
34.450 - p->arch = hashtable_tokenize(&importer->table, arch);
34.451 -
34.452 - importer->package = p;
34.453 - array_init(&importer->properties);
34.454 -}
34.455 -
34.456 -void
34.457 -razor_importer_finish_package(struct razor_importer *importer)
34.458 -{
34.459 - list_set_array(&importer->package->properties,
34.460 - &importer->set->property_pool,
34.461 - &importer->properties,
34.462 - 1);
34.463 -
34.464 - array_release(&importer->properties);
34.465 -}
34.466 -
34.467 -void
34.468 -razor_importer_add_details(struct razor_importer *importer,
34.469 - const char *summary,
34.470 - const char *description,
34.471 - const char *url,
34.472 - const char *license)
34.473 -{
34.474 - importer->package->summary = hashtable_tokenize(&importer->details_table, summary);
34.475 - importer->package->description = hashtable_tokenize(&importer->details_table, description);
34.476 - importer->package->url = hashtable_tokenize(&importer->details_table, url);
34.477 - importer->package->license = hashtable_tokenize(&importer->details_table, license);
34.478 -}
34.479 -
34.480 -void
34.481 -razor_importer_add_property(struct razor_importer *importer,
34.482 - const char *name,
34.483 - enum razor_version_relation relation,
34.484 - const char *version,
34.485 - enum razor_property_type type)
34.486 -{
34.487 - struct razor_property *p;
34.488 - uint32_t *r;
34.489 -
34.490 - p = array_add(&importer->set->properties, sizeof *p);
34.491 - p->name = hashtable_tokenize(&importer->table, name);
34.492 - p->flags = 0;
34.493 - p->type = type;
34.494 - p->relation = relation;
34.495 - p->version = hashtable_tokenize(&importer->table, version);
34.496 - list_set_ptr(&p->packages, importer->package -
34.497 - (struct razor_package *) importer->set->packages.data);
34.498 -
34.499 - r = array_add(&importer->properties, sizeof *r);
34.500 - *r = p - (struct razor_property *) importer->set->properties.data;
34.501 -
34.502 - if (type == RAZOR_PROPERTY_REQUIRES && *name == '/') {
34.503 - r = array_add(&importer->file_requires, sizeof *r);
34.504 - *r = p->name;
34.505 - }
34.506 -}
34.507 -
34.508 -void
34.509 -razor_importer_add_file(struct razor_importer *importer, const char *name)
34.510 -{
34.511 - struct import_entry *e;
34.512 -
34.513 - e = array_add(&importer->files, sizeof *e);
34.514 -
34.515 - e->package = importer->package -
34.516 - (struct razor_package *) importer->set->packages.data;
34.517 - e->name = strdup(name);
34.518 -}
34.519 -
34.520 -struct razor_importer *
34.521 -razor_importer_new(void)
34.522 -{
34.523 - struct razor_importer *importer;
34.524 -
34.525 - importer = zalloc(sizeof *importer);
34.526 - importer->set = razor_set_create();
34.527 - hashtable_init(&importer->table, &importer->set->string_pool);
34.528 - hashtable_init(&importer->file_table, &importer->set->file_string_pool);
34.529 - hashtable_init(&importer->details_table, &importer->set->details_string_pool);
34.530 -
34.531 - return importer;
34.532 -}
34.533 -
34.534 -/* Destroy an importer without creating the set. */
34.535 -void
34.536 -razor_importer_destroy(struct razor_importer *importer)
34.537 -{
34.538 - /* FIXME: write this */
34.539 -}
34.540 -
34.541 -static int
34.542 -versioncmp(const char *s1, const char *s2)
34.543 -{
34.544 - const char *p1, *p2;
34.545 - long n1, n2;
34.546 - int res;
34.547 -
34.548 - n1 = strtol(s1, (char **) &p1, 10);
34.549 - n2 = strtol(s2, (char **) &p2, 10);
34.550 -
34.551 - /* Epoch; if one but not the other has an epoch set, default
34.552 - * the epoch-less version to 0. */
34.553 - res = (*p1 == ':') - (*p2 == ':');
34.554 - if (res < 0) {
34.555 - n1 = 0;
34.556 - p1 = s1;
34.557 - p2++;
34.558 - } else if (res > 0) {
34.559 - p1++;
34.560 - n2 = 0;
34.561 - p2 = s2;
34.562 - }
34.563 -
34.564 - if (n1 != n2)
34.565 - return n1 - n2;
34.566 - while (*p1 && *p2) {
34.567 - if (*p1 != *p2)
34.568 - return *p1 - *p2;
34.569 - p1++;
34.570 - p2++;
34.571 - if (isdigit(*p1) && isdigit(*p2))
34.572 - return versioncmp(p1, p2);
34.573 - }
34.574 -
34.575 - return *p1 - *p2;
34.576 -}
34.577 -
34.578 -static int
34.579 -compare_packages(const void *p1, const void *p2, void *data)
34.580 -{
34.581 - const struct razor_package *pkg1 = p1, *pkg2 = p2;
34.582 - struct razor_set *set = data;
34.583 - char *pool = set->string_pool.data;
34.584 -
34.585 - /* FIXME: what if the flags are different? */
34.586 - if (pkg1->name == pkg2->name)
34.587 - return versioncmp(&pool[pkg1->version], &pool[pkg2->version]);
34.588 - else
34.589 - return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
34.590 -}
34.591 -
34.592 -static int
34.593 -compare_properties(const void *p1, const void *p2, void *data)
34.594 -{
34.595 - const struct razor_property *prop1 = p1, *prop2 = p2;
34.596 - struct razor_set *set = data;
34.597 - char *pool = set->string_pool.data;
34.598 -
34.599 - if (prop1->name != prop2->name)
34.600 - return strcmp(&pool[prop1->name], &pool[prop2->name]);
34.601 - else if (prop1->type != prop2->type)
34.602 - return prop1->type - prop2->type;
34.603 - else if (prop1->relation != prop2->relation)
34.604 - return prop1->relation - prop2->relation;
34.605 - else
34.606 - return versioncmp(&pool[prop1->version], &pool[prop2->version]);
34.607 -}
34.608 -
34.609 -static uint32_t *
34.610 -uniqueify_properties(struct razor_set *set)
34.611 -{
34.612 - struct razor_property *rp, *up, *rp_end;
34.613 - struct array *pkgs, *p;
34.614 - struct list_head *r;
34.615 - uint32_t *map, *rmap;
34.616 - int i, count, unique;
34.617 -
34.618 - count = set->properties.size / sizeof(struct razor_property);
34.619 - map = razor_qsort_with_data(set->properties.data,
34.620 - count,
34.621 - sizeof(struct razor_property),
34.622 - compare_properties,
34.623 - set);
34.624 -
34.625 - rp_end = set->properties.data + set->properties.size;
34.626 - rmap = malloc(count * sizeof *map);
34.627 - pkgs = zalloc(count * sizeof *pkgs);
34.628 - for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
34.629 - if (rp->name != up->name || rp->type != up->type ||
34.630 - rp->relation != up->relation || rp->version != up->version) {
34.631 - up++;
34.632 - up->name = rp->name;
34.633 - up->flags = 0;
34.634 - up->type = rp->type;
34.635 - up->relation = rp->relation;
34.636 - up->version = rp->version;
34.637 - }
34.638 -
34.639 - unique = up - (struct razor_property *) set->properties.data;
34.640 - rmap[map[i]] = unique;
34.641 - r = array_add(&pkgs[unique], sizeof *r);
34.642 - *r = rp->packages;
34.643 - }
34.644 - free(map);
34.645 -
34.646 - if (up != rp)
34.647 - up++;
34.648 - set->properties.size = (void *) up - set->properties.data;
34.649 - rp_end = up;
34.650 - for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
34.651 - list_set_array(&rp->packages, &set->package_pool, p, 0);
34.652 - array_release(p);
34.653 - }
34.654 -
34.655 - free(pkgs);
34.656 -
34.657 - return rmap;
34.658 -}
34.659 -
34.660 -static int
34.661 -compare_filenames(const void *p1, const void *p2, void *data)
34.662 -{
34.663 - const struct import_entry *e1 = p1;
34.664 - const struct import_entry *e2 = p2;
34.665 - const char *n1 = e1->name;
34.666 - const char *n2 = e2->name;
34.667 -
34.668 - /* Need to make sure that the contents of a directory
34.669 - * are sorted immediately after it. So "foo/bar" has to
34.670 - * sort before "foo.conf"
34.671 - *
34.672 - * FIXME: this is about 60% slower than strcmp
34.673 - */
34.674 - while (*n1 && *n2) {
34.675 - if (*n1 < *n2)
34.676 - return *n2 == '/' ? 1 : -1;
34.677 - else if (*n1 > *n2)
34.678 - return *n1 == '/' ? -1 : 1;
34.679 - n1++;
34.680 - n2++;
34.681 - }
34.682 - if (*n1)
34.683 - return 1;
34.684 - else if (*n2)
34.685 - return -1;
34.686 - else
34.687 - return 0;
34.688 -}
34.689 -
34.690 -static void
34.691 -count_entries(struct import_directory *d)
34.692 -{
34.693 - struct import_directory *p, *end;
34.694 -
34.695 - p = d->files.data;
34.696 - end = d->files.data + d->files.size;
34.697 - d->count = 0;
34.698 - while (p < end) {
34.699 - count_entries(p);
34.700 - d->count += p->count + 1;
34.701 - p++;
34.702 - }
34.703 -}
34.704 -
34.705 -static void
34.706 -serialize_files(struct razor_set *set,
34.707 - struct import_directory *d, struct array *array)
34.708 -{
34.709 - struct import_directory *p, *end;
34.710 - struct razor_entry *e = NULL;
34.711 - uint32_t s;
34.712 -
34.713 - p = d->files.data;
34.714 - end = d->files.data + d->files.size;
34.715 - s = array->size / sizeof *e + d->files.size / sizeof *p;
34.716 - while (p < end) {
34.717 - e = array_add(array, sizeof *e);
34.718 - e->name = p->name;
34.719 - e->flags = 0;
34.720 - e->start = p->count > 0 ? s : 0;
34.721 - s += p->count;
34.722 -
34.723 - list_set_array(&e->packages, &set->package_pool, &p->packages, 0);
34.724 - array_release(&p->packages);
34.725 - p++;
34.726 - }
34.727 - if (e != NULL)
34.728 - e->flags |= RAZOR_ENTRY_LAST;
34.729 -
34.730 - p = d->files.data;
34.731 - end = d->files.data + d->files.size;
34.732 - while (p < end) {
34.733 - serialize_files(set, p, array);
34.734 - p++;
34.735 - }
34.736 -}
34.737 -
34.738 -static void
34.739 -remap_property_package_links(struct array *properties, uint32_t *rmap)
34.740 -{
34.741 - struct razor_property *p, *end;
34.742 -
34.743 - end = properties->data + properties->size;
34.744 - for (p = properties->data; p < end; p++)
34.745 - list_remap_head(&p->packages, rmap);
34.746 -}
34.747 -
34.748 -static void
34.749 -build_file_tree(struct razor_importer *importer)
34.750 -{
34.751 - int count, i, length;
34.752 - struct import_entry *filenames;
34.753 - char *f, *end;
34.754 - uint32_t name, *r;
34.755 - char dirname[256];
34.756 - struct import_directory *d, root;
34.757 - struct razor_entry *e;
34.758 -
34.759 - count = importer->files.size / sizeof (struct import_entry);
34.760 - razor_qsort_with_data(importer->files.data,
34.761 - count,
34.762 - sizeof (struct import_entry),
34.763 - compare_filenames,
34.764 - NULL);
34.765 -
34.766 - root.name = hashtable_tokenize(&importer->file_table, "");
34.767 - array_init(&root.files);
34.768 - array_init(&root.packages);
34.769 - root.last = NULL;
34.770 -
34.771 - filenames = importer->files.data;
34.772 - for (i = 0; i < count; i++) {
34.773 - f = filenames[i].name;
34.774 - if (*f != '/')
34.775 - continue;
34.776 - f++;
34.777 -
34.778 - d = &root;
34.779 - while (*f) {
34.780 - end = strchr(f, '/');
34.781 - if (end == NULL)
34.782 - end = f + strlen(f);
34.783 - length = end - f;
34.784 - memcpy(dirname, f, length);
34.785 - dirname[length] ='\0';
34.786 - name = hashtable_tokenize(&importer->file_table, dirname);
34.787 - if (d->last == NULL || d->last->name != name) {
34.788 - d->last = array_add(&d->files, sizeof *d);
34.789 - d->last->name = name;
34.790 - d->last->last = NULL;
34.791 - array_init(&d->last->files);
34.792 - array_init(&d->last->packages);
34.793 - }
34.794 - d = d->last;
34.795 - f = end + 1;
34.796 - if (*end == '\0')
34.797 - break;
34.798 - }
34.799 -
34.800 - r = array_add(&d->packages, sizeof *r);
34.801 - *r = filenames[i].package;
34.802 - free(filenames[i].name);
34.803 - }
34.804 -
34.805 - count_entries(&root);
34.806 - e = importer->set->files.data;
34.807 - e->name = root.name;
34.808 - e->flags = RAZOR_ENTRY_LAST;
34.809 - e->start = importer->files.size ? 1 : 0;
34.810 - list_set_empty(&e->packages);
34.811 -
34.812 - serialize_files(importer->set, &root, &importer->set->files);
34.813 -
34.814 - array_release(&importer->files);
34.815 -}
34.816 -
34.817 -static struct razor_entry *
34.818 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern);
34.819 -
34.820 -static void
34.821 -list_to_array(struct list *list, struct array *array)
34.822 -{
34.823 - uint32_t *item;
34.824 -
34.825 - while (list) {
34.826 - item = array_add(array, sizeof *item);
34.827 - *item = list->data;
34.828 - list = list_next(list);
34.829 - }
34.830 -}
34.831 -
34.832 -static int
34.833 -compare_file_requires(const void *p1, const void *p2, void *data)
34.834 -{
34.835 - uint32_t *f1 = (void *)p1, *f2 = (void *)p2;
34.836 - const char *pool = data;
34.837 -
34.838 - return strcmp(&pool[*f1], &pool[*f2]);
34.839 -}
34.840 -
34.841 -static void
34.842 -find_file_provides(struct razor_importer *importer)
34.843 -{
34.844 - struct razor_property *prop;
34.845 - struct razor_entry *top, *entry;
34.846 - struct razor_package *packages;
34.847 - struct array pkgprops;
34.848 - struct list *pkg;
34.849 - uint32_t *req, *req_start, *req_end;
34.850 - uint32_t *map, *newprop;
34.851 - char *pool;
34.852 -
34.853 - pool = importer->set->string_pool.data;
34.854 - packages = importer->set->packages.data;
34.855 - top = importer->set->files.data;
34.856 -
34.857 - req = req_start = importer->file_requires.data;
34.858 - req_end = importer->file_requires.data + importer->file_requires.size;
34.859 - map = razor_qsort_with_data(req, req_end - req, sizeof *req,
34.860 - compare_file_requires, pool);
34.861 - free(map);
34.862 -
34.863 - for (req = req_start; req < req_end; req++) {
34.864 - if (req > req_start && req[0] == req[-1])
34.865 - continue;
34.866 - entry = find_entry(importer->set, top, &pool[*req]);
34.867 - if (!entry)
34.868 - continue;
34.869 -
34.870 - for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
34.871 - prop = array_add(&importer->set->properties, sizeof *prop);
34.872 - prop->name = *req;
34.873 - prop->type = RAZOR_PROPERTY_PROVIDES;
34.874 - prop->relation = RAZOR_VERSION_EQUAL;
34.875 - prop->version = hashtable_tokenize(&importer->table, "");
34.876 - list_set_ptr(&prop->packages, pkg->data);
34.877 -
34.878 - /* Update property list of pkg */
34.879 - array_init(&pkgprops);
34.880 - list_to_array(list_first(&packages[pkg->data].properties, &importer->set->property_pool), &pkgprops);
34.881 - newprop = array_add(&pkgprops, sizeof *newprop);
34.882 - *newprop = prop - (struct razor_property *)importer->set->properties.data;
34.883 - list_set_array(&packages[pkg->data].properties, &importer->set->property_pool, &pkgprops, 1);
34.884 - array_release(&pkgprops);
34.885 - }
34.886 - }
34.887 -
34.888 - array_release(&importer->file_requires);
34.889 -}
34.890 -
34.891 -static void
34.892 -build_package_file_lists(struct razor_set *set, uint32_t *rmap)
34.893 -{
34.894 - struct razor_package *p, *packages;
34.895 - struct array *pkgs;
34.896 - struct razor_entry *e, *end;
34.897 - struct list *r;
34.898 - uint32_t *q;
34.899 - int i, count;
34.900 -
34.901 - count = set->packages.size / sizeof *p;
34.902 - pkgs = zalloc(count * sizeof *pkgs);
34.903 -
34.904 - end = set->files.data + set->files.size;
34.905 - for (e = set->files.data; e < end; e++) {
34.906 - list_remap_head(&e->packages, rmap);
34.907 - r = list_first(&e->packages, &set->package_pool);
34.908 - while (r) {
34.909 - q = array_add(&pkgs[r->data], sizeof *q);
34.910 - *q = e - (struct razor_entry *) set->files.data;
34.911 - r = list_next(r);
34.912 - }
34.913 - }
34.914 -
34.915 - packages = set->packages.data;
34.916 - for (i = 0; i < count; i++) {
34.917 - list_set_array(&packages[i].files, &set->file_pool, &pkgs[i], 0);
34.918 - array_release(&pkgs[i]);
34.919 - }
34.920 - free(pkgs);
34.921 -}
34.922 -
34.923 -struct razor_set *
34.924 -razor_importer_finish(struct razor_importer *importer)
34.925 -{
34.926 - struct razor_set *set;
34.927 - uint32_t *map, *rmap;
34.928 - int i, count;
34.929 -
34.930 - build_file_tree(importer);
34.931 - find_file_provides(importer);
34.932 -
34.933 - map = uniqueify_properties(importer->set);
34.934 - list_remap_pool(&importer->set->property_pool, map);
34.935 - free(map);
34.936 -
34.937 - count = importer->set->packages.size / sizeof(struct razor_package);
34.938 - map = razor_qsort_with_data(importer->set->packages.data,
34.939 - count,
34.940 - sizeof(struct razor_package),
34.941 - compare_packages,
34.942 - importer->set);
34.943 -
34.944 - rmap = malloc(count * sizeof *rmap);
34.945 - for (i = 0; i < count; i++)
34.946 - rmap[map[i]] = i;
34.947 - free(map);
34.948 -
34.949 - list_remap_pool(&importer->set->package_pool, rmap);
34.950 - build_package_file_lists(importer->set, rmap);
34.951 - remap_property_package_links(&importer->set->properties, rmap);
34.952 - free(rmap);
34.953 -
34.954 - set = importer->set;
34.955 - hashtable_release(&importer->table);
34.956 - hashtable_release(&importer->file_table);
34.957 - hashtable_release(&importer->details_table);
34.958 - free(importer);
34.959 -
34.960 - return set;
34.961 -}
34.962 -
34.963 -struct razor_package_iterator {
34.964 - struct razor_set *set;
34.965 - struct razor_package *package, *end;
34.966 - struct list *index;
34.967 - int free_index;
34.968 -};
34.969 -
34.970 -static struct razor_package_iterator *
34.971 -razor_package_iterator_create_with_index(struct razor_set *set,
34.972 - struct list *index)
34.973 -{
34.974 - struct razor_package_iterator *pi;
34.975 -
34.976 - pi = zalloc(sizeof *pi);
34.977 - pi->set = set;
34.978 - pi->index = index;
34.979 -
34.980 - return pi;
34.981 -}
34.982 -
34.983 -struct razor_package_iterator *
34.984 -razor_package_iterator_create(struct razor_set *set)
34.985 -{
34.986 - struct razor_package_iterator *pi;
34.987 -
34.988 - pi = zalloc(sizeof *pi);
34.989 - pi->set = set;
34.990 - pi->end = set->packages.data + set->packages.size;
34.991 - pi->package = set->packages.data;
34.992 -
34.993 - return pi;
34.994 -}
34.995 -
34.996 -struct razor_package_iterator *
34.997 -razor_package_iterator_create_for_property(struct razor_set *set,
34.998 - struct razor_property *property)
34.999 -{
34.1000 - struct list *index;
34.1001 -
34.1002 - index = list_first(&property->packages, &set->package_pool);
34.1003 - return razor_package_iterator_create_with_index(set, index);
34.1004 -}
34.1005 -
34.1006 -int
34.1007 -razor_package_iterator_next(struct razor_package_iterator *pi,
34.1008 - struct razor_package **package,
34.1009 - const char **name,
34.1010 - const char **version,
34.1011 - const char **arch)
34.1012 -{
34.1013 - char *pool;
34.1014 - int valid;
34.1015 - struct razor_package *p, *packages;
34.1016 -
34.1017 - if (pi->package) {
34.1018 - p = pi->package++;
34.1019 - valid = p < pi->end;
34.1020 - } else if (pi->index) {
34.1021 - packages = pi->set->packages.data;
34.1022 - p = &packages[pi->index->data];
34.1023 - pi->index = list_next(pi->index);
34.1024 - valid = 1;
34.1025 - } else
34.1026 - valid = 0;
34.1027 -
34.1028 - if (valid) {
34.1029 - pool = pi->set->string_pool.data;
34.1030 - *package = p;
34.1031 - *name = &pool[p->name];
34.1032 - *version = &pool[p->version];
34.1033 - *arch = &pool[p->arch];
34.1034 - } else {
34.1035 - *package = NULL;
34.1036 - }
34.1037 -
34.1038 - return valid;
34.1039 -}
34.1040 -
34.1041 -void
34.1042 -razor_package_iterator_destroy(struct razor_package_iterator *pi)
34.1043 -{
34.1044 - if (pi->free_index)
34.1045 - free(pi->index);
34.1046 -
34.1047 - free(pi);
34.1048 -}
34.1049 -
34.1050 -struct razor_package *
34.1051 -razor_set_get_package(struct razor_set *set, const char *package)
34.1052 -{
34.1053 - struct razor_package_iterator *pi;
34.1054 - struct razor_package *p;
34.1055 - const char *name, *version, *arch;
34.1056 -
34.1057 - pi = razor_package_iterator_create(set);
34.1058 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
34.1059 - if (strcmp(package, name) == 0)
34.1060 - break;
34.1061 - }
34.1062 - razor_package_iterator_destroy(pi);
34.1063 -
34.1064 - return p;
34.1065 -}
34.1066 -
34.1067 -void
34.1068 -razor_package_get_details(struct razor_set *set, struct razor_package *package,
34.1069 - const char **summary, const char **description,
34.1070 - const char **url, const char **license)
34.1071 -{
34.1072 - const char *pool = set->details_string_pool.data;
34.1073 -
34.1074 - *summary = &pool[package->summary];
34.1075 - *description = &pool[package->description];
34.1076 - *url = &pool[package->url];
34.1077 - *license = &pool[package->license];
34.1078 -}
34.1079 -
34.1080 -struct razor_property_iterator {
34.1081 - struct razor_set *set;
34.1082 - struct razor_property *property, *end;
34.1083 - struct list *index;
34.1084 -};
34.1085 -
34.1086 -struct razor_property_iterator *
34.1087 -razor_property_iterator_create(struct razor_set *set,
34.1088 - struct razor_package *package)
34.1089 -{
34.1090 - struct razor_property_iterator *pi;
34.1091 -
34.1092 - pi = zalloc(sizeof *pi);
34.1093 - pi->set = set;
34.1094 -
34.1095 - if (package) {
34.1096 - pi->index = list_first(&package->properties,
34.1097 - &set->property_pool);
34.1098 - } else {
34.1099 - pi->property = set->properties.data;
34.1100 - pi->end = set->properties.data + set->properties.size;
34.1101 - }
34.1102 -
34.1103 - return pi;
34.1104 -}
34.1105 -
34.1106 -int
34.1107 -razor_property_iterator_next(struct razor_property_iterator *pi,
34.1108 - struct razor_property **property,
34.1109 - const char **name,
34.1110 - enum razor_version_relation *relation,
34.1111 - const char **version,
34.1112 - enum razor_property_type *type)
34.1113 -{
34.1114 - char *pool;
34.1115 - int valid;
34.1116 - struct razor_property *p, *properties;
34.1117 -
34.1118 - if (pi->property) {
34.1119 - p = pi->property++;
34.1120 - valid = p < pi->end;
34.1121 - } else if (pi->index) {
34.1122 - properties = pi->set->properties.data;
34.1123 - p = &properties[pi->index->data];
34.1124 - pi->index = list_next(pi->index);
34.1125 - valid = 1;
34.1126 - } else
34.1127 - valid = 0;
34.1128 -
34.1129 - if (valid) {
34.1130 - pool = pi->set->string_pool.data;
34.1131 - *property = p;
34.1132 - *name = &pool[p->name];
34.1133 - *relation = p->relation;
34.1134 - *version = &pool[p->version];
34.1135 - *type = p->type;
34.1136 - } else {
34.1137 - *property = NULL;
34.1138 - }
34.1139 -
34.1140 - return valid;
34.1141 -}
34.1142 -
34.1143 -void
34.1144 -razor_property_iterator_destroy(struct razor_property_iterator *pi)
34.1145 -{
34.1146 - free(pi);
34.1147 -}
34.1148 -
34.1149 -static struct razor_entry *
34.1150 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
34.1151 -{
34.1152 - struct razor_entry *e;
34.1153 - const char *n, *pool = set->file_string_pool.data;
34.1154 - int len;
34.1155 -
34.1156 - e = (struct razor_entry *) set->files.data + dir->start;
34.1157 - do {
34.1158 - n = pool + e->name;
34.1159 - if (strcmp(pattern + 1, n) == 0)
34.1160 - return e;
34.1161 - len = strlen(n);
34.1162 - if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
34.1163 - pattern[len + 1] == '/') {
34.1164 - return find_entry(set, e, pattern + len + 1);
34.1165 - }
34.1166 - } while (!((e++)->flags & RAZOR_ENTRY_LAST));
34.1167 -
34.1168 - return NULL;
34.1169 -}
34.1170 -
34.1171 -static void
34.1172 -list_dir(struct razor_set *set, struct razor_entry *dir,
34.1173 - char *prefix, const char *pattern)
34.1174 -{
34.1175 - struct razor_entry *e;
34.1176 - const char *n, *pool = set->file_string_pool.data;
34.1177 -
34.1178 - e = (struct razor_entry *) set->files.data + dir->start;
34.1179 - do {
34.1180 - n = pool + e->name;
34.1181 - if (pattern && pattern[0] && fnmatch(pattern, n, 0) != 0)
34.1182 - continue;
34.1183 - printf("%s/%s\n", prefix, n);
34.1184 - if (e->start) {
34.1185 - char *sub = prefix + strlen (prefix);
34.1186 - *sub = '/';
34.1187 - strcpy (sub + 1, n);
34.1188 - list_dir(set, e, prefix, pattern);
34.1189 - *sub = '\0';
34.1190 - }
34.1191 - } while (!((e++)->flags & RAZOR_ENTRY_LAST));
34.1192 -}
34.1193 -
34.1194 -void
34.1195 -razor_set_list_files(struct razor_set *set, const char *pattern)
34.1196 -{
34.1197 - struct razor_entry *e;
34.1198 - char buffer[512], *p, *base;
34.1199 -
34.1200 - if (pattern == NULL || !strcmp (pattern, "/")) {
34.1201 - buffer[0] = '\0';
34.1202 - list_dir(set, set->files.data, buffer, NULL);
34.1203 - return;
34.1204 - }
34.1205 -
34.1206 - strcpy(buffer, pattern);
34.1207 - e = find_entry(set, set->files.data, buffer);
34.1208 - if (e && e->start > 0) {
34.1209 - base = NULL;
34.1210 - } else {
34.1211 - p = strrchr(buffer, '/');
34.1212 - if (p) {
34.1213 - *p = '\0';
34.1214 - base = p + 1;
34.1215 - } else {
34.1216 - base = NULL;
34.1217 - }
34.1218 - }
34.1219 - e = find_entry(set, set->files.data, buffer);
34.1220 - if (e->start != 0)
34.1221 - list_dir(set, e, buffer, base);
34.1222 -}
34.1223 -
34.1224 -struct razor_package_iterator *
34.1225 -razor_package_iterator_create_for_file(struct razor_set *set,
34.1226 - const char *filename)
34.1227 -{
34.1228 - struct razor_entry *entry;
34.1229 - struct list *index;
34.1230 -
34.1231 - entry = find_entry(set, set->files.data, filename);
34.1232 - if (entry == NULL)
34.1233 - return NULL;
34.1234 -
34.1235 - index = list_first(&entry->packages, &set->package_pool);
34.1236 - return razor_package_iterator_create_with_index(set, index);
34.1237 -}
34.1238 -
34.1239 -static struct list *
34.1240 -list_package_files(struct razor_set *set, struct list *r,
34.1241 - struct razor_entry *dir, uint32_t end,
34.1242 - char *prefix)
34.1243 -{
34.1244 - struct razor_entry *e, *f, *entries;
34.1245 - uint32_t next, file;
34.1246 - char *pool;
34.1247 - int len;
34.1248 -
34.1249 - entries = (struct razor_entry *) set->files.data;
34.1250 - pool = set->file_string_pool.data;
34.1251 -
34.1252 - e = entries + dir->start;
34.1253 - do {
34.1254 - if (entries + r->data == e) {
34.1255 - printf("%s/%s\n", prefix, pool + e->name);
34.1256 - r = list_next(r);
34.1257 - if (!r)
34.1258 - return NULL;
34.1259 - if (r->data >= end)
34.1260 - return r;
34.1261 - }
34.1262 - } while (!((e++)->flags & RAZOR_ENTRY_LAST));
34.1263 -
34.1264 - e = entries + dir->start;
34.1265 - do {
34.1266 - if (e->start == 0)
34.1267 - continue;
34.1268 -
34.1269 - if (e->flags & RAZOR_ENTRY_LAST)
34.1270 - next = end;
34.1271 - else {
34.1272 - f = e + 1;
34.1273 - while (f->start == 0 && !(f->flags & RAZOR_ENTRY_LAST))
34.1274 - f++;
34.1275 - if (f->start == 0)
34.1276 - next = end;
34.1277 - else
34.1278 - next = f->start;
34.1279 - }
34.1280 -
34.1281 - file = r->data;
34.1282 - if (e->start <= file && file < next) {
34.1283 - len = strlen(prefix);
34.1284 - prefix[len] = '/';
34.1285 - strcpy(prefix + len + 1, pool + e->name);
34.1286 - r = list_package_files(set, r, e, next, prefix);
34.1287 - prefix[len] = '\0';
34.1288 - }
34.1289 - } while (!((e++)->flags & RAZOR_ENTRY_LAST) && r != NULL);
34.1290 -
34.1291 - return r;
34.1292 -}
34.1293 -
34.1294 -void
34.1295 -razor_set_list_package_files(struct razor_set *set, const char *name)
34.1296 -{
34.1297 - struct razor_package *package;
34.1298 - struct list *r;
34.1299 - uint32_t end;
34.1300 - char buffer[512];
34.1301 -
34.1302 - package = razor_set_get_package(set, name);
34.1303 -
34.1304 - r = list_first(&package->files, &set->file_pool);
34.1305 - end = set->files.size / sizeof (struct razor_entry);
34.1306 - buffer[0] = '\0';
34.1307 - list_package_files(set, r, set->files.data, end, buffer);
34.1308 -}
34.1309 -
34.1310 -static void
34.1311 -razor_set_validate(struct razor_set *set, struct array *unsatisfied)
34.1312 -{
34.1313 - struct razor_property *r, *p, *end;
34.1314 - uint32_t *u;
34.1315 - char *pool;
34.1316 -
34.1317 - end = set->properties.data + set->properties.size;
34.1318 - pool = set->string_pool.data;
34.1319 -
34.1320 - for (r = set->properties.data, p = r; r < end; r++) {
34.1321 - if (r->type != RAZOR_PROPERTY_REQUIRES)
34.1322 - continue;
34.1323 -
34.1324 - p = r;
34.1325 - while (p < end && p->name == r->name &&
34.1326 - p->type == r->type)
34.1327 - p++;
34.1328 -
34.1329 - /* If there is more than one version of a provides,
34.1330 - * seek to the end for the highest version. */
34.1331 - /* FIXME: This doesn't work if we have a series of
34.1332 - * requires a = 1, provides a = 1, requires a = 2,
34.1333 - * provides a = 2, as the kernel and kernel-devel
34.1334 - * does.*/
34.1335 - while (p + 1 < end && p->name == (p + 1)->name &&
34.1336 - p->type == (p + 1)->type)
34.1337 - p++;
34.1338 -
34.1339 - /* FIXME: We need to track property flags (<, <=, =
34.1340 - * etc) to properly determine if a requires is
34.1341 - * satisfied. The current code doesn't track that the
34.1342 - * requires a = 1 isn't satisfied by a = 2 provides. */
34.1343 -
34.1344 - if (p == end ||
34.1345 - p->type != RAZOR_PROPERTY_PROVIDES ||
34.1346 - r->name != p->name ||
34.1347 - versioncmp(&pool[r->version], &pool[p->version]) > 0) {
34.1348 - /* FIXME: We ignore file requires for now. */
34.1349 - if (pool[r->name] == '/')
34.1350 - continue;
34.1351 - u = array_add(unsatisfied, sizeof *u);
34.1352 - *u = r - (struct razor_property *) set->properties.data;
34.1353 - }
34.1354 - }
34.1355 -}
34.1356 -
34.1357 -void
34.1358 -razor_set_list_unsatisfied(struct razor_set *set)
34.1359 -{
34.1360 - struct array unsatisfied;
34.1361 - struct razor_property *properties, *r;
34.1362 - uint32_t *u, *end;
34.1363 - char *pool;
34.1364 -
34.1365 - array_init(&unsatisfied);
34.1366 - razor_set_validate(set, &unsatisfied);
34.1367 -
34.1368 - end = unsatisfied.data + unsatisfied.size;
34.1369 - properties = set->properties.data;
34.1370 - pool = set->string_pool.data;
34.1371 -
34.1372 - for (u = unsatisfied.data; u < end; u++) {
34.1373 - r = properties + *u;
34.1374 - if (pool[r->version] == '\0')
34.1375 - printf("%s not satisfied\n",
34.1376 - &pool[r->name]);
34.1377 - else
34.1378 - printf("%s-%s not satisfied\n",
34.1379 - &pool[r->name],
34.1380 - &pool[r->version]);
34.1381 - }
34.1382 -
34.1383 - array_release(&unsatisfied);
34.1384 -}
34.1385 -
34.1386 -#define UPSTREAM_SOURCE 0x80
34.1387 -
34.1388 -struct source {
34.1389 - struct razor_set *set;
34.1390 - uint32_t *property_map;
34.1391 - uint32_t *file_map;
34.1392 -};
34.1393 -
34.1394 -struct razor_merger {
34.1395 - struct razor_set *set;
34.1396 - struct hashtable table;
34.1397 - struct hashtable file_table;
34.1398 - struct hashtable details_table;
34.1399 - struct source source1;
34.1400 - struct source source2;
34.1401 -};
34.1402 -
34.1403 -static struct razor_merger *
34.1404 -razor_merger_create(struct razor_set *set1, struct razor_set *set2)
34.1405 -{
34.1406 - struct razor_merger *merger;
34.1407 - int count;
34.1408 - size_t size;
34.1409 -
34.1410 - merger = zalloc(sizeof *merger);
34.1411 - merger->set = razor_set_create();
34.1412 - hashtable_init(&merger->table, &merger->set->string_pool);
34.1413 - hashtable_init(&merger->file_table, &merger->set->file_string_pool);
34.1414 - hashtable_init(&merger->details_table, &merger->set->details_string_pool);
34.1415 -
34.1416 - merger->source1.set = set1;
34.1417 - count = set1->properties.size / sizeof (struct razor_property);
34.1418 - size = count * sizeof merger->source1.property_map[0];
34.1419 - merger->source1.property_map = zalloc(size);
34.1420 - count = set1->files.size / sizeof (struct razor_entry);
34.1421 - size = count * sizeof merger->source1.file_map[0];
34.1422 - merger->source1.file_map = zalloc(size);
34.1423 -
34.1424 - merger->source2.set = set2;
34.1425 - count = set2->properties.size / sizeof (struct razor_property);
34.1426 - size = count * sizeof merger->source2.property_map[0];
34.1427 - merger->source2.property_map = zalloc(size);
34.1428 - count = set2->files.size / sizeof (struct razor_entry);
34.1429 - size = count * sizeof merger->source2.file_map[0];
34.1430 - merger->source2.file_map = zalloc(size);
34.1431 -
34.1432 - return merger;
34.1433 -}
34.1434 -
34.1435 -static void
34.1436 -add_package(struct razor_merger *merger,
34.1437 - struct razor_package *package, struct source *source,
34.1438 - uint32_t flags)
34.1439 -{
34.1440 - char *pool;
34.1441 - struct list *r;
34.1442 - struct razor_package *p;
34.1443 -
34.1444 - pool = source->set->string_pool.data;
34.1445 - p = array_add(&merger->set->packages, sizeof *p);
34.1446 - p->name = hashtable_tokenize(&merger->table, &pool[package->name]);
34.1447 - p->flags = flags;
34.1448 - p->version = hashtable_tokenize(&merger->table,
34.1449 - &pool[package->version]);
34.1450 - p->arch = hashtable_tokenize(&merger->table,
34.1451 - &pool[package->arch]);
34.1452 -
34.1453 - p->properties = package->properties;
34.1454 - r = list_first(&package->properties, &source->set->property_pool);
34.1455 - while (r) {
34.1456 - source->property_map[r->data] = 1;
34.1457 - r = list_next(r);
34.1458 - }
34.1459 -
34.1460 - p->files = package->files;
34.1461 - r = list_first(&package->files, &source->set->file_pool);
34.1462 - while (r) {
34.1463 - source->file_map[r->data] = 1;
34.1464 - r = list_next(r);
34.1465 - }
34.1466 -}
34.1467 -
34.1468 -static uint32_t
34.1469 -add_property(struct razor_merger *merger,
34.1470 - const char *name, enum razor_version_relation relation,
34.1471 - const char *version, int type)
34.1472 -{
34.1473 - struct razor_property *p;
34.1474 -
34.1475 - p = array_add(&merger->set->properties, sizeof *p);
34.1476 - p->name = hashtable_tokenize(&merger->table, name);
34.1477 - p->flags = 0;
34.1478 - p->type = type;
34.1479 - p->relation = relation;
34.1480 - p->version = hashtable_tokenize(&merger->table, version);
34.1481 -
34.1482 - return p - (struct razor_property *) merger->set->properties.data;
34.1483 -}
34.1484 -
34.1485 -static void
34.1486 -merge_properties(struct razor_merger *merger)
34.1487 -{
34.1488 - struct razor_property *p1, *p2;
34.1489 - struct razor_set *set1, *set2;
34.1490 - uint32_t *map1, *map2;
34.1491 - int i, j, cmp, count1, count2;
34.1492 - char *pool1, *pool2;
34.1493 -
34.1494 - set1 = merger->source1.set;
34.1495 - set2 = merger->source2.set;
34.1496 - map1 = merger->source1.property_map;
34.1497 - map2 = merger->source2.property_map;
34.1498 -
34.1499 - i = 0;
34.1500 - j = 0;
34.1501 - pool1 = set1->string_pool.data;
34.1502 - pool2 = set2->string_pool.data;
34.1503 -
34.1504 - count1 = set1->properties.size / sizeof *p1;
34.1505 - count2 = set2->properties.size / sizeof *p2;
34.1506 - while (i < count1 || j < count2) {
34.1507 - if (i < count1 && map1[i] == 0) {
34.1508 - i++;
34.1509 - continue;
34.1510 - }
34.1511 - if (j < count2 && map2[j] == 0) {
34.1512 - j++;
34.1513 - continue;
34.1514 - }
34.1515 - p1 = (struct razor_property *) set1->properties.data + i;
34.1516 - p2 = (struct razor_property *) set2->properties.data + j;
34.1517 - if (i < count1 && j < count2)
34.1518 - cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
34.1519 - else if (i < count1)
34.1520 - cmp = -1;
34.1521 - else
34.1522 - cmp = 1;
34.1523 - if (cmp == 0)
34.1524 - cmp = p1->type - p2->type;
34.1525 - if (cmp == 0)
34.1526 - cmp = p1->relation - p2->relation;
34.1527 - if (cmp == 0)
34.1528 - cmp = versioncmp(&pool1[p1->version],
34.1529 - &pool2[p2->version]);
34.1530 - if (cmp < 0) {
34.1531 - map1[i++] = add_property(merger,
34.1532 - &pool1[p1->name],
34.1533 - p1->relation,
34.1534 - &pool1[p1->version],
34.1535 - p1->type);
34.1536 - } else if (cmp > 0) {
34.1537 - map2[j++] = add_property(merger,
34.1538 - &pool2[p2->name],
34.1539 - p2->relation,
34.1540 - &pool2[p2->version],
34.1541 - p2->type);
34.1542 - } else {
34.1543 - map1[i++] = map2[j++] = add_property(merger,
34.1544 - &pool1[p1->name],
34.1545 - p1->relation,
34.1546 - &pool1[p1->version],
34.1547 - p1->type);
34.1548 - }
34.1549 - }
34.1550 -}
34.1551 -
34.1552 -static void
34.1553 -emit_properties(struct list_head *properties, struct array *source_pool,
34.1554 - uint32_t *map, struct array *pool)
34.1555 -{
34.1556 - uint32_t r;
34.1557 - struct list *p, *q;
34.1558 -
34.1559 - r = pool->size / sizeof *q;
34.1560 - p = list_first(properties, source_pool);
34.1561 - while (p) {
34.1562 - q = array_add(pool, sizeof *q);
34.1563 - q->data = map[p->data];
34.1564 - q->flags = p->flags;
34.1565 - p = list_next(p);
34.1566 - }
34.1567 -
34.1568 - list_set_ptr(properties, r);
34.1569 -}
34.1570 -
34.1571 -static uint32_t
34.1572 -add_file(struct razor_merger *merger, const char *name)
34.1573 -{
34.1574 - struct razor_entry *e;
34.1575 -
34.1576 - e = array_add(&merger->set->files, sizeof *e);
34.1577 - e->name = hashtable_tokenize(&merger->file_table, name);
34.1578 - e->flags = 0;
34.1579 - e->start = 0;
34.1580 -
34.1581 - return e - (struct razor_entry *)merger->set->files.data;
34.1582 -}
34.1583 -
34.1584 -/* FIXME. Blah */
34.1585 -static int
34.1586 -fix_file_map(uint32_t *map,
34.1587 - struct razor_entry *files,
34.1588 - struct razor_entry *top)
34.1589 -{
34.1590 - uint32_t e;
34.1591 - int found_file = 0;
34.1592 -
34.1593 - e = top->start;
34.1594 - do {
34.1595 - if (files[e].start)
34.1596 - fix_file_map(map, files, &files[e]);
34.1597 - if (map[e])
34.1598 - found_file = 1;
34.1599 - } while (!(files[e++].flags & RAZOR_ENTRY_LAST));
34.1600 -
34.1601 - if (found_file)
34.1602 - map[top - files] = 1;
34.1603 - return found_file;
34.1604 -}
34.1605 -
34.1606 -struct merge_directory {
34.1607 - uint32_t merged, dir1, dir2;
34.1608 -};
34.1609 -
34.1610 -static void
34.1611 -merge_one_directory(struct razor_merger *merger, struct merge_directory *md)
34.1612 -{
34.1613 - struct razor_entry *root1, *root2, *mroot, *e1, *e2;
34.1614 - struct razor_set *set1, *set2;
34.1615 - struct array merge_stack;
34.1616 - struct merge_directory *child_md, *end_md;
34.1617 - uint32_t *map1, *map2, start, last;
34.1618 - int cmp;
34.1619 - char *pool1, *pool2;
34.1620 -
34.1621 - set1 = merger->source1.set;
34.1622 - set2 = merger->source2.set;
34.1623 - map1 = merger->source1.file_map;
34.1624 - map2 = merger->source2.file_map;
34.1625 - pool1 = set1->string_pool.data;
34.1626 - pool2 = set2->string_pool.data;
34.1627 - root1 = (struct razor_entry *) set1->files.data;
34.1628 - root2 = (struct razor_entry *) set2->files.data;
34.1629 -
34.1630 - array_init(&merge_stack);
34.1631 -
34.1632 - start = merger->set->files.size / sizeof (struct razor_entry);
34.1633 - last = 0;
34.1634 - e1 = md->dir1 ? root1 + md->dir1 : NULL;
34.1635 - e2 = md->dir2 ? root2 + md->dir2 : NULL;
34.1636 - while (e1 || e2) {
34.1637 - if (!e2 && !map1[e1 - root1]) {
34.1638 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
34.1639 - e1 = NULL;
34.1640 - continue;
34.1641 - }
34.1642 - if (!e1 && !map2[e2 - root2]) {
34.1643 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
34.1644 - e2 = NULL;
34.1645 - continue;
34.1646 - }
34.1647 - if (e1 && !map1[e1 - root1] &&
34.1648 - e2 && !map1[e2 - root2]) {
34.1649 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
34.1650 - e1 = NULL;
34.1651 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
34.1652 - e2 = NULL;
34.1653 - continue;
34.1654 - }
34.1655 -
34.1656 - if (!e1)
34.1657 - cmp = 1;
34.1658 - else if (!e2)
34.1659 - cmp = -1;
34.1660 - else {
34.1661 - cmp = strcmp (&pool1[e1->name],
34.1662 - &pool2[e2->name]);
34.1663 - }
34.1664 -
34.1665 - if (cmp < 0) {
34.1666 - if (map1[e1 - root1]) {
34.1667 - map1[e1 - root1] = last =
34.1668 - add_file(merger, &pool1[e1->name]);
34.1669 - if (e1->start) {
34.1670 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
34.1671 - child_md->merged = last;
34.1672 - child_md->dir1 = e1->start;
34.1673 - child_md->dir2 = 0;
34.1674 - }
34.1675 - }
34.1676 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
34.1677 - e1 = NULL;
34.1678 - } else if (cmp > 0) {
34.1679 - if (map2[e2 - root2]) {
34.1680 - map2[e2 - root2] = last =
34.1681 - add_file(merger, &pool2[e2->name]);
34.1682 - if (e2->start) {
34.1683 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
34.1684 - child_md->merged = last;
34.1685 - child_md->dir1 = 0;
34.1686 - child_md->dir2 = e2->start;
34.1687 - }
34.1688 - }
34.1689 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
34.1690 - e2 = NULL;
34.1691 - } else {
34.1692 - map1[e1 - root1] = map2[e2- root2] = last =
34.1693 - add_file(merger, &pool1[e1->name]);
34.1694 - if (e1->start || e2->start) {
34.1695 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
34.1696 - child_md->merged = last;
34.1697 - child_md->dir1 = e1->start;
34.1698 - child_md->dir2 = e2->start;
34.1699 - }
34.1700 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
34.1701 - e1 = NULL;
34.1702 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
34.1703 - e2 = NULL;
34.1704 - }
34.1705 - }
34.1706 -
34.1707 - mroot = (struct razor_entry *)merger->set->files.data;
34.1708 - if (last) {
34.1709 - mroot[last].flags = RAZOR_ENTRY_LAST;
34.1710 - mroot[md->merged].start = start;
34.1711 - } else
34.1712 - mroot[md->merged].start = 0;
34.1713 -
34.1714 - end_md = merge_stack.data + merge_stack.size;
34.1715 - for (child_md = merge_stack.data; child_md < end_md; child_md++)
34.1716 - merge_one_directory(merger, child_md);
34.1717 - array_release(&merge_stack);
34.1718 -}
34.1719 -
34.1720 -static void
34.1721 -merge_files(struct razor_merger *merger)
34.1722 -{
34.1723 - struct razor_entry *root;
34.1724 - struct merge_directory md;
34.1725 - uint32_t *map1, *map2;
34.1726 -
34.1727 - map1 = merger->source1.file_map;
34.1728 - map2 = merger->source2.file_map;
34.1729 -
34.1730 - md.merged = 0;
34.1731 -
34.1732 - if (merger->source1.set->files.size) {
34.1733 - root = (struct razor_entry *) merger->source1.set->files.data;
34.1734 - if (root->start)
34.1735 - fix_file_map(map1, root, root);
34.1736 - md.dir1 = root->start;
34.1737 - } else
34.1738 - md.dir1 = 0;
34.1739 -
34.1740 - if (merger->source2.set->files.size) {
34.1741 - root = (struct razor_entry *) merger->source2.set->files.data;
34.1742 - if (root->start)
34.1743 - fix_file_map(map2, root, root);
34.1744 - md.dir2 = root->start;
34.1745 - } else
34.1746 - md.dir2 = 0;
34.1747 -
34.1748 - merge_one_directory(merger, &md);
34.1749 -}
34.1750 -
34.1751 -static void
34.1752 -emit_files(struct list_head *files, struct array *source_pool,
34.1753 - uint32_t *map, struct array *pool)
34.1754 -{
34.1755 - uint32_t r;
34.1756 - struct list *p, *q;
34.1757 -
34.1758 - r = pool->size / sizeof *q;
34.1759 - p = list_first(files, source_pool);
34.1760 - while (p) {
34.1761 - q = array_add(pool, sizeof *q);
34.1762 - q->data = map[p->data];
34.1763 - q->flags = p->flags;
34.1764 - p = list_next(p);
34.1765 - }
34.1766 -
34.1767 - list_set_ptr(files, r);
34.1768 -}
34.1769 -
34.1770 -/* Rebuild property->packages maps. We can't just remap these, as a
34.1771 - * property may have lost or gained a number of packages. Allocate an
34.1772 - * array per property and loop through the packages and add them to
34.1773 - * the arrays for their properties. */
34.1774 -static void
34.1775 -rebuild_property_package_lists(struct razor_set *set)
34.1776 -{
34.1777 - struct array *pkgs, *a;
34.1778 - struct razor_package *pkg, *pkg_end;
34.1779 - struct razor_property *prop, *prop_end;
34.1780 - struct list *r;
34.1781 - uint32_t *q;
34.1782 - int count;
34.1783 -
34.1784 - count = set->properties.size / sizeof (struct razor_property);
34.1785 - pkgs = zalloc(count * sizeof *pkgs);
34.1786 - pkg_end = set->packages.data + set->packages.size;
34.1787 -
34.1788 - for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
34.1789 - r = list_first(&pkg->properties, &set->property_pool);
34.1790 - while (r) {
34.1791 - q = array_add(&pkgs[r->data], sizeof *q);
34.1792 - *q = pkg - (struct razor_package *) set->packages.data;
34.1793 - r = list_next(r);
34.1794 - }
34.1795 - }
34.1796 -
34.1797 - prop_end = set->properties.data + set->properties.size;
34.1798 - a = pkgs;
34.1799 - for (prop = set->properties.data; prop < prop_end; prop++, a++) {
34.1800 - list_set_array(&prop->packages, &set->package_pool, a, 0);
34.1801 - array_release(a);
34.1802 - }
34.1803 - free(pkgs);
34.1804 -}
34.1805 -
34.1806 -static void
34.1807 -rebuild_file_package_lists(struct razor_set *set)
34.1808 -{
34.1809 - struct array *pkgs, *a;
34.1810 - struct razor_package *pkg, *pkg_end;
34.1811 - struct razor_entry *entry, *entry_end;
34.1812 - struct list *r;
34.1813 - uint32_t *q;
34.1814 - int count;
34.1815 -
34.1816 - count = set->files.size / sizeof (struct razor_entry);
34.1817 - pkgs = zalloc(count * sizeof *pkgs);
34.1818 - pkg_end = set->packages.data + set->packages.size;
34.1819 -
34.1820 - for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
34.1821 - r = list_first(&pkg->files, &set->file_pool);
34.1822 - while (r) {
34.1823 - q = array_add(&pkgs[r->data], sizeof *q);
34.1824 - *q = pkg - (struct razor_package *) set->packages.data;
34.1825 - r = list_next(r);
34.1826 - }
34.1827 - }
34.1828 -
34.1829 - entry_end = set->files.data + set->files.size;
34.1830 - a = pkgs;
34.1831 - for (entry = set->files.data; entry < entry_end; entry++, a++) {
34.1832 - list_set_array(&entry->packages, &set->package_pool, a, 0);
34.1833 - array_release(a);
34.1834 - }
34.1835 - free(pkgs);
34.1836 -}
34.1837 -
34.1838 -static struct razor_set *
34.1839 -razor_merger_finish(struct razor_merger *merger)
34.1840 -{
34.1841 - struct razor_set *result;
34.1842 - struct razor_package *p, *pend;
34.1843 -
34.1844 - /* As we built the package list, we filled out a bitvector of
34.1845 - * the properties that are referenced by the packages in the
34.1846 - * new set. Now we do a parallel loop through the properties
34.1847 - * and emit those marked in the bit vector to the new set. In
34.1848 - * the process, we update the bit vector to actually map from
34.1849 - * indices in the old property list to indices in the new
34.1850 - * property list for both sets. */
34.1851 -
34.1852 - merge_properties(merger);
34.1853 - merge_files(merger);
34.1854 -
34.1855 - /* Now we loop through the packages again and emit the
34.1856 - * property lists, remapped to point to the new properties. */
34.1857 -
34.1858 - pend = merger->set->packages.data + merger->set->packages.size;
34.1859 - for (p = merger->set->packages.data; p < pend; p++) {
34.1860 - struct source *src;
34.1861 -
34.1862 - if (p->flags & UPSTREAM_SOURCE)
34.1863 - src = &merger->source2;
34.1864 - else
34.1865 - src = &merger->source1;
34.1866 -
34.1867 - emit_properties(&p->properties,
34.1868 - &src->set->property_pool,
34.1869 - src->property_map,
34.1870 - &merger->set->property_pool);
34.1871 - emit_files(&p->files,
34.1872 - &src->set->file_pool,
34.1873 - src->file_map,
34.1874 - &merger->set->file_pool);
34.1875 - p->flags &= ~UPSTREAM_SOURCE;
34.1876 - }
34.1877 -
34.1878 - rebuild_property_package_lists(merger->set);
34.1879 - rebuild_file_package_lists(merger->set);
34.1880 -
34.1881 - result = merger->set;
34.1882 - hashtable_release(&merger->table);
34.1883 - hashtable_release(&merger->file_table);
34.1884 - hashtable_release(&merger->details_table);
34.1885 - free(merger);
34.1886 -
34.1887 - return result;
34.1888 -}
34.1889 -
34.1890 -/* The diff order matters. We should sort the packages so that a
34.1891 - * REMOVE of a package comes before the INSTALL, and so that all
34.1892 - * requires for a package have been installed before the package.
34.1893 - **/
34.1894 -
34.1895 -void
34.1896 -razor_set_diff(struct razor_set *set, struct razor_set *upstream,
34.1897 - razor_package_callback_t callback, void *data)
34.1898 -{
34.1899 - struct razor_package_iterator *pi1, *pi2;
34.1900 - struct razor_package *p1, *p2;
34.1901 - const char *name1, *name2, *version1, *version2, *arch1, *arch2;
34.1902 - int res;
34.1903 -
34.1904 - pi1 = razor_package_iterator_create(set);
34.1905 - pi2 = razor_package_iterator_create(upstream);
34.1906 -
34.1907 - razor_package_iterator_next(pi1, &p1, &name1, &version1, &arch1);
34.1908 - razor_package_iterator_next(pi2, &p2, &name2, &version2, &arch2);
34.1909 -
34.1910 - while (p1 || p2) {
34.1911 - if (p1 && p2) {
34.1912 - res = strcmp(name1, name2);
34.1913 - if (res == 0)
34.1914 - res = versioncmp(version1, version2);
34.1915 - } else {
34.1916 - res = 0;
34.1917 - }
34.1918 -
34.1919 - if (p2 == NULL || res < 0)
34.1920 - callback(name1, version1, NULL, arch1, data);
34.1921 - else if (p1 == NULL || res > 0)
34.1922 - callback(name2, NULL, version2, arch2, data);
34.1923 -
34.1924 - if (p1 != NULL && res <= 0)
34.1925 - razor_package_iterator_next(pi1, &p1,
34.1926 - &name1, &version1, &arch1);
34.1927 - if (p2 != NULL && res >= 0)
34.1928 - razor_package_iterator_next(pi2, &p2,
34.1929 - &name2, &version2, &arch2);
34.1930 - }
34.1931 -
34.1932 - razor_package_iterator_destroy(pi1);
34.1933 - razor_package_iterator_destroy(pi2);
34.1934 -}
34.1935 -
34.1936 -struct razor_transaction;
34.1937 -struct razor_transaction_package;
34.1938 -struct razor_transaction_resolver;
34.1939 -
34.1940 -struct razor_transaction {
34.1941 - int package_count, errors;
34.1942 - struct razor_set *system, *upstream;
34.1943 -
34.1944 - struct bitarray syspkgs, uppkgs;
34.1945 - struct array packages;
34.1946 -};
34.1947 -
34.1948 -struct razor_transaction_package {
34.1949 - const char *name, *old_version, *new_version;
34.1950 - struct razor_package *old_package, *new_package;
34.1951 - enum razor_transaction_package_state state;
34.1952 -
34.1953 - /* dep_package is the name of the package that resulted in
34.1954 - * this entry being created (or NULL if the user requested the
34.1955 - * install/remove), with the other dep_ fields providing
34.1956 - * additional information.
34.1957 - *
34.1958 - * For INSTALL, if dep_type is REQUIRES, then dep_package
34.1959 - * required something that this package provides. If dep_type
34.1960 - * is CONFLICTS, then dep_package is a package that conflicted
34.1961 - * with an older version of this package, forcing an upgrade.
34.1962 - *
34.1963 - * For REMOVE, if dep_type is REQUIRES, then dep_package is a
34.1964 - * package that is being removed. If dep_type is OBSOLETES,
34.1965 - * then dep_package is a package that obsoletes this one.
34.1966 - *
34.1967 - * For OLD_CONFLICT or NEW_CONFLICT, dep_package is an
34.1968 - * existing package that conflicts with this one. The
34.1969 - * conflicting property comes from the already-installed
34.1970 - * package for OLD_CONFLICT, or the to-be-installed package
34.1971 - * for NEW_CONFLICT.
34.1972 - *
34.1973 - * For UNSATISFIABLE, the dep_ fields are as for an INSTALL,
34.1974 - * but the name field will be NULL.
34.1975 - */
34.1976 - const char *dep_package;
34.1977 - enum razor_property_type dep_type;
34.1978 - const char *dep_property;
34.1979 - enum razor_version_relation dep_relation;
34.1980 - const char *dep_version;
34.1981 -};
34.1982 -
34.1983 -static int
34.1984 -package_in_set(void *package, struct razor_set *set)
34.1985 -{
34.1986 - return package >= set->packages.data &&
34.1987 - package < set->packages.data + set->packages.size;
34.1988 -}
34.1989 -
34.1990 -static int
34.1991 -property_in_set(void *property, struct razor_set *set)
34.1992 -{
34.1993 - return property >= set->properties.data &&
34.1994 - property < set->properties.data + set->properties.size;
34.1995 -}
34.1996 -
34.1997 -static struct razor_package *
34.1998 -property_provider_package(struct razor_transaction *trans,
34.1999 - struct razor_property *prop,
34.2000 - int installed)
34.2001 -{
34.2002 - struct razor_set *set;
34.2003 - struct bitarray *pkgbits;
34.2004 - struct razor_package *pkgs;
34.2005 - struct list *p;
34.2006 -
34.2007 - if (installed && prop->type != RAZOR_PROPERTY_PROVIDES)
34.2008 - return NULL;
34.2009 - else if (!installed &&
34.2010 - prop->type != RAZOR_PROPERTY_PROVIDES &&
34.2011 - prop->type != RAZOR_PROPERTY_OBSOLETES)
34.2012 - return NULL;
34.2013 -
34.2014 - if (property_in_set(prop, trans->system)) {
34.2015 - set = trans->system;
34.2016 - pkgbits = &trans->syspkgs;
34.2017 - } else {
34.2018 - set = trans->upstream;
34.2019 - pkgbits = &trans->uppkgs;
34.2020 - }
34.2021 - pkgs = set->packages.data;
34.2022 -
34.2023 - for (p = list_first(&prop->packages, &set->package_pool); p; p = list_next(p)) {
34.2024 - if (bitarray_get(pkgbits, p->data) != installed)
34.2025 - continue;
34.2026 - if (prop->type == RAZOR_PROPERTY_OBSOLETES ||
34.2027 - pkgs[p->data].name == prop->name)
34.2028 - return &pkgs[p->data];
34.2029 - }
34.2030 - return NULL;
34.2031 -}
34.2032 -
34.2033 -static int
34.2034 -compare_transaction_packages(const void *one, const void *two)
34.2035 -{
34.2036 - struct razor_transaction_package **tp1 = (void *)one;
34.2037 - struct razor_transaction_package **tp2 = (void *)two;
34.2038 -
34.2039 - if (!(*tp1)->name)
34.2040 - return 1;
34.2041 - else if (!(*tp2)->name)
34.2042 - return -1;
34.2043 - else
34.2044 - return strcmp((*tp1)->name, (*tp2)->name);
34.2045 -}
34.2046 -
34.2047 -/* FIXME: merge this into the other property loop in razor_transaction_satisfy */
34.2048 -static void
34.2049 -resolve_new_packages(struct razor_transaction *trans,
34.2050 - int start, int end)
34.2051 -{
34.2052 - struct razor_property *sp, *up, *sp_end, *up_end;
34.2053 - struct razor_package *spkg, *spkgs, *upkg, *upkgs;
34.2054 - struct razor_transaction_package **packages;
34.2055 - const char *spool, *upool;
34.2056 - int i;
34.2057 -
34.2058 - sp_end = trans->system->properties.data + trans->system->properties.size;
34.2059 - spool = trans->system->string_pool.data;
34.2060 - spkgs = trans->system->packages.data;
34.2061 - up_end = trans->upstream->properties.data + trans->upstream->properties.size;
34.2062 - upool = trans->upstream->string_pool.data;
34.2063 - upkgs = trans->upstream->packages.data;
34.2064 -
34.2065 - /* FIXME, check if sorting the packages directly (rather than
34.2066 - * sorting pointers-to-packages) still results in confusing
34.2067 - * descriptions.
34.2068 - */
34.2069 - packages = calloc(end - start, sizeof *packages);
34.2070 - for (i = start; i < end; i++)
34.2071 - packages[i - start] = ((struct razor_transaction_package *)trans->packages.data) + i;
34.2072 - qsort(packages, end - start, sizeof *packages,
34.2073 - compare_transaction_packages);
34.2074 -
34.2075 - sp = trans->system->properties.data;
34.2076 - up = trans->upstream->properties.data;
34.2077 - for (i = 0; i < end - start; i++) {
34.2078 - if (!packages[i]->name ||
34.2079 - packages[i]->state >= RAZOR_PACKAGE_FIRST_ERROR_STATE)
34.2080 - continue;
34.2081 -
34.2082 - spkg = NULL;
34.2083 - while (sp < sp_end &&
34.2084 - strcmp(&spool[sp->name], packages[i]->name) < 0)
34.2085 - sp++;
34.2086 - while (sp < sp_end &&
34.2087 - strcmp(&spool[sp->name], packages[i]->name) == 0 &&
34.2088 - !(spkg = property_provider_package(trans, sp, 1)))
34.2089 - sp++;
34.2090 -
34.2091 - upkg = NULL;
34.2092 - while (up < up_end &&
34.2093 - strcmp(&upool[up->name], packages[i]->name) < 0)
34.2094 - up++;
34.2095 - while (up < up_end &&
34.2096 - strcmp(&upool[up->name], packages[i]->name) == 0 &&
34.2097 - !(upkg = property_provider_package(trans, up, 0)))
34.2098 - up++;
34.2099 -
34.2100 - if (packages[i]->state == RAZOR_PACKAGE_REMOVE ||
34.2101 - packages[i]->state == RAZOR_PACKAGE_OBSOLETED) {
34.2102 - if (spkg) {
34.2103 - packages[i]->old_package = spkg;
34.2104 - packages[i]->name = &spool[spkg->name];
34.2105 - packages[i]->old_version = &spool[spkg->version];
34.2106 - bitarray_set(&trans->syspkgs, spkg - spkgs, 0);
34.2107 - }
34.2108 - if (!packages[i]->old_package) {
34.2109 - packages[i]->name = strdup(packages[i]->name);
34.2110 - packages[i]->state |= RAZOR_PACKAGE_UNAVAILABLE_FLAG;
34.2111 - trans->errors++;
34.2112 - }
34.2113 - } else {
34.2114 - if (upkg) {
34.2115 - packages[i]->new_package = upkg;
34.2116 - packages[i]->name = &upool[upkg->name];
34.2117 - packages[i]->new_version = &upool[upkg->version];
34.2118 -
34.2119 - if (up->name != upkg->name) {
34.2120 - packages[i]->dep_package = &upool[upkg->name];
34.2121 - packages[i]->dep_type = up->type;
34.2122 - packages[i]->dep_property = &upool[up->name];
34.2123 - packages[i]->dep_relation = up->relation;
34.2124 - packages[i]->dep_version = &upool[up->version];
34.2125 - }
34.2126 -
34.2127 - if (spkg) {
34.2128 - packages[i]->old_package = spkg;
34.2129 - packages[i]->old_version = &spool[spkg->version];
34.2130 - if (versioncmp(&spool[spkg->version], &upool[up->version]) >= 0) {
34.2131 - packages[i]->state = RAZOR_PACKAGE_UP_TO_DATE;
34.2132 - trans->errors++;
34.2133 - continue;
34.2134 - }
34.2135 - bitarray_set(&trans->syspkgs, spkg - spkgs, 0);
34.2136 - }
34.2137 - bitarray_set(&trans->uppkgs, upkg - upkgs, 1);
34.2138 - }
34.2139 - if (!packages[i]->new_package) {
34.2140 - packages[i]->name = strdup(packages[i]->name);
34.2141 - packages[i]->state |= RAZOR_PACKAGE_UNAVAILABLE_FLAG;
34.2142 - trans->errors++;
34.2143 - }
34.2144 - }
34.2145 - }
34.2146 -}
34.2147 -
34.2148 -static int
34.2149 -provider_satisfies_requirement(struct razor_property *provider,
34.2150 - const char *provider_strings,
34.2151 - struct razor_property *requirement,
34.2152 - const char *requirement_strings)
34.2153 -{
34.2154 - int cmp, len;
34.2155 - const char *provided = &provider_strings[provider->version];
34.2156 - const char *required = &requirement_strings[requirement->version];
34.2157 -
34.2158 - if (!*required)
34.2159 - return 1;
34.2160 - if (!*provided) {
34.2161 - if (requirement->relation >= RAZOR_VERSION_EQUAL)
34.2162 - return 1;
34.2163 - else
34.2164 - return 0;
34.2165 - }
34.2166 -
34.2167 - cmp = versioncmp(provided, required);
34.2168 -
34.2169 - switch (requirement->relation) {
34.2170 - case RAZOR_VERSION_LESS:
34.2171 - return cmp < 0;
34.2172 -
34.2173 - case RAZOR_VERSION_LESS_OR_EQUAL:
34.2174 - if (cmp <= 0)
34.2175 - return 1;
34.2176 - /* fall through: FIXME, make sure this is correct */
34.2177 -
34.2178 - case RAZOR_VERSION_EQUAL:
34.2179 - if (cmp == 0)
34.2180 - return 1;
34.2181 -
34.2182 - /* "foo == 1.1" is satisfied by "foo 1.1-2" */
34.2183 - len = strlen(required);
34.2184 - if (!strncmp(required, provided, len) && provided[len] == '-')
34.2185 - return 1;
34.2186 - return 0;
34.2187 -
34.2188 - case RAZOR_VERSION_GREATER_OR_EQUAL:
34.2189 - return cmp >= 0;
34.2190 -
34.2191 - case RAZOR_VERSION_GREATER:
34.2192 - return cmp > 0;
34.2193 - }
34.2194 -
34.2195 - /* shouldn't happen */
34.2196 - return 0;
34.2197 -}
34.2198 -
34.2199 -static struct razor_package *
34.2200 -find_package_for_file(struct razor_set *set, struct bitarray *pkgbits,
34.2201 - const char *filename, int installed)
34.2202 -{
34.2203 - struct razor_package *pkgs = set->packages.data;
34.2204 - struct razor_entry *entry;
34.2205 - struct list *p;
34.2206 -
34.2207 - if (filename[0] != '/')
34.2208 - return 0;
34.2209 -
34.2210 - entry = find_entry(set, set->files.data, filename);
34.2211 - if (!entry)
34.2212 - return 0;
34.2213 -
34.2214 - for (p = list_first(&entry->packages, &set->package_pool); p; p = list_next(p)) {
34.2215 - if (bitarray_get(pkgbits, p->data) == installed)
34.2216 - return &pkgs[p->data];
34.2217 - }
34.2218 - return NULL;
34.2219 -}
34.2220 -
34.2221 -static struct razor_package *
34.2222 -find_installed_package_for_file(struct razor_transaction *trans,
34.2223 - const char *filename)
34.2224 -{
34.2225 - struct razor_package *pkg;
34.2226 -
34.2227 - pkg = find_package_for_file(trans->system, &trans->syspkgs,
34.2228 - filename, 1);
34.2229 - if (!pkg)
34.2230 - pkg = find_package_for_file(trans->upstream, &trans->uppkgs,
34.2231 - filename, 1);
34.2232 - return pkg;
34.2233 -}
34.2234 -
34.2235 -static struct razor_package *
34.2236 -find_uninstalled_package_for_file(struct razor_transaction *trans,
34.2237 - const char *filename)
34.2238 -{
34.2239 - struct razor_package *pkg;
34.2240 -
34.2241 - pkg = find_package_for_file(trans->upstream, &trans->uppkgs,
34.2242 - filename, 0);
34.2243 - if (!pkg)
34.2244 - pkg = find_package_for_file(trans->system, &trans->syspkgs,
34.2245 - filename, 0);
34.2246 - return pkg;
34.2247 -}
34.2248 -
34.2249 -static struct razor_property *
34.2250 -skip_to_matching_property(struct razor_transaction *trans,
34.2251 - struct razor_property *match,
34.2252 - struct razor_property *prop)
34.2253 -{
34.2254 - struct razor_set *mset, *pset;
34.2255 - const char *ppool, *mpool;
34.2256 - struct razor_property *prop_end;
34.2257 -
34.2258 - if (property_in_set(match, trans->system))
34.2259 - mset = trans->system;
34.2260 - else
34.2261 - mset = trans->upstream;
34.2262 -
34.2263 - if (property_in_set(prop, trans->system))
34.2264 - pset = trans->system;
34.2265 - else if (property_in_set(prop, trans->upstream))
34.2266 - pset = trans->upstream;
34.2267 - else
34.2268 - return prop;
34.2269 -
34.2270 - prop_end = pset->properties.data + pset->properties.size;
34.2271 - ppool = pset->string_pool.data;
34.2272 - mpool = mset->string_pool.data;
34.2273 -
34.2274 - while (prop < prop_end &&
34.2275 - strcmp(&ppool[prop->name], &mpool[match->name]) < 0)
34.2276 - prop++;
34.2277 - return prop;
34.2278 -}
34.2279 -
34.2280 -static struct razor_package *
34.2281 -find_package_matching(struct razor_transaction *trans, int installed,
34.2282 - struct razor_property *prop,
34.2283 - struct razor_property *req,
34.2284 - struct razor_set *req_set)
34.2285 -{
34.2286 - struct razor_set *set;
34.2287 - struct bitarray *pkgbits;
34.2288 - struct razor_package *pkgs;
34.2289 - struct razor_property *props, *prop_end;
34.2290 - enum razor_property_type match_type;
34.2291 - const char *pool;
34.2292 - const char *rpool;
34.2293 - int match_name = (req->type == RAZOR_PROPERTY_OBSOLETES);
34.2294 - int match;
34.2295 -
34.2296 - if (property_in_set(prop, trans->system)) {
34.2297 - set = trans->system;
34.2298 - pkgbits = &trans->syspkgs;
34.2299 - } else if (property_in_set(prop, trans->upstream)) {
34.2300 - set = trans->upstream;
34.2301 - pkgbits = &trans->uppkgs;
34.2302 - } else
34.2303 - return NULL;
34.2304 -
34.2305 - if (!req_set) {
34.2306 - if (property_in_set(req, trans->system))
34.2307 - req_set = trans->system;
34.2308 - else
34.2309 - req_set = trans->upstream;
34.2310 - }
34.2311 - rpool = req_set->string_pool.data;
34.2312 -
34.2313 - if (req->type == RAZOR_PROPERTY_PROVIDES)
34.2314 - match_type = RAZOR_PROPERTY_CONFLICTS;
34.2315 - else
34.2316 - match_type = RAZOR_PROPERTY_PROVIDES;
34.2317 -
34.2318 - pkgs = set->packages.data;
34.2319 - props = set->properties.data;
34.2320 - prop_end = set->properties.data + set->properties.size;
34.2321 - pool = set->string_pool.data;
34.2322 -
34.2323 - /* Find first matching property */
34.2324 - while (prop < prop_end &&
34.2325 - strcmp(&pool[prop->name], &rpool[req->name]) < 0)
34.2326 - prop++;
34.2327 - if (prop == prop_end ||
34.2328 - strcmp(&pool[prop->name], &rpool[req->name]) > 0)
34.2329 - return NULL;
34.2330 -
34.2331 - if (prop->type < match_type) {
34.2332 - while (prop < prop_end && prop->type != match_type)
34.2333 - prop++;
34.2334 - } else {
34.2335 - while (prop >= props && prop->type != match_type)
34.2336 - prop--;
34.2337 - while (prop > props + 1 && (prop - 1)->name == prop->name &&
34.2338 - (prop - 1)->type == match_type)
34.2339 - prop--;
34.2340 - }
34.2341 -
34.2342 - /* Scan matching properties */
34.2343 - while (prop < prop_end && prop->type == match_type &&
34.2344 - strcmp(&pool[prop->name], &rpool[req->name]) == 0) {
34.2345 - if (match_type == RAZOR_PROPERTY_PROVIDES)
34.2346 - match = provider_satisfies_requirement(prop, pool, req, rpool);
34.2347 - else
34.2348 - match = provider_satisfies_requirement(req, rpool, prop, pool);
34.2349 - if (match) {
34.2350 - struct list *pkg;
34.2351 -
34.2352 - for (pkg = list_first(&prop->packages, &set->package_pool); pkg; pkg = list_next(pkg)) {
34.2353 - if (bitarray_get(pkgbits, pkg->data) != installed)
34.2354 - continue;
34.2355 - if (!match_name ||
34.2356 - strcmp(&pool[pkgs[pkg->data].name],
34.2357 - &rpool[req->name]) == 0)
34.2358 - return &pkgs[pkg->data];
34.2359 - }
34.2360 - }
34.2361 - prop++;
34.2362 - }
34.2363 -
34.2364 - return NULL;
34.2365 -}
34.2366 -
34.2367 -static struct razor_package *
34.2368 -find_installed_package_for_property(struct razor_transaction *trans,
34.2369 - struct razor_property *sys_start,
34.2370 - struct razor_property *up_start,
34.2371 - struct razor_property *req)
34.2372 -{
34.2373 - struct razor_package *pkg;
34.2374 -
34.2375 - pkg = find_package_matching(trans, 1, sys_start, req, NULL);
34.2376 - if (!pkg)
34.2377 - pkg = find_package_matching(trans, 1, up_start, req, NULL);
34.2378 - return pkg;
34.2379 -}
34.2380 -
34.2381 -static struct razor_package *
34.2382 -find_uninstalled_package_for_property(struct razor_transaction *trans,
34.2383 - struct razor_property *sys_start,
34.2384 - struct razor_property *up_start,
34.2385 - struct razor_property *req)
34.2386 -{
34.2387 - struct razor_package *pkg;
34.2388 -
34.2389 - pkg = find_package_matching(trans, 0, up_start, req, NULL);
34.2390 - if (!pkg)
34.2391 - pkg = find_package_matching(trans, 0, sys_start, req, NULL);
34.2392 - return pkg;
34.2393 -}
34.2394 -
34.2395 -static struct razor_transaction_package *
34.2396 -find_transaction_package(struct razor_transaction *trans, const char *name)
34.2397 -{
34.2398 - struct razor_transaction_package *packages;
34.2399 - int count, i;
34.2400 -
34.2401 - packages = trans->packages.data;
34.2402 - count = trans->packages.size / sizeof *packages;
34.2403 - for (i = 0; i < count; i++) {
34.2404 - if (packages[i].name && !strcmp(packages[i].name, name))
34.2405 - return &packages[i];
34.2406 - }
34.2407 - return NULL;
34.2408 -}
34.2409 -
34.2410 -/* FIXME? */
34.2411 -static int
34.2412 -prop_is_being_installed(struct razor_transaction *trans,
34.2413 - struct razor_property *prop)
34.2414 -{
34.2415 - struct list *pkg;
34.2416 -
34.2417 - for (pkg = list_first(&prop->packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
34.2418 - if (bitarray_get(&trans->uppkgs, pkg->data))
34.2419 - return 1;
34.2420 - }
34.2421 - return 0;
34.2422 -}
34.2423 -
34.2424 -static int
34.2425 -prop_is_being_removed(struct razor_transaction *trans,
34.2426 - struct razor_property *prop)
34.2427 -{
34.2428 - struct list *pkg;
34.2429 -
34.2430 - for (pkg = list_first(&prop->packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
34.2431 - if (bitarray_get(&trans->syspkgs, pkg->data))
34.2432 - return 0;
34.2433 - }
34.2434 - return 1;
34.2435 -}
34.2436 -
34.2437 -static int
34.2438 -prop_is_being_updated(struct razor_transaction *trans,
34.2439 - struct razor_property *prop)
34.2440 -{
34.2441 - struct razor_package *packages = trans->system->packages.data;
34.2442 - const char *pool = trans->system->string_pool.data;
34.2443 - struct razor_transaction_package *tp;
34.2444 - struct list *pkg;
34.2445 -
34.2446 - /* Assumes prop_is_being_removed returns true */
34.2447 -
34.2448 - for (pkg = list_first(&prop->packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
34.2449 - tp = find_transaction_package(trans, &pool[packages[pkg->data].name]);
34.2450 - if (tp && tp->state == RAZOR_PACKAGE_REMOVE)
34.2451 - return 0;
34.2452 - }
34.2453 - return 1;
34.2454 -}
34.2455 -
34.2456 -static void
34.2457 -add_transaction_package(struct razor_transaction *trans,
34.2458 - struct razor_package *new_package,
34.2459 - struct razor_package *old_package,
34.2460 - enum razor_transaction_package_state state,
34.2461 - const char *req_package,
34.2462 - struct razor_property *req_prop)
34.2463 -{
34.2464 - struct razor_set *new_package_set, *old_package_set, *req_set;
34.2465 - struct bitarray *reqpkgbits;
34.2466 - struct razor_transaction_package *tp, *already;
34.2467 - const char *pool;
34.2468 - struct razor_package *pkgs;
34.2469 - struct list *pkg;
34.2470 - int contradiction = 0;
34.2471 -
34.2472 - if (package_in_set(new_package, trans->system))
34.2473 - new_package_set = trans->system;
34.2474 - else
34.2475 - new_package_set = trans->upstream;
34.2476 - if (package_in_set(old_package, trans->system))
34.2477 - old_package_set = trans->system;
34.2478 - else
34.2479 - old_package_set = trans->upstream;
34.2480 - if (property_in_set(req_prop, trans->system)) {
34.2481 - req_set = trans->system;
34.2482 - reqpkgbits = &trans->syspkgs;
34.2483 - } else {
34.2484 - req_set = trans->upstream;
34.2485 - reqpkgbits = &trans->uppkgs;
34.2486 - }
34.2487 -
34.2488 - if (new_package) {
34.2489 - pool = new_package_set->string_pool.data;
34.2490 - already = find_transaction_package(trans, &pool[new_package->name]);
34.2491 - if (already) {
34.2492 - if (already->new_package == new_package) {
34.2493 - /* Already taken care of */
34.2494 - return;
34.2495 - } else if (new_package_set == trans->upstream &&
34.2496 - already->state == RAZOR_PACKAGE_FORCED_UPDATE) {
34.2497 - already->new_package = new_package;
34.2498 - return;
34.2499 - } else if (new_package_set == trans->upstream) {
34.2500 - return;
34.2501 - }
34.2502 -
34.2503 - /* Oops. We lose */
34.2504 - if (state != RAZOR_PACKAGE_CONTRADICTION)
34.2505 - contradiction = 1;
34.2506 - }
34.2507 - } else if (old_package) {
34.2508 - pool = old_package_set->string_pool.data;
34.2509 - already = find_transaction_package(trans, &pool[old_package->name]);
34.2510 - if (already) {
34.2511 - if (already->old_package == old_package) {
34.2512 - /* Already taken care of */
34.2513 - return;
34.2514 - } else if (old_package_set == trans->system) {
34.2515 - already->old_package = old_package;
34.2516 - return;
34.2517 - }
34.2518 -
34.2519 - /* Oops. We lose */
34.2520 - if (state != RAZOR_PACKAGE_CONTRADICTION)
34.2521 - contradiction = 1;
34.2522 - }
34.2523 - } else
34.2524 - state = RAZOR_PACKAGE_UNSATISFIABLE;
34.2525 -
34.2526 - tp = array_add(&trans->packages, sizeof *tp);
34.2527 - memset(tp, 0, sizeof *tp);
34.2528 -
34.2529 - if (new_package) {
34.2530 - pool = new_package_set->string_pool.data;
34.2531 - tp->new_package = new_package;
34.2532 - tp->name = &pool[new_package->name];
34.2533 - tp->new_version = &pool[new_package->version];
34.2534 -
34.2535 - pkgs = new_package_set->packages.data;
34.2536 - }
34.2537 - if (old_package) {
34.2538 - pool = old_package_set->string_pool.data;
34.2539 - tp->old_package = old_package;
34.2540 - tp->name = &pool[old_package->name];
34.2541 - tp->old_version = &pool[old_package->version];
34.2542 -
34.2543 - pkgs = old_package_set->packages.data;
34.2544 - }
34.2545 -
34.2546 - tp->state = state;
34.2547 - if (state != RAZOR_PACKAGE_INSTALL &&
34.2548 - state != RAZOR_PACKAGE_FORCED_UPDATE &&
34.2549 - state != RAZOR_PACKAGE_REMOVE &&
34.2550 - state != RAZOR_PACKAGE_OBSOLETED)
34.2551 - trans->errors++;
34.2552 -
34.2553 - if (contradiction) {
34.2554 - /* Do this now, after adding tp, so that it ends up
34.2555 - * after both the INSTALL and the REMOVE in the array.
34.2556 - */
34.2557 - add_transaction_package(trans, new_package, old_package,
34.2558 - RAZOR_PACKAGE_CONTRADICTION,
34.2559 - NULL, NULL);
34.2560 - }
34.2561 -
34.2562 - if (req_package)
34.2563 - tp->dep_package = req_package;
34.2564 - if (!req_prop)
34.2565 - return;
34.2566 -
34.2567 - pool = req_set->string_pool.data;
34.2568 - pkgs = req_set->packages.data;
34.2569 - if (!req_package) {
34.2570 - for (pkg = list_first(&req_prop->packages, &req_set->package_pool); pkg; pkg = list_next(pkg)) {
34.2571 - if (bitarray_get(reqpkgbits, pkg->data))
34.2572 - break;
34.2573 - }
34.2574 - if (pkg)
34.2575 - tp->dep_package = &pool[pkgs[pkg->data].name];
34.2576 - }
34.2577 -
34.2578 - tp->dep_type = req_prop->type;
34.2579 - tp->dep_property = &pool[req_prop->name];
34.2580 - tp->dep_relation = req_prop->relation;
34.2581 - tp->dep_version = &pool[req_prop->version];
34.2582 -}
34.2583 -
34.2584 -static void
34.2585 -razor_transaction_satisfy(struct razor_transaction *trans)
34.2586 -{
34.2587 - struct razor_package *spkgs, *upkgs, *pkg;
34.2588 - struct razor_property *sp, *sprops, *sprop_end;
34.2589 - struct razor_property *up, *uprops, *uprop_end;
34.2590 - struct razor_property *sr, *ur, *first_up;
34.2591 - const char *spool, *upool, *removed_package;
34.2592 - struct list *reqpkg;
34.2593 -
34.2594 - spkgs = trans->system->packages.data;
34.2595 - sprops = trans->system->properties.data;
34.2596 - sprop_end = trans->system->properties.data + trans->system->properties.size;
34.2597 - spool = trans->system->string_pool.data;
34.2598 - upkgs = trans->upstream->packages.data;
34.2599 - uprops = trans->upstream->properties.data;
34.2600 - uprop_end = trans->upstream->properties.data + trans->upstream->properties.size;
34.2601 - upool = trans->upstream->string_pool.data;
34.2602 -
34.2603 - sp = sprops;
34.2604 - for (up = uprops; up < uprop_end; up++) {
34.2605 - /* Skip 'up' ahead to a property of a package which is
34.2606 - * to-be-installed.
34.2607 - */
34.2608 - while (up < uprop_end &&
34.2609 - !prop_is_being_installed(trans, up))
34.2610 - up++;
34.2611 - if (up == uprop_end)
34.2612 - break;
34.2613 - sp = skip_to_matching_property(trans, up, sp);
34.2614 -
34.2615 - switch (up->type) {
34.2616 - case RAZOR_PROPERTY_REQUIRES:
34.2617 - if (!strncmp(&upool[up->name], "rpmlib(", 7))
34.2618 - break;
34.2619 -
34.2620 - if (find_installed_package_for_property(trans, sp, up, up) ||
34.2621 - find_installed_package_for_file(trans, &upool[up->name])) {
34.2622 - /* Requires something that is either installed
34.2623 - * or to-be-installed.
34.2624 - */
34.2625 - break;
34.2626 - }
34.2627 -
34.2628 - /* See if we can install a new upstream provider */
34.2629 - pkg = find_uninstalled_package_for_property(trans, sp, up, up);
34.2630 - if (!pkg)
34.2631 - pkg = find_uninstalled_package_for_file(trans, &upool[up->name]);
34.2632 - add_transaction_package(trans, pkg, NULL,
34.2633 - RAZOR_PACKAGE_INSTALL,
34.2634 - NULL, up);
34.2635 - break;
34.2636 -
34.2637 - case RAZOR_PROPERTY_PROVIDES:
34.2638 - /* find_installed_package_for_property works backwards
34.2639 - * here, finding a *conflicting* installed package.
34.2640 - */
34.2641 - pkg = find_installed_package_for_property(trans, sp, up, up);
34.2642 - if (!pkg)
34.2643 - break;
34.2644 -
34.2645 - if (package_in_set(pkg, trans->system)) {
34.2646 - /* pkg CONFLICTS with what 'up' PROVIDES. Try
34.2647 - * finding an upgrade
34.2648 - */
34.2649 - add_transaction_package(trans, NULL, pkg,
34.2650 - RAZOR_PACKAGE_FORCED_UPDATE,
34.2651 - &upool[up->name], sp);
34.2652 - } else {
34.2653 - add_transaction_package(trans, NULL, pkg,
34.2654 - RAZOR_PACKAGE_CONTRADICTION,
34.2655 - NULL, up);
34.2656 - }
34.2657 - break;
34.2658 -
34.2659 - case RAZOR_PROPERTY_CONFLICTS:
34.2660 - pkg = find_installed_package_for_property(trans, sp, up, up);
34.2661 - if (!pkg)
34.2662 - break;
34.2663 -
34.2664 - if (package_in_set(pkg, trans->system)) {
34.2665 - /* Conflicts with something already installed.
34.2666 - * Try to upgrade out.
34.2667 - */
34.2668 - add_transaction_package(trans, NULL, pkg,
34.2669 - RAZOR_PACKAGE_FORCED_UPDATE,
34.2670 - NULL, up);
34.2671 - } else {
34.2672 - add_transaction_package(trans, pkg, NULL,
34.2673 - RAZOR_PACKAGE_CONTRADICTION,
34.2674 - NULL, up);
34.2675 - }
34.2676 - break;
34.2677 -
34.2678 - case RAZOR_PROPERTY_OBSOLETES:
34.2679 - pkg = find_installed_package_for_property(trans, sp, up, up);
34.2680 - if (pkg) {
34.2681 - /* If pkg is to-be-installed, this
34.2682 - * will add a CONTRADICTION error as well.
34.2683 - */
34.2684 - add_transaction_package(trans, NULL, pkg,
34.2685 - RAZOR_PACKAGE_OBSOLETED,
34.2686 - NULL, up);
34.2687 - }
34.2688 - break;
34.2689 -
34.2690 - default:
34.2691 - /* can't happen */
34.2692 - break;
34.2693 - }
34.2694 - }
34.2695 -
34.2696 - up = uprops;
34.2697 - for (sp = sprops; sp < sprop_end; sp++) {
34.2698 - /* Skip 'sp' ahead to a PROVIDES of a package which is
34.2699 - * to-be-removed.
34.2700 - */
34.2701 - while (sp < sprop_end &&
34.2702 - (sp->type != RAZOR_PROPERTY_PROVIDES ||
34.2703 - !prop_is_being_removed(trans, sp)))
34.2704 - sp++;
34.2705 - if (sp == sprop_end)
34.2706 - break;
34.2707 -
34.2708 - removed_package = &spool[spkgs[list_first(&sp->packages, &trans->system->package_pool)->data].name];
34.2709 -
34.2710 - /* Skip 'up' to match */
34.2711 - up = skip_to_matching_property(trans, sp, up);
34.2712 - ur = first_up = up;
34.2713 -
34.2714 - /* If the package is just being upgraded, we may
34.2715 - * already be installing an identical PROVIDES, so
34.2716 - * check for that.
34.2717 - */
34.2718 - while (up < uprop_end &&
34.2719 - strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
34.2720 - (up->type != RAZOR_PROPERTY_PROVIDES ||
34.2721 - sp->relation != up->relation ||
34.2722 - strcmp(&spool[sp->name], &upool[up->name]) != 0))
34.2723 - up++;
34.2724 - if (up < uprop_end &&
34.2725 - up->type == RAZOR_PROPERTY_PROVIDES &&
34.2726 - strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
34.2727 - sp->relation == up->relation &&
34.2728 - strcmp(&spool[sp->version], &upool[up->version]) == 0 &&
34.2729 - prop_is_being_installed(trans, up)) {
34.2730 - up = first_up;
34.2731 - continue;
34.2732 - }
34.2733 - up = first_up;
34.2734 -
34.2735 - /* For all still-installed packages that require
34.2736 - * sp->name, see if they are satisfied by any other
34.2737 - * still-installed or to-be-installed property. If
34.2738 - * not, either remove or attempt to update the
34.2739 - * package, depending on why the required property has
34.2740 - * disappeared
34.2741 - */
34.2742 - sr = sp;
34.2743 - while (sr > sprops + 1 && (sr - 1)->name == sr->name)
34.2744 - sr--;
34.2745 - for (; sr->type == RAZOR_PROPERTY_REQUIRES; sr++) {
34.2746 - if (prop_is_being_removed(trans, sr))
34.2747 - continue;
34.2748 - if (find_installed_package_for_property(trans, sp, up, sr))
34.2749 - continue;
34.2750 -
34.2751 - for (reqpkg = list_first(&sr->packages, &trans->system->package_pool); reqpkg; reqpkg = list_next(reqpkg)) {
34.2752 - if (!bitarray_get(&trans->syspkgs, reqpkg->data))
34.2753 - continue;
34.2754 - pkg = &spkgs[reqpkg->data];
34.2755 - if (prop_is_being_updated(trans, sp)) {
34.2756 - add_transaction_package(trans, NULL, pkg,
34.2757 - RAZOR_PACKAGE_FORCED_UPDATE,
34.2758 - removed_package, NULL);
34.2759 - } else {
34.2760 - add_transaction_package(trans, NULL, pkg,
34.2761 - RAZOR_PACKAGE_REMOVE,
34.2762 - removed_package, sr);
34.2763 - }
34.2764 - }
34.2765 - }
34.2766 - }
34.2767 -}
34.2768 -
34.2769 -void
34.2770 -razor_transaction_install_package(struct razor_transaction *transaction,
34.2771 - struct razor_package *package)
34.2772 -{
34.2773 - add_transaction_package(transaction, package, NULL,
34.2774 - RAZOR_PACKAGE_INSTALL, NULL, NULL);
34.2775 -}
34.2776 -
34.2777 -void
34.2778 -razor_transaction_remove_package(struct razor_transaction *transaction,
34.2779 - struct razor_package *package)
34.2780 -{
34.2781 - add_transaction_package(transaction, NULL, package,
34.2782 - RAZOR_PACKAGE_REMOVE, NULL, NULL);
34.2783 -}
34.2784 -
34.2785 -void
34.2786 -razor_transaction_update_all(struct razor_transaction *trans)
34.2787 -{
34.2788 - struct razor_package *sp, *spkgs, *send, *up, *upkgs, *uend;
34.2789 - const char *spool, *upool;
34.2790 -
34.2791 - spkgs = trans->system->packages.data;
34.2792 - send = trans->system->packages.data + trans->system->packages.size;
34.2793 - spool = trans->system->string_pool.data;
34.2794 - up = upkgs = trans->upstream->packages.data;
34.2795 - uend = trans->upstream->packages.data + trans->upstream->packages.size;
34.2796 - upool = trans->upstream->string_pool.data;
34.2797 -
34.2798 - for (sp = spkgs; sp < send; sp++) {
34.2799 - while (up < uend && strcmp(&spool[sp->name], &upool[up->name]) > 0)
34.2800 - up++;
34.2801 - if (strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
34.2802 - versioncmp(&spool[sp->version], &upool[up->version]) < 0) {
34.2803 - add_transaction_package(trans, up, sp,
34.2804 - RAZOR_PACKAGE_INSTALL,
34.2805 - NULL, NULL);
34.2806 - }
34.2807 - }
34.2808 -}
34.2809 -
34.2810 -struct razor_transaction *
34.2811 -razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
34.2812 -{
34.2813 - struct razor_transaction *trans;
34.2814 - int count;
34.2815 -
34.2816 - trans = zalloc(sizeof *trans);
34.2817 -
34.2818 - trans->system = system;
34.2819 - trans->upstream = upstream ? upstream : razor_set_create();
34.2820 - array_init(&trans->packages);
34.2821 - count = trans->system->packages.size / sizeof (struct razor_package);
34.2822 - bitarray_init(&trans->syspkgs, count, 1);
34.2823 - count = trans->upstream->packages.size / sizeof (struct razor_package);
34.2824 - bitarray_init(&trans->uppkgs, count, 0);
34.2825 -
34.2826 - return trans;
34.2827 -}
34.2828 -
34.2829 -static void
34.2830 -resolve_transaction(struct razor_transaction *trans)
34.2831 -{
34.2832 - int start, end;
34.2833 -
34.2834 - if (trans->package_count > 0)
34.2835 - /* Already did this, return. */
34.2836 - return;
34.2837 -
34.2838 - start = 0;
34.2839 - end = trans->packages.size / sizeof (struct razor_transaction_package);
34.2840 -
34.2841 - while (start != end) {
34.2842 - resolve_new_packages(trans, start, end);
34.2843 - if (trans->errors)
34.2844 - break;
34.2845 -
34.2846 - razor_transaction_satisfy(trans);
34.2847 -
34.2848 - start = end;
34.2849 - end = trans->packages.size / sizeof (struct razor_transaction_package);
34.2850 - }
34.2851 -
34.2852 - trans->package_count = end;
34.2853 -}
34.2854 -
34.2855 -const char * const razor_version_relations[] = {
34.2856 - /* same order as enum razor_version_relation */
34.2857 - "<", "<=", "=", ">=", ">"
34.2858 -};
34.2859 -
34.2860 -const char * const razor_property_types[] = {
34.2861 - /* same order as enum razor_property_type */
34.2862 - "requires", "provides", "conflicts with", "obsoletes"
34.2863 -};
34.2864 -
34.2865 -static void
34.2866 -print_requirement(struct razor_transaction_package *p)
34.2867 -{
34.2868 - if (p->dep_type == RAZOR_PROPERTY_CONFLICTS &&
34.2869 - !strcmp(p->dep_package, p->name)) {
34.2870 - printf(" because %s %s conflicts with %s",
34.2871 - p->name, p->old_version, p->dep_property);
34.2872 - if (*p->dep_version) {
34.2873 - printf(" %s %s",
34.2874 - razor_version_relations[p->dep_relation],
34.2875 - p->dep_version);
34.2876 - }
34.2877 - } else {
34.2878 - if (strcmp(p->name, p->dep_package) != 0)
34.2879 - printf(" for %s", p->dep_package);
34.2880 - if (*p->dep_version) {
34.2881 - printf(", which %s %s %s %s",
34.2882 - razor_property_types[p->dep_type],
34.2883 - p->dep_property,
34.2884 - razor_version_relations[p->dep_relation],
34.2885 - p->dep_version);
34.2886 - } else if (strcmp(p->dep_property, p->name) != 0) {
34.2887 - printf(", which %s %s",
34.2888 - razor_property_types[p->dep_type],
34.2889 - p->dep_property);
34.2890 - }
34.2891 - }
34.2892 -}
34.2893 -
34.2894 -int
34.2895 -razor_transaction_resolve(struct razor_transaction *trans)
34.2896 -{
34.2897 - struct razor_transaction_package *p, *pend, *tps;
34.2898 - int errors_only = 0;
34.2899 -
34.2900 - resolve_transaction(trans);
34.2901 -
34.2902 - tps = trans->packages.data;
34.2903 - pend = trans->packages.data + trans->packages.size;
34.2904 - for (p = trans->packages.data; p < pend; p++) {
34.2905 - switch (p->state) {
34.2906 - case RAZOR_PACKAGE_INSTALL:
34.2907 - if (errors_only)
34.2908 - break;
34.2909 -
34.2910 - printf("Installing %s %s", p->name, p->new_version);
34.2911 - if (p->dep_package)
34.2912 - print_requirement(p);
34.2913 - printf("\n");
34.2914 - break;
34.2915 -
34.2916 - case RAZOR_PACKAGE_FORCED_UPDATE:
34.2917 - if (errors_only)
34.2918 - break;
34.2919 -
34.2920 - printf("Updating %s to %s due to update of %s\n",
34.2921 - p->name, p->new_version, p->dep_package);
34.2922 - break;
34.2923 -
34.2924 - case RAZOR_PACKAGE_REMOVE:
34.2925 - if (errors_only)
34.2926 - break;
34.2927 - printf("Removing %s %s", p->name, p->old_version);
34.2928 - if (p->dep_package) {
34.2929 - printf(" which required %s",
34.2930 - p->dep_package);
34.2931 - if (strcmp(p->dep_property, p->dep_package) != 0)
34.2932 - printf(" for %s", p->dep_property);
34.2933 - }
34.2934 - printf("\n");
34.2935 - break;
34.2936 -
34.2937 - case RAZOR_PACKAGE_OBSOLETED:
34.2938 - if (errors_only)
34.2939 - break;
34.2940 - printf("Removing %s %s", p->name, p->old_version);
34.2941 - if (p->dep_package) {
34.2942 - printf(" which is obsoleted by %s",
34.2943 - p->dep_package);
34.2944 - }
34.2945 - printf("\n");
34.2946 - break;
34.2947 -
34.2948 - case RAZOR_PACKAGE_INSTALL_UNAVAILABLE:
34.2949 - printf("Error: can't find %s", p->name);
34.2950 - if (p->dep_package) {
34.2951 - printf(" (which is required");
34.2952 - print_requirement(p);
34.2953 - printf(")");
34.2954 - }
34.2955 - printf("\n");
34.2956 - errors_only = 1;
34.2957 - break;
34.2958 -
34.2959 - case RAZOR_PACKAGE_UPDATE_UNAVAILABLE:
34.2960 - printf("Error: can't find an updated version of %s (which must be updated due to update of %s)\n",
34.2961 - p->name, p->dep_package);
34.2962 - errors_only = 1;
34.2963 - break;
34.2964 -
34.2965 - case RAZOR_PACKAGE_REMOVE_NOT_INSTALLED:
34.2966 - printf("Error: can't remove %s: not installed\n", p->name);
34.2967 - errors_only = 1;
34.2968 - break;
34.2969 -
34.2970 - case RAZOR_PACKAGE_UP_TO_DATE:
34.2971 - printf("Error: can't update %s", p->name);
34.2972 - if (p->dep_package)
34.2973 - printf(" (which must be updated due to update of %s)", p->dep_package);
34.2974 - printf(": %s is most recent version\n", p->old_version);
34.2975 - errors_only = 1;
34.2976 - break;
34.2977 -
34.2978 - case RAZOR_PACKAGE_CONTRADICTION:
34.2979 - printf("Error: package %s is marked for both installation and removal\n", p->name);
34.2980 - errors_only = 1;
34.2981 - break;
34.2982 -
34.2983 - case RAZOR_PACKAGE_OLD_CONFLICT:
34.2984 - printf("Error: can't install %s, because installed package %s conflicts with ",
34.2985 - p->name, p->dep_package);
34.2986 - if (*p->dep_version) {
34.2987 - printf("%s %s %s",
34.2988 - p->dep_property,
34.2989 - razor_version_relations[p->dep_relation],
34.2990 - p->dep_version);
34.2991 - } else
34.2992 - printf("it");
34.2993 - printf("\n");
34.2994 -
34.2995 - errors_only = 1;
34.2996 - break;
34.2997 -
34.2998 - case RAZOR_PACKAGE_NEW_CONFLICT:
34.2999 - printf("Error: can't install %s, because it conflicts with %s",
34.3000 - p->name, p->dep_package);
34.3001 - if (*p->dep_version) {
34.3002 - printf(" %s %s",
34.3003 - razor_version_relations[p->dep_relation],
34.3004 - p->dep_version);
34.3005 - }
34.3006 - printf("\n");
34.3007 -
34.3008 - errors_only = 1;
34.3009 - break;
34.3010 -
34.3011 - case RAZOR_PACKAGE_UNSATISFIABLE:
34.3012 - printf("Error: can't find package for %s", p->dep_property);
34.3013 - if (*p->dep_version) {
34.3014 - printf(" %s %s",
34.3015 - razor_version_relations[p->dep_relation],
34.3016 - p->dep_version);
34.3017 - }
34.3018 - printf(" which is required by %s\n",
34.3019 - p->dep_package);
34.3020 - errors_only = 1;
34.3021 - break;
34.3022 -
34.3023 - default:
34.3024 - /* Shouldn't actually happen */
34.3025 - break;
34.3026 - }
34.3027 - }
34.3028 -
34.3029 - return trans->errors;
34.3030 -}
34.3031 -
34.3032 -int
34.3033 -razor_transaction_unsatisfied_property(struct razor_transaction *trans,
34.3034 - const char *name,
34.3035 - enum razor_version_relation rel,
34.3036 - const char *version)
34.3037 -{
34.3038 - struct razor_transaction_package *p, *end;
34.3039 -
34.3040 - end = trans->packages.data + trans->packages.size;
34.3041 - for (p = trans->packages.data; p < end; p++) {
34.3042 - if (p->state != RAZOR_PACKAGE_UNSATISFIABLE)
34.3043 - continue;
34.3044 - if (strcmp(name, p->dep_property) != 0 ||
34.3045 - rel != p->dep_relation ||
34.3046 - strcmp(version, p->dep_version) != 0)
34.3047 - continue;
34.3048 -
34.3049 - return 1;
34.3050 - }
34.3051 -
34.3052 - return 0;
34.3053 -}
34.3054 -
34.3055 -struct razor_set *
34.3056 -razor_transaction_finish(struct razor_transaction *trans)
34.3057 -{
34.3058 - struct array install_packages, remove_packages;
34.3059 - struct razor_merger *merger;
34.3060 - struct razor_package *pkg, *i, *iend, *r, *rend, *s, *send;
34.3061 - struct razor_set *set;
34.3062 - struct source *source1, *source2;
34.3063 - char *spool, *ipool, *rpool;
34.3064 - uint32_t *map;
34.3065 - struct razor_transaction_package *p, *end;
34.3066 - int cmp;
34.3067 -
34.3068 - /* FIXME */
34.3069 - if (trans->errors)
34.3070 - return NULL;
34.3071 -
34.3072 - /* Sort the transaction packages into two arrays */
34.3073 - array_init(&install_packages);
34.3074 - array_init(&remove_packages);
34.3075 -
34.3076 - end = trans->packages.data + trans->packages.size;
34.3077 - for (p = trans->packages.data; p < end; p++) {
34.3078 - if (p->new_package) {
34.3079 - pkg = array_add(&install_packages, sizeof *pkg);
34.3080 - *pkg = *p->new_package;
34.3081 - } else {
34.3082 - pkg = array_add(&remove_packages, sizeof *pkg);
34.3083 - *pkg = *p->old_package;
34.3084 - }
34.3085 - }
34.3086 - map = razor_qsort_with_data(install_packages.data,
34.3087 - install_packages.size / sizeof *pkg,
34.3088 - sizeof *pkg,
34.3089 - compare_packages,
34.3090 - trans->upstream);
34.3091 - free(map);
34.3092 - map = razor_qsort_with_data(remove_packages.data,
34.3093 - remove_packages.size / sizeof *pkg,
34.3094 - sizeof *pkg,
34.3095 - compare_packages,
34.3096 - trans->system);
34.3097 - free(map);
34.3098 -
34.3099 - merger = razor_merger_create(trans->system, trans->upstream);
34.3100 -
34.3101 - source1 = &merger->source1;
34.3102 - source2 = &merger->source2;
34.3103 -
34.3104 - i = install_packages.data;
34.3105 - iend = install_packages.data + install_packages.size;
34.3106 - ipool = trans->upstream->string_pool.data;
34.3107 -
34.3108 - r = remove_packages.data;
34.3109 - rend = remove_packages.data + remove_packages.size;
34.3110 - rpool = trans->system->string_pool.data;
34.3111 -
34.3112 - s = trans->system->packages.data;
34.3113 - send = trans->system->packages.data + trans->system->packages.size;
34.3114 - spool = trans->system->string_pool.data;
34.3115 -
34.3116 - while (s < send || i < iend) {
34.3117 - /* Check if s is being removed */
34.3118 - if (s < send && r < rend &&
34.3119 - s->name == r->name && s->version && r->version) {
34.3120 - s++;
34.3121 - r++;
34.3122 - continue;
34.3123 - }
34.3124 -
34.3125 - if (s < send && i < iend)
34.3126 - cmp = strcmp(&spool[s->name], &ipool[i->name]);
34.3127 - else if (s < send)
34.3128 - cmp = -1;
34.3129 - else
34.3130 - cmp = 1;
34.3131 - if (cmp < 0) {
34.3132 - add_package(merger, s, source1, 0);
34.3133 - s++;
34.3134 - } else if (cmp == 0) {
34.3135 - add_package(merger, i, source2, UPSTREAM_SOURCE);
34.3136 - s++;
34.3137 - i++;
34.3138 - } else {
34.3139 - add_package(merger, i, source2, UPSTREAM_SOURCE);
34.3140 - i++;
34.3141 - }
34.3142 - }
34.3143 -
34.3144 - array_release(&install_packages);
34.3145 - array_release(&remove_packages);
34.3146 -
34.3147 - set = razor_merger_finish(merger);
34.3148 - razor_transaction_destroy(trans);
34.3149 -
34.3150 - return set;
34.3151 -}
34.3152 -
34.3153 -void
34.3154 -razor_transaction_destroy(struct razor_transaction *trans)
34.3155 -{
34.3156 - struct razor_transaction_package *p, *end;
34.3157 -
34.3158 - end = trans->packages.data + trans->packages.size;
34.3159 - for (p = trans->packages.data; p < end; p++) {
34.3160 - if (!p->dep_package &&
34.3161 - (p->state == RAZOR_PACKAGE_INSTALL_UNAVAILABLE ||
34.3162 - p->state == RAZOR_PACKAGE_REMOVE_NOT_INSTALLED))
34.3163 - free((char *)p->name);
34.3164 - }
34.3165 -
34.3166 - array_release(&trans->packages);
34.3167 - bitarray_release(&trans->syspkgs);
34.3168 - bitarray_release(&trans->uppkgs);
34.3169 - free(trans);
34.3170 -
34.3171 - /* FIXME: free upstream if it was created as an empty set */
34.3172 -}
34.3173 -
34.3174 -struct razor_package_query {
34.3175 - struct razor_set *set;
34.3176 - char *vector;
34.3177 - int count;
34.3178 -};
34.3179 -
34.3180 -struct razor_package_query *
34.3181 -razor_package_query_create(struct razor_set *set)
34.3182 -{
34.3183 - struct razor_package_query *pq;
34.3184 - int count;
34.3185 -
34.3186 - pq = zalloc(sizeof *pq);
34.3187 - pq->set = set;
34.3188 - count = set->packages.size / sizeof(struct razor_package);
34.3189 - pq->vector = zalloc(count * sizeof(char));
34.3190 -
34.3191 - return pq;
34.3192 -}
34.3193 -
34.3194 -void
34.3195 -razor_package_query_add_package(struct razor_package_query *pq,
34.3196 - struct razor_package *p)
34.3197 -{
34.3198 - struct razor_package *packages;
34.3199 -
34.3200 - packages = pq->set->packages.data;
34.3201 - pq->count += pq->vector[p - packages] ^ 1;
34.3202 - pq->vector[p - packages] = 1;
34.3203 -}
34.3204 -
34.3205 -void
34.3206 -razor_package_query_add_iterator(struct razor_package_query *pq,
34.3207 - struct razor_package_iterator *pi)
34.3208 -{
34.3209 - struct razor_package *packages, *p;
34.3210 - const char *name, *version, *arch;
34.3211 -
34.3212 - packages = pq->set->packages.data;
34.3213 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
34.3214 - pq->count += pq->vector[p - packages] ^ 1;
34.3215 - pq->vector[p - packages] = 1;
34.3216 - }
34.3217 -}
34.3218 -
34.3219 -struct razor_package_iterator *
34.3220 -razor_package_query_finish(struct razor_package_query *pq)
34.3221 -{
34.3222 - struct razor_package_iterator *pi;
34.3223 - struct razor_set *set;
34.3224 - struct list *index;
34.3225 - int i, j, count;
34.3226 -
34.3227 - set = pq->set;
34.3228 - count = set->packages.size / sizeof(struct razor_package);
34.3229 - index = zalloc(pq->count * sizeof *index);
34.3230 -
34.3231 - for (i = 0, j = 0; i < count; i++) {
34.3232 - if (!pq->vector[i])
34.3233 - continue;
34.3234 -
34.3235 - index[j].data = i;
34.3236 - if (j == pq->count - 1)
34.3237 - index[j].flags = 0x80;
34.3238 - j++;
34.3239 - }
34.3240 -
34.3241 - free(pq);
34.3242 -
34.3243 - pi = razor_package_iterator_create_with_index(set, index);
34.3244 - pi->free_index = 1;
34.3245 -
34.3246 - return pi;
34.3247 -}
35.1 --- a/razor.h Sun Jun 15 18:16:20 2008 -0400
35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3 @@ -1,220 +0,0 @@
35.4 -/*
35.5 - * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
35.6 - * Copyright (C) 2008 Red Hat, Inc
35.7 - *
35.8 - * This program is free software; you can redistribute it and/or modify
35.9 - * it under the terms of the GNU General Public License as published by
35.10 - * the Free Software Foundation; either version 2 of the License, or
35.11 - * (at your option) any later version.
35.12 - *
35.13 - * This program is distributed in the hope that it will be useful,
35.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
35.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35.16 - * GNU General Public License for more details.
35.17 - *
35.18 - * You should have received a copy of the GNU General Public License along
35.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
35.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35.21 - */
35.22 -
35.23 -#ifndef _RAZOR_H_
35.24 -#define _RAZOR_H_
35.25 -
35.26 -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
35.27 -
35.28 -struct razor_set;
35.29 -struct razor_package;
35.30 -struct razor_property;
35.31 -
35.32 -enum razor_repo_file_type {
35.33 - RAZOR_REPO_FILE_MAIN,
35.34 - RAZOR_REPO_FILE_DETAILS,
35.35 - RAZOR_REPO_FILE_FILES
35.36 -};
35.37 -
35.38 -enum razor_property_type {
35.39 - RAZOR_PROPERTY_REQUIRES,
35.40 - RAZOR_PROPERTY_PROVIDES,
35.41 - RAZOR_PROPERTY_CONFLICTS,
35.42 - RAZOR_PROPERTY_OBSOLETES
35.43 -};
35.44 -
35.45 -enum razor_version_relation {
35.46 - RAZOR_VERSION_LESS,
35.47 - RAZOR_VERSION_LESS_OR_EQUAL,
35.48 - RAZOR_VERSION_EQUAL,
35.49 - RAZOR_VERSION_GREATER_OR_EQUAL,
35.50 - RAZOR_VERSION_GREATER
35.51 -};
35.52 -extern const char * const razor_version_relations[];
35.53 -
35.54 -struct razor_set *razor_set_create(void);
35.55 -struct razor_set *razor_set_open(const char *filename);
35.56 -void razor_set_destroy(struct razor_set *set);
35.57 -int razor_set_write_to_fd(struct razor_set *set, int fd,
35.58 - enum razor_repo_file_type type);
35.59 -int razor_set_write(struct razor_set *set, const char *filename,
35.60 - enum razor_repo_file_type type);
35.61 -
35.62 -void razor_set_open_details(struct razor_set *set, const char *filename);
35.63 -void razor_set_open_files(struct razor_set *set, const char *filename);
35.64 -
35.65 -struct razor_package *
35.66 -razor_set_get_package(struct razor_set *set, const char *package);
35.67 -
35.68 -void
35.69 -razor_package_get_details(struct razor_set *set, struct razor_package *package,
35.70 - const char **summary, const char **description,
35.71 - const char **url, const char **license);
35.72 -
35.73 -struct razor_package_iterator;
35.74 -struct razor_package_iterator *
35.75 -razor_package_iterator_create(struct razor_set *set);
35.76 -struct razor_package_iterator *
35.77 -razor_package_iterator_create_for_property(struct razor_set *set,
35.78 - struct razor_property *property);
35.79 -struct razor_package_iterator *
35.80 -razor_package_iterator_create_for_file(struct razor_set *set,
35.81 - const char *filename);
35.82 -
35.83 -int razor_package_iterator_next(struct razor_package_iterator *pi,
35.84 - struct razor_package **package,
35.85 - const char **name,
35.86 - const char **version,
35.87 - const char **arch);
35.88 -void razor_package_iterator_destroy(struct razor_package_iterator *pi);
35.89 -
35.90 -struct razor_package_query *
35.91 -razor_package_query_create(struct razor_set *set);
35.92 -void
35.93 -razor_package_query_add_package(struct razor_package_query *pq,
35.94 - struct razor_package *p);
35.95 -void
35.96 -razor_package_query_add_iterator(struct razor_package_query *pq,
35.97 - struct razor_package_iterator *pi);
35.98 -struct razor_package_iterator *
35.99 -razor_package_query_finish(struct razor_package_query *pq);
35.100 -
35.101 -struct razor_property_iterator;
35.102 -struct razor_property_iterator *
35.103 -razor_property_iterator_create(struct razor_set *set,
35.104 - struct razor_package *package);
35.105 -int razor_property_iterator_next(struct razor_property_iterator *pi,
35.106 - struct razor_property **property,
35.107 - const char **name,
35.108 - enum razor_version_relation *relation,
35.109 - const char **version,
35.110 - enum razor_property_type *type);
35.111 -void
35.112 -razor_property_iterator_destroy(struct razor_property_iterator *pi);
35.113 -
35.114 -void razor_set_list_files(struct razor_set *set, const char *prefix);
35.115 -void razor_set_list_package_files(struct razor_set *set, const char *name);
35.116 -
35.117 -void razor_set_list_unsatisfied(struct razor_set *set);
35.118 -
35.119 -typedef void (*razor_package_callback_t)(const char *name,
35.120 - const char *old_version,
35.121 - const char *new_version,
35.122 - const char *arch,
35.123 - void *data);
35.124 -void
35.125 -razor_set_diff(struct razor_set *set, struct razor_set *upstream,
35.126 - razor_package_callback_t callback, void *data);
35.127 -
35.128 -/* Package transactions */
35.129 -
35.130 -enum razor_transaction_package_state {
35.131 - /* Basic states */
35.132 - RAZOR_PACKAGE_INSTALL,
35.133 - RAZOR_PACKAGE_FORCED_UPDATE,
35.134 - RAZOR_PACKAGE_REMOVE,
35.135 - RAZOR_PACKAGE_OBSOLETED,
35.136 -
35.137 - /* Error states */
35.138 -
35.139 - RAZOR_PACKAGE_FIRST_ERROR_STATE = 0x4,
35.140 - RAZOR_PACKAGE_UNAVAILABLE_FLAG = 0x4,
35.141 -
35.142 - /* Package requested for install does not exist */
35.143 - RAZOR_PACKAGE_INSTALL_UNAVAILABLE = RAZOR_PACKAGE_INSTALL | RAZOR_PACKAGE_UNAVAILABLE_FLAG,
35.144 - /* Package requiring update does not have any update */
35.145 - RAZOR_PACKAGE_UPDATE_UNAVAILABLE = RAZOR_PACKAGE_FORCED_UPDATE | RAZOR_PACKAGE_UNAVAILABLE_FLAG,
35.146 - /* Package requested for removal does not exist */
35.147 - RAZOR_PACKAGE_REMOVE_NOT_INSTALLED = RAZOR_PACKAGE_REMOVE | RAZOR_PACKAGE_UNAVAILABLE_FLAG,
35.148 - /* (not used) */
35.149 - RAZOR_PACKAGE_OBSOLETE_UNAVAILABLE = RAZOR_PACKAGE_OBSOLETED | RAZOR_PACKAGE_UNAVAILABLE_FLAG,
35.150 -
35.151 - /* No newer version of package is available */
35.152 - RAZOR_PACKAGE_UP_TO_DATE,
35.153 - /* Package marked for both install and remove */
35.154 - RAZOR_PACKAGE_CONTRADICTION,
35.155 - /* Package would add a conflict with an already-installed package */
35.156 - RAZOR_PACKAGE_NEW_CONFLICT,
35.157 - /* Already-installed package has a conflict against this package */
35.158 - RAZOR_PACKAGE_OLD_CONFLICT,
35.159 - /* Requirement of to-be-installed package can't be satisfied */
35.160 - RAZOR_PACKAGE_UNSATISFIABLE,
35.161 -};
35.162 -
35.163 -struct razor_transaction *
35.164 -razor_transaction_create(struct razor_set *system, struct razor_set *upstream);
35.165 -void razor_transaction_install_package(struct razor_transaction *transaction,
35.166 - struct razor_package *package);
35.167 -void razor_transaction_remove_package(struct razor_transaction *transaction,
35.168 - struct razor_package *package);
35.169 -void razor_transaction_update_all(struct razor_transaction *transaction);
35.170 -int razor_transaction_resolve(struct razor_transaction *trans);
35.171 -struct razor_set *razor_transaction_finish(struct razor_transaction *trans);
35.172 -void razor_transaction_destroy(struct razor_transaction *trans);
35.173 -
35.174 -/* Temporary helper for test suite. */
35.175 -int razor_transaction_unsatisfied_property(struct razor_transaction *trans,
35.176 - const char *name,
35.177 - enum razor_version_relation rel,
35.178 - const char *version);
35.179 -
35.180 -/* Importer interface; for building a razor set from external sources,
35.181 - * like yum, rpmdb or razor package files. */
35.182 -
35.183 -struct razor_importer;
35.184 -struct razor_rpm;
35.185 -
35.186 -struct razor_importer *razor_importer_new(void);
35.187 -void razor_importer_destroy(struct razor_importer *importer);
35.188 -void razor_importer_begin_package(struct razor_importer *importer,
35.189 - const char *name,
35.190 - const char *version,
35.191 - const char *arch);
35.192 -void razor_importer_add_details(struct razor_importer *importer,
35.193 - const char *summary,
35.194 - const char *description,
35.195 - const char *url,
35.196 - const char *license);
35.197 -void razor_importer_add_property(struct razor_importer *importer,
35.198 - const char *name,
35.199 - enum razor_version_relation relation,
35.200 - const char *version,
35.201 - enum razor_property_type type);
35.202 -void razor_importer_add_file(struct razor_importer *importer,
35.203 - const char *name);
35.204 -void razor_importer_finish_package(struct razor_importer *importer);
35.205 -
35.206 -int razor_importer_add_rpm(struct razor_importer *importer,
35.207 - struct razor_rpm *rpm);
35.208 -
35.209 -struct razor_set *razor_importer_finish(struct razor_importer *importer);
35.210 -
35.211 -void razor_build_evr(char *evr_buf, int size, const char *epoch,
35.212 - const char *version, const char *release);
35.213 -
35.214 -struct razor_set *razor_set_create_from_yum(void);
35.215 -struct razor_set *razor_set_create_from_rpmdb(void);
35.216 -
35.217 -/* RPM functions */
35.218 -
35.219 -struct razor_rpm *razor_rpm_open(const char *filename);
35.220 -int razor_rpm_install(struct razor_rpm *rpm, const char *root);
35.221 -int razor_rpm_close(struct razor_rpm *rpm);
35.222 -
35.223 -#endif /* _RAZOR_H_ */
36.1 --- a/rpm-razor.c Sun Jun 15 18:16:20 2008 -0400
36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
36.3 @@ -1,789 +0,0 @@
36.4 -/*
36.5 - * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
36.6 - * Copyright (C) 2008 Red Hat, Inc
36.7 - *
36.8 - * This program is free software; you can redistribute it and/or modify
36.9 - * it under the terms of the GNU General Public License as published by
36.10 - * the Free Software Foundation; either version 2 of the License, or
36.11 - * (at your option) any later version.
36.12 - *
36.13 - * This program is distributed in the hope that it will be useful,
36.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
36.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
36.16 - * GNU General Public License for more details.
36.17 - *
36.18 - * You should have received a copy of the GNU General Public License along
36.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
36.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
36.21 - */
36.22 -
36.23 -#include <stdlib.h>
36.24 -#include <string.h>
36.25 -#include <stdio.h>
36.26 -#include "razor.h"
36.27 -
36.28 -enum option_type {
36.29 - OPTION_LAST,
36.30 - OPTION_GROUP,
36.31 - OPTION_BOOL,
36.32 - OPTION_STRING
36.33 -};
36.34 -
36.35 -struct option {
36.36 - enum option_type type;
36.37 - const char *name;
36.38 - char short_name;
36.39 - const char *arg_name;
36.40 - const char *description;
36.41 - void *data;
36.42 -};
36.43 -
36.44 -/* A note about all these options: rpm allows options to mean
36.45 - * different things depending on what other options are present on the
36.46 - * command line. For example, if -q or --query is present, -i no
36.47 - * longer means install, but info. The way we handle this is by
36.48 - * setting all the options that may match (ie if -i is given we set
36.49 - * install and info), and then look at the relevent one depending on
36.50 - * what else in on the command line. */
36.51 -
36.52 -static int option_all, option_whatrequires, option_whatprovides;
36.53 -static int option_package;
36.54 -
36.55 -static const struct option query_options[] = {
36.56 - { OPTION_BOOL, "configfiles", 'c', NULL, "list all configuration files", NULL },
36.57 - { OPTION_BOOL, "docfiles", 'd', NULL, "list all documentation files", NULL },
36.58 - { OPTION_BOOL, "dump", 0, NULL, "dump basic file information", NULL },
36.59 - { OPTION_BOOL, "list", 0, NULL, "list files in package", NULL },
36.60 - { OPTION_STRING, "queryformat", 0, "QUERYFORMAT", "use the following query format", NULL },
36.61 - { OPTION_BOOL, "state", 's', NULL, "display the states of the listed files", NULL },
36.62 - { OPTION_BOOL, "all", 'a', NULL, "query/verify all packages", &option_all },
36.63 - { OPTION_BOOL, "file", 'f', NULL, "query/verify package(s) owning file", NULL },
36.64 - { OPTION_BOOL, "group", 'g', NULL, "query/verify package(s) in group", NULL },
36.65 - { OPTION_BOOL, "package", 'p', NULL, "query/verify a package file", &option_package },
36.66 - { OPTION_BOOL, "ftswalk", 'W', NULL, "query/verify package(s) from TOP file tree walk", NULL },
36.67 - { OPTION_BOOL, "pkgid", 0, NULL, "query/verify package(s) with package identifier", NULL },
36.68 - { OPTION_BOOL, "hdrid", 0, NULL, "query/verify package(s) with header identifier", NULL },
36.69 - { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL },
36.70 - { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL, },
36.71 - { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL },
36.72 - { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires },
36.73 - { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides },
36.74 - { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL },
36.75 - { }
36.76 -};
36.77 -
36.78 -static const struct option verify_options[] = {
36.79 - { OPTION_BOOL, "nomd5", 0, NULL, "don't verify MD5 digest of files", NULL },
36.80 - { OPTION_BOOL, "nofiles", 0, NULL, "don't verify files in package", NULL },
36.81 - { OPTION_BOOL, "nodeps", 0, NULL, "don't verify package dependencies", NULL },
36.82 - { OPTION_BOOL, "noscript", 0, NULL, "don't execute verify script(s)", NULL, },
36.83 - { OPTION_BOOL, "all", 'a', NULL, "query/verify all packages", &option_all },
36.84 - { OPTION_BOOL, "file", 'f', NULL, "query/verify package(s) owning file", NULL },
36.85 - { OPTION_BOOL, "group", 'g', NULL, "query/verify package(s) in group", NULL },
36.86 - { OPTION_BOOL, "package", 'p', NULL, "query/verify a package file", &option_package },
36.87 - { OPTION_BOOL, "ftswalk", 'W', NULL, "query/verify package(s) from TOP file tree walk", NULL },
36.88 - { OPTION_BOOL, "pkgid", 0, NULL, "query/verify package(s) with package identifier", NULL },
36.89 - { OPTION_BOOL, "hdrid", 0, NULL, "query/verify package(s) with header identifier", NULL },
36.90 - { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL },
36.91 - { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL },
36.92 - { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL },
36.93 - { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires },
36.94 - { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides },
36.95 - { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL },
36.96 - { }
36.97 -};
36.98 -
36.99 -static const struct option ftw_options[] = {
36.100 - { OPTION_BOOL, "comfollow", 0, NULL, "FTS_COMFOLLOW: follow command line symlinks", NULL },
36.101 - { OPTION_BOOL, "logical", 0, NULL, "FTS_LOGICAL: logical walk", NULL },
36.102 - { OPTION_BOOL, "nochdir", 0, NULL, "FTS_NOCHDIR: don't change directories", NULL },
36.103 - { OPTION_BOOL, "nostat", 0, NULL, "FTS_NOSTAT: don't get stat info", NULL },
36.104 - { OPTION_BOOL, "physical", 0, NULL, "FTS_PHYSICAL: physical walk", NULL },
36.105 - { OPTION_BOOL, "seedot", 0, NULL, "FTS_SEEDOT: return dot and dot-dot", NULL },
36.106 - { OPTION_BOOL, "xdev", 0, NULL, "FTS_XDEV: don't cross devices", NULL },
36.107 - { OPTION_BOOL, "whiteout", 0, NULL, "FTS_WHITEOUT: return whiteout information", NULL },
36.108 - { }
36.109 -};
36.110 -
36.111 -static const struct option signature_options[] = {
36.112 - { OPTION_BOOL, "addsign", 0, NULL, "sign package(s) (identical to --resign)", NULL, },
36.113 - { OPTION_BOOL, "checksig", 'K', NULL, "verify package signature(s)", NULL, },
36.114 - { OPTION_BOOL, "delsign", 0, NULL, "delete package signatures", NULL, },
36.115 - { OPTION_BOOL, "import", 0, NULL, "import an armored public key", NULL, },
36.116 - { OPTION_BOOL, "resign", 0, NULL, "sign package(s) (identical to --addsign)", NULL, },
36.117 - { OPTION_BOOL, "nodigest", 0, NULL, "don't verify package digest(s)", NULL, },
36.118 - { OPTION_BOOL, "nosignature", 0, NULL, "don't verify package signature(s)", NULL },
36.119 - { }
36.120 -};
36.121 -
36.122 -static const struct option database_options[] = {
36.123 - { OPTION_BOOL, "initdb", 0, NULL, "initialize database", NULL },
36.124 - { OPTION_BOOL, "rebuilddb", 0, NULL, "rebuild database inverted lists from installed package headers", NULL },
36.125 - { }
36.126 -};
36.127 -
36.128 -static int option_erase, option_install, option_upgrade;
36.129 -
36.130 -static const struct option install_options[] = {
36.131 - { OPTION_BOOL, "aid", 0, NULL, "add suggested packages to transaction", NULL, },
36.132 - { OPTION_BOOL, "allfiles", 0, NULL, "install all files, even configurations which might otherwise be skipped", NULL, },
36.133 - { OPTION_BOOL, "allmatches", 0, NULL, "remove all packages which match <package> (normally an error is generated if <package> specified multiple packages)", NULL, },
36.134 - { OPTION_BOOL, "badreloc", 0, NULL, "relocate files in non-relocatable package", NULL },
36.135 - { OPTION_BOOL, "erase", 'e', "<package>", "erase (uninstall) package", &option_erase },
36.136 - { OPTION_BOOL, "excludedocs", 0, NULL, "do not install documentation", NULL, },
36.137 - { OPTION_BOOL, "excludepath", 0, "<path>", "skip files with leading component <path> ", NULL, },
36.138 - { OPTION_BOOL, "fileconflicts", 0, NULL, "detect file conflicts between packages", NULL, },
36.139 - { OPTION_BOOL, "force", 0, NULL, "short hand for --replacepkgs --replacefiles", NULL },
36.140 - { OPTION_BOOL, "freshen", 'F', "<packagefile>+", "upgrade package(s) if already installed", NULL },
36.141 - { OPTION_BOOL, "hash", 'h', NULL, "print hash marks as package installs (good with -v)", NULL },
36.142 - { OPTION_BOOL, "ignorearch", 0, NULL, "don't verify package architecture", NULL, },
36.143 - { OPTION_BOOL, "ignoreos", 0, NULL, "don't verify package operating system", NULL, },
36.144 - { OPTION_BOOL, "ignoresize", 0, NULL, "don't check disk space before installing", NULL },
36.145 - { OPTION_BOOL, "install", 'i', NULL, "install package(s)", &option_install },
36.146 - { OPTION_BOOL, "justdb", 0, NULL, "update the database, but do not modify the filesystem", NULL, },
36.147 - { OPTION_BOOL, "nodeps", 0, NULL, "do not verify package dependencies", NULL, },
36.148 - { OPTION_BOOL, "nomd5", 0, NULL, "don't verify MD5 digest of files", NULL, },
36.149 - { OPTION_BOOL, "nocontexts", 0, NULL, "don't install file security contexts", NULL, },
36.150 - { OPTION_BOOL, "noorder", 0, NULL, "do not reorder package installation to satisfy dependencies", NULL, },
36.151 - { OPTION_BOOL, "nosuggest", 0, NULL, "do not suggest missing dependency resolution(s)", NULL, },
36.152 - { OPTION_BOOL, "noscripts", 0, NULL, "do not execute package scriptlet(s)", NULL, },
36.153 - { OPTION_BOOL, "notriggers", 0, NULL, "do not execute any scriptlet(s) triggered by this package", NULL, },
36.154 - { OPTION_BOOL, "oldpackage", 0, NULL, "upgrade to an old version of the package (--force on upgrades does this automatically)", NULL },
36.155 - { OPTION_BOOL, "percent", 0, NULL, "print percentages as package installs", NULL, },
36.156 - { OPTION_STRING, "prefix", 0, "<dir>", "relocate the package to <dir>, if relocatable", NULL, },
36.157 - { OPTION_STRING, "relocate", 0, "<old>=<new>", "relocate files from path <old> to <new>", NULL, },
36.158 - { OPTION_BOOL, "repackage", 0, NULL, "save erased package files by repackaging", NULL, },
36.159 - { OPTION_BOOL, "replacefiles", 0, NULL, "ignore file conflicts between packages", NULL, },
36.160 - { OPTION_BOOL, "replacepkgs", 0, NULL, "reinstall if the package is already present", NULL, },
36.161 - { OPTION_BOOL, "test", 0, NULL, "don't install, but tell if it would work or not", NULL },
36.162 - { OPTION_BOOL, "upgrade", 'U', "<packagefile>+", "upgrade package(s)", &option_upgrade },
36.163 - { }
36.164 -};
36.165 -
36.166 -static int option_version;
36.167 -
36.168 -static const struct option common_options[] = {
36.169 - { OPTION_STRING, "define", 'D', "MACRO EXPR", "define MACRO with value EXPR", NULL, },
36.170 - { OPTION_STRING, "eval", 'E', "EXPR", "print macro expansion of EXPR", NULL },
36.171 - { OPTION_STRING, "macros", 0, "<FILE:...>", "read <FILE:...> instead of default file(s)", NULL },
36.172 - { OPTION_BOOL, "nodigest", 0, NULL, "don't verify package digest(s)", NULL, },
36.173 - { OPTION_BOOL, "nosignature", 0, NULL, "don't verify package signature(s)", NULL, },
36.174 - { OPTION_STRING, "rcfile", 0, "<FILE:...>", "read <FILE:...> instead of default file(s)", NULL },
36.175 - { OPTION_STRING, "root", 'r', "ROOT", "use ROOT as top level directory (default: \"/\")", NULL },
36.176 - { OPTION_BOOL, "querytags", 0, NULL, "display known query tags", NULL, },
36.177 - { OPTION_BOOL, "showrc", 0, NULL, "display final rpmrc and macro configuration", NULL, },
36.178 - { OPTION_BOOL, "quiet", 0, NULL, "provide less detailed output", NULL },
36.179 - { OPTION_BOOL, "verbose", 'v', NULL, "provide more detailed output", NULL },
36.180 - { OPTION_BOOL, "version", 0, NULL, "print the version of rpm being used", &option_version },
36.181 - { }
36.182 -};
36.183 -
36.184 -static int option_conflicts, option_obsoletes, option_requires;
36.185 -static int option_provides, option_info, option_changelog;
36.186 -
36.187 -static const struct option alias_options[] = {
36.188 - { OPTION_BOOL, "scripts", 0, NULL, "list install/erase scriptlets from package(s)", NULL, },
36.189 - { OPTION_BOOL, "setperms", 0, NULL, "set permissions of files in a package", NULL, },
36.190 - { OPTION_BOOL, "setugids", 0, NULL, "set user/group ownership of files in a package", NULL, },
36.191 - { OPTION_BOOL, "conflicts", 0, NULL, "list capabilities this package conflicts with", &option_conflicts, },
36.192 - { OPTION_BOOL, "obsoletes", 0, NULL, "list other packages removed by installing this package", &option_obsoletes, },
36.193 - { OPTION_BOOL, "provides", 0, NULL, "list capabilities that this package provides", &option_provides, },
36.194 - { OPTION_BOOL, "requires", 0, NULL, "list capabilities required by package(s)", &option_requires, },
36.195 - { OPTION_BOOL, "info", 'i', NULL, "list descriptive information from package(s)", &option_info, },
36.196 - { OPTION_BOOL, "changelog", 0, NULL, "list change logs for this package", &option_changelog, },
36.197 - { OPTION_BOOL, "xml", 0, NULL, "list metadata in xml", NULL, },
36.198 - { OPTION_BOOL, "triggers", 0, NULL, "list trigger scriptlets from package(s)", NULL, },
36.199 - { OPTION_BOOL, "last", 0, NULL, "list package(s) by install time, most recent first", NULL, },
36.200 - { OPTION_BOOL, "dupes", 0, NULL, "list duplicated packages", NULL, },
36.201 - { OPTION_BOOL, "filesbypkg", 0, NULL, "list all files from each package", NULL, },
36.202 - { OPTION_BOOL, "fileclass", 0, NULL, "list file names with classes", NULL, },
36.203 - { OPTION_BOOL, "filecolor", 0, NULL, "list file names with colors", NULL, },
36.204 - { OPTION_BOOL, "filecontext", 0, NULL, "list file names with security context from header", NULL, },
36.205 - { OPTION_BOOL, "fscontext", 0, NULL, "list file names with security context from file system", NULL, },
36.206 - { OPTION_BOOL, "recontext", 0, NULL, "list file names with security context from policy RE", NULL, },
36.207 - { OPTION_BOOL, "fileprovide", 0, NULL, "list file names with provides", NULL, },
36.208 - { OPTION_BOOL, "filerequire", 0, NULL, "list file names with requires", NULL, },
36.209 - { OPTION_BOOL, "redhatprovides", 0, NULL, "find package name that contains a provided capability (needs rpmdb-redhat package installed)", NULL, },
36.210 - { OPTION_BOOL, "redhatrequires", 0, NULL, "find package name that contains a required capability (needs rpmdb-redhat package installed)", NULL, },
36.211 - { OPTION_STRING, "buildpolicy", 0, "<policy>", "set buildroot <policy> (e.g. compress man pages)", NULL, },
36.212 - { OPTION_BOOL, "with", 0, "<option>", "enable configure <option> for build", NULL, },
36.213 - { OPTION_BOOL, "without", 0, "<option>", "disable configure <option> for build", NULL },
36.214 - { }
36.215 -};
36.216 -
36.217 -static int option_help, option_usage;
36.218 -
36.219 -static const struct option help_options[] = {
36.220 - { OPTION_BOOL, "help", '?', NULL, "Show this help message", &option_help },
36.221 - { OPTION_BOOL, "usage", 0, NULL, "Display brief usage message", &option_usage},
36.222 - { }
36.223 -};
36.224 -
36.225 -static int option_query, option_verify;
36.226 -
36.227 -static const struct option rpm_options[] = {
36.228 - { OPTION_BOOL, "query", 'q', NULL, "Query rpm database", &option_query },
36.229 - { OPTION_BOOL, "verify", 'V', NULL, "Verify rpm database", &option_verify },
36.230 - { OPTION_GROUP, NULL, 0, NULL, "Query options (with -q or --query):", &query_options },
36.231 - { OPTION_GROUP, NULL, 0, NULL, "Verify options (with -V or --verify):", &verify_options },
36.232 - { OPTION_GROUP, NULL, 0, NULL, "File tree walk options (with --ftswalk):", &ftw_options },
36.233 - { OPTION_GROUP, NULL, 0, NULL, "Signature options:", &signature_options },
36.234 - { OPTION_GROUP, NULL, 0, NULL, "Database options:", &database_options },
36.235 - { OPTION_GROUP, NULL, 0, NULL, "Install/Upgrade/Erase options:", &install_options },
36.236 - { OPTION_GROUP, NULL, 0, NULL, "Common options for all rpm modes and executables:", &common_options },
36.237 - { OPTION_GROUP, NULL, 0, NULL, "Options implemented via popt alias/exec:", &alias_options },
36.238 - { OPTION_GROUP, NULL, 0, NULL, "Help options", &help_options },
36.239 - { }
36.240 -};
36.241 -
36.242 -static const char system_repo_filename[] = "system.repo";
36.243 -static const char *repo_filename = system_repo_filename;
36.244 -
36.245 -static struct razor_property *
36.246 -add_property_packages(struct razor_set *set,
36.247 - struct razor_package_query *query,
36.248 - const char *ref_name,
36.249 - const char *ref_version,
36.250 - enum razor_property_type ref_type)
36.251 -{
36.252 - struct razor_property *property;
36.253 - struct razor_property_iterator *pi;
36.254 - struct razor_package_iterator *pkgi;
36.255 - const char *name, *version;
36.256 - enum razor_property_type type;
36.257 - enum razor_version_relation relation;
36.258 -
36.259 - pi = razor_property_iterator_create(set, NULL);
36.260 - while (razor_property_iterator_next(pi, &property, &name,
36.261 - &relation, &version, &type)) {
36.262 - if (strcmp(ref_name, name) != 0)
36.263 - continue;
36.264 - if (ref_version && relation == RAZOR_VERSION_EQUAL &&
36.265 - strcmp(ref_version, version) != 0)
36.266 - continue;
36.267 - if (ref_type != type)
36.268 - continue;
36.269 -
36.270 - pkgi = razor_package_iterator_create_for_property(set,
36.271 - property);
36.272 - razor_package_query_add_iterator(query, pkgi);
36.273 - razor_package_iterator_destroy(pkgi);
36.274 - }
36.275 - razor_property_iterator_destroy(pi);
36.276 -
36.277 - return property;
36.278 -}
36.279 -
36.280 -static int
36.281 -strcmpp(const void *p1, const void *p2)
36.282 -{
36.283 - return strcmp(*(char * const *) p1, *(char * const *) p2);
36.284 -}
36.285 -
36.286 -static void
36.287 -add_command_line_packages(struct razor_set *set,
36.288 - struct razor_package_query *query,
36.289 - int argc, const char **argv)
36.290 -{
36.291 - struct razor_package *package;
36.292 - struct razor_package_iterator *pi;
36.293 - const char *name, *version, *arch;
36.294 - int i, cmp;
36.295 -
36.296 - qsort(argv, argc, sizeof(*argv), strcmpp);
36.297 - i = 0;
36.298 -
36.299 - pi = razor_package_iterator_create(set);
36.300 -
36.301 - while (razor_package_iterator_next(pi, &package,
36.302 - &name, &version, &arch)) {
36.303 - while (cmp = strcmp(argv[i], name), cmp < 0 && i < argc) {
36.304 - printf("package %s is not installed\n", argv[i]);
36.305 - i++;
36.306 - }
36.307 -
36.308 - if (cmp == 0) {
36.309 - razor_package_query_add_package(query, package);
36.310 - i++;
36.311 - }
36.312 - }
36.313 -
36.314 - razor_package_iterator_destroy(pi);
36.315 -}
36.316 -
36.317 -static struct razor_package_iterator *
36.318 -get_query_packages(struct razor_set *set, int argc, const char *argv[])
36.319 -{
36.320 - struct razor_package_query *query;
36.321 - struct razor_package_iterator *pi;
36.322 - int i;
36.323 -
36.324 - if (option_all + option_whatprovides + option_whatrequires > 1) {
36.325 - printf("only one type of query/verify "
36.326 - "may be performed at a time\n");
36.327 - exit(1);
36.328 - }
36.329 -
36.330 - query = razor_package_query_create(set);
36.331 -
36.332 - if (option_all) {
36.333 - pi = razor_package_iterator_create(set);
36.334 - razor_package_query_add_iterator(query, pi);
36.335 - razor_package_iterator_destroy(pi);
36.336 - } else if (option_whatrequires) {
36.337 - for (i = 0; i < argc; i++)
36.338 - add_property_packages(set, query,
36.339 - argv[i], NULL,
36.340 - RAZOR_PROPERTY_REQUIRES);
36.341 - } else if (option_whatprovides) {
36.342 - for (i = 0; i < argc; i++)
36.343 - add_property_packages(set, query,
36.344 - argv[i], NULL,
36.345 - RAZOR_PROPERTY_PROVIDES);
36.346 - } else if (argc > 0) {
36.347 - add_command_line_packages(set, query, argc, argv);
36.348 - } else {
36.349 - printf("no arguments given for query/verify\n");
36.350 - exit(1);
36.351 - }
36.352 -
36.353 - return razor_package_query_finish(query);
36.354 -}
36.355 -
36.356 -static void
36.357 -print_package_properties(struct razor_set *set,
36.358 - struct razor_package *package,
36.359 - enum razor_property_type ref_type)
36.360 -{
36.361 - struct razor_property *property;
36.362 - struct razor_property_iterator *pi;
36.363 - const char *name, *version;
36.364 - enum razor_property_type type;
36.365 - enum razor_version_relation relation;
36.366 -
36.367 - pi = razor_property_iterator_create(set, package);
36.368 - while (razor_property_iterator_next(pi, &property,
36.369 - &name, &relation, &version,
36.370 - &type)) {
36.371 - if (type != ref_type)
36.372 - continue;
36.373 - if (version[0] == '\0')
36.374 - printf("%s\n", name);
36.375 - else
36.376 - printf("%s %s %s\n", name,
36.377 - razor_version_relations[relation], version);
36.378 - }
36.379 - razor_property_iterator_destroy(pi);
36.380 -}
36.381 -
36.382 -static void
36.383 -print_package_info(struct razor_set *set, struct razor_package *package)
36.384 -{
36.385 - printf("FIXME: Package info not tracked.\n");
36.386 -}
36.387 -
36.388 -static void
36.389 -print_package_changelog(struct razor_set *set, struct razor_package *package)
36.390 -{
36.391 - printf("FIXME: Package changelog not tracked.\n");
36.392 -}
36.393 -
36.394 -static struct razor_set *
36.395 -create_set_from_command_line(int argc, const char *argv[])
36.396 -{
36.397 - struct razor_importer *importer;
36.398 - struct razor_rpm *rpm;
36.399 - int i;
36.400 -
36.401 - importer = razor_importer_new();
36.402 -
36.403 - for (i = 0; i < argc; i++) {
36.404 - rpm = razor_rpm_open(argv[i]);
36.405 - if (rpm == NULL)
36.406 - continue;
36.407 - if (razor_importer_add_rpm(importer, rpm))
36.408 - printf("couldn't import %s\n", argv[i]);
36.409 -
36.410 - razor_rpm_close(rpm);
36.411 - }
36.412 -
36.413 - return razor_importer_finish(importer);
36.414 -}
36.415 -
36.416 -static void
36.417 -command_query(int argc, const char *argv[])
36.418 -{
36.419 - struct razor_set *set;
36.420 - struct razor_package_iterator *pi;
36.421 - struct razor_package *package;
36.422 - const char *name, *version, *arch;
36.423 -
36.424 - if (option_package) {
36.425 - set = create_set_from_command_line(argc, argv);
36.426 - argc = 0;
36.427 - option_all = 1;
36.428 - } else {
36.429 - set = razor_set_open(repo_filename);
36.430 - }
36.431 -
36.432 - pi = get_query_packages(set, argc, argv);
36.433 -
36.434 - while (razor_package_iterator_next(pi, &package,
36.435 - &name, &version, &arch)) {
36.436 - if (option_conflicts)
36.437 - print_package_properties(set, package,
36.438 - RAZOR_PROPERTY_CONFLICTS);
36.439 - if (option_obsoletes)
36.440 - print_package_properties(set, package,
36.441 - RAZOR_PROPERTY_OBSOLETES);
36.442 - if (option_requires)
36.443 - print_package_properties(set, package,
36.444 - RAZOR_PROPERTY_REQUIRES);
36.445 - if (option_provides)
36.446 - print_package_properties(set, package,
36.447 - RAZOR_PROPERTY_PROVIDES);
36.448 - if (option_info)
36.449 - print_package_info(set, package);
36.450 - if (option_changelog)
36.451 - print_package_changelog(set, package);
36.452 -
36.453 - if (option_conflicts + option_obsoletes +
36.454 - option_requires + option_provides +
36.455 - option_info + option_changelog == 0)
36.456 - printf("%s-%s.%s\n", name, version, arch);
36.457 - }
36.458 -
36.459 - razor_package_iterator_destroy(pi);
36.460 -
36.461 - razor_set_destroy(set);
36.462 -
36.463 - return;
36.464 -}
36.465 -
36.466 -static void
36.467 -command_verify(int argc, const char *argv[])
36.468 -{
36.469 - struct razor_set *set;
36.470 - struct razor_package_iterator *pi;
36.471 - struct razor_package *package;
36.472 - const char *name, *version, *arch;
36.473 -
36.474 - if (option_package) {
36.475 - set = create_set_from_command_line(argc, argv);
36.476 - argc = 0;
36.477 - option_all = 1;
36.478 - } else {
36.479 - set = razor_set_open(repo_filename);
36.480 - }
36.481 -
36.482 - pi = get_query_packages(set, argc, argv);
36.483 -
36.484 - while (razor_package_iterator_next(pi, &package,
36.485 - &name, &version, &arch)) {
36.486 - printf("verify %s-%s.%s - not implemented\n",
36.487 - name, version, arch);
36.488 - }
36.489 -
36.490 - razor_package_iterator_destroy(pi);
36.491 -}
36.492 -
36.493 -static void
36.494 -command_erase(int argc, const char *argv[])
36.495 -{
36.496 - struct razor_set *set, *next;
36.497 - struct razor_transaction *trans;
36.498 - struct razor_package_query *query;
36.499 - struct razor_package_iterator *pi;
36.500 - struct razor_package *package;
36.501 - const char *name, *version, *arch;
36.502 -
36.503 - if (argc == 0) {
36.504 - printf("no packages given for erase\n");
36.505 - exit(1);
36.506 - }
36.507 -
36.508 - set = razor_set_open(repo_filename);
36.509 -
36.510 - trans = razor_transaction_create(set, NULL);
36.511 -
36.512 - query = razor_package_query_create(set);
36.513 - add_command_line_packages(set, query, argc, argv);
36.514 -
36.515 - pi = razor_package_query_finish(query);
36.516 - while (razor_package_iterator_next(pi, &package,
36.517 - &name, &version, &arch))
36.518 - razor_transaction_remove_package(trans, package);
36.519 - razor_package_iterator_destroy(pi);
36.520 -
36.521 - next = razor_transaction_finish(trans);
36.522 - razor_set_destroy(set);
36.523 -
36.524 - razor_set_list_unsatisfied(next);
36.525 - razor_set_destroy(next);
36.526 -}
36.527 -
36.528 -static void
36.529 -command_install(int argc, const char *argv[])
36.530 -{
36.531 - struct razor_set *set, *upstream, *next;
36.532 - struct razor_transaction *trans;
36.533 - struct razor_package_iterator *pi;
36.534 - struct razor_package *package;
36.535 - const char *name, *version, *arch;
36.536 -
36.537 - if (argc == 0) {
36.538 - printf("no packages given for install\n");
36.539 - exit(1);
36.540 - }
36.541 -
36.542 - set = razor_set_open(repo_filename);
36.543 - upstream = create_set_from_command_line(argc, argv);
36.544 -
36.545 - trans = razor_transaction_create(set, upstream);
36.546 -
36.547 - pi = razor_package_iterator_create(upstream);
36.548 - while (razor_package_iterator_next(pi, &package,
36.549 - &name, &version, &arch))
36.550 - razor_transaction_install_package(trans, package);
36.551 - razor_package_iterator_destroy(pi);
36.552 -
36.553 - next = razor_transaction_finish(trans);
36.554 - razor_set_destroy(set);
36.555 - razor_set_destroy(upstream);
36.556 -
36.557 - razor_set_list_unsatisfied(next);
36.558 -
36.559 - razor_set_destroy(next);
36.560 -}
36.561 -
36.562 -static void
36.563 -command_update(int argc, const char *argv[])
36.564 -{
36.565 - if (argc == 0) {
36.566 - printf("no packages given for update\n");
36.567 - exit(1);
36.568 - }
36.569 -
36.570 - printf("command update - not implemented\n");
36.571 -}
36.572 -
36.573 -static int
36.574 -for_each_option(const struct option *options,
36.575 - const char *name, char short_name,
36.576 - void (*fn)(const struct option *o,
36.577 - const char *name, char short_name,
36.578 - void *data), void *data)
36.579 -{
36.580 - int i, count = 0;
36.581 -
36.582 - for (i = 0; options[i].type != OPTION_LAST; i++) {
36.583 - switch (options[i].type) {
36.584 - case OPTION_GROUP:
36.585 - count += for_each_option(options[i].data,
36.586 - name, short_name, fn, data);
36.587 - break;
36.588 -
36.589 - case OPTION_BOOL:
36.590 - case OPTION_STRING:
36.591 - if (name && strcmp(options[i].name, name) == 0) {
36.592 - fn(&options[i], name, 0, data);
36.593 - count++;
36.594 - break;
36.595 - }
36.596 -
36.597 - if (short_name &&
36.598 - short_name == options[i].short_name) {
36.599 - fn(&options[i], NULL, short_name, data);
36.600 - count++;
36.601 - break;
36.602 - }
36.603 - break;
36.604 -
36.605 - case OPTION_LAST:
36.606 - break;
36.607 - }
36.608 - }
36.609 -
36.610 - return count;
36.611 -}
36.612 -
36.613 -static void
36.614 -handle_option(const struct option *o,
36.615 - const char *name, char short_name, void *data)
36.616 -{
36.617 - if (o->data == NULL) {
36.618 - if (name)
36.619 - printf("option --%s not supported\n", name);
36.620 - else
36.621 - printf("option -%c not supported\n", short_name);
36.622 - return;
36.623 - }
36.624 -
36.625 - switch (o->type) {
36.626 - case OPTION_BOOL:
36.627 - *(int *) o->data = 1;
36.628 - break;
36.629 -
36.630 - case OPTION_STRING:
36.631 - *(const char **) o->data = name + strlen(o->name) + 1;
36.632 - break;
36.633 -
36.634 - case OPTION_LAST:
36.635 - case OPTION_GROUP:
36.636 - /* Shouldn't happen. */
36.637 - break;
36.638 - }
36.639 -}
36.640 -
36.641 -static int
36.642 -parse_options(const struct option *options, int argc, const char **argv)
36.643 -{
36.644 - int i, j, k;
36.645 -
36.646 - for (i = 1, j = 0; i < argc; i++) {
36.647 - if (argv[i][0] != '-') {
36.648 - argv[j++] = argv[i];
36.649 - continue;
36.650 - }
36.651 -
36.652 - if (argv[i][1] == '-') {
36.653 - if (for_each_option(options, &argv[i][2], 0,
36.654 - handle_option, NULL) == 0) {
36.655 - printf("unknown option: %s\n", argv[i]);
36.656 - exit(1);
36.657 - }
36.658 - continue;
36.659 - }
36.660 -
36.661 - for (k = 1; argv[i][k]; k++) {
36.662 - if (for_each_option(options, NULL, argv[i][k],
36.663 - handle_option, NULL) == 0) {
36.664 - printf("unknown option: -%c\n", argv[i][k]);
36.665 - exit(1);
36.666 - }
36.667 - }
36.668 - }
36.669 -
36.670 - return j;
36.671 -}
36.672 -
36.673 -static void
36.674 -print_options_help(const struct option *options)
36.675 -{
36.676 - int i;
36.677 -
36.678 - for (i = 0; options[i].type != OPTION_LAST; i++) {
36.679 - switch (options[i].type) {
36.680 - case OPTION_GROUP:
36.681 - printf("%s\n", options[i].description);
36.682 - print_options_help(options[i].data);
36.683 - printf("\n");
36.684 - break;
36.685 -
36.686 - case OPTION_BOOL:
36.687 - case OPTION_STRING:
36.688 - printf(" ");
36.689 - if (options[i].short_name)
36.690 - printf("-%c", options[i].short_name);
36.691 - if (options[i].short_name && options[i].name)
36.692 - printf(", ");
36.693 - if (options[i].name)
36.694 - printf("--%s", options[i].name);
36.695 - if (options[i].arg_name)
36.696 - printf("=%s", options[i].arg_name);
36.697 - if (options[i].description)
36.698 - printf("\t\t%s", options[i].description);
36.699 - printf("\n");
36.700 - break;
36.701 -
36.702 - case OPTION_LAST:
36.703 - break;
36.704 - }
36.705 - }
36.706 -}
36.707 -
36.708 -static void
36.709 -print_options_usage(const struct option *options)
36.710 -{
36.711 - int i;
36.712 -
36.713 - for (i = 0; options[i].type != OPTION_LAST; i++) {
36.714 - switch (options[i].type) {
36.715 - case OPTION_GROUP:
36.716 - print_options_usage(options[i].data);
36.717 - break;
36.718 -
36.719 - case OPTION_BOOL:
36.720 - printf("[");
36.721 - if (options[i].short_name)
36.722 - printf("-%c", options[i].short_name);
36.723 - if (options[i].short_name && options[i].name)
36.724 - printf("|");
36.725 - if (options[i].name)
36.726 - printf("--%s", options[i].name);
36.727 - printf("] ");
36.728 - break;
36.729 -
36.730 - case OPTION_STRING:
36.731 - printf("[");
36.732 - if (options[i].short_name)
36.733 - printf("-%c", options[i].short_name);
36.734 - if (options[i].short_name && options[i].name)
36.735 - printf("|");
36.736 - if (options[i].name)
36.737 - printf("--%s", options[i].name);
36.738 - if (options[i].arg_name)
36.739 - printf("=%s", options[i].arg_name);
36.740 - printf("] ");
36.741 - break;
36.742 -
36.743 -
36.744 - break;
36.745 -
36.746 - case OPTION_LAST:
36.747 - break;
36.748 - }
36.749 - }
36.750 -}
36.751 -
36.752 -int
36.753 -main(int argc, const char *argv[])
36.754 -{
36.755 - argc = parse_options(rpm_options, argc, argv);
36.756 -
36.757 - if (option_version) {
36.758 - printf("razor rpm version hoopla.\n");
36.759 - exit(0);
36.760 - }
36.761 -
36.762 - if (option_help) {
36.763 - printf("Usage: rpm [OPTION...]\n");
36.764 - print_options_help(rpm_options);
36.765 - exit(0);
36.766 - }
36.767 -
36.768 - if (option_usage) {
36.769 - printf("Usage: rpm [OPTION...]\n");
36.770 - print_options_usage(rpm_options);
36.771 - printf("\n");
36.772 - exit(0);
36.773 - }
36.774 -
36.775 - if (option_verify) {
36.776 - command_verify(argc, argv);
36.777 - } else if (option_query) {
36.778 - command_query(argc, argv);
36.779 - } else if (option_install) {
36.780 - command_install(argc, argv);
36.781 - } else if (option_upgrade) {
36.782 - command_update(argc, argv);
36.783 - } else if (option_erase) {
36.784 - command_erase(argc, argv);
36.785 - } else {
36.786 - print_options_usage(rpm_options);
36.787 - printf("\n");
36.788 - exit(0);
36.789 - }
36.790 -
36.791 - return 0;
36.792 -}
37.1 --- a/rpm.c Sun Jun 15 18:16:20 2008 -0400
37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
37.3 @@ -1,757 +0,0 @@
37.4 -/*
37.5 - * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
37.6 - * Copyright (C) 2008 Red Hat, Inc
37.7 - *
37.8 - * This program is free software; you can redistribute it and/or modify
37.9 - * it under the terms of the GNU General Public License as published by
37.10 - * the Free Software Foundation; either version 2 of the License, or
37.11 - * (at your option) any later version.
37.12 - *
37.13 - * This program is distributed in the hope that it will be useful,
37.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
37.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37.16 - * GNU General Public License for more details.
37.17 - *
37.18 - * You should have received a copy of the GNU General Public License along
37.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
37.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
37.21 - */
37.22 -
37.23 -#include <stdio.h>
37.24 -#include <stddef.h>
37.25 -#include <string.h>
37.26 -#include <errno.h>
37.27 -#include <sys/stat.h>
37.28 -#include <sys/mman.h>
37.29 -#include <sys/types.h>
37.30 -#include <sys/wait.h>
37.31 -#include <fcntl.h>
37.32 -#include <unistd.h>
37.33 -#include <arpa/inet.h>
37.34 -#include <rpm/rpmlib.h>
37.35 -#include <rpm/rpmdb.h>
37.36 -#include <zlib.h>
37.37 -
37.38 -#include "razor.h"
37.39 -#include "razor-internal.h"
37.40 -
37.41 -#define RPM_LEAD_SIZE 96
37.42 -
37.43 -struct rpm_header {
37.44 - unsigned char magic[4];
37.45 - unsigned char reserved[4];
37.46 - int nindex;
37.47 - int hsize;
37.48 -};
37.49 -
37.50 -struct rpm_header_index {
37.51 - int tag;
37.52 - int type;
37.53 - int offset;
37.54 - int count;
37.55 -};
37.56 -
37.57 -struct razor_rpm {
37.58 - struct rpm_header *signature;
37.59 - struct rpm_header *header;
37.60 - const char **dirs;
37.61 - const char *pool;
37.62 - void *map;
37.63 - size_t size;
37.64 - void *payload;
37.65 -};
37.66 -
37.67 -static struct rpm_header_index *
37.68 -razor_rpm_get_header(struct razor_rpm *rpm, unsigned int tag)
37.69 -{
37.70 - struct rpm_header_index *index, *end;
37.71 -
37.72 - index = (struct rpm_header_index *) (rpm->header + 1);
37.73 - end = index + ntohl(rpm->header->nindex);
37.74 - while (index < end) {
37.75 - if (ntohl(index->tag) == tag)
37.76 - return index;
37.77 - index++;
37.78 - }
37.79 -
37.80 - return NULL;
37.81 -}
37.82 -
37.83 -static const void *
37.84 -razor_rpm_get_indirect(struct razor_rpm *rpm,
37.85 - unsigned int tag, unsigned int *count)
37.86 -{
37.87 - struct rpm_header_index *index;
37.88 -
37.89 - index = razor_rpm_get_header(rpm, tag);
37.90 - if (index != NULL) {
37.91 - if (count)
37.92 - *count = ntohl(index->count);
37.93 -
37.94 - return rpm->pool + ntohl(index->offset);
37.95 - }
37.96 -
37.97 - return NULL;
37.98 -}
37.99 -
37.100 -static enum razor_version_relation
37.101 -rpm_to_razor_flags (uint_32 flags)
37.102 -{
37.103 - switch (flags & (RPMSENSE_LESS | RPMSENSE_EQUAL | RPMSENSE_GREATER)) {
37.104 - case RPMSENSE_LESS:
37.105 - return RAZOR_VERSION_LESS;
37.106 - case RPMSENSE_LESS|RPMSENSE_EQUAL:
37.107 - return RAZOR_VERSION_LESS_OR_EQUAL;
37.108 - case RPMSENSE_EQUAL:
37.109 - return RAZOR_VERSION_EQUAL;
37.110 - case RPMSENSE_GREATER|RPMSENSE_EQUAL:
37.111 - return RAZOR_VERSION_GREATER_OR_EQUAL;
37.112 - case RPMSENSE_GREATER:
37.113 - return RAZOR_VERSION_GREATER;
37.114 - }
37.115 -
37.116 - /* FIXME? */
37.117 - return RAZOR_VERSION_EQUAL;
37.118 -}
37.119 -
37.120 -static void
37.121 -import_properties(struct razor_importer *importer, unsigned long type,
37.122 - struct razor_rpm *rpm,
37.123 - int name_tag, int version_tag, int flags_tag)
37.124 -{
37.125 - const char *name, *version;
37.126 - const uint_32 *flags;
37.127 - uint_32 f;
37.128 - unsigned int i, count;
37.129 -
37.130 - name = razor_rpm_get_indirect(rpm, name_tag, &count);
37.131 - if (name == NULL)
37.132 - return;
37.133 -
37.134 - flags = razor_rpm_get_indirect(rpm, flags_tag, &count);
37.135 -
37.136 - version = razor_rpm_get_indirect(rpm, version_tag, &count);
37.137 - for (i = 0; i < count; i++) {
37.138 - f = rpm_to_razor_flags(ntohl(flags[i]));
37.139 - razor_importer_add_property(importer, name, f, version, type);
37.140 - name += strlen(name) + 1;
37.141 - version += strlen(version) + 1;
37.142 - }
37.143 -}
37.144 -
37.145 -static void
37.146 -import_files(struct razor_importer *importer, struct razor_rpm *rpm)
37.147 -{
37.148 - const char *name;
37.149 - const uint32_t *index;
37.150 - unsigned int i, count;
37.151 - char buffer[256];
37.152 -
37.153 - /* assert: count is the same for all arrays */
37.154 -
37.155 - index = razor_rpm_get_indirect(rpm, RPMTAG_DIRINDEXES, &count);
37.156 - name = razor_rpm_get_indirect(rpm, RPMTAG_BASENAMES, &count);
37.157 - for (i = 0; i < count; i++) {
37.158 - snprintf(buffer, sizeof buffer,
37.159 - "%s%s", rpm->dirs[ntohl(*index)], name);
37.160 - razor_importer_add_file(importer, buffer);
37.161 - name += strlen(name) + 1;
37.162 - index++;
37.163 - }
37.164 -}
37.165 -
37.166 -struct razor_rpm *
37.167 -razor_rpm_open(const char *filename)
37.168 -{
37.169 - struct razor_rpm *rpm;
37.170 - struct rpm_header_index *base, *index;
37.171 - struct stat buf;
37.172 - unsigned int count, i, nindex, hsize;
37.173 - const char *name;
37.174 - int fd;
37.175 -
37.176 - rpm = malloc(sizeof *rpm);
37.177 - memset(rpm, 0, sizeof *rpm);
37.178 -
37.179 - fd = open(filename, O_RDONLY);
37.180 - if (fd < 0) {
37.181 - fprintf(stderr, "couldn't open %s\n", filename);
37.182 - return NULL;
37.183 - }
37.184 -
37.185 - if (fstat(fd, &buf) < 0) {
37.186 - fprintf(stderr, "failed to stat %s (%m)\n", filename);
37.187 - return NULL;
37.188 - }
37.189 -
37.190 - rpm->size = buf.st_size;
37.191 - rpm->map = mmap(NULL, rpm->size, PROT_READ, MAP_PRIVATE, fd, 0);
37.192 - if (rpm->map == MAP_FAILED) {
37.193 - fprintf(stderr, "couldn't mmap %s\n", filename);
37.194 - return NULL;
37.195 - }
37.196 - close(fd);
37.197 -
37.198 - rpm->signature = rpm->map + RPM_LEAD_SIZE;
37.199 - nindex = ntohl(rpm->signature->nindex);
37.200 - hsize = ntohl(rpm->signature->hsize);
37.201 - rpm->header = (void *) (rpm->signature + 1) +
37.202 - ALIGN(nindex * sizeof *index + hsize, 8);
37.203 - nindex = ntohl(rpm->header->nindex);
37.204 - hsize = ntohl(rpm->header->hsize);
37.205 - rpm->payload = (void *) (rpm->header + 1) +
37.206 - nindex * sizeof *index + hsize;
37.207 -
37.208 - base = (struct rpm_header_index *) (rpm->header + 1);
37.209 - rpm->pool = (void *) base + nindex * sizeof *index;
37.210 -
37.211 - /* Look up dir names now so we can index them directly. */
37.212 - name = razor_rpm_get_indirect(rpm, RPMTAG_DIRNAMES, &count);
37.213 - if (name) {
37.214 - rpm->dirs = calloc(count, sizeof *rpm->dirs);
37.215 - for (i = 0; i < count; i++) {
37.216 - rpm->dirs[i] = name;
37.217 - name += strlen(name) + 1;
37.218 - }
37.219 - } else {
37.220 - name = razor_rpm_get_indirect(rpm, RPMTAG_OLDFILENAMES,
37.221 - &count);
37.222 - if (name) {
37.223 - fprintf(stderr, "old filenames not supported\n");
37.224 - return NULL;
37.225 - }
37.226 - }
37.227 -
37.228 - return rpm;
37.229 -}
37.230 -
37.231 -struct cpio_file_header {
37.232 - char magic[6];
37.233 - char inode[8];
37.234 - char mode[8];
37.235 - char uid[8];
37.236 - char gid[8];
37.237 - char nlink[8];
37.238 - char mtime[8];
37.239 - char filesize[8];
37.240 - char devmajor[8];
37.241 - char devminor[8];
37.242 - char rdevmajor[8];
37.243 - char rdevminor[8];
37.244 - char namesize[8];
37.245 - char checksum[8];
37.246 - char filename[0];
37.247 -};
37.248 -
37.249 -/* gzip flags */
37.250 -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
37.251 -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
37.252 -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
37.253 -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
37.254 -#define COMMENT 0x10 /* bit 4 set: file comment present */
37.255 -#define RESERVED 0xE0 /* bits 5..7: reserved */
37.256 -
37.257 -struct installer {
37.258 - const char *root;
37.259 - struct razor_rpm *rpm;
37.260 - z_stream stream;
37.261 - unsigned char buffer[32768];
37.262 - size_t rest, length;
37.263 -};
37.264 -
37.265 -static int
37.266 -installer_inflate(struct installer *installer)
37.267 -{
37.268 - size_t length;
37.269 - int err;
37.270 -
37.271 - if (installer->rest > sizeof installer->buffer)
37.272 - length = sizeof installer->buffer;
37.273 - else
37.274 - length = installer->rest;
37.275 -
37.276 - installer->stream.next_out = installer->buffer;
37.277 - installer->stream.avail_out = length;
37.278 - err = inflate(&installer->stream, Z_SYNC_FLUSH);
37.279 - if (err != Z_OK && err != Z_STREAM_END) {
37.280 - fprintf(stderr, "inflate error: %d (%m)\n", err);
37.281 - return -1;
37.282 - }
37.283 -
37.284 - installer->rest -= length;
37.285 - installer->length = length;
37.286 -
37.287 - return 0;
37.288 -}
37.289 -
37.290 -static int
37.291 -installer_align(struct installer *installer, size_t size)
37.292 -{
37.293 - unsigned char buffer[4];
37.294 - int err;
37.295 -
37.296 - installer->stream.next_out = buffer;
37.297 - installer->stream.avail_out =
37.298 - (size - installer->stream.total_out) & (size - 1);
37.299 -
37.300 - if (installer->stream.avail_out == 0)
37.301 - return 0;
37.302 -
37.303 - err = inflate(&installer->stream, Z_SYNC_FLUSH);
37.304 - if (err != Z_OK && err != Z_STREAM_END) {
37.305 - fprintf(stderr, "inflate error: %d (%m)\n", err);
37.306 - return -1;
37.307 - }
37.308 -
37.309 - return 0;
37.310 -}
37.311 -
37.312 -static int
37.313 -create_path(struct installer *installer, const char *path, unsigned int mode)
37.314 -{
37.315 - char buffer[PATH_MAX];
37.316 - struct stat buf;
37.317 - int fd, ret;
37.318 -
37.319 - if (razor_create_dir(installer->root, path) < 0)
37.320 - return -1;
37.321 -
37.322 - snprintf(buffer, sizeof buffer, "%s%s", installer->root, path);
37.323 -
37.324 - switch (mode >> 12) {
37.325 - case REG:
37.326 - /* FIXME: handle the case where a file is already there. */
37.327 - fd = open(buffer, O_WRONLY | O_CREAT | O_TRUNC, mode & 0x1ff);
37.328 - if (fd < 0){
37.329 - fprintf(stderr, "failed to create file %s\n", buffer);
37.330 - return -1;
37.331 - }
37.332 - while (installer->rest > 0) {
37.333 - if (installer_inflate(installer)) {
37.334 - fprintf(stderr, "failed to inflate\n");
37.335 - return -1;
37.336 - }
37.337 - if (razor_write(fd, installer->buffer,
37.338 - installer->length)) {
37.339 - fprintf(stderr, "failed to write payload\n");
37.340 - return -1;
37.341 - }
37.342 - }
37.343 - if (close(fd) < 0) {
37.344 - fprintf(stderr, "failed to close %s: %m\n", buffer);
37.345 - return -1;
37.346 - }
37.347 - return 0;
37.348 - case XDIR:
37.349 - ret = mkdir(buffer, mode & 0x1ff);
37.350 - if (ret == 0 || errno != EEXIST)
37.351 - return ret;
37.352 - if (stat(buffer, &buf) || !S_ISDIR(buf.st_mode)) {
37.353 - /* FIXME: also check that mode match. */
37.354 - fprintf(stderr,
37.355 - "%s exists but is not a directory\n", buffer);
37.356 - return -1;
37.357 - }
37.358 - return 0;
37.359 - case PIPE:
37.360 - case CDEV:
37.361 - case BDEV:
37.362 - case SOCK:
37.363 - printf("%s: unhandled file type %d\n", buffer, mode >> 12);
37.364 - return 0;
37.365 - case LINK:
37.366 - if (installer_inflate(installer)) {
37.367 - fprintf(stderr, "failed to inflate\n");
37.368 - return -1;
37.369 - }
37.370 - if (installer->length >= sizeof installer->buffer) {
37.371 - fprintf(stderr, "link name too long\n");
37.372 - return -1;
37.373 - }
37.374 - installer->buffer[installer->length] = '\0';
37.375 - if (symlink((const char *) installer->buffer, buffer)) {
37.376 - fprintf(stderr, "failed to create symlink, %m\n");
37.377 - return -1;
37.378 - }
37.379 - return 0;
37.380 - default:
37.381 - printf("%s: unknown file type %d\n", buffer, mode >> 12);
37.382 - return 0;
37.383 - }
37.384 -}
37.385 -
37.386 -static int
37.387 -run_script(struct installer *installer,
37.388 - unsigned int program_tag, unsigned int script_tag)
37.389 -{
37.390 - int pid, status, fd[2];
37.391 - const char *script = NULL, *program = NULL;
37.392 -
37.393 - program = razor_rpm_get_indirect(installer->rpm, program_tag, NULL);
37.394 - script = razor_rpm_get_indirect(installer->rpm, script_tag, NULL);
37.395 - if (program == NULL && script == NULL) {
37.396 - return 0;
37.397 - } else if (program == NULL) {
37.398 - program = "/bin/sh";
37.399 - }
37.400 -
37.401 - if (pipe(fd) < 0) {
37.402 - fprintf(stderr, "failed to create pipe\n");
37.403 - return -1;
37.404 - }
37.405 - pid = fork();
37.406 - if (pid < 0) {
37.407 - fprintf(stderr, "failed to fork, %m\n");
37.408 - } else if (pid == 0) {
37.409 - if (dup2(fd[0], STDIN_FILENO) < 0) {
37.410 - fprintf(stderr, "failed redirect stdin, %m\n");
37.411 - return -1;
37.412 - }
37.413 - if (close(fd[0]) < 0 || close(fd[1]) < 0) {
37.414 - fprintf(stderr, "failed to close pipe, %m\n");
37.415 - return -1;
37.416 - }
37.417 - if (chroot(installer->root) < 0) {
37.418 - fprintf(stderr, "failed to chroot to %s, %m\n",
37.419 - installer->root);
37.420 - return -1;
37.421 - }
37.422 - printf("executing program %s in chroot %s\n",
37.423 - program, installer->root);
37.424 - if (execl(program, program, NULL)) {
37.425 - fprintf(stderr, "failed to exec %s, %m\n", program);
37.426 - exit(-1);
37.427 - }
37.428 - } else {
37.429 - if (script && razor_write(fd[1], script, strlen(script)) < 0) {
37.430 - fprintf(stderr, "failed to pipe script, %m\n");
37.431 - return -1;
37.432 - }
37.433 - if (close(fd[0]) || close(fd[1])) {
37.434 - fprintf(stderr, "failed to close pipe, %m\n");
37.435 - return -1;
37.436 - }
37.437 - if (wait(&status) < 0) {
37.438 - fprintf(stderr, "wait for child failed, %m");
37.439 - return -1;
37.440 - }
37.441 - if (status)
37.442 - printf("script exited with status %d\n", status);
37.443 - }
37.444 -
37.445 - return 0;
37.446 -}
37.447 -
37.448 -static int
37.449 -installer_init(struct installer *installer)
37.450 -{
37.451 - unsigned char *gz_header;
37.452 - int method, flags, err;
37.453 -
37.454 - gz_header = installer->rpm->payload;
37.455 - if (gz_header[0] != 0x1f || gz_header[1] != 0x8b) {
37.456 - fprintf(stderr, "payload section doesn't have gz header\n");
37.457 - return -1;
37.458 - }
37.459 -
37.460 - method = gz_header[2];
37.461 - flags = gz_header[3];
37.462 -
37.463 - if (method != Z_DEFLATED || flags != 0) {
37.464 - fprintf(stderr,
37.465 - "unknown payload compression method or flags set\n");
37.466 - return -1;
37.467 - }
37.468 -
37.469 - installer->stream.zalloc = NULL;
37.470 - installer->stream.zfree = NULL;
37.471 - installer->stream.opaque = NULL;
37.472 -
37.473 - installer->stream.next_in = gz_header + 10;
37.474 - installer->stream.avail_in =
37.475 - (installer->rpm->map + installer->rpm->size) -
37.476 - (void *) installer->stream.next_in;
37.477 - installer->stream.next_out = NULL;
37.478 - installer->stream.avail_out = 0;
37.479 -
37.480 - err = inflateInit2(&installer->stream, -MAX_WBITS);
37.481 - if (err != Z_OK) {
37.482 - fprintf(stderr, "inflateInit error: %d\n", err);
37.483 - return -1;
37.484 - }
37.485 -
37.486 - return 0;
37.487 -}
37.488 -
37.489 -static int
37.490 -installer_finish(struct installer *installer)
37.491 -{
37.492 - int err;
37.493 -
37.494 - err = inflateEnd(&installer->stream);
37.495 -
37.496 - if (err != Z_OK) {
37.497 - fprintf(stderr, "inflateEnd error: %d\n", err);
37.498 - return -1;
37.499 - }
37.500 -
37.501 - return 0;
37.502 -}
37.503 -
37.504 -static unsigned long
37.505 -fixed_hex_to_ulong(const char *hex, int length)
37.506 -{
37.507 - long l;
37.508 - int i;
37.509 -
37.510 - for (i = 0, l = 0; i < length; i++) {
37.511 - if (hex[i] < 'a')
37.512 - l = l * 16 + hex[i] - '0';
37.513 - else
37.514 - l = l * 16 + hex[i] - 'a' + 10;
37.515 - }
37.516 -
37.517 - return l;
37.518 -}
37.519 -
37.520 -int
37.521 -razor_rpm_install(struct razor_rpm *rpm, const char *root)
37.522 -{
37.523 - struct installer installer;
37.524 - struct cpio_file_header *header;
37.525 - struct stat buf;
37.526 - unsigned int mode;
37.527 - char *path;
37.528 - size_t filesize;
37.529 -
37.530 - installer.rpm = rpm;
37.531 - installer.root = root;
37.532 -
37.533 - /* FIXME: Only do this before a transaction, not per rpm. */
37.534 - if (stat(root, &buf) < 0 || !S_ISDIR(buf.st_mode)) {
37.535 - fprintf(stderr,
37.536 - "root installation directory \"%s\" does not exist\n",
37.537 - root);
37.538 - return -1;
37.539 - }
37.540 -
37.541 - if (installer_init(&installer))
37.542 - return -1;
37.543 -
37.544 - run_script(&installer, RPMTAG_PREINPROG, RPMTAG_PREIN);
37.545 -
37.546 - while (installer.stream.avail_in > 0) {
37.547 - installer.rest = sizeof *header;
37.548 - if (installer_inflate(&installer))
37.549 - return -1;
37.550 -
37.551 - header = (struct cpio_file_header *) installer.buffer;
37.552 - mode = fixed_hex_to_ulong(header->mode, sizeof header->mode);
37.553 - filesize = fixed_hex_to_ulong(header->filesize,
37.554 - sizeof header->filesize);
37.555 -
37.556 - installer.rest = fixed_hex_to_ulong(header->namesize,
37.557 - sizeof header->namesize);
37.558 -
37.559 - if (installer_inflate(&installer) ||
37.560 - installer_align(&installer, 4))
37.561 - return -1;
37.562 -
37.563 - path = (char *) installer.buffer;
37.564 - /* This convention is so lame... */
37.565 - if (strcmp(path, "TRAILER!!!") == 0)
37.566 - break;
37.567 -
37.568 - installer.rest = filesize;
37.569 - if (create_path(&installer, path + 1, mode) < 0)
37.570 - return -1;
37.571 - if (installer_align(&installer, 4))
37.572 - return -1;
37.573 - }
37.574 -
37.575 - if (installer_finish(&installer))
37.576 - return -1;
37.577 -
37.578 - run_script(&installer, RPMTAG_POSTINPROG, RPMTAG_POSTIN);
37.579 -
37.580 - return 0;
37.581 -}
37.582 -
37.583 -int
37.584 -razor_rpm_close(struct razor_rpm *rpm)
37.585 -{
37.586 - int err;
37.587 -
37.588 - free(rpm->dirs);
37.589 - err = munmap(rpm->map, rpm->size);
37.590 - free(rpm);
37.591 -
37.592 - return err;
37.593 -}
37.594 -
37.595 -int
37.596 -razor_importer_add_rpm(struct razor_importer *importer, struct razor_rpm *rpm)
37.597 -{
37.598 - const char *name, *version, *release, *arch, *summary;
37.599 - const uint_32 *epoch;
37.600 - char evr[128], buf[16];
37.601 -
37.602 - name = razor_rpm_get_indirect(rpm, RPMTAG_NAME, NULL);
37.603 - epoch = razor_rpm_get_indirect(rpm, RPMTAG_EPOCH, NULL);
37.604 - version = razor_rpm_get_indirect(rpm, RPMTAG_VERSION, NULL);
37.605 - release = razor_rpm_get_indirect(rpm, RPMTAG_RELEASE, NULL);
37.606 - arch = razor_rpm_get_indirect(rpm, RPMTAG_ARCH, NULL);
37.607 - summary = razor_rpm_get_indirect(rpm, RPMTAG_SUMMARY, NULL);
37.608 -
37.609 - if (epoch) {
37.610 - snprintf(buf, sizeof buf, "%u", ntohl(*epoch));
37.611 - razor_build_evr(evr, sizeof evr, buf, version, release);
37.612 - } else {
37.613 - razor_build_evr(evr, sizeof evr, NULL, version, release);
37.614 - }
37.615 - razor_importer_begin_package(importer, name, evr, arch);
37.616 -
37.617 - import_properties(importer, RAZOR_PROPERTY_REQUIRES, rpm,
37.618 - RPMTAG_REQUIRENAME,
37.619 - RPMTAG_REQUIREVERSION,
37.620 - RPMTAG_REQUIREFLAGS);
37.621 -
37.622 - import_properties(importer, RAZOR_PROPERTY_PROVIDES, rpm,
37.623 - RPMTAG_PROVIDENAME,
37.624 - RPMTAG_PROVIDEVERSION,
37.625 - RPMTAG_PROVIDEFLAGS);
37.626 -
37.627 - import_properties(importer, RAZOR_PROPERTY_OBSOLETES, rpm,
37.628 - RPMTAG_OBSOLETENAME,
37.629 - RPMTAG_OBSOLETEVERSION,
37.630 - RPMTAG_OBSOLETEFLAGS);
37.631 -
37.632 - import_properties(importer, RAZOR_PROPERTY_CONFLICTS, rpm,
37.633 - RPMTAG_CONFLICTNAME,
37.634 - RPMTAG_CONFLICTVERSION,
37.635 - RPMTAG_CONFLICTFLAGS);
37.636 -
37.637 - import_files(importer, rpm);
37.638 -
37.639 - razor_importer_finish_package(importer);
37.640 -
37.641 - return 0;
37.642 -}
37.643 -
37.644 -union rpm_entry {
37.645 - void *p;
37.646 - char *string;
37.647 - char **list;
37.648 - uint_32 *flags;
37.649 - uint_32 integer;
37.650 -};
37.651 -
37.652 -static void
37.653 -add_properties(struct razor_importer *importer,
37.654 - enum razor_property_type property_type,
37.655 - Header h, int_32 name_tag, int_32 version_tag, int_32 flags_tag)
37.656 -{
37.657 - union rpm_entry names, versions, flags;
37.658 - int_32 i, type, count;
37.659 -
37.660 - headerGetEntry(h, name_tag, &type, &names.p, &count);
37.661 - headerGetEntry(h, version_tag, &type, &versions.p, &count);
37.662 - headerGetEntry(h, flags_tag, &type, &flags.p, &count);
37.663 -
37.664 - for (i = 0; i < count; i++)
37.665 - razor_importer_add_property(importer,
37.666 - names.list[i],
37.667 - rpm_to_razor_flags (flags.flags[i]),
37.668 - versions.list[i],
37.669 - property_type);
37.670 -}
37.671 -
37.672 -struct razor_set *
37.673 -razor_set_create_from_rpmdb(void)
37.674 -{
37.675 - struct razor_importer *importer;
37.676 - rpmdbMatchIterator iter;
37.677 - Header h;
37.678 - int_32 type, count, i;
37.679 - union rpm_entry name, epoch, version, release, arch;
37.680 - union rpm_entry summary, description, url, license;
37.681 - union rpm_entry basenames, dirnames, dirindexes;
37.682 - char filename[PATH_MAX], evr[128], buf[16];
37.683 - rpmdb db;
37.684 -
37.685 - rpmReadConfigFiles(NULL, NULL);
37.686 -
37.687 - if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
37.688 - fprintf(stderr, "cannot open rpm database\n");
37.689 - exit(1);
37.690 - }
37.691 -
37.692 - importer = razor_importer_new();
37.693 -
37.694 - iter = rpmdbInitIterator(db, 0, NULL, 0);
37.695 - while (h = rpmdbNextIterator(iter), h != NULL) {
37.696 - headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
37.697 - headerGetEntry(h, RPMTAG_EPOCH, &type, &epoch.p, &count);
37.698 - headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
37.699 - headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
37.700 - headerGetEntry(h, RPMTAG_ARCH, &type, &arch.p, &count);
37.701 - headerGetEntry(h, RPMTAG_SUMMARY, &type, &summary.p, &count);
37.702 - headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &description.p, &count);
37.703 - headerGetEntry(h, RPMTAG_URL, &type, &url.p, &count);
37.704 - headerGetEntry(h, RPMTAG_LICENSE, &type, &license.p, &count);
37.705 -
37.706 - if (epoch.flags != NULL) {
37.707 - snprintf(buf, sizeof buf, "%u", *epoch.flags);
37.708 - razor_build_evr(evr, sizeof evr,
37.709 - buf, version.string, release.string);
37.710 - } else {
37.711 - razor_build_evr(evr, sizeof evr,
37.712 - NULL, version.string, release.string);
37.713 - }
37.714 -
37.715 - razor_importer_begin_package(importer,
37.716 - name.string, evr, arch.string);
37.717 - razor_importer_add_details(importer, summary.string,
37.718 - description.string, url.string,
37.719 - license.string);
37.720 -
37.721 - add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
37.722 - RPMTAG_REQUIRENAME,
37.723 - RPMTAG_REQUIREVERSION,
37.724 - RPMTAG_REQUIREFLAGS);
37.725 -
37.726 - add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
37.727 - RPMTAG_PROVIDENAME,
37.728 - RPMTAG_PROVIDEVERSION,
37.729 - RPMTAG_PROVIDEFLAGS);
37.730 -
37.731 - add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
37.732 - RPMTAG_OBSOLETENAME,
37.733 - RPMTAG_OBSOLETEVERSION,
37.734 - RPMTAG_OBSOLETEFLAGS);
37.735 -
37.736 - add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
37.737 - RPMTAG_CONFLICTNAME,
37.738 - RPMTAG_CONFLICTVERSION,
37.739 - RPMTAG_CONFLICTFLAGS);
37.740 -
37.741 - headerGetEntry(h, RPMTAG_BASENAMES, &type,
37.742 - &basenames.p, &count);
37.743 - headerGetEntry(h, RPMTAG_DIRNAMES, &type,
37.744 - &dirnames.p, &count);
37.745 - headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
37.746 - &dirindexes.p, &count);
37.747 - for (i = 0; i < count; i++) {
37.748 - snprintf(filename, sizeof filename, "%s%s",
37.749 - dirnames.list[dirindexes.flags[i]],
37.750 - basenames.list[i]);
37.751 - razor_importer_add_file(importer, filename);
37.752 - }
37.753 -
37.754 - razor_importer_finish_package(importer);
37.755 - }
37.756 -
37.757 - rpmdbClose(db);
37.758 -
37.759 - return razor_importer_finish(importer);
37.760 -}
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
38.2 +++ b/src/.gitignore Fri Jun 20 19:04:47 2008 -0400
38.3 @@ -0,0 +1,8 @@
38.4 +.deps
38.5 +.libs
38.6 +razor
38.7 +rpm
38.8 +*.repo
38.9 +*.xml.gz
38.10 +install
38.11 +rpms
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
39.2 +++ b/src/Makefile.am Fri Jun 20 19:04:47 2008 -0400
39.3 @@ -0,0 +1,26 @@
39.4 +## Process this file with automake to produce Makefile.in
39.5 +
39.6 +INCLUDES = \
39.7 + $(CURL_CFLAGS) \
39.8 + $(EXPAT_CFLAGS) \
39.9 + $(RPM_CFLAGS) \
39.10 + -I$(top_builddir)/src -I$(top_srcdir)/src \
39.11 + -I$(top_srcdir)/librazor \
39.12 + -DPACKAGE_LIBEXEC_DIR=\""$(libexecdir)"\" \
39.13 + -DPACKAGE_SYSCONF_DIR=\""$(sysconfdir)"\" \
39.14 + -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
39.15 + -DPACKAGE_BIN_DIR=\""$(bindir)"\" \
39.16 + -DPACKAGE_LOCALSTATEDIR=\""$(localstatedir)"\" \
39.17 + -DPACKAGE_LOCALE_DIR=\""$(localedir)"\"
39.18 +
39.19 +bin_PROGRAMS = razor rpm
39.20 +
39.21 +razor_SOURCES = main.c import-rpmdb.c import-yum.c
39.22 +razor_LDADD = $(RPM_LIBS) $(EXPAT_LIBS) $(CURL_LIBS) $(top_builddir)/librazor/librazor.la
39.23 +
39.24 +rpm_SOURCES = rpm.c
39.25 +rpm_LDADD = $(top_builddir)/librazor/librazor.la
39.26 +
39.27 +clean-local :
39.28 + rm -f *~
39.29 +
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
40.2 +++ b/src/import-rpmdb.c Fri Jun 20 19:04:47 2008 -0400
40.3 @@ -0,0 +1,170 @@
40.4 +/*
40.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
40.6 + * Copyright (C) 2008 Red Hat, Inc
40.7 + *
40.8 + * This program is free software; you can redistribute it and/or modify
40.9 + * it under the terms of the GNU General Public License as published by
40.10 + * the Free Software Foundation; either version 2 of the License, or
40.11 + * (at your option) any later version.
40.12 + *
40.13 + * This program is distributed in the hope that it will be useful,
40.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
40.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40.16 + * GNU General Public License for more details.
40.17 + *
40.18 + * You should have received a copy of the GNU General Public License along
40.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
40.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
40.21 + */
40.22 +
40.23 +#include <stdio.h>
40.24 +#include <stddef.h>
40.25 +#include <string.h>
40.26 +#include <fcntl.h>
40.27 +#include <rpm/rpmlib.h>
40.28 +#include <rpm/rpmdb.h>
40.29 +
40.30 +#include "razor.h"
40.31 +
40.32 +union rpm_entry {
40.33 + void *p;
40.34 + char *string;
40.35 + char **list;
40.36 + uint_32 *flags;
40.37 + uint_32 integer;
40.38 +};
40.39 +
40.40 +static uint32_t
40.41 +rpm_to_razor_flags(uint32_t flags)
40.42 +{
40.43 + uint32_t razor_flags;
40.44 +
40.45 + razor_flags = 0;
40.46 + if (flags & RPMSENSE_LESS)
40.47 + razor_flags |= RAZOR_PROPERTY_LESS;
40.48 + if (flags & RPMSENSE_EQUAL)
40.49 + razor_flags |= RAZOR_PROPERTY_EQUAL;
40.50 + if (flags & RPMSENSE_GREATER)
40.51 + razor_flags |= RAZOR_PROPERTY_GREATER;
40.52 +
40.53 + if (flags & RPMSENSE_SCRIPT_PRE)
40.54 + razor_flags |= RAZOR_PROPERTY_PRE;
40.55 + if (flags & RPMSENSE_SCRIPT_POST)
40.56 + razor_flags |= RAZOR_PROPERTY_POST;
40.57 + if (flags & RPMSENSE_SCRIPT_PREUN)
40.58 + razor_flags |= RAZOR_PROPERTY_PREUN;
40.59 + if (flags & RPMSENSE_SCRIPT_POSTUN)
40.60 + razor_flags |= RAZOR_PROPERTY_POSTUN;
40.61 +
40.62 + return razor_flags;
40.63 +}
40.64 +
40.65 +static void
40.66 +add_properties(struct razor_importer *importer,
40.67 + uint32_t type_flags,
40.68 + Header h, int_32 name_tag, int_32 version_tag, int_32 flags_tag)
40.69 +{
40.70 + union rpm_entry names, versions, flags;
40.71 + int_32 i, type, count;
40.72 +
40.73 + headerGetEntry(h, name_tag, &type, &names.p, &count);
40.74 + headerGetEntry(h, version_tag, &type, &versions.p, &count);
40.75 + headerGetEntry(h, flags_tag, &type, &flags.p, &count);
40.76 +
40.77 + for (i = 0; i < count; i++)
40.78 + razor_importer_add_property(importer,
40.79 + names.list[i],
40.80 + rpm_to_razor_flags (flags.flags[i]) | type_flags,
40.81 + versions.list[i]);
40.82 +}
40.83 +
40.84 +struct razor_set *
40.85 +razor_set_create_from_rpmdb(void)
40.86 +{
40.87 + struct razor_importer *importer;
40.88 + rpmdbMatchIterator iter;
40.89 + Header h;
40.90 + int_32 type, count, i;
40.91 + union rpm_entry name, epoch, version, release, arch;
40.92 + union rpm_entry summary, description, url, license;
40.93 + union rpm_entry basenames, dirnames, dirindexes;
40.94 + char filename[PATH_MAX], evr[128], buf[16];
40.95 + rpmdb db;
40.96 +
40.97 + rpmReadConfigFiles(NULL, NULL);
40.98 +
40.99 + if (rpmdbOpen("", &db, O_RDONLY, 0644) != 0) {
40.100 + fprintf(stderr, "cannot open rpm database\n");
40.101 + exit(1);
40.102 + }
40.103 +
40.104 + importer = razor_importer_new();
40.105 +
40.106 + iter = rpmdbInitIterator(db, 0, NULL, 0);
40.107 + while (h = rpmdbNextIterator(iter), h != NULL) {
40.108 + headerGetEntry(h, RPMTAG_NAME, &type, &name.p, &count);
40.109 + headerGetEntry(h, RPMTAG_EPOCH, &type, &epoch.p, &count);
40.110 + headerGetEntry(h, RPMTAG_VERSION, &type, &version.p, &count);
40.111 + headerGetEntry(h, RPMTAG_RELEASE, &type, &release.p, &count);
40.112 + headerGetEntry(h, RPMTAG_ARCH, &type, &arch.p, &count);
40.113 + headerGetEntry(h, RPMTAG_SUMMARY, &type, &summary.p, &count);
40.114 + headerGetEntry(h, RPMTAG_DESCRIPTION, &type, &description.p,
40.115 + &count);
40.116 + headerGetEntry(h, RPMTAG_URL, &type, &url.p, &count);
40.117 + headerGetEntry(h, RPMTAG_LICENSE, &type, &license.p, &count);
40.118 +
40.119 + if (epoch.flags != NULL) {
40.120 + snprintf(buf, sizeof buf, "%u", *epoch.flags);
40.121 + razor_build_evr(evr, sizeof evr,
40.122 + buf, version.string, release.string);
40.123 + } else {
40.124 + razor_build_evr(evr, sizeof evr,
40.125 + NULL, version.string, release.string);
40.126 + }
40.127 +
40.128 + razor_importer_begin_package(importer,
40.129 + name.string, evr, arch.string);
40.130 + razor_importer_add_details(importer, summary.string,
40.131 + description.string, url.string,
40.132 + license.string);
40.133 +
40.134 + add_properties(importer, RAZOR_PROPERTY_REQUIRES, h,
40.135 + RPMTAG_REQUIRENAME,
40.136 + RPMTAG_REQUIREVERSION,
40.137 + RPMTAG_REQUIREFLAGS);
40.138 +
40.139 + add_properties(importer, RAZOR_PROPERTY_PROVIDES, h,
40.140 + RPMTAG_PROVIDENAME,
40.141 + RPMTAG_PROVIDEVERSION,
40.142 + RPMTAG_PROVIDEFLAGS);
40.143 +
40.144 + add_properties(importer, RAZOR_PROPERTY_OBSOLETES, h,
40.145 + RPMTAG_OBSOLETENAME,
40.146 + RPMTAG_OBSOLETEVERSION,
40.147 + RPMTAG_OBSOLETEFLAGS);
40.148 +
40.149 + add_properties(importer, RAZOR_PROPERTY_CONFLICTS, h,
40.150 + RPMTAG_CONFLICTNAME,
40.151 + RPMTAG_CONFLICTVERSION,
40.152 + RPMTAG_CONFLICTFLAGS);
40.153 +
40.154 + headerGetEntry(h, RPMTAG_BASENAMES, &type,
40.155 + &basenames.p, &count);
40.156 + headerGetEntry(h, RPMTAG_DIRNAMES, &type,
40.157 + &dirnames.p, &count);
40.158 + headerGetEntry(h, RPMTAG_DIRINDEXES, &type,
40.159 + &dirindexes.p, &count);
40.160 + for (i = 0; i < count; i++) {
40.161 + snprintf(filename, sizeof filename, "%s%s",
40.162 + dirnames.list[dirindexes.flags[i]],
40.163 + basenames.list[i]);
40.164 + razor_importer_add_file(importer, filename);
40.165 + }
40.166 +
40.167 + razor_importer_finish_package(importer);
40.168 + }
40.169 +
40.170 + rpmdbClose(db);
40.171 +
40.172 + return razor_importer_finish(importer);
40.173 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
41.2 +++ b/src/import-yum.c Fri Jun 20 19:04:47 2008 -0400
41.3 @@ -0,0 +1,352 @@
41.4 +/*
41.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
41.6 + * Copyright (C) 2008 Red Hat, Inc
41.7 + *
41.8 + * This program is free software; you can redistribute it and/or modify
41.9 + * it under the terms of the GNU General Public License as published by
41.10 + * the Free Software Foundation; either version 2 of the License, or
41.11 + * (at your option) any later version.
41.12 + *
41.13 + * This program is distributed in the hope that it will be useful,
41.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
41.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41.16 + * GNU General Public License for more details.
41.17 + *
41.18 + * You should have received a copy of the GNU General Public License along
41.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
41.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
41.21 + */
41.22 +
41.23 +#define _GNU_SOURCE
41.24 +
41.25 +#include <string.h>
41.26 +#include <stdio.h>
41.27 +#include <stdint.h>
41.28 +#include <sys/stat.h>
41.29 +#include <sys/mman.h>
41.30 +#include <unistd.h>
41.31 +#include <fcntl.h>
41.32 +#include <errno.h>
41.33 +
41.34 +#include <expat.h>
41.35 +#include <zlib.h>
41.36 +#include "razor.h"
41.37 +
41.38 +/* Import a yum filelist as a razor package set. */
41.39 +
41.40 +enum {
41.41 + YUM_STATE_BEGIN,
41.42 + YUM_STATE_PACKAGE_NAME,
41.43 + YUM_STATE_PACKAGE_ARCH,
41.44 + YUM_STATE_SUMMARY,
41.45 + YUM_STATE_DESCRIPTION,
41.46 + YUM_STATE_URL,
41.47 + YUM_STATE_LICENSE,
41.48 + YUM_STATE_CHECKSUM,
41.49 + YUM_STATE_REQUIRES,
41.50 + YUM_STATE_PROVIDES,
41.51 + YUM_STATE_OBSOLETES,
41.52 + YUM_STATE_CONFLICTS,
41.53 + YUM_STATE_FILE
41.54 +};
41.55 +
41.56 +struct yum_context {
41.57 + XML_Parser primary_parser;
41.58 + XML_Parser filelists_parser;
41.59 + XML_Parser current_parser;
41.60 +
41.61 + struct razor_importer *importer;
41.62 + struct import_property_context *current_property_context;
41.63 + char name[256], arch[64], summary[512], description[4096];
41.64 + char url[256], license[64], buffer[512], *p;
41.65 + char pkgid[128];
41.66 + uint32_t property_type;
41.67 + int state;
41.68 +};
41.69 +
41.70 +static uint32_t
41.71 +yum_to_razor_relation (const char *flags)
41.72 +{
41.73 + if (flags[0] == 'L') {
41.74 + if (flags[1] == 'T')
41.75 + return RAZOR_PROPERTY_LESS;
41.76 + else
41.77 + return RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL;
41.78 + } else if (flags[0] == 'G') {
41.79 + if (flags[1] == 'T')
41.80 + return RAZOR_PROPERTY_GREATER;
41.81 + else
41.82 + return RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL;
41.83 + } else
41.84 + return RAZOR_PROPERTY_EQUAL;
41.85 +}
41.86 +
41.87 +static void
41.88 +yum_primary_start_element(void *data, const char *name, const char **atts)
41.89 +{
41.90 + struct yum_context *ctx = data;
41.91 + const char *n, *epoch, *version, *release;
41.92 + char buffer[128];
41.93 + uint32_t pre, relation, flags;
41.94 + int i;
41.95 +
41.96 + if (strcmp(name, "name") == 0) {
41.97 + ctx->state = YUM_STATE_PACKAGE_NAME;
41.98 + ctx->p = ctx->name;
41.99 + } else if (strcmp(name, "arch") == 0) {
41.100 + ctx->state = YUM_STATE_PACKAGE_ARCH;
41.101 + ctx->p = ctx->arch;
41.102 + } else if (strcmp(name, "version") == 0) {
41.103 + epoch = NULL;
41.104 + version = NULL;
41.105 + release = NULL;
41.106 + for (i = 0; atts[i]; i += 2) {
41.107 + if (strcmp(atts[i], "epoch") == 0)
41.108 + epoch = atts[i + 1];
41.109 + else if (strcmp(atts[i], "ver") == 0)
41.110 + version = atts[i + 1];
41.111 + else if (strcmp(atts[i], "rel") == 0)
41.112 + release = atts[i + 1];
41.113 + }
41.114 + if (version == NULL || release == NULL) {
41.115 + fprintf(stderr, "invalid version tag, "
41.116 + "missing version or release attribute\n");
41.117 + return;
41.118 + }
41.119 +
41.120 + razor_build_evr(buffer, sizeof buffer, epoch, version, release);
41.121 + razor_importer_begin_package(ctx->importer,
41.122 + ctx->name, buffer, ctx->arch);
41.123 + } else if (strcmp(name, "summary") == 0) {
41.124 + ctx->p = ctx->summary;
41.125 + ctx->state = YUM_STATE_SUMMARY;
41.126 + } else if (strcmp(name, "description") == 0) {
41.127 + ctx->p = ctx->description;
41.128 + ctx->state = YUM_STATE_DESCRIPTION;
41.129 + } else if (strcmp(name, "url") == 0) {
41.130 + ctx->p = ctx->url;
41.131 + ctx->state = YUM_STATE_URL;
41.132 + } else if (strcmp(name, "checksum") == 0) {
41.133 + ctx->p = ctx->pkgid;
41.134 + ctx->state = YUM_STATE_CHECKSUM;
41.135 + } else if (strcmp(name, "rpm:license") == 0) {
41.136 + ctx->p = ctx->license;
41.137 + ctx->state = YUM_STATE_LICENSE;
41.138 + } else if (strcmp(name, "rpm:requires") == 0) {
41.139 + ctx->state = YUM_STATE_REQUIRES;
41.140 + ctx->property_type = RAZOR_PROPERTY_REQUIRES;
41.141 + } else if (strcmp(name, "rpm:provides") == 0) {
41.142 + ctx->state = YUM_STATE_PROVIDES;
41.143 + ctx->property_type = RAZOR_PROPERTY_PROVIDES;
41.144 + } else if (strcmp(name, "rpm:obsoletes") == 0) {
41.145 + ctx->state = YUM_STATE_OBSOLETES;
41.146 + ctx->property_type = RAZOR_PROPERTY_OBSOLETES;
41.147 + } else if (strcmp(name, "rpm:conflicts") == 0) {
41.148 + ctx->state = YUM_STATE_CONFLICTS;
41.149 + ctx->property_type = RAZOR_PROPERTY_CONFLICTS;
41.150 + } else if (strcmp(name, "rpm:entry") == 0 &&
41.151 + ctx->state != YUM_STATE_BEGIN) {
41.152 + n = NULL;
41.153 + epoch = NULL;
41.154 + version = NULL;
41.155 + release = NULL;
41.156 + relation = RAZOR_PROPERTY_EQUAL;
41.157 + pre = 0;
41.158 + for (i = 0; atts[i]; i += 2) {
41.159 + if (strcmp(atts[i], "name") == 0)
41.160 + n = atts[i + 1];
41.161 + else if (strcmp(atts[i], "epoch") == 0)
41.162 + epoch = atts[i + 1];
41.163 + else if (strcmp(atts[i], "ver") == 0)
41.164 + version = atts[i + 1];
41.165 + else if (strcmp(atts[i], "rel") == 0)
41.166 + release = atts[i + 1];
41.167 + else if (strcmp(atts[i], "flags") == 0)
41.168 + relation = yum_to_razor_relation(atts[i + 1]);
41.169 + else if (strcmp(atts[i], "pre") == 0)
41.170 + pre =
41.171 + RAZOR_PROPERTY_PRE |
41.172 + RAZOR_PROPERTY_POST |
41.173 + RAZOR_PROPERTY_PREUN |
41.174 + RAZOR_PROPERTY_POSTUN;
41.175 + }
41.176 +
41.177 + if (n == NULL) {
41.178 + fprintf(stderr, "invalid rpm:entry, "
41.179 + "missing name or version attributes\n");
41.180 + return;
41.181 + }
41.182 +
41.183 + razor_build_evr(buffer, sizeof buffer, epoch, version, release);
41.184 + flags = ctx->property_type | relation | pre;
41.185 + razor_importer_add_property(ctx->importer, n, flags, buffer);
41.186 + }
41.187 +}
41.188 +
41.189 +static void
41.190 +yum_primary_end_element (void *data, const char *name)
41.191 +{
41.192 + struct yum_context *ctx = data;
41.193 +
41.194 + switch (ctx->state) {
41.195 + case YUM_STATE_PACKAGE_NAME:
41.196 + case YUM_STATE_PACKAGE_ARCH:
41.197 + case YUM_STATE_SUMMARY:
41.198 + case YUM_STATE_DESCRIPTION:
41.199 + case YUM_STATE_URL:
41.200 + case YUM_STATE_LICENSE:
41.201 + case YUM_STATE_CHECKSUM:
41.202 + case YUM_STATE_FILE:
41.203 + ctx->state = YUM_STATE_BEGIN;
41.204 + break;
41.205 + }
41.206 +
41.207 + if (strcmp(name, "package") == 0) {
41.208 + razor_importer_add_details(ctx->importer, ctx->summary,
41.209 + ctx->description, ctx->url,
41.210 + ctx->license);
41.211 +
41.212 + XML_StopParser(ctx->current_parser, XML_TRUE);
41.213 + ctx->current_parser = ctx->filelists_parser;
41.214 + }
41.215 +}
41.216 +
41.217 +static void
41.218 +yum_character_data (void *data, const XML_Char *s, int len)
41.219 +{
41.220 + struct yum_context *ctx = data;
41.221 +
41.222 + switch (ctx->state) {
41.223 + case YUM_STATE_PACKAGE_NAME:
41.224 + case YUM_STATE_PACKAGE_ARCH:
41.225 + case YUM_STATE_SUMMARY:
41.226 + case YUM_STATE_DESCRIPTION:
41.227 + case YUM_STATE_URL:
41.228 + case YUM_STATE_LICENSE:
41.229 + case YUM_STATE_CHECKSUM:
41.230 + case YUM_STATE_FILE:
41.231 + memcpy(ctx->p, s, len);
41.232 + ctx->p += len;
41.233 + *ctx->p = '\0';
41.234 + break;
41.235 + }
41.236 +}
41.237 +
41.238 +static void
41.239 +yum_filelists_start_element(void *data, const char *name, const char **atts)
41.240 +{
41.241 + struct yum_context *ctx = data;
41.242 + const char *pkg, *pkgid;
41.243 + int i;
41.244 +
41.245 + if (strcmp(name, "package") == 0) {
41.246 + pkg = NULL;
41.247 + pkgid = NULL;
41.248 + for (i = 0; atts[i]; i += 2) {
41.249 + if (strcmp(atts[i], "name") == 0)
41.250 + pkg = atts[i + 1];
41.251 + else if (strcmp(atts[i], "pkgid") == 0)
41.252 + pkgid = atts[i + 1];
41.253 + }
41.254 + if (strcmp(pkgid, ctx->pkgid) != 0)
41.255 + fprintf(stderr, "primary.xml and filelists.xml "
41.256 + "mismatch for %s: %s vs %s",
41.257 + pkg, pkgid, ctx->pkgid);
41.258 + } else if (strcmp(name, "file") == 0) {
41.259 + ctx->state = YUM_STATE_FILE;
41.260 + ctx->p = ctx->buffer;
41.261 + }
41.262 +}
41.263 +
41.264 +
41.265 +static void
41.266 +yum_filelists_end_element (void *data, const char *name)
41.267 +{
41.268 + struct yum_context *ctx = data;
41.269 +
41.270 + ctx->state = YUM_STATE_BEGIN;
41.271 + if (strcmp(name, "package") == 0) {
41.272 + XML_StopParser(ctx->current_parser, XML_TRUE);
41.273 + ctx->current_parser = ctx->primary_parser;
41.274 + razor_importer_finish_package(ctx->importer);
41.275 + } else if (strcmp(name, "file") == 0)
41.276 + razor_importer_add_file(ctx->importer, ctx->buffer);
41.277 +
41.278 +}
41.279 +
41.280 +#define XML_BUFFER_SIZE 4096
41.281 +
41.282 +struct razor_set *
41.283 +razor_set_create_from_yum(void)
41.284 +{
41.285 + struct yum_context ctx;
41.286 + void *buf;
41.287 + int len, ret;
41.288 + gzFile primary, filelists;
41.289 + XML_ParsingStatus status;
41.290 +
41.291 + ctx.importer = razor_importer_new();
41.292 + ctx.state = YUM_STATE_BEGIN;
41.293 +
41.294 + ctx.primary_parser = XML_ParserCreate(NULL);
41.295 + XML_SetUserData(ctx.primary_parser, &ctx);
41.296 + XML_SetElementHandler(ctx.primary_parser,
41.297 + yum_primary_start_element,
41.298 + yum_primary_end_element);
41.299 + XML_SetCharacterDataHandler(ctx.primary_parser,
41.300 + yum_character_data);
41.301 +
41.302 + ctx.filelists_parser = XML_ParserCreate(NULL);
41.303 + XML_SetUserData(ctx.filelists_parser, &ctx);
41.304 + XML_SetElementHandler(ctx.filelists_parser,
41.305 + yum_filelists_start_element,
41.306 + yum_filelists_end_element);
41.307 + XML_SetCharacterDataHandler(ctx.filelists_parser,
41.308 + yum_character_data);
41.309 +
41.310 + primary = gzopen("primary.xml.gz", "rb");
41.311 + if (primary == NULL)
41.312 + return NULL;
41.313 + filelists = gzopen("filelists.xml.gz", "rb");
41.314 + if (filelists == NULL)
41.315 + return NULL;
41.316 +
41.317 + ctx.current_parser = ctx.primary_parser;
41.318 +
41.319 + do {
41.320 + XML_GetParsingStatus(ctx.current_parser, &status);
41.321 + switch (status.parsing) {
41.322 + case XML_SUSPENDED:
41.323 + ret = XML_ResumeParser(ctx.current_parser);
41.324 + break;
41.325 + case XML_PARSING:
41.326 + case XML_INITIALIZED:
41.327 + buf = XML_GetBuffer(ctx.current_parser,
41.328 + XML_BUFFER_SIZE);
41.329 + if (ctx.current_parser == ctx.primary_parser)
41.330 + len = gzread(primary, buf, XML_BUFFER_SIZE);
41.331 + else
41.332 + len = gzread(filelists, buf, XML_BUFFER_SIZE);
41.333 + if (len < 0) {
41.334 + fprintf(stderr,
41.335 + "couldn't read input: %s\n",
41.336 + strerror(errno));
41.337 + return NULL;
41.338 + }
41.339 +
41.340 + XML_ParseBuffer(ctx.current_parser, len, len == 0);
41.341 + break;
41.342 + case XML_FINISHED:
41.343 + break;
41.344 + }
41.345 + } while (status.parsing != XML_FINISHED);
41.346 +
41.347 +
41.348 + XML_ParserFree(ctx.primary_parser);
41.349 + XML_ParserFree(ctx.filelists_parser);
41.350 +
41.351 + gzclose(primary);
41.352 + gzclose(filelists);
41.353 +
41.354 + return razor_importer_finish(ctx.importer);
41.355 +}
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
42.2 +++ b/src/main.c Fri Jun 20 19:04:47 2008 -0400
42.3 @@ -0,0 +1,858 @@
42.4 +/*
42.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
42.6 + * Copyright (C) 2008 Red Hat, Inc
42.7 + *
42.8 + * This program is free software; you can redistribute it and/or modify
42.9 + * it under the terms of the GNU General Public License as published by
42.10 + * the Free Software Foundation; either version 2 of the License, or
42.11 + * (at your option) any later version.
42.12 + *
42.13 + * This program is distributed in the hope that it will be useful,
42.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
42.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
42.16 + * GNU General Public License for more details.
42.17 + *
42.18 + * You should have received a copy of the GNU General Public License along
42.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
42.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
42.21 + */
42.22 +
42.23 +#include <stdlib.h>
42.24 +#include <stddef.h>
42.25 +#include <stdio.h>
42.26 +#include <stdint.h>
42.27 +#include <string.h>
42.28 +#include <sys/stat.h>
42.29 +#include <unistd.h>
42.30 +#include <fcntl.h>
42.31 +#include <dirent.h>
42.32 +#include <curl/curl.h>
42.33 +#include <fnmatch.h>
42.34 +#include <errno.h>
42.35 +#include "razor.h"
42.36 +
42.37 +static const char system_repo_filename[] = "system.repo";
42.38 +static const char next_repo_filename[] = "system-next.repo";
42.39 +static const char rawhide_repo_filename[] = "rawhide.repo";
42.40 +static const char updated_repo_filename[] = "system-updated.repo";
42.41 +static const char install_root[] = "install";
42.42 +static const char *repo_filename = system_repo_filename;
42.43 +static const char *yum_url;
42.44 +
42.45 +static int
42.46 +command_list(int argc, const char *argv[])
42.47 +{
42.48 + struct razor_set *set;
42.49 + struct razor_package_iterator *pi;
42.50 + struct razor_package *package;
42.51 + const char *pattern, *name, *version, *arch;
42.52 + int only_names = 0, i = 0;
42.53 +
42.54 + if (i < argc && strcmp(argv[i], "--only-names") == 0) {
42.55 + only_names = 1;
42.56 + i++;
42.57 + }
42.58 +
42.59 + pattern = argv[i];
42.60 + set = razor_set_open(repo_filename);
42.61 + pi = razor_package_iterator_create(set);
42.62 + while (razor_package_iterator_next(pi, &package,
42.63 + &name, &version, &arch)) {
42.64 + if (pattern && fnmatch(pattern, name, 0) != 0)
42.65 + continue;
42.66 +
42.67 + if (only_names)
42.68 + printf("%s\n", name);
42.69 + else
42.70 + printf("%s-%s.%s\n", name, version, arch);
42.71 + }
42.72 + razor_package_iterator_destroy(pi);
42.73 + razor_set_destroy(set);
42.74 +
42.75 + return 0;
42.76 +}
42.77 +
42.78 +static int
42.79 +list_properties(const char *package_name, uint32_t type)
42.80 +{
42.81 + struct razor_set *set;
42.82 + struct razor_property *property;
42.83 + struct razor_package *package;
42.84 + struct razor_property_iterator *pi;
42.85 + const char *name, *version;
42.86 + uint32_t flags;
42.87 +
42.88 + set = razor_set_open(repo_filename);
42.89 + if (package_name)
42.90 + package = razor_set_get_package(set, package_name);
42.91 + else
42.92 + package = NULL;
42.93 +
42.94 + pi = razor_property_iterator_create(set, package);
42.95 + while (razor_property_iterator_next(pi, &property,
42.96 + &name, &flags, &version)) {
42.97 + if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
42.98 + continue;
42.99 + printf("%s", name);
42.100 + if (version[0] != '\0')
42.101 + printf(" %s %s",
42.102 + razor_property_relation_to_string(property),
42.103 + version);
42.104 +
42.105 + if (flags & ~(RAZOR_PROPERTY_RELATION_MASK | RAZOR_PROPERTY_TYPE_MASK)) {
42.106 + printf(" [");
42.107 + if (flags & RAZOR_PROPERTY_PRE)
42.108 + printf(" pre");
42.109 + if (flags & RAZOR_PROPERTY_POST)
42.110 + printf(" post");
42.111 + if (flags & RAZOR_PROPERTY_PREUN)
42.112 + printf(" preun");
42.113 + if (flags & RAZOR_PROPERTY_POSTUN)
42.114 + printf(" postun");
42.115 + printf(" ]");
42.116 + }
42.117 + printf("\n");
42.118 + }
42.119 + razor_property_iterator_destroy(pi);
42.120 +
42.121 + razor_set_destroy(set);
42.122 +
42.123 + return 0;
42.124 +}
42.125 +
42.126 +static int
42.127 +command_list_requires(int argc, const char *argv[])
42.128 +{
42.129 + return list_properties(argv[0], RAZOR_PROPERTY_REQUIRES);
42.130 +}
42.131 +
42.132 +static int
42.133 +command_list_provides(int argc, const char *argv[])
42.134 +{
42.135 + return list_properties(argv[0], RAZOR_PROPERTY_PROVIDES);
42.136 +}
42.137 +
42.138 +static int
42.139 +command_list_obsoletes(int argc, const char *argv[])
42.140 +{
42.141 + return list_properties(argv[0], RAZOR_PROPERTY_OBSOLETES);
42.142 +}
42.143 +
42.144 +static int
42.145 +command_list_conflicts(int argc, const char *argv[])
42.146 +{
42.147 + return list_properties(argv[0], RAZOR_PROPERTY_CONFLICTS);
42.148 +}
42.149 +
42.150 +static int
42.151 +command_list_files(int argc, const char *argv[])
42.152 +{
42.153 + struct razor_set *set;
42.154 +
42.155 + set = razor_set_open(repo_filename);
42.156 + razor_set_open_files(set, "system-files.repo");
42.157 + if (set == NULL)
42.158 + return 1;
42.159 + razor_set_list_files(set, argv[0]);
42.160 + razor_set_destroy(set);
42.161 +
42.162 + return 0;
42.163 +}
42.164 +
42.165 +static int
42.166 +command_list_file_packages(int argc, const char *argv[])
42.167 +{
42.168 + struct razor_set *set;
42.169 + struct razor_package_iterator *pi;
42.170 + struct razor_package *package;
42.171 + const char *name, *version, *arch;
42.172 +
42.173 + set = razor_set_open(repo_filename);
42.174 + razor_set_open_files(set, "system-files.repo");
42.175 + if (set == NULL)
42.176 + return 1;
42.177 +
42.178 + pi = razor_package_iterator_create_for_file(set, argv[0]);
42.179 + while (razor_package_iterator_next(pi, &package,
42.180 + &name, &version, &arch))
42.181 + printf("%s-%s\n", name, version);
42.182 + razor_package_iterator_destroy(pi);
42.183 +
42.184 + razor_set_destroy(set);
42.185 +
42.186 + return 0;
42.187 +}
42.188 +
42.189 +static int
42.190 +command_list_package_files(int argc, const char *argv[])
42.191 +{
42.192 + struct razor_set *set;
42.193 +
42.194 + set = razor_set_open(repo_filename);
42.195 + razor_set_open_files(set, "system-files.repo");
42.196 + if (set == NULL)
42.197 + return 1;
42.198 + razor_set_list_package_files(set, argv[0]);
42.199 + razor_set_destroy(set);
42.200 +
42.201 + return 0;
42.202 +}
42.203 +
42.204 +static void
42.205 +list_packages_for_property(struct razor_set *set,
42.206 + struct razor_property *property)
42.207 +{
42.208 + struct razor_package_iterator *pi;
42.209 + struct razor_package *package;
42.210 + const char *name, *version, *arch;
42.211 +
42.212 + pi = razor_package_iterator_create_for_property(set, property);
42.213 + while (razor_package_iterator_next(pi, &package,
42.214 + &name, &version, &arch))
42.215 + printf("%s-%s.%s\n", name, version, arch);
42.216 + razor_package_iterator_destroy(pi);
42.217 +}
42.218 +
42.219 +static int
42.220 +list_property_packages(const char *ref_name,
42.221 + const char *ref_version,
42.222 + uint32_t type)
42.223 +{
42.224 + struct razor_set *set;
42.225 + struct razor_property *property;
42.226 + struct razor_property_iterator *pi;
42.227 + const char *name, *version;
42.228 + uint32_t flags;
42.229 +
42.230 + if (ref_name == NULL)
42.231 + return 0;
42.232 +
42.233 + set = razor_set_open(repo_filename);
42.234 + if (set == NULL)
42.235 + return 1;
42.236 +
42.237 + pi = razor_property_iterator_create(set, NULL);
42.238 + while (razor_property_iterator_next(pi, &property,
42.239 + &name, &flags, &version)) {
42.240 + if (strcmp(ref_name, name) != 0)
42.241 + continue;
42.242 + if (ref_version &&
42.243 + (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
42.244 + strcmp(ref_version, version) != 0)
42.245 + continue;
42.246 + if ((flags & RAZOR_PROPERTY_TYPE_MASK) != type)
42.247 + continue;
42.248 +
42.249 + list_packages_for_property(set, property);
42.250 + }
42.251 + razor_property_iterator_destroy(pi);
42.252 +
42.253 + return 0;
42.254 +}
42.255 +
42.256 +static int
42.257 +command_what_requires(int argc, const char *argv[])
42.258 +{
42.259 + return list_property_packages(argv[0], argv[1],
42.260 + RAZOR_PROPERTY_REQUIRES);
42.261 +}
42.262 +
42.263 +static int
42.264 +command_what_provides(int argc, const char *argv[])
42.265 +{
42.266 + return list_property_packages(argv[0], argv[1],
42.267 + RAZOR_PROPERTY_PROVIDES);
42.268 +}
42.269 +
42.270 +static int
42.271 +show_progress(void *clientp,
42.272 + double dltotal, double dlnow, double ultotal, double ulnow)
42.273 +{
42.274 + const char *file = clientp;
42.275 +
42.276 + if (!dlnow < dltotal)
42.277 + fprintf(stderr, "\rdownloading %s, %dkB/%dkB",
42.278 + file, (int) dlnow / 1024, (int) dltotal / 1024);
42.279 +
42.280 + return 0;
42.281 +}
42.282 +
42.283 +static int
42.284 +download_if_missing(const char *url, const char *file)
42.285 +{
42.286 + CURL *curl;
42.287 + struct stat buf;
42.288 + char error[256];
42.289 + FILE *fp;
42.290 + CURLcode res;
42.291 + long response;
42.292 +
42.293 + curl = curl_easy_init();
42.294 + if (curl == NULL)
42.295 + return 1;
42.296 +
42.297 + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error);
42.298 + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
42.299 + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, show_progress);
42.300 + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, file);
42.301 +
42.302 + if (stat(file, &buf) < 0) {
42.303 + fp = fopen(file, "w");
42.304 + if (fp == NULL) {
42.305 + fprintf(stderr,
42.306 + "failed to open %s for writing\n", file);
42.307 + return -1;
42.308 + }
42.309 + curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
42.310 + curl_easy_setopt(curl, CURLOPT_URL, url);
42.311 + res = curl_easy_perform(curl);
42.312 + fclose(fp);
42.313 + if (res != CURLE_OK) {
42.314 + fprintf(stderr, "curl error: %s\n", error);
42.315 + unlink(file);
42.316 + return -1;
42.317 + }
42.318 + res = curl_easy_getinfo(curl,
42.319 + CURLINFO_RESPONSE_CODE, &response);
42.320 + if (res != CURLE_OK) {
42.321 + fprintf(stderr, "curl error: %s\n", error);
42.322 + unlink(file);
42.323 + return -1;
42.324 + }
42.325 + if (response != 200) {
42.326 + fprintf(stderr, " - failed %ld\n", response);
42.327 + unlink(file);
42.328 + return -1;
42.329 + }
42.330 + fprintf(stderr, "\n");
42.331 + }
42.332 +
42.333 + curl_easy_cleanup(curl);
42.334 +
42.335 + return 0;
42.336 +}
42.337 +
42.338 +#define YUM_URL "http://download.fedora.redhat.com" \
42.339 + "/pub/fedora/linux/development/i386/os"
42.340 +
42.341 +static int
42.342 +command_import_yum(int argc, const char *argv[])
42.343 +{
42.344 + struct razor_set *set;
42.345 + char buffer[512];
42.346 +
42.347 + printf("downloading from %s.\n", yum_url);
42.348 + snprintf(buffer, sizeof buffer,
42.349 + "%s/repodata/primary.xml.gz", yum_url);
42.350 + if (download_if_missing(buffer, "primary.xml.gz") < 0)
42.351 + return -1;
42.352 + snprintf(buffer, sizeof buffer,
42.353 + "%s/repodata/filelists.xml.gz", yum_url);
42.354 + if (download_if_missing(buffer, "filelists.xml.gz") < 0)
42.355 + return -1;
42.356 +
42.357 + set = razor_set_create_from_yum();
42.358 + if (set == NULL)
42.359 + return 1;
42.360 + razor_set_write(set, rawhide_repo_filename, RAZOR_REPO_FILE_MAIN);
42.361 + razor_set_write(set, "rawhide-details.repo", RAZOR_REPO_FILE_DETAILS);
42.362 + razor_set_write(set, "rawhide-files.repo", RAZOR_REPO_FILE_FILES);
42.363 + razor_set_destroy(set);
42.364 + printf("wrote %s\n", rawhide_repo_filename);
42.365 +
42.366 + return 0;
42.367 +}
42.368 +
42.369 +static int
42.370 +command_import_rpmdb(int argc, const char *argv[])
42.371 +{
42.372 + struct razor_set *set;
42.373 +
42.374 + set = razor_set_create_from_rpmdb();
42.375 + if (set == NULL)
42.376 + return 1;
42.377 + razor_set_write(set, repo_filename, RAZOR_REPO_FILE_MAIN);
42.378 + razor_set_write(set, "system-details.repo", RAZOR_REPO_FILE_DETAILS);
42.379 + razor_set_write(set, "system-files.repo", RAZOR_REPO_FILE_FILES);
42.380 + razor_set_destroy(set);
42.381 + printf("wrote %s\n", repo_filename);
42.382 +
42.383 + return 0;
42.384 +}
42.385 +
42.386 +static int
42.387 +mark_packages_for_update(struct razor_transaction *trans,
42.388 + struct razor_set *set, const char *pattern)
42.389 +{
42.390 + struct razor_package_iterator *pi;
42.391 + struct razor_package *package;
42.392 + const char *name, *version, *arch;
42.393 + int matches = 0;
42.394 +
42.395 + pi = razor_package_iterator_create(set);
42.396 + while (razor_package_iterator_next(pi, &package,
42.397 + &name, &version, &arch)) {
42.398 + if (pattern && fnmatch(pattern, name, 0) == 0) {
42.399 + razor_transaction_update_package(trans, package);
42.400 + matches++;
42.401 + }
42.402 + }
42.403 + razor_package_iterator_destroy(pi);
42.404 +
42.405 + return matches;
42.406 +}
42.407 +
42.408 +static int
42.409 +mark_packages_for_removal(struct razor_transaction *trans,
42.410 + struct razor_set *set, const char *pattern)
42.411 +{
42.412 + struct razor_package_iterator *pi;
42.413 + struct razor_package *package;
42.414 + const char *name, *version, *arch;
42.415 + int matches = 0;
42.416 +
42.417 + pi = razor_package_iterator_create(set);
42.418 + while (razor_package_iterator_next(pi, &package,
42.419 + &name, &version, &arch)) {
42.420 + if (pattern && fnmatch(pattern, name, 0) == 0) {
42.421 + razor_transaction_remove_package(trans, package);
42.422 + matches++;
42.423 + }
42.424 + }
42.425 + razor_package_iterator_destroy(pi);
42.426 +
42.427 + return matches;
42.428 +}
42.429 +
42.430 +static int
42.431 +command_update(int argc, const char *argv[])
42.432 +{
42.433 + struct razor_set *set, *upstream;
42.434 + struct razor_transaction *trans;
42.435 + int i, errors;
42.436 +
42.437 + set = razor_set_open(repo_filename);
42.438 + upstream = razor_set_open(rawhide_repo_filename);
42.439 + if (set == NULL || upstream == NULL)
42.440 + return 1;
42.441 +
42.442 + trans = razor_transaction_create(set, upstream);
42.443 + if (argc == 0)
42.444 + razor_transaction_update_all(trans);
42.445 + for (i = 0; i < argc; i++) {
42.446 + if (mark_packages_for_update(trans, set, argv[i]) == 0) {
42.447 + fprintf(stderr, "no match for %s\n", argv[i]);
42.448 + return 1;
42.449 + }
42.450 + }
42.451 +
42.452 + errors = razor_transaction_resolve(trans);
42.453 + if (errors)
42.454 + return 1;
42.455 +
42.456 + set = razor_transaction_finish(trans);
42.457 + razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
42.458 + razor_set_destroy(set);
42.459 + razor_set_destroy(upstream);
42.460 + printf("wrote system-updated.repo\n");
42.461 +
42.462 + return 0;
42.463 +}
42.464 +
42.465 +static int
42.466 +command_remove(int argc, const char *argv[])
42.467 +{
42.468 + struct razor_set *set, *upstream;
42.469 + struct razor_transaction *trans;
42.470 + int i, errors;
42.471 +
42.472 + set = razor_set_open(repo_filename);
42.473 + if (set == NULL)
42.474 + return 1;
42.475 +
42.476 + upstream = razor_set_create();
42.477 + trans = razor_transaction_create(set, upstream);
42.478 + for (i = 0; i < argc; i++) {
42.479 + if (mark_packages_for_removal(trans, set, argv[i]) == 0) {
42.480 + fprintf(stderr, "no match for %s\n", argv[i]);
42.481 + return 1;
42.482 + }
42.483 + }
42.484 +
42.485 + errors = razor_transaction_resolve(trans);
42.486 + if (errors)
42.487 + return 1;
42.488 +
42.489 + set = razor_transaction_finish(trans);
42.490 + razor_set_write(set, updated_repo_filename, RAZOR_REPO_FILE_MAIN);
42.491 + razor_set_destroy(set);
42.492 + razor_set_destroy(upstream);
42.493 + printf("wrote system-updated.repo\n");
42.494 +
42.495 + return 0;
42.496 +}
42.497 +
42.498 +static void
42.499 +print_diff(const char *name,
42.500 + const char *old_version, const char *new_version, const char *arch,
42.501 + void *data)
42.502 +{
42.503 + if (old_version)
42.504 + printf("removing %s %s\n", name, old_version);
42.505 + else
42.506 + printf("install %s %s\n", name, new_version);
42.507 +}
42.508 +
42.509 +static int
42.510 +command_diff(int argc, const char *argv[])
42.511 +{
42.512 + struct razor_set *set, *updated;
42.513 +
42.514 + set = razor_set_open(repo_filename);
42.515 + updated = razor_set_open(updated_repo_filename);
42.516 + if (set == NULL || updated == NULL)
42.517 + return 1;
42.518 +
42.519 + razor_set_diff(set, updated, print_diff, NULL);
42.520 +
42.521 + razor_set_destroy(set);
42.522 + razor_set_destroy(updated);
42.523 +
42.524 + return 0;
42.525 +}
42.526 +
42.527 +static int
42.528 +command_import_rpms(int argc, const char *argv[])
42.529 +{
42.530 + DIR *dir;
42.531 + struct dirent *de;
42.532 + struct razor_importer *importer;
42.533 + struct razor_set *set;
42.534 + struct razor_rpm *rpm;
42.535 + int len;
42.536 + char filename[256];
42.537 + const char *dirname = argv[0];
42.538 +
42.539 + if (dirname == NULL) {
42.540 + fprintf(stderr, "usage: razor import-rpms DIR\n");
42.541 + return -1;
42.542 + }
42.543 +
42.544 + dir = opendir(dirname);
42.545 + if (dir == NULL) {
42.546 + fprintf(stderr, "couldn't read dir %s\n", dirname);
42.547 + return -1;
42.548 + }
42.549 +
42.550 + importer = razor_importer_new();
42.551 +
42.552 + while (de = readdir(dir), de != NULL) {
42.553 + len = strlen(de->d_name);
42.554 + if (len < 5 || strcmp(de->d_name + len - 4, ".rpm") != 0)
42.555 + continue;
42.556 + snprintf(filename, sizeof filename,
42.557 + "%s/%s", dirname, de->d_name);
42.558 + rpm = razor_rpm_open(filename);
42.559 + if (rpm == NULL) {
42.560 + fprintf(stderr,
42.561 + "failed to open rpm \"%s\"\n", filename);
42.562 + continue;
42.563 + }
42.564 + if (razor_importer_add_rpm(importer, rpm)) {
42.565 + fprintf(stderr, "couldn't import %s\n", filename);
42.566 + break;
42.567 + }
42.568 + razor_rpm_close(rpm);
42.569 + }
42.570 +
42.571 + if (de != NULL) {
42.572 + razor_importer_destroy(importer);
42.573 + return -1;
42.574 + }
42.575 +
42.576 + set = razor_importer_finish(importer);
42.577 +
42.578 + razor_set_write(set, repo_filename, RAZOR_REPO_FILE_MAIN);
42.579 + razor_set_destroy(set);
42.580 + printf("wrote %s\n", repo_filename);
42.581 +
42.582 + return 0;
42.583 +}
42.584 +
42.585 +static void
42.586 +download_package(const char *name,
42.587 + const char *old_version,
42.588 + const char *new_version,
42.589 + const char *arch,
42.590 + void *data)
42.591 +{
42.592 + char file[PATH_MAX], url[256];
42.593 + const char *v;
42.594 + int *errors = data;
42.595 +
42.596 + if (old_version)
42.597 + return;
42.598 +
42.599 + /* Skip epoch */
42.600 + v = strchr(new_version, ':');
42.601 + if (v != NULL)
42.602 + v = v + 1;
42.603 + else
42.604 + v = new_version;
42.605 +
42.606 + snprintf(url, sizeof url,
42.607 + "%s/Packages/%s-%s.%s.rpm", yum_url, name, v, arch);
42.608 + snprintf(file, sizeof file,
42.609 + "rpms/%s-%s.%s.rpm", name, v, arch);
42.610 + if (download_if_missing(url, file) < 0)
42.611 + (*errors)++;
42.612 +}
42.613 +
42.614 +static void
42.615 +install_package(const char *name,
42.616 + const char *old_version,
42.617 + const char *new_version,
42.618 + const char *arch,
42.619 + void *data)
42.620 +{
42.621 + const char *v, *root = data;
42.622 + char file[PATH_MAX];
42.623 + struct razor_rpm *rpm;
42.624 +
42.625 + if (old_version) {
42.626 + printf("removing %s %s not handled\n", name, old_version);
42.627 + return;
42.628 + }
42.629 +
42.630 + /* Skip epoch */
42.631 + v = strchr(new_version, ':');
42.632 + if (v != NULL)
42.633 + v = v + 1;
42.634 + else
42.635 + v = new_version;
42.636 +
42.637 + printf("install %s %s\n", name, v);
42.638 + snprintf(file, sizeof file, "rpms/%s-%s.%s.rpm", name, v, arch);
42.639 +
42.640 + rpm = razor_rpm_open(file);
42.641 + if (rpm == NULL) {
42.642 + fprintf(stderr, "failed to open rpm %s\n", file);
42.643 + return;
42.644 + }
42.645 + if (razor_rpm_install(rpm, root) < 0) {
42.646 + fprintf(stderr,
42.647 + "failed to install rpm %s\n", file);
42.648 + return;
42.649 + }
42.650 + razor_rpm_close(rpm);
42.651 +}
42.652 +
42.653 +static int
42.654 +command_install(int argc, const char *argv[])
42.655 +{
42.656 + struct razor_root *root;
42.657 + struct razor_set *upstream, *next;
42.658 + struct razor_transaction *trans;
42.659 + int i = 0, errors, dependencies = 1;
42.660 +
42.661 + if (i < argc && strcmp(argv[i], "--no-dependencies") == 0) {
42.662 + dependencies = 0;
42.663 + i++;
42.664 + }
42.665 +
42.666 + root = razor_root_open(install_root, RAZOR_ROOT_OPEN_WRITE);
42.667 + upstream = razor_set_open(rawhide_repo_filename);
42.668 + trans = razor_root_create_transaction(root, upstream);
42.669 +
42.670 + for (; i < argc; i++) {
42.671 + if (mark_packages_for_update(trans, upstream, argv[i]) == 0) {
42.672 + fprintf(stderr, "no package matched %s\n", argv[i]);
42.673 + razor_root_close(root);
42.674 + return 1;
42.675 + }
42.676 + }
42.677 +
42.678 + if (dependencies) {
42.679 + razor_transaction_resolve(trans);
42.680 + if (razor_transaction_describe(trans) > 0) {
42.681 + razor_root_close(root);
42.682 + return 1;
42.683 + }
42.684 + }
42.685 +
42.686 + next = razor_transaction_finish(trans);
42.687 +
42.688 + razor_root_update(root, next);
42.689 +
42.690 + if (mkdir("rpms", 0777) && errno != EEXIST) {
42.691 + fprintf(stderr, "failed to create rpms directory.\n");
42.692 + razor_root_close(root);
42.693 + return 1;
42.694 + }
42.695 +
42.696 + errors = 0;
42.697 + razor_root_diff(root, download_package, &errors);
42.698 + if (errors > 0) {
42.699 + fprintf(stderr, "failed to download %d packages\n", errors);
42.700 + razor_root_close(root);
42.701 + return 1;
42.702 + }
42.703 +
42.704 + /* FIXME: We need to figure out the right install order here,
42.705 + * so the post and pre scripts can run. */
42.706 + razor_root_diff(root, install_package, (void *) install_root);
42.707 +
42.708 + razor_set_destroy(next);
42.709 + razor_set_destroy(upstream);
42.710 +
42.711 + return razor_root_commit(root);
42.712 +}
42.713 +
42.714 +static int
42.715 +command_init(int argc, const char *argv[])
42.716 +{
42.717 + return razor_root_create(install_root);
42.718 +}
42.719 +
42.720 +static int
42.721 +command_download(int argc, const char *argv[])
42.722 +{
42.723 + struct razor_set *set;
42.724 + struct razor_package_iterator *pi;
42.725 + struct razor_package *package;
42.726 + const char *pattern = argv[0], *name, *version, *arch;
42.727 + char url[256], file[256];
42.728 + int matches = 0;
42.729 +
42.730 + if (mkdir("rpms", 0777) && errno != EEXIST) {
42.731 + fprintf(stderr, "failed to create rpms directory.\n");
42.732 + return 1;
42.733 + }
42.734 +
42.735 + set = razor_set_open(rawhide_repo_filename);
42.736 + pi = razor_package_iterator_create(set);
42.737 + while (razor_package_iterator_next(pi, &package,
42.738 + &name, &version, &arch)) {
42.739 + if (pattern && fnmatch(pattern, name, 0) != 0)
42.740 + continue;
42.741 +
42.742 + matches++;
42.743 + snprintf(url, sizeof url,
42.744 + "%s/Packages/%s-%s.%s.rpm",
42.745 + yum_url, name, version, arch);
42.746 + snprintf(file, sizeof file,
42.747 + "rpms/%s-%s.%s.rpm", name, version, arch);
42.748 + download_if_missing(url, file);
42.749 + }
42.750 + razor_package_iterator_destroy(pi);
42.751 + razor_set_destroy(set);
42.752 +
42.753 + if (matches == 0)
42.754 + fprintf(stderr, "no packages matched \"%s\"\n", pattern);
42.755 + else if (matches == 1)
42.756 + fprintf(stderr, "downloaded 1 package\n");
42.757 + else
42.758 + fprintf(stderr, "downloaded %d packages\n", matches);
42.759 +
42.760 + return 0;
42.761 +}
42.762 +
42.763 +static int
42.764 +command_info(int argc, const char *argv[])
42.765 +{
42.766 + struct razor_set *set;
42.767 + struct razor_package_iterator *pi;
42.768 + struct razor_package *package;
42.769 + const char *pattern = argv[0], *name, *version, *arch;
42.770 + const char *summary, *description, *url, *license;
42.771 +
42.772 + set = razor_set_open(repo_filename);
42.773 + razor_set_open_details(set, "system-details.repo");
42.774 + pi = razor_package_iterator_create(set);
42.775 + while (razor_package_iterator_next(pi, &package,
42.776 + &name, &version, &arch)) {
42.777 + if (pattern && fnmatch(pattern, name, 0) != 0)
42.778 + continue;
42.779 +
42.780 + razor_package_get_details (set, package, &summary, &description,
42.781 + &url, &license);
42.782 +
42.783 + printf ("Name: %s\n", name);
42.784 + printf ("Arch: %s\n", arch);
42.785 + printf ("Version: %s\n", version);
42.786 + printf ("URL: %s\n", url);
42.787 + printf ("License: %s\n", license);
42.788 + printf ("Summary: %s\n", summary);
42.789 + printf ("Description:\n");
42.790 + printf ("%s\n", description);
42.791 + printf ("\n");
42.792 + }
42.793 + razor_package_iterator_destroy(pi);
42.794 + razor_set_destroy(set);
42.795 +
42.796 + return 0;
42.797 +}
42.798 +
42.799 +static struct {
42.800 + const char *name;
42.801 + const char *description;
42.802 + int (*func)(int argc, const char *argv[]);
42.803 +} razor_commands[] = {
42.804 + { "list", "list all packages", command_list },
42.805 + { "list-requires", "list all requires for the given package", command_list_requires },
42.806 + { "list-provides", "list all provides for the given package", command_list_provides },
42.807 + { "list-obsoletes", "list all obsoletes for the given package", command_list_obsoletes },
42.808 + { "list-conflicts", "list all conflicts for the given package", command_list_conflicts },
42.809 + { "list-files", "list files for package set", command_list_files },
42.810 + { "list-file-packages", "list packages owning file", command_list_file_packages },
42.811 + { "list-package-files", "list files in package", command_list_package_files },
42.812 + { "what-requires", "list the packages that have the given requires", command_what_requires },
42.813 + { "what-provides", "list the packages that have the given provides", command_what_provides },
42.814 + { "import-yum", "import yum metadata files", command_import_yum },
42.815 + { "import-rpmdb", "import the system rpm database", command_import_rpmdb },
42.816 + { "import-rpms", "import rpms from the given directory", command_import_rpms },
42.817 + { "update", "update all or specified packages", command_update },
42.818 + { "remove", "remove specified packages", command_remove },
42.819 + { "diff", "show diff between two package sets", command_diff },
42.820 + { "install", "install rpm", command_install },
42.821 + { "init", "init razor root", command_init },
42.822 + { "download", "download packages", command_download },
42.823 + { "info", "display package details", command_info }
42.824 +};
42.825 +
42.826 +static int
42.827 +usage(void)
42.828 +{
42.829 + int i;
42.830 +
42.831 + printf("usage:\n");
42.832 + for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
42.833 + printf(" %-20s%s\n",
42.834 + razor_commands[i].name, razor_commands[i].description);
42.835 +
42.836 + return 1;
42.837 +}
42.838 +
42.839 +int
42.840 +main(int argc, const char *argv[])
42.841 +{
42.842 + char *repo;
42.843 + int i;
42.844 +
42.845 + repo = getenv("RAZOR_REPO");
42.846 + if (repo != NULL)
42.847 + repo_filename = repo;
42.848 +
42.849 + yum_url = getenv("YUM_URL");
42.850 + if (yum_url == NULL)
42.851 + yum_url = YUM_URL;
42.852 +
42.853 + if (argc < 2)
42.854 + return usage();
42.855 +
42.856 + for (i = 0; i < ARRAY_SIZE(razor_commands); i++)
42.857 + if (strcmp(razor_commands[i].name, argv[1]) == 0)
42.858 + return razor_commands[i].func(argc - 2, argv + 2);
42.859 +
42.860 + return usage();
42.861 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
43.2 +++ b/src/rpm.c Fri Jun 20 19:04:47 2008 -0400
43.3 @@ -0,0 +1,895 @@
43.4 +/*
43.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
43.6 + * Copyright (C) 2008 Red Hat, Inc
43.7 + *
43.8 + * This program is free software; you can redistribute it and/or modify
43.9 + * it under the terms of the GNU General Public License as published by
43.10 + * the Free Software Foundation; either version 2 of the License, or
43.11 + * (at your option) any later version.
43.12 + *
43.13 + * This program is distributed in the hope that it will be useful,
43.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
43.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
43.16 + * GNU General Public License for more details.
43.17 + *
43.18 + * You should have received a copy of the GNU General Public License along
43.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
43.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43.21 + */
43.22 +
43.23 +#include <stdlib.h>
43.24 +#include <string.h>
43.25 +#include <stdio.h>
43.26 +#include <stdint.h>
43.27 +#include <dirent.h>
43.28 +#include "razor.h"
43.29 +
43.30 +enum option_type {
43.31 + OPTION_LAST,
43.32 + OPTION_GROUP,
43.33 + OPTION_BOOL,
43.34 + OPTION_STRING
43.35 +};
43.36 +
43.37 +struct option {
43.38 + enum option_type type;
43.39 + const char *name;
43.40 + char short_name;
43.41 + const char *arg_name;
43.42 + const char *description;
43.43 + void *data;
43.44 +};
43.45 +
43.46 +/* A note about all these options: rpm allows options to mean
43.47 + * different things depending on what other options are present on the
43.48 + * command line. For example, if -q or --query is present, -i no
43.49 + * longer means install, but info. The way we handle this is by
43.50 + * setting all the options that may match (ie if -i is given we set
43.51 + * install and info), and then look at the relevent one depending on
43.52 + * what else in on the command line. */
43.53 +
43.54 +static int option_all, option_whatrequires, option_whatprovides;
43.55 +static int option_package;
43.56 +
43.57 +static const struct option query_options[] = {
43.58 + { OPTION_BOOL, "configfiles", 'c', NULL, "list all configuration files", NULL },
43.59 + { OPTION_BOOL, "docfiles", 'd', NULL, "list all documentation files", NULL },
43.60 + { OPTION_BOOL, "dump", 0, NULL, "dump basic file information", NULL },
43.61 + { OPTION_BOOL, "list", 0, NULL, "list files in package", NULL },
43.62 + { OPTION_STRING, "queryformat", 0, "QUERYFORMAT", "use the following query format", NULL },
43.63 + { OPTION_BOOL, "state", 's', NULL, "display the states of the listed files", NULL },
43.64 + { OPTION_BOOL, "all", 'a', NULL, "query/verify all packages", &option_all },
43.65 + { OPTION_BOOL, "file", 'f', NULL, "query/verify package(s) owning file", NULL },
43.66 + { OPTION_BOOL, "group", 'g', NULL, "query/verify package(s) in group", NULL },
43.67 + { OPTION_BOOL, "package", 'p', NULL, "query/verify a package file", &option_package },
43.68 + { OPTION_BOOL, "ftswalk", 'W', NULL, "query/verify package(s) from TOP file tree walk", NULL },
43.69 + { OPTION_BOOL, "pkgid", 0, NULL, "query/verify package(s) with package identifier", NULL },
43.70 + { OPTION_BOOL, "hdrid", 0, NULL, "query/verify package(s) with header identifier", NULL },
43.71 + { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL },
43.72 + { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL, },
43.73 + { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL },
43.74 + { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires },
43.75 + { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides },
43.76 + { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL },
43.77 + { }
43.78 +};
43.79 +
43.80 +static int option_nodeps;
43.81 +
43.82 +static const struct option verify_options[] = {
43.83 + { OPTION_BOOL, "nomd5", 0, NULL, "don't verify MD5 digest of files", NULL },
43.84 + { OPTION_BOOL, "nofiles", 0, NULL, "don't verify files in package", NULL },
43.85 + { OPTION_BOOL, "nodeps", 0, NULL, "don't verify package dependencies", &option_nodeps },
43.86 + { OPTION_BOOL, "noscript", 0, NULL, "don't execute verify script(s)", NULL, },
43.87 + { OPTION_BOOL, "all", 'a', NULL, "query/verify all packages", &option_all },
43.88 + { OPTION_BOOL, "file", 'f', NULL, "query/verify package(s) owning file", NULL },
43.89 + { OPTION_BOOL, "group", 'g', NULL, "query/verify package(s) in group", NULL },
43.90 + { OPTION_BOOL, "package", 'p', NULL, "query/verify a package file", &option_package },
43.91 + { OPTION_BOOL, "ftswalk", 'W', NULL, "query/verify package(s) from TOP file tree walk", NULL },
43.92 + { OPTION_BOOL, "pkgid", 0, NULL, "query/verify package(s) with package identifier", NULL },
43.93 + { OPTION_BOOL, "hdrid", 0, NULL, "query/verify package(s) with header identifier", NULL },
43.94 + { OPTION_BOOL, "fileid", 0, NULL, "query/verify package(s) with file identifier", NULL },
43.95 + { OPTION_BOOL, "specfile", 0, NULL, "query a spec file", NULL },
43.96 + { OPTION_BOOL, "triggeredby", 0, NULL, "query the package(s) triggered by the package", NULL },
43.97 + { OPTION_BOOL, "whatrequires", 0, NULL, "query/verify the package(s) which require a dependency", &option_whatrequires },
43.98 + { OPTION_BOOL, "whatprovides", 0, NULL, "query/verify the package(s) which provide a dependency", &option_whatprovides },
43.99 + { OPTION_BOOL, "nomanifest", 0, NULL, "do not process non-package files as manifests", NULL },
43.100 + { }
43.101 +};
43.102 +
43.103 +static const struct option ftw_options[] = {
43.104 + { OPTION_BOOL, "comfollow", 0, NULL, "FTS_COMFOLLOW: follow command line symlinks", NULL },
43.105 + { OPTION_BOOL, "logical", 0, NULL, "FTS_LOGICAL: logical walk", NULL },
43.106 + { OPTION_BOOL, "nochdir", 0, NULL, "FTS_NOCHDIR: don't change directories", NULL },
43.107 + { OPTION_BOOL, "nostat", 0, NULL, "FTS_NOSTAT: don't get stat info", NULL },
43.108 + { OPTION_BOOL, "physical", 0, NULL, "FTS_PHYSICAL: physical walk", NULL },
43.109 + { OPTION_BOOL, "seedot", 0, NULL, "FTS_SEEDOT: return dot and dot-dot", NULL },
43.110 + { OPTION_BOOL, "xdev", 0, NULL, "FTS_XDEV: don't cross devices", NULL },
43.111 + { OPTION_BOOL, "whiteout", 0, NULL, "FTS_WHITEOUT: return whiteout information", NULL },
43.112 + { }
43.113 +};
43.114 +
43.115 +static const struct option signature_options[] = {
43.116 + { OPTION_BOOL, "addsign", 0, NULL, "sign package(s) (identical to --resign)", NULL, },
43.117 + { OPTION_BOOL, "checksig", 'K', NULL, "verify package signature(s)", NULL, },
43.118 + { OPTION_BOOL, "delsign", 0, NULL, "delete package signatures", NULL, },
43.119 + { OPTION_BOOL, "import", 0, NULL, "import an armored public key", NULL, },
43.120 + { OPTION_BOOL, "resign", 0, NULL, "sign package(s) (identical to --addsign)", NULL, },
43.121 + { OPTION_BOOL, "nodigest", 0, NULL, "don't verify package digest(s)", NULL, },
43.122 + { OPTION_BOOL, "nosignature", 0, NULL, "don't verify package signature(s)", NULL },
43.123 + { }
43.124 +};
43.125 +
43.126 +static int option_initdb;
43.127 +
43.128 +static const struct option database_options[] = {
43.129 + { OPTION_BOOL, "initdb", 0, NULL, "initialize database", &option_initdb },
43.130 + { OPTION_BOOL, "rebuilddb", 0, NULL, "rebuild database inverted lists from installed package headers", NULL },
43.131 + { }
43.132 +};
43.133 +
43.134 +static int option_erase, option_install, option_upgrade, option_justdb;
43.135 +static int option_test;
43.136 +
43.137 +static const struct option install_options[] = {
43.138 + { OPTION_BOOL, "aid", 0, NULL, "add suggested packages to transaction", NULL, },
43.139 + { OPTION_BOOL, "allfiles", 0, NULL, "install all files, even configurations which might otherwise be skipped", NULL, },
43.140 + { OPTION_BOOL, "allmatches", 0, NULL, "remove all packages which match <package> (normally an error is generated if <package> specified multiple packages)", NULL, },
43.141 + { OPTION_BOOL, "badreloc", 0, NULL, "relocate files in non-relocatable package", NULL },
43.142 + { OPTION_BOOL, "erase", 'e', "<package>", "erase (uninstall) package", &option_erase },
43.143 + { OPTION_BOOL, "excludedocs", 0, NULL, "do not install documentation", NULL, },
43.144 + { OPTION_BOOL, "excludepath", 0, "<path>", "skip files with leading component <path> ", NULL, },
43.145 + { OPTION_BOOL, "fileconflicts", 0, NULL, "detect file conflicts between packages", NULL, },
43.146 + { OPTION_BOOL, "force", 0, NULL, "short hand for --replacepkgs --replacefiles", NULL },
43.147 + { OPTION_BOOL, "freshen", 'F', "<packagefile>+", "upgrade package(s) if already installed", NULL },
43.148 + { OPTION_BOOL, "hash", 'h', NULL, "print hash marks as package installs (good with -v)", NULL },
43.149 + { OPTION_BOOL, "ignorearch", 0, NULL, "don't verify package architecture", NULL, },
43.150 + { OPTION_BOOL, "ignoreos", 0, NULL, "don't verify package operating system", NULL, },
43.151 + { OPTION_BOOL, "ignoresize", 0, NULL, "don't check disk space before installing", NULL },
43.152 + { OPTION_BOOL, "install", 'i', NULL, "install package(s)", &option_install },
43.153 + { OPTION_BOOL, "justdb", 0, NULL, "update the database, but do not modify the filesystem", &option_justdb, },
43.154 + { OPTION_BOOL, "nodeps", 0, NULL, "do not verify package dependencies", &option_nodeps, },
43.155 + { OPTION_BOOL, "nomd5", 0, NULL, "don't verify MD5 digest of files", NULL, },
43.156 + { OPTION_BOOL, "nocontexts", 0, NULL, "don't install file security contexts", NULL, },
43.157 + { OPTION_BOOL, "noorder", 0, NULL, "do not reorder package installation to satisfy dependencies", NULL, },
43.158 + { OPTION_BOOL, "nosuggest", 0, NULL, "do not suggest missing dependency resolution(s)", NULL, },
43.159 + { OPTION_BOOL, "noscripts", 0, NULL, "do not execute package scriptlet(s)", NULL, },
43.160 + { OPTION_BOOL, "notriggers", 0, NULL, "do not execute any scriptlet(s) triggered by this package", NULL, },
43.161 + { OPTION_BOOL, "oldpackage", 0, NULL, "upgrade to an old version of the package (--force on upgrades does this automatically)", NULL },
43.162 + { OPTION_BOOL, "percent", 0, NULL, "print percentages as package installs", NULL, },
43.163 + { OPTION_STRING, "prefix", 0, "<dir>", "relocate the package to <dir>, if relocatable", NULL, },
43.164 + { OPTION_STRING, "relocate", 0, "<old>=<new>", "relocate files from path <old> to <new>", NULL, },
43.165 + { OPTION_BOOL, "repackage", 0, NULL, "save erased package files by repackaging", NULL, },
43.166 + { OPTION_BOOL, "replacefiles", 0, NULL, "ignore file conflicts between packages", NULL, },
43.167 + { OPTION_BOOL, "replacepkgs", 0, NULL, "reinstall if the package is already present", NULL, },
43.168 + { OPTION_BOOL, "test", 0, NULL, "don't install, but tell if it would work or not", &option_test },
43.169 + { OPTION_BOOL, "upgrade", 'U', "<packagefile>+", "upgrade package(s)", &option_upgrade },
43.170 + { }
43.171 +};
43.172 +
43.173 +static int option_version;
43.174 +static const char *option_root = "install";
43.175 +
43.176 +static const struct option common_options[] = {
43.177 + { OPTION_STRING, "define", 'D', "MACRO EXPR", "define MACRO with value EXPR", NULL, },
43.178 + { OPTION_STRING, "eval", 'E', "EXPR", "print macro expansion of EXPR", NULL },
43.179 + { OPTION_STRING, "macros", 0, "<FILE:...>", "read <FILE:...> instead of default file(s)", NULL },
43.180 + { OPTION_BOOL, "nodigest", 0, NULL, "don't verify package digest(s)", NULL, },
43.181 + { OPTION_BOOL, "nosignature", 0, NULL, "don't verify package signature(s)", NULL, },
43.182 + { OPTION_STRING, "rcfile", 0, "<FILE:...>", "read <FILE:...> instead of default file(s)", NULL },
43.183 + { OPTION_STRING, "root", 'r', "ROOT", "use ROOT as top level directory (default: \"/\")", &option_root },
43.184 + { OPTION_BOOL, "querytags", 0, NULL, "display known query tags", NULL, },
43.185 + { OPTION_BOOL, "showrc", 0, NULL, "display final rpmrc and macro configuration", NULL, },
43.186 + { OPTION_BOOL, "quiet", 0, NULL, "provide less detailed output", NULL },
43.187 + { OPTION_BOOL, "verbose", 'v', NULL, "provide more detailed output", NULL },
43.188 + { OPTION_BOOL, "version", 0, NULL, "print the version of rpm being used", &option_version },
43.189 + { }
43.190 +};
43.191 +
43.192 +static int option_conflicts, option_obsoletes, option_requires;
43.193 +static int option_provides, option_info, option_changelog;
43.194 +
43.195 +static const struct option alias_options[] = {
43.196 + { OPTION_BOOL, "scripts", 0, NULL, "list install/erase scriptlets from package(s)", NULL, },
43.197 + { OPTION_BOOL, "setperms", 0, NULL, "set permissions of files in a package", NULL, },
43.198 + { OPTION_BOOL, "setugids", 0, NULL, "set user/group ownership of files in a package", NULL, },
43.199 + { OPTION_BOOL, "conflicts", 0, NULL, "list capabilities this package conflicts with", &option_conflicts, },
43.200 + { OPTION_BOOL, "obsoletes", 0, NULL, "list other packages removed by installing this package", &option_obsoletes, },
43.201 + { OPTION_BOOL, "provides", 0, NULL, "list capabilities that this package provides", &option_provides, },
43.202 + { OPTION_BOOL, "requires", 0, NULL, "list capabilities required by package(s)", &option_requires, },
43.203 + { OPTION_BOOL, "info", 'i', NULL, "list descriptive information from package(s)", &option_info, },
43.204 + { OPTION_BOOL, "changelog", 0, NULL, "list change logs for this package", &option_changelog, },
43.205 + { OPTION_BOOL, "xml", 0, NULL, "list metadata in xml", NULL, },
43.206 + { OPTION_BOOL, "triggers", 0, NULL, "list trigger scriptlets from package(s)", NULL, },
43.207 + { OPTION_BOOL, "last", 0, NULL, "list package(s) by install time, most recent first", NULL, },
43.208 + { OPTION_BOOL, "dupes", 0, NULL, "list duplicated packages", NULL, },
43.209 + { OPTION_BOOL, "filesbypkg", 0, NULL, "list all files from each package", NULL, },
43.210 + { OPTION_BOOL, "fileclass", 0, NULL, "list file names with classes", NULL, },
43.211 + { OPTION_BOOL, "filecolor", 0, NULL, "list file names with colors", NULL, },
43.212 + { OPTION_BOOL, "filecontext", 0, NULL, "list file names with security context from header", NULL, },
43.213 + { OPTION_BOOL, "fscontext", 0, NULL, "list file names with security context from file system", NULL, },
43.214 + { OPTION_BOOL, "recontext", 0, NULL, "list file names with security context from policy RE", NULL, },
43.215 + { OPTION_BOOL, "fileprovide", 0, NULL, "list file names with provides", NULL, },
43.216 + { OPTION_BOOL, "filerequire", 0, NULL, "list file names with requires", NULL, },
43.217 + { OPTION_BOOL, "redhatprovides", 0, NULL, "find package name that contains a provided capability (needs rpmdb-redhat package installed)", NULL, },
43.218 + { OPTION_BOOL, "redhatrequires", 0, NULL, "find package name that contains a required capability (needs rpmdb-redhat package installed)", NULL, },
43.219 + { OPTION_STRING, "buildpolicy", 0, "<policy>", "set buildroot <policy> (e.g. compress man pages)", NULL, },
43.220 + { OPTION_BOOL, "with", 0, "<option>", "enable configure <option> for build", NULL, },
43.221 + { OPTION_BOOL, "without", 0, "<option>", "disable configure <option> for build", NULL },
43.222 + { }
43.223 +};
43.224 +
43.225 +static int option_help, option_usage;
43.226 +
43.227 +static const struct option help_options[] = {
43.228 + { OPTION_BOOL, "help", '?', NULL, "Show this help message", &option_help },
43.229 + { OPTION_BOOL, "usage", 0, NULL, "Display brief usage message", &option_usage},
43.230 + { }
43.231 +};
43.232 +
43.233 +static int option_query, option_verify;
43.234 +
43.235 +static const struct option rpm_options[] = {
43.236 + { OPTION_BOOL, "query", 'q', NULL, "Query rpm database", &option_query },
43.237 + { OPTION_BOOL, "verify", 'V', NULL, "Verify rpm database", &option_verify },
43.238 + { OPTION_GROUP, NULL, 0, NULL, "Query options (with -q or --query):", &query_options },
43.239 + { OPTION_GROUP, NULL, 0, NULL, "Verify options (with -V or --verify):", &verify_options },
43.240 + { OPTION_GROUP, NULL, 0, NULL, "File tree walk options (with --ftswalk):", &ftw_options },
43.241 + { OPTION_GROUP, NULL, 0, NULL, "Signature options:", &signature_options },
43.242 + { OPTION_GROUP, NULL, 0, NULL, "Database options:", &database_options },
43.243 + { OPTION_GROUP, NULL, 0, NULL, "Install/Upgrade/Erase options:", &install_options },
43.244 + { OPTION_GROUP, NULL, 0, NULL, "Common options for all rpm modes and executables:", &common_options },
43.245 + { OPTION_GROUP, NULL, 0, NULL, "Options implemented via popt alias/exec:", &alias_options },
43.246 + { OPTION_GROUP, NULL, 0, NULL, "Help options", &help_options },
43.247 + { }
43.248 +};
43.249 +
43.250 +static const char system_repo_filename[] = "system.repo";
43.251 +static const char *repo_filename = system_repo_filename;
43.252 +
43.253 +static void
43.254 +command_initdb(int argc, const char *argv[])
43.255 +{
43.256 + razor_root_create(option_root);
43.257 +}
43.258 +
43.259 +static struct razor_property *
43.260 +add_property_packages(struct razor_set *set,
43.261 + struct razor_package_query *query,
43.262 + const char *ref_name,
43.263 + const char *ref_version,
43.264 + uint32_t ref_type)
43.265 +{
43.266 + struct razor_property *property;
43.267 + struct razor_property_iterator *pi;
43.268 + struct razor_package_iterator *pkgi;
43.269 + const char *name, *version;
43.270 + uint32_t flags;
43.271 +
43.272 + pi = razor_property_iterator_create(set, NULL);
43.273 + while (razor_property_iterator_next(pi, &property, &name,
43.274 + &flags, &version)) {
43.275 + if (strcmp(ref_name, name) != 0)
43.276 + continue;
43.277 + if (ref_version &&
43.278 + (flags & RAZOR_PROPERTY_RELATION_MASK) == RAZOR_PROPERTY_EQUAL &&
43.279 + strcmp(ref_version, version) != 0)
43.280 + continue;
43.281 + if ((flags & RAZOR_PROPERTY_TYPE_MASK) != ref_type)
43.282 + continue;
43.283 +
43.284 + pkgi = razor_package_iterator_create_for_property(set,
43.285 + property);
43.286 + razor_package_query_add_iterator(query, pkgi);
43.287 + razor_package_iterator_destroy(pkgi);
43.288 + }
43.289 + razor_property_iterator_destroy(pi);
43.290 +
43.291 + return property;
43.292 +}
43.293 +
43.294 +static int
43.295 +strcmpp(const void *p1, const void *p2)
43.296 +{
43.297 + return strcmp(*(char * const *) p1, *(char * const *) p2);
43.298 +}
43.299 +
43.300 +static void
43.301 +add_command_line_packages(struct razor_set *set,
43.302 + struct razor_package_query *query,
43.303 + int argc, const char **argv)
43.304 +{
43.305 + struct razor_package *package;
43.306 + struct razor_package_iterator *pi;
43.307 + const char *name, *version, *arch;
43.308 + int i, cmp, errors;
43.309 +
43.310 + qsort(argv, argc, sizeof(*argv), strcmpp);
43.311 + i = 0;
43.312 + errors = 0;
43.313 +
43.314 + pi = razor_package_iterator_create(set);
43.315 +
43.316 + while (razor_package_iterator_next(pi, &package,
43.317 + &name, &version, &arch)) {
43.318 + while (cmp = strcmp(argv[i], name), cmp < 0 && i < argc) {
43.319 + fprintf(stderr, "error: package %s is not installed\n",
43.320 + argv[i]);
43.321 + errors++;
43.322 + i++;
43.323 + }
43.324 +
43.325 + if (cmp == 0) {
43.326 + razor_package_query_add_package(query, package);
43.327 + i++;
43.328 + }
43.329 + }
43.330 +
43.331 + razor_package_iterator_destroy(pi);
43.332 +
43.333 + if (errors)
43.334 + exit(1);
43.335 +}
43.336 +
43.337 +static struct razor_package_iterator *
43.338 +get_query_packages(struct razor_set *set, int argc, const char *argv[])
43.339 +{
43.340 + struct razor_package_query *query;
43.341 + struct razor_package_iterator *pi;
43.342 + int i;
43.343 +
43.344 + if (option_all + option_whatprovides + option_whatrequires > 1) {
43.345 + printf("only one type of query/verify "
43.346 + "may be performed at a time\n");
43.347 + exit(1);
43.348 + }
43.349 +
43.350 + query = razor_package_query_create(set);
43.351 +
43.352 + if (option_all) {
43.353 + pi = razor_package_iterator_create(set);
43.354 + razor_package_query_add_iterator(query, pi);
43.355 + razor_package_iterator_destroy(pi);
43.356 + } else if (option_whatrequires) {
43.357 + for (i = 0; i < argc; i++)
43.358 + add_property_packages(set, query,
43.359 + argv[i], NULL,
43.360 + RAZOR_PROPERTY_REQUIRES);
43.361 + } else if (option_whatprovides) {
43.362 + for (i = 0; i < argc; i++)
43.363 + add_property_packages(set, query,
43.364 + argv[i], NULL,
43.365 + RAZOR_PROPERTY_PROVIDES);
43.366 + } else if (argc > 0) {
43.367 + add_command_line_packages(set, query, argc, argv);
43.368 + } else {
43.369 + printf("no arguments given for query/verify\n");
43.370 + exit(1);
43.371 + }
43.372 +
43.373 + return razor_package_query_finish(query);
43.374 +}
43.375 +
43.376 +static void
43.377 +print_package_properties(struct razor_set *set,
43.378 + struct razor_package *package,
43.379 + uint32_t ref_type)
43.380 +{
43.381 + struct razor_property *property;
43.382 + struct razor_property_iterator *pi;
43.383 + const char *name, *version;
43.384 + uint32_t flags;
43.385 +
43.386 + pi = razor_property_iterator_create(set, package);
43.387 + while (razor_property_iterator_next(pi, &property,
43.388 + &name, &flags, &version)) {
43.389 + if ((flags & RAZOR_PROPERTY_TYPE_MASK) != ref_type)
43.390 + continue;
43.391 + if (version[0] == '\0')
43.392 + printf("%s\n", name);
43.393 + else
43.394 + printf("%s %s %s\n", name,
43.395 + razor_property_relation_to_string(property),
43.396 + version);
43.397 + }
43.398 + razor_property_iterator_destroy(pi);
43.399 +}
43.400 +
43.401 +static void
43.402 +print_package_info(struct razor_set *set, struct razor_package *package)
43.403 +{
43.404 + printf("FIXME: Package info not tracked.\n");
43.405 +}
43.406 +
43.407 +static void
43.408 +print_package_changelog(struct razor_set *set, struct razor_package *package)
43.409 +{
43.410 + printf("FIXME: Package changelog not tracked.\n");
43.411 +}
43.412 +
43.413 +static struct razor_set *
43.414 +create_set_from_command_line(int argc, const char *argv[])
43.415 +{
43.416 + struct razor_importer *importer;
43.417 + struct razor_rpm *rpm;
43.418 + int i;
43.419 +
43.420 + importer = razor_importer_new();
43.421 +
43.422 + for (i = 0; i < argc; i++) {
43.423 + rpm = razor_rpm_open(argv[i]);
43.424 + if (rpm == NULL)
43.425 + continue;
43.426 + if (razor_importer_add_rpm(importer, rpm))
43.427 + printf("couldn't import %s\n", argv[i]);
43.428 +
43.429 + razor_rpm_close(rpm);
43.430 + }
43.431 +
43.432 + return razor_importer_finish(importer);
43.433 +}
43.434 +
43.435 +static void
43.436 +command_query(int argc, const char *argv[])
43.437 +{
43.438 + struct razor_set *set;
43.439 + struct razor_package_iterator *pi;
43.440 + struct razor_package *package;
43.441 + const char *name, *version, *arch;
43.442 +
43.443 + if (option_package) {
43.444 + set = create_set_from_command_line(argc, argv);
43.445 + argc = 0;
43.446 + option_all = 1;
43.447 + } else {
43.448 + set = razor_root_open_read_only(option_root);
43.449 + }
43.450 +
43.451 + pi = get_query_packages(set, argc, argv);
43.452 +
43.453 + while (razor_package_iterator_next(pi, &package,
43.454 + &name, &version, &arch)) {
43.455 + if (option_conflicts)
43.456 + print_package_properties(set, package,
43.457 + RAZOR_PROPERTY_CONFLICTS);
43.458 + if (option_obsoletes)
43.459 + print_package_properties(set, package,
43.460 + RAZOR_PROPERTY_OBSOLETES);
43.461 + if (option_requires)
43.462 + print_package_properties(set, package,
43.463 + RAZOR_PROPERTY_REQUIRES);
43.464 + if (option_provides)
43.465 + print_package_properties(set, package,
43.466 + RAZOR_PROPERTY_PROVIDES);
43.467 + if (option_info)
43.468 + print_package_info(set, package);
43.469 + if (option_changelog)
43.470 + print_package_changelog(set, package);
43.471 +
43.472 + if (option_conflicts + option_obsoletes +
43.473 + option_requires + option_provides +
43.474 + option_info + option_changelog == 0)
43.475 + printf("%s-%s.%s\n", name, version, arch);
43.476 + }
43.477 +
43.478 + razor_package_iterator_destroy(pi);
43.479 +
43.480 + razor_set_destroy(set);
43.481 +
43.482 + return;
43.483 +}
43.484 +
43.485 +static void
43.486 +command_verify(int argc, const char *argv[])
43.487 +{
43.488 + struct razor_set *set;
43.489 + struct razor_package_iterator *pi;
43.490 + struct razor_package *package;
43.491 + const char *name, *version, *arch;
43.492 +
43.493 + if (option_package) {
43.494 + set = create_set_from_command_line(argc, argv);
43.495 + argc = 0;
43.496 + option_all = 1;
43.497 + } else {
43.498 + set = razor_root_open_read_only(option_root);
43.499 + }
43.500 +
43.501 + pi = get_query_packages(set, argc, argv);
43.502 +
43.503 + while (razor_package_iterator_next(pi, &package,
43.504 + &name, &version, &arch)) {
43.505 + printf("verify %s-%s.%s - not implemented\n",
43.506 + name, version, arch);
43.507 + }
43.508 +
43.509 + razor_package_iterator_destroy(pi);
43.510 +}
43.511 +
43.512 +static void
43.513 +remove_package(const char *name,
43.514 + const char *old_version, const char *new_version,
43.515 + const char *arch, void *data)
43.516 +{
43.517 + if (old_version)
43.518 + printf("remove %s-%s.%s\n", name, old_version, arch);
43.519 +}
43.520 +
43.521 +static void
43.522 +command_erase(int argc, const char *argv[])
43.523 +{
43.524 + struct razor_set *set, *upstream, *next;
43.525 + struct razor_transaction *trans;
43.526 + struct razor_package_query *query;
43.527 + struct razor_package_iterator *pi;
43.528 + struct razor_package *package;
43.529 + const char *name, *version, *arch;
43.530 +
43.531 + if (argc == 0) {
43.532 + printf("no packages given for erase\n");
43.533 + exit(1);
43.534 + }
43.535 +
43.536 + set = razor_set_open(repo_filename);
43.537 + upstream = razor_set_create();
43.538 +
43.539 + trans = razor_transaction_create(set, upstream);
43.540 +
43.541 + query = razor_package_query_create(set);
43.542 + add_command_line_packages(set, query, argc, argv);
43.543 +
43.544 + pi = razor_package_query_finish(query);
43.545 + while (razor_package_iterator_next(pi, &package,
43.546 + &name, &version, &arch))
43.547 + razor_transaction_remove_package(trans, package);
43.548 + razor_package_iterator_destroy(pi);
43.549 +
43.550 + if (!option_nodeps && razor_transaction_describe(trans) > 0) {
43.551 + printf("unsatisfied dependencies.\n");
43.552 + exit(1);
43.553 + }
43.554 +
43.555 + if (option_test)
43.556 + exit(0);
43.557 +
43.558 + next = razor_transaction_finish(trans);
43.559 +
43.560 + if (!option_justdb)
43.561 + razor_set_diff(set, next, remove_package, NULL);
43.562 +
43.563 + razor_set_destroy(set);
43.564 + razor_set_destroy(upstream);
43.565 +
43.566 + razor_set_destroy(next);
43.567 +}
43.568 +
43.569 +static void
43.570 +install_package(const char *name,
43.571 + const char *old_version, const char *new_version,
43.572 + const char *arch, void *data)
43.573 +{
43.574 + if (new_version)
43.575 + printf("install %s-%s.%s\n", name, new_version, arch);
43.576 +}
43.577 +
43.578 +static void
43.579 +command_install(int argc, const char *argv[])
43.580 +{
43.581 + struct razor_set *set, *upstream, *next;
43.582 + struct razor_transaction *trans;
43.583 + struct razor_package_iterator *pi;
43.584 + struct razor_package *package;
43.585 + const char *name, *version, *arch;
43.586 +
43.587 + if (argc == 0) {
43.588 + printf("no packages given for install\n");
43.589 + exit(1);
43.590 + }
43.591 +
43.592 + set = razor_set_open(repo_filename);
43.593 + upstream = create_set_from_command_line(argc, argv);
43.594 +
43.595 + trans = razor_transaction_create(set, upstream);
43.596 +
43.597 + pi = razor_package_iterator_create(upstream);
43.598 + while (razor_package_iterator_next(pi, &package,
43.599 + &name, &version, &arch))
43.600 + razor_transaction_install_package(trans, package);
43.601 + razor_package_iterator_destroy(pi);
43.602 +
43.603 + if (!option_nodeps && razor_transaction_describe(trans) > 0) {
43.604 + printf("unsatisfied dependencies.\n");
43.605 + exit(1);
43.606 + }
43.607 +
43.608 + if (option_test)
43.609 + exit(0);
43.610 +
43.611 + next = razor_transaction_finish(trans);
43.612 +
43.613 + if (!option_justdb)
43.614 + razor_set_diff(set, next, install_package, NULL);
43.615 +
43.616 + razor_set_destroy(set);
43.617 + razor_set_destroy(upstream);
43.618 +
43.619 + razor_set_destroy(next);
43.620 +}
43.621 +
43.622 +static void
43.623 +update_package(const char *name,
43.624 + const char *old_version, const char *new_version,
43.625 + const char *arch, void *data)
43.626 +{
43.627 + if (old_version)
43.628 + printf("remove %s-%s.%s\n", name, old_version, arch);
43.629 + if (new_version)
43.630 + printf("install %s-%s.%s\n", name, new_version, arch);
43.631 +}
43.632 +
43.633 +static void
43.634 +command_update(int argc, const char *argv[])
43.635 +{
43.636 + struct razor_set *set, *upstream, *next;
43.637 + struct razor_transaction *trans;
43.638 + struct razor_package_iterator *pi;
43.639 + struct razor_package *package;
43.640 + const char *name, *version, *arch;
43.641 +
43.642 + if (argc == 0) {
43.643 + printf("no packages given for update\n");
43.644 + exit(1);
43.645 + }
43.646 +
43.647 + set = razor_set_open(repo_filename);
43.648 + upstream = create_set_from_command_line(argc, argv);
43.649 +
43.650 + trans = razor_transaction_create(set, upstream);
43.651 +
43.652 + pi = razor_package_iterator_create(upstream);
43.653 + while (razor_package_iterator_next(pi, &package,
43.654 + &name, &version, &arch))
43.655 + razor_transaction_update_package(trans, package);
43.656 + razor_package_iterator_destroy(pi);
43.657 +
43.658 + if (!option_nodeps && razor_transaction_describe(trans) > 0) {
43.659 + printf("unsatisfied dependencies.\n");
43.660 + exit(1);
43.661 + }
43.662 +
43.663 + if (option_test)
43.664 + exit(0);
43.665 +
43.666 + next = razor_transaction_finish(trans);
43.667 +
43.668 + if (!option_justdb)
43.669 + razor_set_diff(set, next, update_package, NULL);
43.670 +
43.671 + razor_set_destroy(set);
43.672 + razor_set_destroy(upstream);
43.673 +
43.674 + razor_set_destroy(next);
43.675 +}
43.676 +
43.677 +static int
43.678 +for_each_option(const struct option *options,
43.679 + const char *name, char short_name,
43.680 + void (*fn)(const struct option *o,
43.681 + const char *name, char short_name,
43.682 + void *data), void *data)
43.683 +{
43.684 + int i, count = 0;
43.685 +
43.686 + for (i = 0; options[i].type != OPTION_LAST; i++) {
43.687 + switch (options[i].type) {
43.688 + case OPTION_GROUP:
43.689 + count += for_each_option(options[i].data,
43.690 + name, short_name, fn, data);
43.691 + break;
43.692 +
43.693 + case OPTION_BOOL:
43.694 + case OPTION_STRING:
43.695 + if (name && strcmp(options[i].name, name) == 0) {
43.696 + fn(&options[i], name, 0, data);
43.697 + count++;
43.698 + break;
43.699 + }
43.700 +
43.701 + if (short_name &&
43.702 + short_name == options[i].short_name) {
43.703 + fn(&options[i], NULL, short_name, data);
43.704 + count++;
43.705 + break;
43.706 + }
43.707 + break;
43.708 +
43.709 + case OPTION_LAST:
43.710 + break;
43.711 + }
43.712 + }
43.713 +
43.714 + return count;
43.715 +}
43.716 +
43.717 +static void
43.718 +handle_option(const struct option *o,
43.719 + const char *name, char short_name, void *data)
43.720 +{
43.721 + if (o->data == NULL) {
43.722 + if (name)
43.723 + printf("option --%s not supported\n", name);
43.724 + else
43.725 + printf("option -%c not supported\n", short_name);
43.726 + return;
43.727 + }
43.728 +
43.729 + switch (o->type) {
43.730 + case OPTION_BOOL:
43.731 + *(int *) o->data = 1;
43.732 + break;
43.733 +
43.734 + case OPTION_STRING:
43.735 + *(const char **) o->data = name + strlen(o->name) + 1;
43.736 + break;
43.737 +
43.738 + case OPTION_LAST:
43.739 + case OPTION_GROUP:
43.740 + /* Shouldn't happen. */
43.741 + break;
43.742 + }
43.743 +}
43.744 +
43.745 +static int
43.746 +parse_options(const struct option *options, int argc, const char **argv)
43.747 +{
43.748 + int i, j, k;
43.749 +
43.750 + for (i = 1, j = 0; i < argc; i++) {
43.751 + if (argv[i][0] != '-') {
43.752 + argv[j++] = argv[i];
43.753 + continue;
43.754 + }
43.755 +
43.756 + if (argv[i][1] == '-') {
43.757 + if (for_each_option(options, &argv[i][2], 0,
43.758 + handle_option, NULL) == 0) {
43.759 + printf("unknown option: %s\n", argv[i]);
43.760 + exit(1);
43.761 + }
43.762 + continue;
43.763 + }
43.764 +
43.765 + for (k = 1; argv[i][k]; k++) {
43.766 + if (for_each_option(options, NULL, argv[i][k],
43.767 + handle_option, NULL) == 0) {
43.768 + printf("unknown option: -%c\n", argv[i][k]);
43.769 + exit(1);
43.770 + }
43.771 + }
43.772 + }
43.773 +
43.774 + return j;
43.775 +}
43.776 +
43.777 +static void
43.778 +print_options_help(const struct option *options)
43.779 +{
43.780 + int i;
43.781 +
43.782 + for (i = 0; options[i].type != OPTION_LAST; i++) {
43.783 + switch (options[i].type) {
43.784 + case OPTION_GROUP:
43.785 + printf("%s\n", options[i].description);
43.786 + print_options_help(options[i].data);
43.787 + printf("\n");
43.788 + break;
43.789 +
43.790 + case OPTION_BOOL:
43.791 + case OPTION_STRING:
43.792 + printf(" ");
43.793 + if (options[i].short_name)
43.794 + printf("-%c", options[i].short_name);
43.795 + if (options[i].short_name && options[i].name)
43.796 + printf(", ");
43.797 + if (options[i].name)
43.798 + printf("--%s", options[i].name);
43.799 + if (options[i].arg_name)
43.800 + printf("=%s", options[i].arg_name);
43.801 + if (options[i].description)
43.802 + printf("\t\t%s", options[i].description);
43.803 + printf("\n");
43.804 + break;
43.805 +
43.806 + case OPTION_LAST:
43.807 + break;
43.808 + }
43.809 + }
43.810 +}
43.811 +
43.812 +static void
43.813 +print_options_usage(const struct option *options)
43.814 +{
43.815 + int i;
43.816 +
43.817 + for (i = 0; options[i].type != OPTION_LAST; i++) {
43.818 + switch (options[i].type) {
43.819 + case OPTION_GROUP:
43.820 + print_options_usage(options[i].data);
43.821 + break;
43.822 +
43.823 + case OPTION_BOOL:
43.824 + printf("[");
43.825 + if (options[i].short_name)
43.826 + printf("-%c", options[i].short_name);
43.827 + if (options[i].short_name && options[i].name)
43.828 + printf("|");
43.829 + if (options[i].name)
43.830 + printf("--%s", options[i].name);
43.831 + printf("] ");
43.832 + break;
43.833 +
43.834 + case OPTION_STRING:
43.835 + printf("[");
43.836 + if (options[i].short_name)
43.837 + printf("-%c", options[i].short_name);
43.838 + if (options[i].short_name && options[i].name)
43.839 + printf("|");
43.840 + if (options[i].name)
43.841 + printf("--%s", options[i].name);
43.842 + if (options[i].arg_name)
43.843 + printf("=%s", options[i].arg_name);
43.844 + printf("] ");
43.845 + break;
43.846 +
43.847 +
43.848 + break;
43.849 +
43.850 + case OPTION_LAST:
43.851 + break;
43.852 + }
43.853 + }
43.854 +}
43.855 +
43.856 +int
43.857 +main(int argc, const char *argv[])
43.858 +{
43.859 + argc = parse_options(rpm_options, argc, argv);
43.860 +
43.861 + if (option_version) {
43.862 + printf("razor rpm version hoopla.\n");
43.863 + exit(0);
43.864 + }
43.865 +
43.866 + if (option_help) {
43.867 + printf("Usage: rpm [OPTION...]\n");
43.868 + print_options_help(rpm_options);
43.869 + exit(0);
43.870 + }
43.871 +
43.872 + if (option_usage) {
43.873 + printf("Usage: rpm [OPTION...]\n");
43.874 + print_options_usage(rpm_options);
43.875 + printf("\n");
43.876 + exit(0);
43.877 + }
43.878 +
43.879 + if (option_initdb) {
43.880 + command_initdb(argc, argv);
43.881 + } else if (option_verify) {
43.882 + command_verify(argc, argv);
43.883 + } else if (option_query) {
43.884 + command_query(argc, argv);
43.885 + } else if (option_install) {
43.886 + command_install(argc, argv);
43.887 + } else if (option_upgrade) {
43.888 + command_update(argc, argv);
43.889 + } else if (option_erase) {
43.890 + command_erase(argc, argv);
43.891 + } else {
43.892 + print_options_usage(rpm_options);
43.893 + printf("\n");
43.894 + exit(0);
43.895 + }
43.896 +
43.897 + return 0;
43.898 +}
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
44.2 +++ b/src/test-driver.c Fri Jun 20 19:04:47 2008 -0400
44.3 @@ -0,0 +1,463 @@
44.4 +#include <stdio.h>
44.5 +#include <string.h>
44.6 +#include <stdarg.h>
44.7 +#include <unistd.h>
44.8 +#include <fcntl.h>
44.9 +#include <errno.h>
44.10 +#include <expat.h>
44.11 +
44.12 +#include "razor.h"
44.13 +
44.14 +#define XML_BUFFER_SIZE 4096
44.15 +
44.16 +static void
44.17 +parse_xml_file(const char *filename,
44.18 + XML_StartElementHandler start,
44.19 + XML_EndElementHandler end,
44.20 + void *data)
44.21 +{
44.22 + XML_Parser parser;
44.23 + char *buffer;
44.24 + int fd, len, err;
44.25 +
44.26 + parser = XML_ParserCreate(NULL);
44.27 + XML_SetElementHandler(parser, start, end);
44.28 + XML_SetUserData(parser, data);
44.29 +
44.30 + fd = open(filename, O_RDONLY);
44.31 + if (fd < 0) {
44.32 + fprintf(stderr, "failed to open %s: %m\n", filename);
44.33 + exit(-1);
44.34 + }
44.35 +
44.36 + while (1) {
44.37 + buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
44.38 + len = read(fd, buffer, XML_BUFFER_SIZE);
44.39 + if (len == 0)
44.40 + break;
44.41 + err = XML_ParseBuffer(parser, len, len == 0);
44.42 + if (err == XML_STATUS_ERROR) {
44.43 + fprintf(stderr, "parse error at line %lu:\n%s\n",
44.44 + XML_GetCurrentLineNumber(parser),
44.45 + XML_ErrorString(XML_GetErrorCode(parser)));
44.46 + exit(-1);
44.47 + }
44.48 + }
44.49 +
44.50 + if (fd < 0) {
44.51 + fprintf(stderr, "read: %m\n");
44.52 + exit(-1);
44.53 + }
44.54 +
44.55 + close(fd);
44.56 +}
44.57 +
44.58 +struct test_context {
44.59 + struct razor_set *system_set, *repo_set, *result_set;
44.60 +
44.61 + struct razor_importer *importer;
44.62 + struct razor_set **importer_set;
44.63 +
44.64 + struct razor_transaction *trans;
44.65 +
44.66 + char *install_pkgs[3], *remove_pkgs[3];
44.67 + int n_install_pkgs, n_remove_pkgs;
44.68 +
44.69 + int unsat;
44.70 + int in_result;
44.71 +
44.72 + int debug, errors;
44.73 +};
44.74 +
44.75 +static void
44.76 +get_atts(const char **atts, ...)
44.77 +{
44.78 + va_list ap;
44.79 + const char *name, **ptr;
44.80 + int i;
44.81 +
44.82 + va_start(ap, atts);
44.83 + while (name = va_arg(ap, const char *), name != NULL) {
44.84 + ptr = va_arg(ap, const char **);
44.85 + *ptr = NULL;
44.86 + for (i = 0; atts[i]; i += 2) {
44.87 + if (strcmp(atts[i], name) == 0)
44.88 + *ptr = atts[i + 1];
44.89 + }
44.90 + }
44.91 + va_end(ap);
44.92 +}
44.93 +
44.94 +static enum razor_version_relation
44.95 +parse_relation (const char *rel_str)
44.96 +{
44.97 + if (!rel_str)
44.98 + return -1;
44.99 + if (rel_str[0] == 'L')
44.100 + return rel_str[1] == 'E' ? RAZOR_VERSION_LESS_OR_EQUAL : RAZOR_VERSION_LESS;
44.101 + else if (rel_str[0] == 'G')
44.102 + return rel_str[1] == 'E' ? RAZOR_VERSION_GREATER_OR_EQUAL : RAZOR_VERSION_GREATER;
44.103 + else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
44.104 + return RAZOR_VERSION_EQUAL;
44.105 + else
44.106 + return -1;
44.107 +}
44.108 +
44.109 +static void
44.110 +start_test(struct test_context *ctx, const char **atts)
44.111 +{
44.112 + const char *name = NULL;
44.113 +
44.114 + get_atts(atts, "name", &name, NULL);
44.115 + if (!name) {
44.116 + fprintf(stderr, "Test with no name\n");
44.117 + exit(1);
44.118 + }
44.119 + printf("%s\n", name);
44.120 +}
44.121 +
44.122 +static void
44.123 +end_test(struct test_context *ctx)
44.124 +{
44.125 + if (ctx->system_set) {
44.126 + razor_set_destroy(ctx->system_set);
44.127 + ctx->system_set = NULL;
44.128 + }
44.129 + if (ctx->repo_set) {
44.130 + razor_set_destroy(ctx->repo_set);
44.131 + ctx->repo_set = NULL;
44.132 + }
44.133 + if (ctx->result_set) {
44.134 + razor_set_destroy(ctx->result_set);
44.135 + ctx->result_set = NULL;
44.136 + }
44.137 + if (ctx->trans) {
44.138 + razor_transaction_destroy(ctx->trans);
44.139 + ctx->trans = NULL;
44.140 + }
44.141 +}
44.142 +
44.143 +static void
44.144 +start_set(struct test_context *ctx, const char **atts)
44.145 +{
44.146 + const char *name = NULL;
44.147 +
44.148 + ctx->importer = razor_importer_new();
44.149 + get_atts(atts, "name", &name, NULL);
44.150 + if (!name)
44.151 + ctx->importer_set = &ctx->result_set;
44.152 + else if (!strcmp(name, "system"))
44.153 + ctx->importer_set = &ctx->system_set;
44.154 + else if (!strcmp(name, "repo"))
44.155 + ctx->importer_set = &ctx->repo_set;
44.156 + else {
44.157 + fprintf(stderr, " bad set name '%s'\n", name);
44.158 + exit(1);
44.159 + }
44.160 +}
44.161 +
44.162 +static void
44.163 +end_set(struct test_context *ctx)
44.164 +{
44.165 + *ctx->importer_set = razor_importer_finish(ctx->importer);
44.166 + ctx->importer = NULL;
44.167 +}
44.168 +
44.169 +static void
44.170 +start_package(struct test_context *ctx, const char **atts)
44.171 +{
44.172 + const char *name = NULL, *version = NULL, *arch = NULL;
44.173 +
44.174 + get_atts(atts, "name", &name,
44.175 + "version", &version,
44.176 + "arch", &arch,
44.177 + NULL);
44.178 +
44.179 + if (!name) {
44.180 + fprintf(stderr, " package with no name\n");
44.181 + exit(1);
44.182 + }
44.183 +
44.184 + razor_importer_begin_package(ctx->importer, name, version, arch);
44.185 + razor_importer_add_property(ctx->importer, name,
44.186 + RAZOR_VERSION_EQUAL, version,
44.187 + RAZOR_PROPERTY_PROVIDES);
44.188 +}
44.189 +
44.190 +static void
44.191 +end_package(struct test_context *ctx)
44.192 +{
44.193 + razor_importer_finish_package(ctx->importer);
44.194 +}
44.195 +
44.196 +static void
44.197 +add_property(struct test_context *ctx, enum razor_property_type type, const char *name, enum razor_version_relation rel, const char *version)
44.198 +{
44.199 + razor_importer_add_property(ctx->importer, name,
44.200 + rel, version, type);
44.201 +}
44.202 +
44.203 +static void
44.204 +check_unsatisfiable_property(struct test_context *ctx,
44.205 + enum razor_property_type type,
44.206 + const char *name,
44.207 + enum razor_version_relation rel,
44.208 + const char *version)
44.209 +{
44.210 + static const char *relation_string[] = { "<", "<=", "=", ">=", ">" };
44.211 +
44.212 + if (!version)
44.213 + version = "";
44.214 +
44.215 + if (razor_transaction_unsatisfied_property(ctx->trans,
44.216 + name, rel, version, type))
44.217 + return;
44.218 +
44.219 + fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
44.220 + name, relation_string[rel], version);
44.221 + ctx->errors++;
44.222 +}
44.223 +
44.224 +static void
44.225 +start_property(struct test_context *ctx, enum razor_property_type type, const char **atts)
44.226 +{
44.227 + const char *name = NULL, *rel_str = NULL, *version = NULL;
44.228 + enum razor_version_relation rel;
44.229 +
44.230 + get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
44.231 + if (name == NULL) {
44.232 + fprintf(stderr, " no name specified for property\n");
44.233 + exit(1);
44.234 + }
44.235 + if (version) {
44.236 + rel = parse_relation(rel_str);
44.237 + if (rel == -1) {
44.238 + fprintf(stderr, " bad or missing version relation for property %s\n", name);
44.239 + exit(1);
44.240 + }
44.241 + } else
44.242 + rel = RAZOR_VERSION_EQUAL;
44.243 +
44.244 + if (ctx->unsat)
44.245 + check_unsatisfiable_property(ctx, type, name, rel, version);
44.246 + else
44.247 + add_property(ctx, type, name, rel, version);
44.248 +}
44.249 +
44.250 +static void
44.251 +start_transaction(struct test_context *ctx, const char **atts)
44.252 +{
44.253 + ctx->n_install_pkgs = 0;
44.254 + ctx->n_remove_pkgs = 0;
44.255 +}
44.256 +
44.257 +static void
44.258 +end_transaction(struct test_context *ctx)
44.259 +{
44.260 + struct razor_package *pkg;
44.261 + int errors, i;
44.262 +
44.263 + ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
44.264 + for (i = 0; i < ctx->n_install_pkgs; i++) {
44.265 + pkg = razor_set_get_package(ctx->repo_set,
44.266 + ctx->install_pkgs[i]);
44.267 + razor_transaction_install_package(ctx->trans, pkg);
44.268 + }
44.269 + for (i = 0; i < ctx->n_remove_pkgs; i++) {
44.270 + pkg = razor_set_get_package(ctx->system_set,
44.271 + ctx->remove_pkgs[i]);
44.272 + if (!pkg)
44.273 + pkg = razor_set_get_package(ctx->repo_set,
44.274 + ctx->remove_pkgs[i]);
44.275 +
44.276 + razor_transaction_remove_package(ctx->trans, pkg);
44.277 + }
44.278 +
44.279 + errors = razor_transaction_resolve(ctx->trans);
44.280 + printf("\n");
44.281 +
44.282 + while (ctx->n_install_pkgs--)
44.283 + free(ctx->install_pkgs[ctx->n_install_pkgs]);
44.284 + while (ctx->n_remove_pkgs--)
44.285 + free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
44.286 +
44.287 + if (!errors) {
44.288 + struct razor_set *new;
44.289 + new = razor_transaction_finish(ctx->trans);
44.290 + ctx->trans = NULL;
44.291 + ctx->system_set = new;
44.292 + }
44.293 +}
44.294 +
44.295 +static void
44.296 +start_install_or_update(struct test_context *ctx, const char **atts)
44.297 +{
44.298 + const char *name = NULL;
44.299 +
44.300 + get_atts(atts, "name", &name, NULL);
44.301 + if (!name) {
44.302 + fprintf(stderr, " install/update with no name\n");
44.303 + exit(1);
44.304 + }
44.305 +
44.306 + ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
44.307 +}
44.308 +
44.309 +static void
44.310 +start_remove(struct test_context *ctx, const char **atts)
44.311 +{
44.312 + const char *name = NULL;
44.313 +
44.314 + get_atts(atts, "name", &name, NULL);
44.315 + if (!name) {
44.316 + fprintf(stderr, " remove with no name\n");
44.317 + exit(1);
44.318 + }
44.319 +
44.320 + ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
44.321 +}
44.322 +
44.323 +static void
44.324 +start_result(struct test_context *ctx, const char **atts)
44.325 +{
44.326 + ctx->in_result = 1;
44.327 +}
44.328 +
44.329 +static void
44.330 +diff_callback(const char *name,
44.331 + const char *old_version,
44.332 + const char *new_version,
44.333 + const char *arch,
44.334 + void *data)
44.335 +{
44.336 + struct test_context *ctx = data;
44.337 +
44.338 + ctx->errors++;
44.339 + if (old_version) {
44.340 + fprintf(stderr, " result set should not contain %s %s\n",
44.341 + name, old_version);
44.342 + } else {
44.343 + fprintf(stderr, " result set should contain %s %s\n",
44.344 + name, new_version);
44.345 + }
44.346 +}
44.347 +
44.348 +static void
44.349 +end_result(struct test_context *ctx)
44.350 +{
44.351 + ctx->in_result = 0;
44.352 +
44.353 + if (ctx->result_set) {
44.354 + if (!ctx->system_set)
44.355 + ctx->system_set = razor_set_create();
44.356 + razor_set_diff(ctx->system_set, ctx->result_set,
44.357 + diff_callback, ctx);
44.358 + }
44.359 +}
44.360 +
44.361 +static void
44.362 +start_unsatisfiable(struct test_context *ctx, const char **atts)
44.363 +{
44.364 + if (ctx->result_set) {
44.365 + fprintf(stderr, "Expected to fail, but didn't\n");
44.366 + exit(1);
44.367 + }
44.368 +
44.369 + ctx->unsat = 1;
44.370 +}
44.371 +
44.372 +static void
44.373 +end_unsatisfiable(struct test_context *ctx)
44.374 +{
44.375 + ctx->unsat = 0;
44.376 +}
44.377 +
44.378 +static void
44.379 +start_test_element(void *data, const char *element, const char **atts)
44.380 +{
44.381 + struct test_context *ctx = data;
44.382 +
44.383 + if (strcmp(element, "tests") == 0) {
44.384 + ;
44.385 + } else if (strcmp(element, "test") == 0) {
44.386 + start_test(ctx, atts);
44.387 + } else if (strcmp(element, "set") == 0) {
44.388 + start_set(ctx, atts);
44.389 + } else if (strcmp(element, "transaction") == 0) {
44.390 + start_transaction(ctx, atts);
44.391 + } else if (strcmp(element, "install") == 0) {
44.392 + start_install_or_update(ctx, atts);
44.393 + } else if (strcmp(element, "install") == 0) {
44.394 + start_install_or_update(ctx, atts);
44.395 + } else if (strcmp(element, "remove") == 0) {
44.396 + start_remove(ctx, atts);
44.397 + } else if (strcmp(element, "result") == 0) {
44.398 + start_result(ctx, atts);
44.399 + } else if (strcmp(element, "unsatisfiable") == 0) {
44.400 + start_unsatisfiable(ctx, atts);
44.401 + } else if (strcmp(element, "package") == 0) {
44.402 + start_package(ctx, atts);
44.403 + } else if (strcmp(element, "requires") == 0) {
44.404 + start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
44.405 + } else if (strcmp(element, "provides") == 0) {
44.406 + start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
44.407 + } else if (strcmp(element, "conflicts") == 0) {
44.408 + start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
44.409 + } else if (strcmp(element, "obsoletes") == 0) {
44.410 + start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
44.411 + } else {
44.412 + fprintf(stderr, "Unrecognized element '%s'\n", element);
44.413 + exit(1);
44.414 + }
44.415 +}
44.416 +
44.417 +static void
44.418 +end_test_element (void *data, const char *element)
44.419 +{
44.420 + struct test_context *ctx = data;
44.421 +
44.422 + if (strcmp(element, "test") == 0) {
44.423 + end_test(ctx);
44.424 + } else if (strcmp(element, "set") == 0) {
44.425 + end_set(ctx);
44.426 + } else if (strcmp(element, "package") == 0) {
44.427 + end_package(ctx);
44.428 + } else if (strcmp(element, "transaction") == 0) {
44.429 + end_transaction(ctx);
44.430 + } else if (strcmp(element, "result") == 0) {
44.431 + end_result(ctx);
44.432 + } else if (strcmp(element, "unsatisfiable") == 0) {
44.433 + end_unsatisfiable(ctx);
44.434 + }
44.435 +}
44.436 +
44.437 +int main(int argc, char *argv[])
44.438 +{
44.439 + struct test_context ctx;
44.440 + const char *test_file;
44.441 +
44.442 + memset(&ctx, 0, sizeof ctx);
44.443 +
44.444 + if (argc > 3) {
44.445 + fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
44.446 + exit(-1);
44.447 + }
44.448 +
44.449 + if (argc >= 2 && !strcmp (argv[1], "-d")) {
44.450 + ctx.debug = 1;
44.451 + argc--;
44.452 + argv++;
44.453 + }
44.454 + if (argc == 2)
44.455 + test_file = argv[1];
44.456 + else
44.457 + test_file = "test.xml";
44.458 +
44.459 + parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
44.460 +
44.461 + if (ctx.errors) {
44.462 + fprintf(stderr, "\n%d errors\n", ctx.errors);
44.463 + return 1;
44.464 + } else
44.465 + return 0;
44.466 +}
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
45.2 +++ b/src/test.xml Fri Jun 20 19:04:47 2008 -0400
45.3 @@ -0,0 +1,858 @@
45.4 +<tests>
45.5 +
45.6 + <test name="testEmpty">
45.7 + <set name="system"/>
45.8 + <set name="repo">
45.9 + <package name="zsh" version="1-1" arch="i386"/>
45.10 + </set>
45.11 + <transaction>
45.12 + <install name="zsh"/>
45.13 + <remove name="zsh"/>
45.14 + </transaction>
45.15 + <result>
45.16 + <set/>
45.17 + </result>
45.18 + </test>
45.19 +
45.20 + <test name="testInstallSinglePackageNoRequires">
45.21 + <set name="system"/>
45.22 + <set name="repo">
45.23 + <package name="zsh" version="1-1" arch="i386"/>
45.24 + </set>
45.25 + <transaction>
45.26 + <install name="zsh"/>
45.27 + </transaction>
45.28 + <result>
45.29 + <set>
45.30 + <package name="zsh" version="1-1" arch="i386"/>
45.31 + </set>
45.32 + </result>
45.33 + </test>
45.34 +
45.35 + <test name="testInstallSinglePackageRequireNotProvided">
45.36 + <set name="system"/>
45.37 + <set name="repo">
45.38 + <package name="zsh" version="1-1" arch="i386">
45.39 + <requires name="zip"/>
45.40 + </package>
45.41 + </set>
45.42 + <transaction>
45.43 + <install name="zsh"/>
45.44 + </transaction>
45.45 + <result>
45.46 + <unsatisfiable>
45.47 + <requires name="zip"/>
45.48 + </unsatisfiable>
45.49 + </result>
45.50 + </test>
45.51 +
45.52 + <test name="testInstallSinglePackageRequireInstalled">
45.53 + <set name="system">
45.54 + <package name="zip" version="1-1" arch="i386"/>
45.55 + </set>
45.56 + <set name="repo">
45.57 + <package name="zsh" version="1-1" arch="i386">
45.58 + <requires name="zip"/>
45.59 + </package>
45.60 + </set>
45.61 + <transaction>
45.62 + <install name="zsh"/>
45.63 + </transaction>
45.64 + <result>
45.65 + <set>
45.66 + <package name="zip" version="1-1" arch="i386"/>
45.67 + <package name="zsh" version="1-1" arch="i386"/>
45.68 + </set>
45.69 + </result>
45.70 + </test>
45.71 +
45.72 + <test name="testInstallSinglePackageRequireInstalledRequireNotProvided">
45.73 + <set name="system">
45.74 + <package name="zip" version="1-2" arch="i386"/>
45.75 + </set>
45.76 + <set name="repo">
45.77 + <package name="zsh" version="1-1" arch="i386">
45.78 + <requires name="zip"/>
45.79 + <!-- This may be a bug in the python test: it looks
45.80 + like they meant to have zip require zap, not zsh.
45.81 + But the install succeeds if you do that...
45.82 + -->
45.83 + <requires name="zap"/>
45.84 + </package>
45.85 + </set>
45.86 + <transaction>
45.87 + <install name="zsh"/>
45.88 + </transaction>
45.89 + <result>
45.90 + <unsatisfiable>
45.91 + <requires name="zap"/>
45.92 + </unsatisfiable>
45.93 + </result>
45.94 + </test>
45.95 +
45.96 + <test name="testInstallSinglePackageRequireInstalledRequireInstall">
45.97 + <set name="system">
45.98 + <package name="zip" version="1-3" arch="i386">
45.99 + <requires name="zap"/>
45.100 + </package>
45.101 + </set>
45.102 + <set name="repo">
45.103 + <package name="zsh" version="1-1" arch="i386">
45.104 + <requires name="zip"/>
45.105 + </package>
45.106 + <package name="zap" version="1-2" arch="i386"/>
45.107 + </set>
45.108 + <transaction>
45.109 + <install name="zsh"/>
45.110 + <install name="zap"/>
45.111 + </transaction>
45.112 + <result>
45.113 + <set>
45.114 + <package name="zap" version="1-2" arch="i386"/>
45.115 + <package name="zip" version="1-3" arch="i386"/>
45.116 + <package name="zsh" version="1-1" arch="i386"/>
45.117 + </set>
45.118 + </result>
45.119 + </test>
45.120 +
45.121 + <test name="testInstallSinglePackageRequireVer1NotProvided">
45.122 + <set name="system">
45.123 + <package name="zip" version="1.0-2" arch="i386"/>
45.124 + </set>
45.125 + <set name="repo">
45.126 + <package name="zsh" version="1-1" arch="i386">
45.127 + <requires name="zip" relation="EQ" version="1.3-2"/>
45.128 + </package>
45.129 + </set>
45.130 + <transaction>
45.131 + <install name="zsh"/>
45.132 + </transaction>
45.133 + <result>
45.134 + <unsatisfiable>
45.135 + <requires name="zip" relation="EQ" version="1.3-2"/>
45.136 + </unsatisfiable>
45.137 + </result>
45.138 + </test>
45.139 +
45.140 + <test name="testInstallSinglePackageRequireVer1Installed">
45.141 + <set name="system">
45.142 + <package name="zip" version="1.3-2" arch="i386"/>
45.143 + </set>
45.144 + <set name="repo">
45.145 + <package name="zsh" version="1-1" arch="i386">
45.146 + <requires name="zip" relation="EQ" version="1.3-2"/>
45.147 + </package>
45.148 + </set>
45.149 + <transaction>
45.150 + <install name="zsh"/>
45.151 + </transaction>
45.152 + <result>
45.153 + <set>
45.154 + <package name="zip" version="1.3-2" arch="i386"/>
45.155 + <package name="zsh" version="1-1" arch="i386"/>
45.156 + </set>
45.157 + </result>
45.158 + </test>
45.159 +
45.160 + <test name="testInstallSinglePackageRequireVer2NotProvided">
45.161 + <set name="system">
45.162 + <package name="zip" version="1.3-2" arch="i386"/>
45.163 + </set>
45.164 + <set name="repo">
45.165 + <package name="zsh" version="1-1" arch="i386">
45.166 + <requires name="zip" relation="EQ" version="1.3-4"/>
45.167 + </package>
45.168 + </set>
45.169 + <transaction>
45.170 + <install name="zsh"/>
45.171 + </transaction>
45.172 + <result>
45.173 + <unsatisfiable>
45.174 + <requires name="zip" relation="EQ" version="1.3-4"/>
45.175 + </unsatisfiable>
45.176 + </result>
45.177 + </test>
45.178 +
45.179 + <test name="testInstallSinglePackageRequireVer2Installed">
45.180 + <set name="system">
45.181 + <package name="zip" version="1.3-4" arch="i386"/>
45.182 + </set>
45.183 + <set name="repo">
45.184 + <package name="zsh" version="1-1" arch="i386">
45.185 + <requires name="zip" relation="EQ" version="1.3-4"/>
45.186 + </package>
45.187 + </set>
45.188 + <transaction>
45.189 + <install name="zsh"/>
45.190 + </transaction>
45.191 + <result>
45.192 + <set>
45.193 + <package name="zip" version="1.3-4" arch="i386"/>
45.194 + <package name="zsh" version="1-1" arch="i386"/>
45.195 + </set>
45.196 + </result>
45.197 + </test>
45.198 +
45.199 + <test name="testInstallSinglePackageRequireVer3NotProvided">
45.200 + <set name="system">
45.201 + <package name="zip" version="0:1.3-4" arch="i386"/>
45.202 + </set>
45.203 + <set name="repo">
45.204 + <package name="zsh" version="1-1" arch="i386">
45.205 + <requires name="zip" relation="GE" version="1:1.3-4"/>
45.206 + </package>
45.207 + </set>
45.208 + <transaction>
45.209 + <install name="zsh"/>
45.210 + </transaction>
45.211 + <result>
45.212 + <unsatisfiable>
45.213 + <requires name="zip" relation="GE" version="1:1.3-4"/>
45.214 + </unsatisfiable>
45.215 + </result>
45.216 + </test>
45.217 +
45.218 + <test name="testInstallSinglePackageRequireVer3Installed">
45.219 + <set name="system">
45.220 + <package name="zip" version="2:1.3-4" arch="i386"/>
45.221 + </set>
45.222 + <set name="repo">
45.223 + <package name="zsh" version="1-1" arch="i386">
45.224 + <requires name="zip" relation="GE" version="2:1.3-4"/>
45.225 + </package>
45.226 + </set>
45.227 + <transaction>
45.228 + <install name="zsh"/>
45.229 + </transaction>
45.230 + <result>
45.231 + <set>
45.232 + <package name="zip" version="2:1.3-4" arch="i386"/>
45.233 + <package name="zsh" version="1-1" arch="i386"/>
45.234 + </set>
45.235 + </result>
45.236 + </test>
45.237 +
45.238 + <test name="testInstallSinglePackageRequireVer4NotProvided">
45.239 + <set name="system">
45.240 + <package name="zip" version="2:1.3-4" arch="i386"/>
45.241 + </set>
45.242 + <set name="repo">
45.243 + <package name="zsh" version="1-1" arch="i386">
45.244 + <requires name="zip" relation="LT" version="2:1.3-4"/>
45.245 + </package>
45.246 + </set>
45.247 + <transaction>
45.248 + <install name="zsh"/>
45.249 + </transaction>
45.250 + <result>
45.251 + <unsatisfiable>
45.252 + <requires name="zip" relation="LT" version="2:1.3-4"/>
45.253 + </unsatisfiable>
45.254 + </result>
45.255 + </test>
45.256 +
45.257 + <test name="testInstallSinglePackageRequireVer4_1Installed">
45.258 + <set name="system">
45.259 + <package name="zip" version="2:1.0-4" arch="i386"/>
45.260 + </set>
45.261 + <set name="repo">
45.262 + <package name="zsh" version="1-1" arch="i386">
45.263 + <requires name="zip" relation="LT" version="2:1.3-4"/>
45.264 + </package>
45.265 + </set>
45.266 + <transaction>
45.267 + <install name="zsh"/>
45.268 + </transaction>
45.269 + <result>
45.270 + <set>
45.271 + <package name="zip" version="2:1.0-4" arch="i386"/>
45.272 + <package name="zsh" version="1-1" arch="i386"/>
45.273 + </set>
45.274 + </result>
45.275 + </test>
45.276 +
45.277 + <test name="testInstallSinglePackageRequireVer4_2Installed">
45.278 + <set name="system">
45.279 + <package name="zip" version="2:1.3-3" arch="i386"/>
45.280 + </set>
45.281 + <set name="repo">
45.282 + <package name="zsh" version="1-1" arch="i386">
45.283 + <requires name="zip" relation="LT" version="2:1.3-4"/>
45.284 + </package>
45.285 + </set>
45.286 + <transaction>
45.287 + <install name="zsh"/>
45.288 + </transaction>
45.289 + <result>
45.290 + <set>
45.291 + <package name="zip" version="2:1.3-3" arch="i386"/>
45.292 + <package name="zsh" version="1-1" arch="i386"/>
45.293 + </set>
45.294 + </result>
45.295 + </test>
45.296 +
45.297 + <test name="testInstallSinglePackageRequireVer4_3Installed">
45.298 + <set name="system">
45.299 + <package name="zip" version="1.3-4" arch="i386"/>
45.300 + </set>
45.301 + <set name="repo">
45.302 + <package name="zsh" version="1-1" arch="i386">
45.303 + <requires name="zip" relation="LT" version="2:1.3-4"/>
45.304 + </package>
45.305 + </set>
45.306 + <transaction>
45.307 + <install name="zsh"/>
45.308 + </transaction>
45.309 + <result>
45.310 + <set>
45.311 + <package name="zip" version="1.3-4" arch="i386"/>
45.312 + <package name="zsh" version="1-1" arch="i386"/>
45.313 + </set>
45.314 + </result>
45.315 + </test>
45.316 +
45.317 + <test name="testInstallSinglePackageRequireVer4_4Installed">
45.318 + <set name="system">
45.319 + <package name="zip" version="1:1.3-4" arch="i386"/>
45.320 + </set>
45.321 + <set name="repo">
45.322 + <package name="zsh" version="1-1" arch="i386">
45.323 + <requires name="zip" relation="LT" version="2:1.3-4"/>
45.324 + </package>
45.325 + </set>
45.326 + <transaction>
45.327 + <install name="zsh"/>
45.328 + </transaction>
45.329 + <result>
45.330 + <set>
45.331 + <package name="zip" version="1:1.3-4" arch="i386"/>
45.332 + <package name="zsh" version="1-1" arch="i386"/>
45.333 + </set>
45.334 + </result>
45.335 + </test>
45.336 +
45.337 + <test name="testInstallSinglePackageRequireVer4_5Installed">
45.338 + <set name="system">
45.339 + <package name="zip" version="2:0.3-4" arch="i386"/>
45.340 + </set>
45.341 + <set name="repo">
45.342 + <package name="zsh" version="1-1" arch="i386">
45.343 + <requires name="zip" relation="LT" version="2:1.3-4"/>
45.344 + </package>
45.345 + </set>
45.346 + <transaction>
45.347 + <install name="zsh"/>
45.348 + </transaction>
45.349 + <result>
45.350 + <set>
45.351 + <package name="zip" version="2:0.3-4" arch="i386"/>
45.352 + <package name="zsh" version="1-1" arch="i386"/>
45.353 + </set>
45.354 + </result>
45.355 + </test>
45.356 +
45.357 + <test name="testInstallSinglePackageRequireXtraBadVer">
45.358 + <set name="system">
45.359 + <package name="zip" version="2:1.3-4" arch="i386"/>
45.360 + </set>
45.361 + <set name="repo">
45.362 + <package name="zsh" version="1-1" arch="i386">
45.363 + <requires name="zip" relation="EQ" version="2:1.3-4"/>
45.364 + <requires name="zap" relation="EQ" version="2:1.3-4"/>
45.365 + </package>
45.366 + <package name="zap" version="0:1.3-4" arch="i386"/>
45.367 + </set>
45.368 + <transaction>
45.369 + <install name="zsh"/>
45.370 + </transaction>
45.371 + <result>
45.372 + <unsatisfiable>
45.373 + <requires name="zap" relation="EQ" version="2:1.3-4"/>
45.374 + </unsatisfiable>
45.375 + </result>
45.376 + </test>
45.377 +
45.378 + <test name="testInstallSinglePackageRequireXtra">
45.379 + <set name="system">
45.380 + <package name="zip" version="2:1.3-4" arch="i386"/>
45.381 + </set>
45.382 + <set name="repo">
45.383 + <package name="zsh" version="1-1" arch="i386">
45.384 + <requires name="zip" relation="EQ" version="2:1.3-4"/>
45.385 + <requires name="zap" relation="EQ" version="4:2.6-8"/>
45.386 + </package>
45.387 + <package name="zap" version="4:2.6-8" arch="i386"/>
45.388 + </set>
45.389 + <transaction>
45.390 + <install name="zsh"/>
45.391 + </transaction>
45.392 + <result>
45.393 + <set>
45.394 + <package name="zap" version="4:2.6-8" arch="i386"/>
45.395 + <package name="zip" version="2:1.3-4" arch="i386"/>
45.396 + <package name="zsh" version="1-1" arch="i386"/>
45.397 + </set>
45.398 + </result>
45.399 + </test>
45.400 +
45.401 + <test name="testInstallSinglePackageRequireInstalledRequireXtra">
45.402 + <set name="system">
45.403 + <package name="zip" version="2:1.3-4" arch="i386">
45.404 + <requires name="zap" relation="EQ" version="4:2.6-8"/>
45.405 + </package>
45.406 + </set>
45.407 + <set name="repo">
45.408 + <package name="zsh" version="1-1" arch="i386">
45.409 + <requires name="zip" relation="EQ" version="2:1.3-4"/>
45.410 + </package>
45.411 + <!-- This may be a bug in the python test; it doesn't
45.412 + actually matter whether or not zap is available
45.413 + -->
45.414 + <package name="zap" version="4:2.6-8" arch="i386"/>
45.415 + </set>
45.416 + <transaction>
45.417 + <install name="zsh"/>
45.418 + </transaction>
45.419 + <result>
45.420 + <set>
45.421 + <package name="zip" version="2:1.3-4" arch="i386"/>
45.422 + <package name="zsh" version="1-1" arch="i386"/>
45.423 + </set>
45.424 + </result>
45.425 + </test>
45.426 +
45.427 + <test name="testInstallSinglePackageRequireUpgradeRequireXtraErr">
45.428 + <set name="system">
45.429 + <package name="zip" version="2:1.3-4" arch="i386">
45.430 + <requires name="zap" relation="EQ" version="2:1.3-3"/>
45.431 + </package>
45.432 + </set>
45.433 + <set name="repo">
45.434 + <package name="zsh" version="1-1" arch="i386">
45.435 + <requires name="zip" relation="EQ" version="4:2.6-8"/>
45.436 + </package>
45.437 + <package name="zip" version="4:2.6-8" arch="i386">
45.438 + <requires name="zap" relation="EQ" version="2:1.3-4"/>
45.439 + </package>
45.440 + <package name="zap" version="2:1.3-4" arch="i386">
45.441 + <requires name="zsh" relation="EQ" version="2:4-8"/>
45.442 + </package>
45.443 + </set>
45.444 + <transaction>
45.445 + <install name="zsh"/>
45.446 + </transaction>
45.447 + <result>
45.448 + <unsatisfiable>
45.449 + <requires name="zsh" relation="EQ" version="2:4-8"/>
45.450 + </unsatisfiable>
45.451 + </result>
45.452 + </test>
45.453 +
45.454 + <test name="testInstallSinglePackageRequireUpgradeRequireXtraOk">
45.455 + <set name="system">
45.456 + <package name="zip" version="2:1.3-4" arch="i386">
45.457 + <requires name="zap" relation="EQ" version="2:1.3-3"/>
45.458 + </package>
45.459 + </set>
45.460 + <set name="repo">
45.461 + <package name="zsh" version="1-1" arch="i386">
45.462 + <requires name="zip" relation="EQ" version="4:2.6-8"/>
45.463 + </package>
45.464 + <package name="zip" version="4:2.6-8" arch="i386">
45.465 + <requires name="zap" relation="EQ" version="2:1.3-4"/>
45.466 + </package>
45.467 + <package name="zap" version="2:1.3-4" arch="i386"/>
45.468 + </set>
45.469 + <transaction>
45.470 + <install name="zsh"/>
45.471 + </transaction>
45.472 + <result>
45.473 + <set>
45.474 + <package name="zap" version="2:1.3-4" arch="i386"/>
45.475 + <package name="zip" version="4:2.6-8" arch="i386"/>
45.476 + <package name="zsh" version="1-1" arch="i386"/>
45.477 + </set>
45.478 + </result>
45.479 + </test>
45.480 +
45.481 + <test name="testInstallSinglePackageRequireMultiXtra">
45.482 + <set name="system"/>
45.483 + <set name="repo">
45.484 + <package name="zsh" version="1-1" arch="i386">
45.485 + <requires name="zip" relation="EQ" version="4:2.6-8"/>
45.486 + </package>
45.487 + <package name="zip" version="4:2.6-8" arch="i386">
45.488 + <requires name="zap" relation="EQ" version="2:1.3-4"/>
45.489 + </package>
45.490 + <package name="zap" version="2:1.3-4" arch="i386"/>
45.491 + </set>
45.492 + <transaction>
45.493 + <install name="zsh"/>
45.494 + </transaction>
45.495 + <result>
45.496 + <set>
45.497 + <package name="zap" version="2:1.3-4" arch="i386"/>
45.498 + <package name="zip" version="4:2.6-8" arch="i386"/>
45.499 + <package name="zsh" version="1-1" arch="i386"/>
45.500 + </set>
45.501 + </result>
45.502 + </test>
45.503 +
45.504 + <test name="testInstallSinglePackageRequireInstalledMultiLib">
45.505 + <set name="system">
45.506 + <package name="zip" version="1-3" arch="i386"/>
45.507 + </set>
45.508 + <set name="repo">
45.509 + <package name="zsh" version="1-1" arch="x86_64">
45.510 + <requires name="zip"/>
45.511 + </package>
45.512 + <package name="zip" version="1-3" arch="x86_64"/>
45.513 + </set>
45.514 + <transaction>
45.515 + <install name="zsh"/>
45.516 + </transaction>
45.517 + <result>
45.518 + <set>
45.519 + <package name="zip" version="1-3" arch="i386"/>
45.520 + <package name="zsh" version="1-1" arch="x86_64"/>
45.521 + </set>
45.522 + </result>
45.523 + </test>
45.524 +
45.525 + <test name="testInstallSinglePackageRequireXtra1MultiLib">
45.526 + <set name="system"/>
45.527 + <set name="repo">
45.528 + <package name="zsh" version="1-1" arch="x86_64">
45.529 + <requires name="zip"/>
45.530 + </package>
45.531 + <package name="zip" version="1-3" arch="i386"/>
45.532 + </set>
45.533 + <transaction>
45.534 + <install name="zsh"/>
45.535 + </transaction>
45.536 + <result>
45.537 + <set>
45.538 + <package name="zip" version="1-3" arch="i386"/>
45.539 + <package name="zsh" version="1-1" arch="x86_64"/>
45.540 + </set>
45.541 + </result>
45.542 + </test>
45.543 +
45.544 + <test name="testInstallSinglePackageRequireXtra2_64MultiLib">
45.545 + <set name="system"/>
45.546 + <set name="repo">
45.547 + <package name="zsh" version="1-1" arch="x86_64">
45.548 + <requires name="zip"/>
45.549 + </package>
45.550 + <package name="zip" version="1-3" arch="i386"/>
45.551 + <package name="zip" version="1-3" arch="x86_64"/>
45.552 + </set>
45.553 + <transaction>
45.554 + <install name="zsh"/>
45.555 + </transaction>
45.556 + <result>
45.557 + <set>
45.558 + <package name="zsh" version="1-1" arch="x86_64"/>
45.559 + <package name="zip" version="1-3" arch="x86_64"/>
45.560 + </set>
45.561 + </result>
45.562 + </test>
45.563 +
45.564 + <test name="testInstallSinglePackageRequireXtra2_32MultiLib">
45.565 + <set name="system"/>
45.566 + <set name="repo">
45.567 + <package name="zsh" version="1-1" arch="i386">
45.568 + <requires name="zip"/>
45.569 + </package>
45.570 + <package name="zip" version="1-3" arch="i386"/>
45.571 + <package name="zip" version="1-3" arch="x86_64"/>
45.572 + </set>
45.573 + <transaction>
45.574 + <install name="zsh"/>
45.575 + </transaction>
45.576 + <result>
45.577 + <set>
45.578 + <package name="zip" version="1-3" arch="i386"/>
45.579 + <package name="zsh" version="1-1" arch="i386"/>
45.580 + </set>
45.581 + </result>
45.582 + </test>
45.583 +
45.584 + <test name="testUpdateSinglePackage">
45.585 + <set name="system">
45.586 + <package name="zsh" version="1-1" arch="i386"/>
45.587 + </set>
45.588 + <set name="repo">
45.589 + <package name="zsh" version="1-3" arch="i386"/>
45.590 + </set>
45.591 + <transaction>
45.592 + <install name="zsh"/>
45.593 + </transaction>
45.594 + <result>
45.595 + <set>
45.596 + <package name="zsh" version="1-3" arch="i386"/>
45.597 + </set>
45.598 + </result>
45.599 + </test>
45.600 +
45.601 + <test name="testUpdateForDependency">
45.602 + <set name="system">
45.603 + <package name="zip" version="0:1-1" arch="i386"/>
45.604 + </set>
45.605 + <set name="repo">
45.606 + <package name="zsh" version="0:1-1" arch="i386">
45.607 + <requires name="zip" relation="EQ" version="0:2-1"/>
45.608 + </package>
45.609 + <package name="zip" version="0:2-1" arch="i386"/>
45.610 + </set>
45.611 + <transaction>
45.612 + <install name="zsh"/>
45.613 + </transaction>
45.614 + <result>
45.615 + <set>
45.616 + <package name="zip" version="0:2-1" arch="i386"/>
45.617 + <package name="zsh" version="0:1-1" arch="i386"/>
45.618 + </set>
45.619 + </result>
45.620 + </test>
45.621 +
45.622 + <test name="testUpdateSplitPackage">
45.623 + <set name="system">
45.624 + <package name="zip" version="0:1-1" arch="i386">
45.625 + <provides name="libzip" relation="EQ" version="0:1-1"/>
45.626 + </package>
45.627 + </set>
45.628 + <set name="repo">
45.629 + <package name="zsh" version="0:1-1" arch="i386">
45.630 + <requires name="libzip" relation="EQ" version="0:2-1"/>
45.631 + </package>
45.632 + <package name="zip" version="0:2-1" arch="i386">
45.633 + <requires name="zip-libs" relation="EQ" version="0:2-1"/>
45.634 + </package>
45.635 + <package name="zip-libs" version="0:2-1" arch="i386">
45.636 + <provides name="libzip" relation="EQ" version="0:2-1"/>
45.637 + </package>
45.638 + </set>
45.639 + <transaction>
45.640 + <install name="zsh"/>
45.641 + </transaction>
45.642 + <result>
45.643 + <set>
45.644 + <package name="zip" version="0:1-1" arch="i386"/>
45.645 + <package name="zip-libs" version="0:2-1" arch="i386"/>
45.646 + <package name="zsh" version="0:1-1" arch="i386"/>
45.647 + </set>
45.648 + </result>
45.649 + </test>
45.650 +
45.651 + <test name="testUpdateSinglePackageNewRequires">
45.652 + <set name="system">
45.653 + <package name="zsh" version="1-1" arch="i386"/>
45.654 + </set>
45.655 + <set name="repo">
45.656 + <package name="zsh" version="1-3" arch="i386">
45.657 + <requires name="zip"/>
45.658 + </package>
45.659 + <package name="zip" version="1-3" arch="x86_64"/>
45.660 + </set>
45.661 + <transaction>
45.662 + <install name="zsh"/>
45.663 + </transaction>
45.664 + <result>
45.665 + <set>
45.666 + <package name="zsh" version="1-3" arch="i386"/>
45.667 + <package name="zip" version="1-3" arch="x86_64"/>
45.668 + </set>
45.669 + </result>
45.670 + </test>
45.671 +
45.672 + <test name="testUpdateSinglePackageOldRequires">
45.673 + <set name="system">
45.674 + <package name="zsh" version="1-1" arch="i386">
45.675 + <requires name="zip"/>
45.676 + </package>
45.677 + <package name="zip" version="1-3" arch="x86_64"/>
45.678 + </set>
45.679 + <set name="repo">
45.680 + <package name="zsh" version="1-3" arch="i386">
45.681 + <requires name="zip"/>
45.682 + </package>
45.683 + </set>
45.684 + <transaction>
45.685 + <install name="zsh"/>
45.686 + </transaction>
45.687 + <result>
45.688 + <set>
45.689 + <package name="zip" version="1-3" arch="x86_64"/>
45.690 + <package name="zsh" version="1-3" arch="i386"/>
45.691 + </set>
45.692 + </result>
45.693 + </test>
45.694 +
45.695 + <test name="testUpdateSinglePackageOldRequiresGone">
45.696 + <set name="system">
45.697 + <package name="zsh" version="1-1" arch="i386">
45.698 + <requires name="zip"/>
45.699 + </package>
45.700 + <package name="zip" version="1-3" arch="x86_64"/>
45.701 + </set>
45.702 + <set name="repo">
45.703 + <package name="zsh" version="1-3" arch="i386"/>
45.704 + </set>
45.705 + <transaction>
45.706 + <install name="zsh"/>
45.707 + </transaction>
45.708 + <result>
45.709 + <set>
45.710 + <package name="zip" version="1-3" arch="x86_64"/>
45.711 + <package name="zsh" version="1-3" arch="i386"/>
45.712 + </set>
45.713 + </result>
45.714 + </test>
45.715 +
45.716 + <test name="testUpdateSinglePackageObsoletesOldRequirement">
45.717 + <set name="system">
45.718 + <package name="zsh" version="1-1" arch="i386">
45.719 + <requires name="zip"/>
45.720 + </package>
45.721 + <package name="zip" version="1-1" arch="i386"/>
45.722 + </set>
45.723 + <set name="repo">
45.724 + <package name="zsh" version="1-3" arch="i386">
45.725 + <!-- depsolvetests.py actually adds the obsoletes
45.726 + to the installed zsh rather than the new zsh,
45.727 + but I'm assuming that's a bug -->
45.728 + <obsoletes name="zip"/>
45.729 + </package>
45.730 + </set>
45.731 + <transaction>
45.732 + <install name="zsh"/>
45.733 + </transaction>
45.734 + <result>
45.735 + <set>
45.736 + <package name="zsh" version="1-3" arch="i386"/>
45.737 + </set>
45.738 + </result>
45.739 + </test>
45.740 +
45.741 + <test name="testUpdateForConflict">
45.742 + <set name="system">
45.743 + <package name="zip" version="0:1-1" arch="i386"/>
45.744 + </set>
45.745 + <set name="repo">
45.746 + <package name="zsh" version="0:1-1" arch="i386">
45.747 + <conflicts name="zip" relation="LE" version="0:1-1"/>
45.748 + </package>
45.749 + <package name="zip" version="0:2-1" arch="i386"/>
45.750 + </set>
45.751 + <transaction>
45.752 + <install name="zsh"/>
45.753 + </transaction>
45.754 + <result>
45.755 + <set>
45.756 + <package name="zip" version="0:2-1" arch="i386"/>
45.757 + <package name="zsh" version="0:1-1" arch="i386"/>
45.758 + </set>
45.759 + </result>
45.760 + </test>
45.761 +
45.762 + <test name="testUpdateForConflict2">
45.763 + <set name="system">
45.764 + <package name="zip" version="0:1-1" arch="i386">
45.765 + <conflicts name="zsh" relation="LE" version="0:1-1"/>
45.766 + </package>
45.767 + </set>
45.768 + <set name="repo">
45.769 + <package name="zsh" version="0:1-1" arch="i386"/>
45.770 + <package name="zip" version="0:2-1" arch="i386"/>
45.771 + </set>
45.772 + <transaction>
45.773 + <install name="zsh"/>
45.774 + </transaction>
45.775 + <result>
45.776 + <set>
45.777 + <package name="zsh" version="0:1-1" arch="i386"/>
45.778 + <package name="zip" version="0:2-1" arch="i386"/>
45.779 + </set>
45.780 + </result>
45.781 + </test>
45.782 +
45.783 + <test name="testUpdateForConflictProvide">
45.784 + <set name="system">
45.785 + <package name="zip" version="0:1-1" arch="i386">
45.786 + <provides name="zippy" relation="EQ" version="0:1-1"/>
45.787 + </package>
45.788 + </set>
45.789 + <set name="repo">
45.790 + <package name="zsh" version="0:1-1" arch="i386">
45.791 + <conflicts name="zippy" relation="LE" version="0:1-1"/>
45.792 + </package>
45.793 + <package name="zip" version="0:2-1" arch="i386"/>
45.794 + </set>
45.795 + <transaction>
45.796 + <install name="zsh"/>
45.797 + </transaction>
45.798 + <result>
45.799 + <set>
45.800 + <package name="zip" version="0:2-1" arch="i386"/>
45.801 + <package name="zsh" version="0:1-1" arch="i386"/>
45.802 + </set>
45.803 + </result>
45.804 + </test>
45.805 +
45.806 + <test name="testUpdateForConflictProvide2">
45.807 + <set name="system">
45.808 + <package name="zip" version="0:1-1" arch="i386">
45.809 + <conflicts name="zippy" relation="GT" version="0:1-1"/>
45.810 + <conflicts name="zippy" relation="LT" version="0:1-1"/>
45.811 + </package>
45.812 + </set>
45.813 + <set name="repo">
45.814 + <package name="zsh" version="0:1-1" arch="i386">
45.815 + <provides name="zippy" relation="EQ" version="0:2-1"/>
45.816 + </package>
45.817 + <package name="zip" version="0:2-1" arch="i386">
45.818 + <conflicts name="zippy" relation="GT" version="0:2-1"/>
45.819 + <conflicts name="zippy" relation="LT" version="0:2-1"/>
45.820 + </package>
45.821 + </set>
45.822 + <transaction>
45.823 + <install name="zsh"/>
45.824 + </transaction>
45.825 + <result>
45.826 + <set>
45.827 + <package name="zip" version="0:2-1" arch="i386"/>
45.828 + <package name="zsh" version="0:1-1" arch="i386"/>
45.829 + </set>
45.830 + </result>
45.831 + </test>
45.832 +
45.833 + <test name="testEraseSinglePackage">
45.834 + <set name="system">
45.835 + <package name="zsh" version="0:1-1" arch="i386"/>
45.836 + </set>
45.837 + <set name="repo"/>
45.838 + <transaction>
45.839 + <remove name="zsh"/>
45.840 + </transaction>
45.841 + <result>
45.842 + <set/>
45.843 + </result>
45.844 + </test>
45.845 +
45.846 + <test name="testEraseSinglePackageRequiredByOneInstalled">
45.847 + <set name="system">
45.848 + <package name="zippy" version="0:1-1" arch="i386">
45.849 + <requires name="zsh"/>
45.850 + </package>
45.851 + <package name="zsh" version="0:1-1" arch="i386"/>
45.852 + </set>
45.853 + <set name="repo"/>
45.854 + <transaction>
45.855 + <remove name="zsh"/>
45.856 + </transaction>
45.857 + <result>
45.858 + <set/>
45.859 + </result>
45.860 + </test>
45.861 +</tests>
46.1 --- a/test-driver.c Sun Jun 15 18:16:20 2008 -0400
46.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
46.3 @@ -1,461 +0,0 @@
46.4 -#include <stdio.h>
46.5 -#include <string.h>
46.6 -#include <stdarg.h>
46.7 -#include <unistd.h>
46.8 -#include <fcntl.h>
46.9 -#include <errno.h>
46.10 -#include <expat.h>
46.11 -
46.12 -#include "razor.h"
46.13 -
46.14 -#define XML_BUFFER_SIZE 4096
46.15 -
46.16 -static void
46.17 -parse_xml_file(const char *filename,
46.18 - XML_StartElementHandler start,
46.19 - XML_EndElementHandler end,
46.20 - void *data)
46.21 -{
46.22 - XML_Parser parser;
46.23 - char *buffer;
46.24 - int fd, len, err;
46.25 -
46.26 - parser = XML_ParserCreate(NULL);
46.27 - XML_SetElementHandler(parser, start, end);
46.28 - XML_SetUserData(parser, data);
46.29 -
46.30 - fd = open(filename, O_RDONLY);
46.31 - if (fd < 0) {
46.32 - fprintf(stderr, "failed to open %s: %m\n", filename);
46.33 - exit(-1);
46.34 - }
46.35 -
46.36 - while (1) {
46.37 - buffer = XML_GetBuffer(parser, XML_BUFFER_SIZE);
46.38 - len = read(fd, buffer, XML_BUFFER_SIZE);
46.39 - if (len == 0)
46.40 - break;
46.41 - err = XML_ParseBuffer(parser, len, len == 0);
46.42 - if (err == XML_STATUS_ERROR) {
46.43 - fprintf(stderr, "parse error at line %lu:\n%s\n",
46.44 - XML_GetCurrentLineNumber(parser),
46.45 - XML_ErrorString(XML_GetErrorCode(parser)));
46.46 - exit(-1);
46.47 - }
46.48 - }
46.49 -
46.50 - if (fd < 0) {
46.51 - fprintf(stderr, "read: %m\n");
46.52 - exit(-1);
46.53 - }
46.54 -
46.55 - close(fd);
46.56 -}
46.57 -
46.58 -struct test_context {
46.59 - struct razor_set *system_set, *repo_set, *result_set;
46.60 -
46.61 - struct razor_importer *importer;
46.62 - struct razor_set **importer_set;
46.63 -
46.64 - struct razor_transaction *trans;
46.65 -
46.66 - char *install_pkgs[3], *remove_pkgs[3];
46.67 - int n_install_pkgs, n_remove_pkgs;
46.68 -
46.69 - int unsat;
46.70 - int in_result;
46.71 -
46.72 - int debug, errors;
46.73 -};
46.74 -
46.75 -static void
46.76 -get_atts(const char **atts, ...)
46.77 -{
46.78 - va_list ap;
46.79 - const char *name, **ptr;
46.80 - int i;
46.81 -
46.82 - va_start(ap, atts);
46.83 - while (name = va_arg(ap, const char *), name != NULL) {
46.84 - ptr = va_arg(ap, const char **);
46.85 - *ptr = NULL;
46.86 - for (i = 0; atts[i]; i += 2) {
46.87 - if (strcmp(atts[i], name) == 0)
46.88 - *ptr = atts[i + 1];
46.89 - }
46.90 - }
46.91 - va_end(ap);
46.92 -}
46.93 -
46.94 -static enum razor_version_relation
46.95 -parse_relation (const char *rel_str)
46.96 -{
46.97 - if (!rel_str)
46.98 - return -1;
46.99 - if (rel_str[0] == 'L')
46.100 - return rel_str[1] == 'E' ? RAZOR_VERSION_LESS_OR_EQUAL : RAZOR_VERSION_LESS;
46.101 - else if (rel_str[0] == 'G')
46.102 - return rel_str[1] == 'E' ? RAZOR_VERSION_GREATER_OR_EQUAL : RAZOR_VERSION_GREATER;
46.103 - else if (rel_str[0] == 'E' || rel_str[1] == 'Q')
46.104 - return RAZOR_VERSION_EQUAL;
46.105 - else
46.106 - return -1;
46.107 -}
46.108 -
46.109 -static void
46.110 -start_test(struct test_context *ctx, const char **atts)
46.111 -{
46.112 - const char *name = NULL;
46.113 -
46.114 - get_atts(atts, "name", &name, NULL);
46.115 - if (!name) {
46.116 - fprintf(stderr, "Test with no name\n");
46.117 - exit(1);
46.118 - }
46.119 - printf("%s\n", name);
46.120 -}
46.121 -
46.122 -static void
46.123 -end_test(struct test_context *ctx)
46.124 -{
46.125 - if (ctx->system_set) {
46.126 - razor_set_destroy(ctx->system_set);
46.127 - ctx->system_set = NULL;
46.128 - }
46.129 - if (ctx->repo_set) {
46.130 - razor_set_destroy(ctx->repo_set);
46.131 - ctx->repo_set = NULL;
46.132 - }
46.133 - if (ctx->result_set) {
46.134 - razor_set_destroy(ctx->result_set);
46.135 - ctx->result_set = NULL;
46.136 - }
46.137 - if (ctx->trans) {
46.138 - razor_transaction_destroy(ctx->trans);
46.139 - ctx->trans = NULL;
46.140 - }
46.141 -}
46.142 -
46.143 -static void
46.144 -start_set(struct test_context *ctx, const char **atts)
46.145 -{
46.146 - const char *name = NULL;
46.147 -
46.148 - ctx->importer = razor_importer_new();
46.149 - get_atts(atts, "name", &name, NULL);
46.150 - if (!name)
46.151 - ctx->importer_set = &ctx->result_set;
46.152 - else if (!strcmp(name, "system"))
46.153 - ctx->importer_set = &ctx->system_set;
46.154 - else if (!strcmp(name, "repo"))
46.155 - ctx->importer_set = &ctx->repo_set;
46.156 - else {
46.157 - fprintf(stderr, " bad set name '%s'\n", name);
46.158 - exit(1);
46.159 - }
46.160 -}
46.161 -
46.162 -static void
46.163 -end_set(struct test_context *ctx)
46.164 -{
46.165 - *ctx->importer_set = razor_importer_finish(ctx->importer);
46.166 - ctx->importer = NULL;
46.167 -}
46.168 -
46.169 -static void
46.170 -start_package(struct test_context *ctx, const char **atts)
46.171 -{
46.172 - const char *name = NULL, *version = NULL, *arch = NULL;
46.173 -
46.174 - get_atts(atts, "name", &name,
46.175 - "version", &version,
46.176 - "arch", &arch,
46.177 - NULL);
46.178 -
46.179 - if (!name) {
46.180 - fprintf(stderr, " package with no name\n");
46.181 - exit(1);
46.182 - }
46.183 -
46.184 - razor_importer_begin_package(ctx->importer, name, version, arch);
46.185 - razor_importer_add_property(ctx->importer, name,
46.186 - RAZOR_VERSION_EQUAL, version,
46.187 - RAZOR_PROPERTY_PROVIDES);
46.188 -}
46.189 -
46.190 -static void
46.191 -end_package(struct test_context *ctx)
46.192 -{
46.193 - razor_importer_finish_package(ctx->importer);
46.194 -}
46.195 -
46.196 -static void
46.197 -add_property(struct test_context *ctx, enum razor_property_type type, const char *name, enum razor_version_relation rel, const char *version)
46.198 -{
46.199 - razor_importer_add_property(ctx->importer, name,
46.200 - rel, version, type);
46.201 -}
46.202 -
46.203 -static void
46.204 -check_unsatisfiable_property(struct test_context *ctx,
46.205 - enum razor_property_type type,
46.206 - const char *name,
46.207 - enum razor_version_relation rel,
46.208 - const char *version)
46.209 -{
46.210 - if (!version)
46.211 - version = "";
46.212 -
46.213 - if (razor_transaction_unsatisfied_property(ctx->trans,
46.214 - name, rel, version))
46.215 - return;
46.216 -
46.217 - fprintf(stderr, " didn't get unsatisfiable '%s %s %s'\n",
46.218 - name, razor_version_relations[rel], version);
46.219 - ctx->errors++;
46.220 -}
46.221 -
46.222 -static void
46.223 -start_property(struct test_context *ctx, enum razor_property_type type, const char **atts)
46.224 -{
46.225 - const char *name = NULL, *rel_str = NULL, *version = NULL;
46.226 - enum razor_version_relation rel;
46.227 -
46.228 - get_atts(atts, "name", &name, "relation", &rel_str, "version", &version, NULL);
46.229 - if (name == NULL) {
46.230 - fprintf(stderr, " no name specified for property\n");
46.231 - exit(1);
46.232 - }
46.233 - if (version) {
46.234 - rel = parse_relation(rel_str);
46.235 - if (rel == -1) {
46.236 - fprintf(stderr, " bad or missing version relation for property %s\n", name);
46.237 - exit(1);
46.238 - }
46.239 - } else
46.240 - rel = RAZOR_VERSION_EQUAL;
46.241 -
46.242 - if (ctx->unsat)
46.243 - check_unsatisfiable_property(ctx, type, name, rel, version);
46.244 - else
46.245 - add_property(ctx, type, name, rel, version);
46.246 -}
46.247 -
46.248 -static void
46.249 -start_transaction(struct test_context *ctx, const char **atts)
46.250 -{
46.251 - ctx->n_install_pkgs = 0;
46.252 - ctx->n_remove_pkgs = 0;
46.253 -}
46.254 -
46.255 -static void
46.256 -end_transaction(struct test_context *ctx)
46.257 -{
46.258 - struct razor_package *pkg;
46.259 - int errors, i;
46.260 -
46.261 - ctx->trans = razor_transaction_create(ctx->system_set, ctx->repo_set);
46.262 - for (i = 0; i < ctx->n_install_pkgs; i++) {
46.263 - pkg = razor_set_get_package(ctx->repo_set,
46.264 - ctx->install_pkgs[i]);
46.265 - razor_transaction_install_package(ctx->trans, pkg);
46.266 - }
46.267 - for (i = 0; i < ctx->n_remove_pkgs; i++) {
46.268 - pkg = razor_set_get_package(ctx->system_set,
46.269 - ctx->remove_pkgs[i]);
46.270 - if (!pkg)
46.271 - pkg = razor_set_get_package(ctx->repo_set,
46.272 - ctx->remove_pkgs[i]);
46.273 -
46.274 - razor_transaction_remove_package(ctx->trans, pkg);
46.275 - }
46.276 -
46.277 - errors = razor_transaction_resolve(ctx->trans);
46.278 - printf("\n");
46.279 -
46.280 - while (ctx->n_install_pkgs--)
46.281 - free(ctx->install_pkgs[ctx->n_install_pkgs]);
46.282 - while (ctx->n_remove_pkgs--)
46.283 - free(ctx->remove_pkgs[ctx->n_remove_pkgs]);
46.284 -
46.285 - if (!errors) {
46.286 - struct razor_set *new;
46.287 - new = razor_transaction_finish(ctx->trans);
46.288 - ctx->trans = NULL;
46.289 - ctx->system_set = new;
46.290 - }
46.291 -}
46.292 -
46.293 -static void
46.294 -start_install_or_update(struct test_context *ctx, const char **atts)
46.295 -{
46.296 - const char *name = NULL;
46.297 -
46.298 - get_atts(atts, "name", &name, NULL);
46.299 - if (!name) {
46.300 - fprintf(stderr, " install/update with no name\n");
46.301 - exit(1);
46.302 - }
46.303 -
46.304 - ctx->install_pkgs[ctx->n_install_pkgs++] = strdup(name);
46.305 -}
46.306 -
46.307 -static void
46.308 -start_remove(struct test_context *ctx, const char **atts)
46.309 -{
46.310 - const char *name = NULL;
46.311 -
46.312 - get_atts(atts, "name", &name, NULL);
46.313 - if (!name) {
46.314 - fprintf(stderr, " remove with no name\n");
46.315 - exit(1);
46.316 - }
46.317 -
46.318 - ctx->remove_pkgs[ctx->n_remove_pkgs++] = strdup(name);
46.319 -}
46.320 -
46.321 -static void
46.322 -start_result(struct test_context *ctx, const char **atts)
46.323 -{
46.324 - ctx->in_result = 1;
46.325 -}
46.326 -
46.327 -static void
46.328 -diff_callback(const char *name,
46.329 - const char *old_version,
46.330 - const char *new_version,
46.331 - const char *arch,
46.332 - void *data)
46.333 -{
46.334 - struct test_context *ctx = data;
46.335 -
46.336 - ctx->errors++;
46.337 - if (old_version) {
46.338 - fprintf(stderr, " result set should not contain %s %s\n",
46.339 - name, old_version);
46.340 - } else {
46.341 - fprintf(stderr, " result set should contain %s %s\n",
46.342 - name, new_version);
46.343 - }
46.344 -}
46.345 -
46.346 -static void
46.347 -end_result(struct test_context *ctx)
46.348 -{
46.349 - ctx->in_result = 0;
46.350 -
46.351 - if (ctx->result_set) {
46.352 - if (!ctx->system_set)
46.353 - ctx->system_set = razor_set_create();
46.354 - razor_set_diff(ctx->system_set, ctx->result_set,
46.355 - diff_callback, ctx);
46.356 - }
46.357 -}
46.358 -
46.359 -static void
46.360 -start_unsatisfiable(struct test_context *ctx, const char **atts)
46.361 -{
46.362 - if (ctx->result_set) {
46.363 - fprintf(stderr, "Expected to fail, but didn't\n");
46.364 - exit(1);
46.365 - }
46.366 -
46.367 - ctx->unsat = 1;
46.368 -}
46.369 -
46.370 -static void
46.371 -end_unsatisfiable(struct test_context *ctx)
46.372 -{
46.373 - ctx->unsat = 0;
46.374 -}
46.375 -
46.376 -static void
46.377 -start_test_element(void *data, const char *element, const char **atts)
46.378 -{
46.379 - struct test_context *ctx = data;
46.380 -
46.381 - if (strcmp(element, "tests") == 0) {
46.382 - ;
46.383 - } else if (strcmp(element, "test") == 0) {
46.384 - start_test(ctx, atts);
46.385 - } else if (strcmp(element, "set") == 0) {
46.386 - start_set(ctx, atts);
46.387 - } else if (strcmp(element, "transaction") == 0) {
46.388 - start_transaction(ctx, atts);
46.389 - } else if (strcmp(element, "install") == 0) {
46.390 - start_install_or_update(ctx, atts);
46.391 - } else if (strcmp(element, "install") == 0) {
46.392 - start_install_or_update(ctx, atts);
46.393 - } else if (strcmp(element, "remove") == 0) {
46.394 - start_remove(ctx, atts);
46.395 - } else if (strcmp(element, "result") == 0) {
46.396 - start_result(ctx, atts);
46.397 - } else if (strcmp(element, "unsatisfiable") == 0) {
46.398 - start_unsatisfiable(ctx, atts);
46.399 - } else if (strcmp(element, "package") == 0) {
46.400 - start_package(ctx, atts);
46.401 - } else if (strcmp(element, "requires") == 0) {
46.402 - start_property(ctx, RAZOR_PROPERTY_REQUIRES, atts);
46.403 - } else if (strcmp(element, "provides") == 0) {
46.404 - start_property(ctx, RAZOR_PROPERTY_PROVIDES, atts);
46.405 - } else if (strcmp(element, "conflicts") == 0) {
46.406 - start_property(ctx, RAZOR_PROPERTY_CONFLICTS, atts);
46.407 - } else if (strcmp(element, "obsoletes") == 0) {
46.408 - start_property(ctx, RAZOR_PROPERTY_OBSOLETES, atts);
46.409 - } else {
46.410 - fprintf(stderr, "Unrecognized element '%s'\n", element);
46.411 - exit(1);
46.412 - }
46.413 -}
46.414 -
46.415 -static void
46.416 -end_test_element (void *data, const char *element)
46.417 -{
46.418 - struct test_context *ctx = data;
46.419 -
46.420 - if (strcmp(element, "test") == 0) {
46.421 - end_test(ctx);
46.422 - } else if (strcmp(element, "set") == 0) {
46.423 - end_set(ctx);
46.424 - } else if (strcmp(element, "package") == 0) {
46.425 - end_package(ctx);
46.426 - } else if (strcmp(element, "transaction") == 0) {
46.427 - end_transaction(ctx);
46.428 - } else if (strcmp(element, "result") == 0) {
46.429 - end_result(ctx);
46.430 - } else if (strcmp(element, "unsatisfiable") == 0) {
46.431 - end_unsatisfiable(ctx);
46.432 - }
46.433 -}
46.434 -
46.435 -int main(int argc, char *argv[])
46.436 -{
46.437 - struct test_context ctx;
46.438 - const char *test_file;
46.439 -
46.440 - memset(&ctx, 0, sizeof ctx);
46.441 -
46.442 - if (argc > 3) {
46.443 - fprintf(stderr, "usage: %s [-d] [TESTS-FILE]\n", argv[0]);
46.444 - exit(-1);
46.445 - }
46.446 -
46.447 - if (argc >= 2 && !strcmp (argv[1], "-d")) {
46.448 - ctx.debug = 1;
46.449 - argc--;
46.450 - argv++;
46.451 - }
46.452 - if (argc == 2)
46.453 - test_file = argv[1];
46.454 - else
46.455 - test_file = "test.xml";
46.456 -
46.457 - parse_xml_file(test_file, start_test_element, end_test_element, &ctx);
46.458 -
46.459 - if (ctx.errors) {
46.460 - fprintf(stderr, "\n%d errors\n", ctx.errors);
46.461 - return 1;
46.462 - } else
46.463 - return 0;
46.464 -}
47.1 --- a/test.xml Sun Jun 15 18:16:20 2008 -0400
47.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
47.3 @@ -1,858 +0,0 @@
47.4 -<tests>
47.5 -
47.6 - <test name="testEmpty">
47.7 - <set name="system"/>
47.8 - <set name="repo">
47.9 - <package name="zsh" version="1-1" arch="i386"/>
47.10 - </set>
47.11 - <transaction>
47.12 - <install name="zsh"/>
47.13 - <remove name="zsh"/>
47.14 - </transaction>
47.15 - <result>
47.16 - <set/>
47.17 - </result>
47.18 - </test>
47.19 -
47.20 - <test name="testInstallSinglePackageNoRequires">
47.21 - <set name="system"/>
47.22 - <set name="repo">
47.23 - <package name="zsh" version="1-1" arch="i386"/>
47.24 - </set>
47.25 - <transaction>
47.26 - <install name="zsh"/>
47.27 - </transaction>
47.28 - <result>
47.29 - <set>
47.30 - <package name="zsh" version="1-1" arch="i386"/>
47.31 - </set>
47.32 - </result>
47.33 - </test>
47.34 -
47.35 - <test name="testInstallSinglePackageRequireNotProvided">
47.36 - <set name="system"/>
47.37 - <set name="repo">
47.38 - <package name="zsh" version="1-1" arch="i386">
47.39 - <requires name="zip"/>
47.40 - </package>
47.41 - </set>
47.42 - <transaction>
47.43 - <install name="zsh"/>
47.44 - </transaction>
47.45 - <result>
47.46 - <unsatisfiable>
47.47 - <requires name="zip"/>
47.48 - </unsatisfiable>
47.49 - </result>
47.50 - </test>
47.51 -
47.52 - <test name="testInstallSinglePackageRequireInstalled">
47.53 - <set name="system">
47.54 - <package name="zip" version="1-1" arch="i386"/>
47.55 - </set>
47.56 - <set name="repo">
47.57 - <package name="zsh" version="1-1" arch="i386">
47.58 - <requires name="zip"/>
47.59 - </package>
47.60 - </set>
47.61 - <transaction>
47.62 - <install name="zsh"/>
47.63 - </transaction>
47.64 - <result>
47.65 - <set>
47.66 - <package name="zip" version="1-1" arch="i386"/>
47.67 - <package name="zsh" version="1-1" arch="i386"/>
47.68 - </set>
47.69 - </result>
47.70 - </test>
47.71 -
47.72 - <test name="testInstallSinglePackageRequireInstalledRequireNotProvided">
47.73 - <set name="system">
47.74 - <package name="zip" version="1-2" arch="i386"/>
47.75 - </set>
47.76 - <set name="repo">
47.77 - <package name="zsh" version="1-1" arch="i386">
47.78 - <requires name="zip"/>
47.79 - <!-- This may be a bug in the python test: it looks
47.80 - like they meant to have zip require zap, not zsh.
47.81 - But the install succeeds if you do that...
47.82 - -->
47.83 - <requires name="zap"/>
47.84 - </package>
47.85 - </set>
47.86 - <transaction>
47.87 - <install name="zsh"/>
47.88 - </transaction>
47.89 - <result>
47.90 - <unsatisfiable>
47.91 - <requires name="zap"/>
47.92 - </unsatisfiable>
47.93 - </result>
47.94 - </test>
47.95 -
47.96 - <test name="testInstallSinglePackageRequireInstalledRequireInstall">
47.97 - <set name="system">
47.98 - <package name="zip" version="1-3" arch="i386">
47.99 - <requires name="zap"/>
47.100 - </package>
47.101 - </set>
47.102 - <set name="repo">
47.103 - <package name="zsh" version="1-1" arch="i386">
47.104 - <requires name="zip"/>
47.105 - </package>
47.106 - <package name="zap" version="1-2" arch="i386"/>
47.107 - </set>
47.108 - <transaction>
47.109 - <install name="zsh"/>
47.110 - <install name="zap"/>
47.111 - </transaction>
47.112 - <result>
47.113 - <set>
47.114 - <package name="zap" version="1-2" arch="i386"/>
47.115 - <package name="zip" version="1-3" arch="i386"/>
47.116 - <package name="zsh" version="1-1" arch="i386"/>
47.117 - </set>
47.118 - </result>
47.119 - </test>
47.120 -
47.121 - <test name="testInstallSinglePackageRequireVer1NotProvided">
47.122 - <set name="system">
47.123 - <package name="zip" version="1.0-2" arch="i386"/>
47.124 - </set>
47.125 - <set name="repo">
47.126 - <package name="zsh" version="1-1" arch="i386">
47.127 - <requires name="zip" relation="EQ" version="1.3-2"/>
47.128 - </package>
47.129 - </set>
47.130 - <transaction>
47.131 - <install name="zsh"/>
47.132 - </transaction>
47.133 - <result>
47.134 - <unsatisfiable>
47.135 - <requires name="zip" relation="EQ" version="1.3-2"/>
47.136 - </unsatisfiable>
47.137 - </result>
47.138 - </test>
47.139 -
47.140 - <test name="testInstallSinglePackageRequireVer1Installed">
47.141 - <set name="system">
47.142 - <package name="zip" version="1.3-2" arch="i386"/>
47.143 - </set>
47.144 - <set name="repo">
47.145 - <package name="zsh" version="1-1" arch="i386">
47.146 - <requires name="zip" relation="EQ" version="1.3-2"/>
47.147 - </package>
47.148 - </set>
47.149 - <transaction>
47.150 - <install name="zsh"/>
47.151 - </transaction>
47.152 - <result>
47.153 - <set>
47.154 - <package name="zip" version="1.3-2" arch="i386"/>
47.155 - <package name="zsh" version="1-1" arch="i386"/>
47.156 - </set>
47.157 - </result>
47.158 - </test>
47.159 -
47.160 - <test name="testInstallSinglePackageRequireVer2NotProvided">
47.161 - <set name="system">
47.162 - <package name="zip" version="1.3-2" arch="i386"/>
47.163 - </set>
47.164 - <set name="repo">
47.165 - <package name="zsh" version="1-1" arch="i386">
47.166 - <requires name="zip" relation="EQ" version="1.3-4"/>
47.167 - </package>
47.168 - </set>
47.169 - <transaction>
47.170 - <install name="zsh"/>
47.171 - </transaction>
47.172 - <result>
47.173 - <unsatisfiable>
47.174 - <requires name="zip" relation="EQ" version="1.3-4"/>
47.175 - </unsatisfiable>
47.176 - </result>
47.177 - </test>
47.178 -
47.179 - <test name="testInstallSinglePackageRequireVer2Installed">
47.180 - <set name="system">
47.181 - <package name="zip" version="1.3-4" arch="i386"/>
47.182 - </set>
47.183 - <set name="repo">
47.184 - <package name="zsh" version="1-1" arch="i386">
47.185 - <requires name="zip" relation="EQ" version="1.3-4"/>
47.186 - </package>
47.187 - </set>
47.188 - <transaction>
47.189 - <install name="zsh"/>
47.190 - </transaction>
47.191 - <result>
47.192 - <set>
47.193 - <package name="zip" version="1.3-4" arch="i386"/>
47.194 - <package name="zsh" version="1-1" arch="i386"/>
47.195 - </set>
47.196 - </result>
47.197 - </test>
47.198 -
47.199 - <test name="testInstallSinglePackageRequireVer3NotProvided">
47.200 - <set name="system">
47.201 - <package name="zip" version="0:1.3-4" arch="i386"/>
47.202 - </set>
47.203 - <set name="repo">
47.204 - <package name="zsh" version="1-1" arch="i386">
47.205 - <requires name="zip" relation="GE" version="1:1.3-4"/>
47.206 - </package>
47.207 - </set>
47.208 - <transaction>
47.209 - <install name="zsh"/>
47.210 - </transaction>
47.211 - <result>
47.212 - <unsatisfiable>
47.213 - <requires name="zip" relation="GE" version="1:1.3-4"/>
47.214 - </unsatisfiable>
47.215 - </result>
47.216 - </test>
47.217 -
47.218 - <test name="testInstallSinglePackageRequireVer3Installed">
47.219 - <set name="system">
47.220 - <package name="zip" version="2:1.3-4" arch="i386"/>
47.221 - </set>
47.222 - <set name="repo">
47.223 - <package name="zsh" version="1-1" arch="i386">
47.224 - <requires name="zip" relation="GE" version="2:1.3-4"/>
47.225 - </package>
47.226 - </set>
47.227 - <transaction>
47.228 - <install name="zsh"/>
47.229 - </transaction>
47.230 - <result>
47.231 - <set>
47.232 - <package name="zip" version="2:1.3-4" arch="i386"/>
47.233 - <package name="zsh" version="1-1" arch="i386"/>
47.234 - </set>
47.235 - </result>
47.236 - </test>
47.237 -
47.238 - <test name="testInstallSinglePackageRequireVer4NotProvided">
47.239 - <set name="system">
47.240 - <package name="zip" version="2:1.3-4" arch="i386"/>
47.241 - </set>
47.242 - <set name="repo">
47.243 - <package name="zsh" version="1-1" arch="i386">
47.244 - <requires name="zip" relation="LT" version="2:1.3-4"/>
47.245 - </package>
47.246 - </set>
47.247 - <transaction>
47.248 - <install name="zsh"/>
47.249 - </transaction>
47.250 - <result>
47.251 - <unsatisfiable>
47.252 - <requires name="zip" relation="LT" version="2:1.3-4"/>
47.253 - </unsatisfiable>
47.254 - </result>
47.255 - </test>
47.256 -
47.257 - <test name="testInstallSinglePackageRequireVer4_1Installed">
47.258 - <set name="system">
47.259 - <package name="zip" version="2:1.0-4" arch="i386"/>
47.260 - </set>
47.261 - <set name="repo">
47.262 - <package name="zsh" version="1-1" arch="i386">
47.263 - <requires name="zip" relation="LT" version="2:1.3-4"/>
47.264 - </package>
47.265 - </set>
47.266 - <transaction>
47.267 - <install name="zsh"/>
47.268 - </transaction>
47.269 - <result>
47.270 - <set>
47.271 - <package name="zip" version="2:1.0-4" arch="i386"/>
47.272 - <package name="zsh" version="1-1" arch="i386"/>
47.273 - </set>
47.274 - </result>
47.275 - </test>
47.276 -
47.277 - <test name="testInstallSinglePackageRequireVer4_2Installed">
47.278 - <set name="system">
47.279 - <package name="zip" version="2:1.3-3" arch="i386"/>
47.280 - </set>
47.281 - <set name="repo">
47.282 - <package name="zsh" version="1-1" arch="i386">
47.283 - <requires name="zip" relation="LT" version="2:1.3-4"/>
47.284 - </package>
47.285 - </set>
47.286 - <transaction>
47.287 - <install name="zsh"/>
47.288 - </transaction>
47.289 - <result>
47.290 - <set>
47.291 - <package name="zip" version="2:1.3-3" arch="i386"/>
47.292 - <package name="zsh" version="1-1" arch="i386"/>
47.293 - </set>
47.294 - </result>
47.295 - </test>
47.296 -
47.297 - <test name="testInstallSinglePackageRequireVer4_3Installed">
47.298 - <set name="system">
47.299 - <package name="zip" version="1.3-4" arch="i386"/>
47.300 - </set>
47.301 - <set name="repo">
47.302 - <package name="zsh" version="1-1" arch="i386">
47.303 - <requires name="zip" relation="LT" version="2:1.3-4"/>
47.304 - </package>
47.305 - </set>
47.306 - <transaction>
47.307 - <install name="zsh"/>
47.308 - </transaction>
47.309 - <result>
47.310 - <set>
47.311 - <package name="zip" version="1.3-4" arch="i386"/>
47.312 - <package name="zsh" version="1-1" arch="i386"/>
47.313 - </set>
47.314 - </result>
47.315 - </test>
47.316 -
47.317 - <test name="testInstallSinglePackageRequireVer4_4Installed">
47.318 - <set name="system">
47.319 - <package name="zip" version="1:1.3-4" arch="i386"/>
47.320 - </set>
47.321 - <set name="repo">
47.322 - <package name="zsh" version="1-1" arch="i386">
47.323 - <requires name="zip" relation="LT" version="2:1.3-4"/>
47.324 - </package>
47.325 - </set>
47.326 - <transaction>
47.327 - <install name="zsh"/>
47.328 - </transaction>
47.329 - <result>
47.330 - <set>
47.331 - <package name="zip" version="1:1.3-4" arch="i386"/>
47.332 - <package name="zsh" version="1-1" arch="i386"/>
47.333 - </set>
47.334 - </result>
47.335 - </test>
47.336 -
47.337 - <test name="testInstallSinglePackageRequireVer4_5Installed">
47.338 - <set name="system">
47.339 - <package name="zip" version="2:0.3-4" arch="i386"/>
47.340 - </set>
47.341 - <set name="repo">
47.342 - <package name="zsh" version="1-1" arch="i386">
47.343 - <requires name="zip" relation="LT" version="2:1.3-4"/>
47.344 - </package>
47.345 - </set>
47.346 - <transaction>
47.347 - <install name="zsh"/>
47.348 - </transaction>
47.349 - <result>
47.350 - <set>
47.351 - <package name="zip" version="2:0.3-4" arch="i386"/>
47.352 - <package name="zsh" version="1-1" arch="i386"/>
47.353 - </set>
47.354 - </result>
47.355 - </test>
47.356 -
47.357 - <test name="testInstallSinglePackageRequireXtraBadVer">
47.358 - <set name="system">
47.359 - <package name="zip" version="2:1.3-4" arch="i386"/>
47.360 - </set>
47.361 - <set name="repo">
47.362 - <package name="zsh" version="1-1" arch="i386">
47.363 - <requires name="zip" relation="EQ" version="2:1.3-4"/>
47.364 - <requires name="zap" relation="EQ" version="2:1.3-4"/>
47.365 - </package>
47.366 - <package name="zap" version="0:1.3-4" arch="i386"/>
47.367 - </set>
47.368 - <transaction>
47.369 - <install name="zsh"/>
47.370 - </transaction>
47.371 - <result>
47.372 - <unsatisfiable>
47.373 - <requires name="zap" relation="EQ" version="2:1.3-4"/>
47.374 - </unsatisfiable>
47.375 - </result>
47.376 - </test>
47.377 -
47.378 - <test name="testInstallSinglePackageRequireXtra">
47.379 - <set name="system">
47.380 - <package name="zip" version="2:1.3-4" arch="i386"/>
47.381 - </set>
47.382 - <set name="repo">
47.383 - <package name="zsh" version="1-1" arch="i386">
47.384 - <requires name="zip" relation="EQ" version="2:1.3-4"/>
47.385 - <requires name="zap" relation="EQ" version="4:2.6-8"/>
47.386 - </package>
47.387 - <package name="zap" version="4:2.6-8" arch="i386"/>
47.388 - </set>
47.389 - <transaction>
47.390 - <install name="zsh"/>
47.391 - </transaction>
47.392 - <result>
47.393 - <set>
47.394 - <package name="zap" version="4:2.6-8" arch="i386"/>
47.395 - <package name="zip" version="2:1.3-4" arch="i386"/>
47.396 - <package name="zsh" version="1-1" arch="i386"/>
47.397 - </set>
47.398 - </result>
47.399 - </test>
47.400 -
47.401 - <test name="testInstallSinglePackageRequireInstalledRequireXtra">
47.402 - <set name="system">
47.403 - <package name="zip" version="2:1.3-4" arch="i386">
47.404 - <requires name="zap" relation="EQ" version="4:2.6-8"/>
47.405 - </package>
47.406 - </set>
47.407 - <set name="repo">
47.408 - <package name="zsh" version="1-1" arch="i386">
47.409 - <requires name="zip" relation="EQ" version="2:1.3-4"/>
47.410 - </package>
47.411 - <!-- This may be a bug in the python test; it doesn't
47.412 - actually matter whether or not zap is available
47.413 - -->
47.414 - <package name="zap" version="4:2.6-8" arch="i386"/>
47.415 - </set>
47.416 - <transaction>
47.417 - <install name="zsh"/>
47.418 - </transaction>
47.419 - <result>
47.420 - <set>
47.421 - <package name="zip" version="2:1.3-4" arch="i386"/>
47.422 - <package name="zsh" version="1-1" arch="i386"/>
47.423 - </set>
47.424 - </result>
47.425 - </test>
47.426 -
47.427 - <test name="testInstallSinglePackageRequireUpgradeRequireXtraErr">
47.428 - <set name="system">
47.429 - <package name="zip" version="2:1.3-4" arch="i386">
47.430 - <requires name="zap" relation="EQ" version="2:1.3-3"/>
47.431 - </package>
47.432 - </set>
47.433 - <set name="repo">
47.434 - <package name="zsh" version="1-1" arch="i386">
47.435 - <requires name="zip" relation="EQ" version="4:2.6-8"/>
47.436 - </package>
47.437 - <package name="zip" version="4:2.6-8" arch="i386">
47.438 - <requires name="zap" relation="EQ" version="2:1.3-4"/>
47.439 - </package>
47.440 - <package name="zap" version="2:1.3-4" arch="i386">
47.441 - <requires name="zsh" relation="EQ" version="2:4-8"/>
47.442 - </package>
47.443 - </set>
47.444 - <transaction>
47.445 - <install name="zsh"/>
47.446 - </transaction>
47.447 - <result>
47.448 - <unsatisfiable>
47.449 - <requires name="zsh" relation="EQ" version="2:4-8"/>
47.450 - </unsatisfiable>
47.451 - </result>
47.452 - </test>
47.453 -
47.454 - <test name="testInstallSinglePackageRequireUpgradeRequireXtraOk">
47.455 - <set name="system">
47.456 - <package name="zip" version="2:1.3-4" arch="i386">
47.457 - <requires name="zap" relation="EQ" version="2:1.3-3"/>
47.458 - </package>
47.459 - </set>
47.460 - <set name="repo">
47.461 - <package name="zsh" version="1-1" arch="i386">
47.462 - <requires name="zip" relation="EQ" version="4:2.6-8"/>
47.463 - </package>
47.464 - <package name="zip" version="4:2.6-8" arch="i386">
47.465 - <requires name="zap" relation="EQ" version="2:1.3-4"/>
47.466 - </package>
47.467 - <package name="zap" version="2:1.3-4" arch="i386"/>
47.468 - </set>
47.469 - <transaction>
47.470 - <install name="zsh"/>
47.471 - </transaction>
47.472 - <result>
47.473 - <set>
47.474 - <package name="zap" version="2:1.3-4" arch="i386"/>
47.475 - <package name="zip" version="4:2.6-8" arch="i386"/>
47.476 - <package name="zsh" version="1-1" arch="i386"/>
47.477 - </set>
47.478 - </result>
47.479 - </test>
47.480 -
47.481 - <test name="testInstallSinglePackageRequireMultiXtra">
47.482 - <set name="system"/>
47.483 - <set name="repo">
47.484 - <package name="zsh" version="1-1" arch="i386">
47.485 - <requires name="zip" relation="EQ" version="4:2.6-8"/>
47.486 - </package>
47.487 - <package name="zip" version="4:2.6-8" arch="i386">
47.488 - <requires name="zap" relation="EQ" version="2:1.3-4"/>
47.489 - </package>
47.490 - <package name="zap" version="2:1.3-4" arch="i386"/>
47.491 - </set>
47.492 - <transaction>
47.493 - <install name="zsh"/>
47.494 - </transaction>
47.495 - <result>
47.496 - <set>
47.497 - <package name="zap" version="2:1.3-4" arch="i386"/>
47.498 - <package name="zip" version="4:2.6-8" arch="i386"/>
47.499 - <package name="zsh" version="1-1" arch="i386"/>
47.500 - </set>
47.501 - </result>
47.502 - </test>
47.503 -
47.504 - <test name="testInstallSinglePackageRequireInstalledMultiLib">
47.505 - <set name="system">
47.506 - <package name="zip" version="1-3" arch="i386"/>
47.507 - </set>
47.508 - <set name="repo">
47.509 - <package name="zsh" version="1-1" arch="x86_64">
47.510 - <requires name="zip"/>
47.511 - </package>
47.512 - <package name="zip" version="1-3" arch="x86_64"/>
47.513 - </set>
47.514 - <transaction>
47.515 - <install name="zsh"/>
47.516 - </transaction>
47.517 - <result>
47.518 - <set>
47.519 - <package name="zip" version="1-3" arch="i386"/>
47.520 - <package name="zsh" version="1-1" arch="x86_64"/>
47.521 - </set>
47.522 - </result>
47.523 - </test>
47.524 -
47.525 - <test name="testInstallSinglePackageRequireXtra1MultiLib">
47.526 - <set name="system"/>
47.527 - <set name="repo">
47.528 - <package name="zsh" version="1-1" arch="x86_64">
47.529 - <requires name="zip"/>
47.530 - </package>
47.531 - <package name="zip" version="1-3" arch="i386"/>
47.532 - </set>
47.533 - <transaction>
47.534 - <install name="zsh"/>
47.535 - </transaction>
47.536 - <result>
47.537 - <set>
47.538 - <package name="zip" version="1-3" arch="i386"/>
47.539 - <package name="zsh" version="1-1" arch="x86_64"/>
47.540 - </set>
47.541 - </result>
47.542 - </test>
47.543 -
47.544 - <test name="testInstallSinglePackageRequireXtra2_64MultiLib">
47.545 - <set name="system"/>
47.546 - <set name="repo">
47.547 - <package name="zsh" version="1-1" arch="x86_64">
47.548 - <requires name="zip"/>
47.549 - </package>
47.550 - <package name="zip" version="1-3" arch="i386"/>
47.551 - <package name="zip" version="1-3" arch="x86_64"/>
47.552 - </set>
47.553 - <transaction>
47.554 - <install name="zsh"/>
47.555 - </transaction>
47.556 - <result>
47.557 - <set>
47.558 - <package name="zsh" version="1-1" arch="x86_64"/>
47.559 - <package name="zip" version="1-3" arch="x86_64"/>
47.560 - </set>
47.561 - </result>
47.562 - </test>
47.563 -
47.564 - <test name="testInstallSinglePackageRequireXtra2_32MultiLib">
47.565 - <set name="system"/>
47.566 - <set name="repo">
47.567 - <package name="zsh" version="1-1" arch="i386">
47.568 - <requires name="zip"/>
47.569 - </package>
47.570 - <package name="zip" version="1-3" arch="i386"/>
47.571 - <package name="zip" version="1-3" arch="x86_64"/>
47.572 - </set>
47.573 - <transaction>
47.574 - <install name="zsh"/>
47.575 - </transaction>
47.576 - <result>
47.577 - <set>
47.578 - <package name="zip" version="1-3" arch="i386"/>
47.579 - <package name="zsh" version="1-1" arch="i386"/>
47.580 - </set>
47.581 - </result>
47.582 - </test>
47.583 -
47.584 - <test name="testUpdateSinglePackage">
47.585 - <set name="system">
47.586 - <package name="zsh" version="1-1" arch="i386"/>
47.587 - </set>
47.588 - <set name="repo">
47.589 - <package name="zsh" version="1-3" arch="i386"/>
47.590 - </set>
47.591 - <transaction>
47.592 - <install name="zsh"/>
47.593 - </transaction>
47.594 - <result>
47.595 - <set>
47.596 - <package name="zsh" version="1-3" arch="i386"/>
47.597 - </set>
47.598 - </result>
47.599 - </test>
47.600 -
47.601 - <test name="testUpdateForDependency">
47.602 - <set name="system">
47.603 - <package name="zip" version="0:1-1" arch="i386"/>
47.604 - </set>
47.605 - <set name="repo">
47.606 - <package name="zsh" version="0:1-1" arch="i386">
47.607 - <requires name="zip" relation="EQ" version="0:2-1"/>
47.608 - </package>
47.609 - <package name="zip" version="0:2-1" arch="i386"/>
47.610 - </set>
47.611 - <transaction>
47.612 - <install name="zsh"/>
47.613 - </transaction>
47.614 - <result>
47.615 - <set>
47.616 - <package name="zip" version="0:2-1" arch="i386"/>
47.617 - <package name="zsh" version="0:1-1" arch="i386"/>
47.618 - </set>
47.619 - </result>
47.620 - </test>
47.621 -
47.622 - <test name="testUpdateSplitPackage">
47.623 - <set name="system">
47.624 - <package name="zip" version="0:1-1" arch="i386">
47.625 - <provides name="libzip" relation="EQ" version="0:1-1"/>
47.626 - </package>
47.627 - </set>
47.628 - <set name="repo">
47.629 - <package name="zsh" version="0:1-1" arch="i386">
47.630 - <requires name="libzip" relation="EQ" version="0:2-1"/>
47.631 - </package>
47.632 - <package name="zip" version="0:2-1" arch="i386">
47.633 - <requires name="zip-libs" relation="EQ" version="0:2-1"/>
47.634 - </package>
47.635 - <package name="zip-libs" version="0:2-1" arch="i386">
47.636 - <provides name="libzip" relation="EQ" version="0:2-1"/>
47.637 - </package>
47.638 - </set>
47.639 - <transaction>
47.640 - <install name="zsh"/>
47.641 - </transaction>
47.642 - <result>
47.643 - <set>
47.644 - <package name="zip" version="0:1-1" arch="i386"/>
47.645 - <package name="zip-libs" version="0:2-1" arch="i386"/>
47.646 - <package name="zsh" version="0:1-1" arch="i386"/>
47.647 - </set>
47.648 - </result>
47.649 - </test>
47.650 -
47.651 - <test name="testUpdateSinglePackageNewRequires">
47.652 - <set name="system">
47.653 - <package name="zsh" version="1-1" arch="i386"/>
47.654 - </set>
47.655 - <set name="repo">
47.656 - <package name="zsh" version="1-3" arch="i386">
47.657 - <requires name="zip"/>
47.658 - </package>
47.659 - <package name="zip" version="1-3" arch="x86_64"/>
47.660 - </set>
47.661 - <transaction>
47.662 - <install name="zsh"/>
47.663 - </transaction>
47.664 - <result>
47.665 - <set>
47.666 - <package name="zsh" version="1-3" arch="i386"/>
47.667 - <package name="zip" version="1-3" arch="x86_64"/>
47.668 - </set>
47.669 - </result>
47.670 - </test>
47.671 -
47.672 - <test name="testUpdateSinglePackageOldRequires">
47.673 - <set name="system">
47.674 - <package name="zsh" version="1-1" arch="i386">
47.675 - <requires name="zip"/>
47.676 - </package>
47.677 - <package name="zip" version="1-3" arch="x86_64"/>
47.678 - </set>
47.679 - <set name="repo">
47.680 - <package name="zsh" version="1-3" arch="i386">
47.681 - <requires name="zip"/>
47.682 - </package>
47.683 - </set>
47.684 - <transaction>
47.685 - <install name="zsh"/>
47.686 - </transaction>
47.687 - <result>
47.688 - <set>
47.689 - <package name="zip" version="1-3" arch="x86_64"/>
47.690 - <package name="zsh" version="1-3" arch="i386"/>
47.691 - </set>
47.692 - </result>
47.693 - </test>
47.694 -
47.695 - <test name="testUpdateSinglePackageOldRequiresGone">
47.696 - <set name="system">
47.697 - <package name="zsh" version="1-1" arch="i386">
47.698 - <requires name="zip"/>
47.699 - </package>
47.700 - <package name="zip" version="1-3" arch="x86_64"/>
47.701 - </set>
47.702 - <set name="repo">
47.703 - <package name="zsh" version="1-3" arch="i386"/>
47.704 - </set>
47.705 - <transaction>
47.706 - <install name="zsh"/>
47.707 - </transaction>
47.708 - <result>
47.709 - <set>
47.710 - <package name="zip" version="1-3" arch="x86_64"/>
47.711 - <package name="zsh" version="1-3" arch="i386"/>
47.712 - </set>
47.713 - </result>
47.714 - </test>
47.715 -
47.716 - <test name="testUpdateSinglePackageObsoletesOldRequirement">
47.717 - <set name="system">
47.718 - <package name="zsh" version="1-1" arch="i386">
47.719 - <requires name="zip"/>
47.720 - </package>
47.721 - <package name="zip" version="1-1" arch="i386"/>
47.722 - </set>
47.723 - <set name="repo">
47.724 - <package name="zsh" version="1-3" arch="i386">
47.725 - <!-- depsolvetests.py actually adds the obsoletes
47.726 - to the installed zsh rather than the new zsh,
47.727 - but I'm assuming that's a bug -->
47.728 - <obsoletes name="zip"/>
47.729 - </package>
47.730 - </set>
47.731 - <transaction>
47.732 - <install name="zsh"/>
47.733 - </transaction>
47.734 - <result>
47.735 - <set>
47.736 - <package name="zsh" version="1-3" arch="i386"/>
47.737 - </set>
47.738 - </result>
47.739 - </test>
47.740 -
47.741 - <test name="testUpdateForConflict">
47.742 - <set name="system">
47.743 - <package name="zip" version="0:1-1" arch="i386"/>
47.744 - </set>
47.745 - <set name="repo">
47.746 - <package name="zsh" version="0:1-1" arch="i386">
47.747 - <conflicts name="zip" relation="LE" version="0:1-1"/>
47.748 - </package>
47.749 - <package name="zip" version="0:2-1" arch="i386"/>
47.750 - </set>
47.751 - <transaction>
47.752 - <install name="zsh"/>
47.753 - </transaction>
47.754 - <result>
47.755 - <set>
47.756 - <package name="zip" version="0:2-1" arch="i386"/>
47.757 - <package name="zsh" version="0:1-1" arch="i386"/>
47.758 - </set>
47.759 - </result>
47.760 - </test>
47.761 -
47.762 - <test name="testUpdateForConflict2">
47.763 - <set name="system">
47.764 - <package name="zip" version="0:1-1" arch="i386">
47.765 - <conflicts name="zsh" relation="LE" version="0:1-1"/>
47.766 - </package>
47.767 - </set>
47.768 - <set name="repo">
47.769 - <package name="zsh" version="0:1-1" arch="i386"/>
47.770 - <package name="zip" version="0:2-1" arch="i386"/>
47.771 - </set>
47.772 - <transaction>
47.773 - <install name="zsh"/>
47.774 - </transaction>
47.775 - <result>
47.776 - <set>
47.777 - <package name="zsh" version="0:1-1" arch="i386"/>
47.778 - <package name="zip" version="0:2-1" arch="i386"/>
47.779 - </set>
47.780 - </result>
47.781 - </test>
47.782 -
47.783 - <test name="testUpdateForConflictProvide">
47.784 - <set name="system">
47.785 - <package name="zip" version="0:1-1" arch="i386">
47.786 - <provides name="zippy" relation="EQ" version="0:1-1"/>
47.787 - </package>
47.788 - </set>
47.789 - <set name="repo">
47.790 - <package name="zsh" version="0:1-1" arch="i386">
47.791 - <conflicts name="zippy" relation="LE" version="0:1-1"/>
47.792 - </package>
47.793 - <package name="zip" version="0:2-1" arch="i386"/>
47.794 - </set>
47.795 - <transaction>
47.796 - <install name="zsh"/>
47.797 - </transaction>
47.798 - <result>
47.799 - <set>
47.800 - <package name="zip" version="0:2-1" arch="i386"/>
47.801 - <package name="zsh" version="0:1-1" arch="i386"/>
47.802 - </set>
47.803 - </result>
47.804 - </test>
47.805 -
47.806 - <test name="testUpdateForConflictProvide2">
47.807 - <set name="system">
47.808 - <package name="zip" version="0:1-1" arch="i386">
47.809 - <conflicts name="zippy" relation="GT" version="0:1-1"/>
47.810 - <conflicts name="zippy" relation="LT" version="0:1-1"/>
47.811 - </package>
47.812 - </set>
47.813 - <set name="repo">
47.814 - <package name="zsh" version="0:1-1" arch="i386">
47.815 - <provides name="zippy" relation="EQ" version="0:2-1"/>
47.816 - </package>
47.817 - <package name="zip" version="0:2-1" arch="i386">
47.818 - <conflicts name="zippy" relation="GT" version="0:2-1"/>
47.819 - <conflicts name="zippy" relation="LT" version="0:2-1"/>
47.820 - </package>
47.821 - </set>
47.822 - <transaction>
47.823 - <install name="zsh"/>
47.824 - </transaction>
47.825 - <result>
47.826 - <set>
47.827 - <package name="zip" version="0:2-1" arch="i386"/>
47.828 - <package name="zsh" version="0:1-1" arch="i386"/>
47.829 - </set>
47.830 - </result>
47.831 - </test>
47.832 -
47.833 - <test name="testEraseSinglePackage">
47.834 - <set name="system">
47.835 - <package name="zsh" version="0:1-1" arch="i386"/>
47.836 - </set>
47.837 - <set name="repo"/>
47.838 - <transaction>
47.839 - <remove name="zsh"/>
47.840 - </transaction>
47.841 - <result>
47.842 - <set/>
47.843 - </result>
47.844 - </test>
47.845 -
47.846 - <test name="testEraseSinglePackageRequiredByOneInstalled">
47.847 - <set name="system">
47.848 - <package name="zippy" version="0:1-1" arch="i386">
47.849 - <requires name="zsh"/>
47.850 - </package>
47.851 - <package name="zsh" version="0:1-1" arch="i386"/>
47.852 - </set>
47.853 - <set name="repo"/>
47.854 - <transaction>
47.855 - <remove name="zsh"/>
47.856 - </transaction>
47.857 - <result>
47.858 - <set/>
47.859 - </result>
47.860 - </test>
47.861 -</tests>
48.1 --- a/types.c Sun Jun 15 18:16:20 2008 -0400
48.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
48.3 @@ -1,277 +0,0 @@
48.4 -#include <stdlib.h>
48.5 -#include <string.h>
48.6 -
48.7 -#include "types.h"
48.8 -
48.9 -void
48.10 -array_init(struct array *array)
48.11 -{
48.12 - memset(array, 0, sizeof *array);
48.13 -}
48.14 -
48.15 -void
48.16 -array_release(struct array *array)
48.17 -{
48.18 - free(array->data);
48.19 -}
48.20 -
48.21 -void *
48.22 -array_add(struct array *array, int size)
48.23 -{
48.24 - int alloc;
48.25 - void *data, *p;
48.26 -
48.27 - if (array->alloc > 0)
48.28 - alloc = array->alloc;
48.29 - else
48.30 - alloc = 16;
48.31 -
48.32 - while (alloc < array->size + size)
48.33 - alloc *= 2;
48.34 -
48.35 - if (array->alloc < alloc) {
48.36 - data = realloc(array->data, alloc);
48.37 - if (data == NULL)
48.38 - return 0;
48.39 - array->data = data;
48.40 - array->alloc = alloc;
48.41 - }
48.42 -
48.43 - p = array->data + array->size;
48.44 - array->size += size;
48.45 -
48.46 - return p;
48.47 -}
48.48 -
48.49 -/* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */
48.50 -#define RAZOR_ENTRY_LAST 0x80
48.51 -#define RAZOR_IMMEDIATE 0x80
48.52 -#define RAZOR_EMPTY_LIST 0xff
48.53 -
48.54 -void
48.55 -list_set_empty(struct list_head *head)
48.56 -{
48.57 - head->list_ptr = ~0;
48.58 - head->flags = RAZOR_EMPTY_LIST;
48.59 -}
48.60 -
48.61 -void
48.62 -list_set_ptr(struct list_head *head, uint32_t ptr)
48.63 -{
48.64 - head->list_ptr = ptr;
48.65 - head->flags = 0;
48.66 -}
48.67 -
48.68 -void
48.69 -list_set_array(struct list_head *head, struct array *pool,
48.70 - struct array *items, int force_indirect)
48.71 -{
48.72 - struct list *p;
48.73 -
48.74 - if (!force_indirect) {
48.75 - if (items->size == 0) {
48.76 - list_set_empty(head);
48.77 - return;
48.78 - } else if (items->size == sizeof (uint32_t)) {
48.79 - head->list_ptr = *(uint32_t *) items->data;
48.80 - head->flags = RAZOR_IMMEDIATE;
48.81 - return;
48.82 - }
48.83 - }
48.84 -
48.85 - p = array_add(pool, items->size);
48.86 - memcpy(p, items->data, items->size);
48.87 - p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST;
48.88 - list_set_ptr(head, p - (struct list *) pool->data);
48.89 -}
48.90 -
48.91 -struct list *
48.92 -list_first(struct list_head *head, struct array *pool)
48.93 -{
48.94 - if (head->flags == RAZOR_EMPTY_LIST)
48.95 - return NULL;
48.96 - else if (head->flags == RAZOR_IMMEDIATE)
48.97 - return (struct list *) head;
48.98 - else
48.99 - return (struct list *) pool->data + head->list_ptr;
48.100 -}
48.101 -
48.102 -struct list *
48.103 -list_next(struct list *list)
48.104 -{
48.105 - if (list->flags)
48.106 - return NULL;
48.107 - return ++list;
48.108 -}
48.109 -
48.110 -void
48.111 -list_remap_pool(struct array *pool, uint32_t *map)
48.112 -{
48.113 - struct list *p, *end;
48.114 -
48.115 - end = pool->data + pool->size;
48.116 - for (p = pool->data; p < end; p++)
48.117 - p->data = map[p->data];
48.118 -}
48.119 -
48.120 -void
48.121 -list_remap_head(struct list_head *head, uint32_t *map)
48.122 -{
48.123 - if (head->flags == RAZOR_IMMEDIATE)
48.124 - head->list_ptr = map[head->list_ptr];
48.125 -}
48.126 -
48.127 -
48.128 -void
48.129 -hashtable_init(struct hashtable *table, struct array *pool)
48.130 -{
48.131 - array_init(&table->buckets);
48.132 - table->pool = pool;
48.133 -}
48.134 -
48.135 -void
48.136 -hashtable_release(struct hashtable *table)
48.137 -{
48.138 - array_release(&table->buckets);
48.139 -}
48.140 -
48.141 -static unsigned int
48.142 -hash_string(const char *key)
48.143 -{
48.144 - const char *p;
48.145 - unsigned int hash = 0;
48.146 -
48.147 - for (p = key; *p; p++)
48.148 - hash = (hash * 617) ^ *p;
48.149 -
48.150 - return hash;
48.151 -}
48.152 -
48.153 -uint32_t
48.154 -hashtable_lookup(struct hashtable *table, const char *key)
48.155 -{
48.156 - unsigned int mask, start, i;
48.157 - uint32_t *b;
48.158 - char *pool;
48.159 -
48.160 - pool = table->pool->data;
48.161 - mask = table->buckets.alloc - 1;
48.162 - start = hash_string(key) * sizeof(uint32_t);
48.163 -
48.164 - for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
48.165 - b = table->buckets.data + ((start + i) & mask);
48.166 -
48.167 - if (*b == 0)
48.168 - return 0;
48.169 -
48.170 - if (strcmp(key, &pool[*b]) == 0)
48.171 - return *b;
48.172 - }
48.173 -
48.174 - return 0;
48.175 -}
48.176 -
48.177 -static void
48.178 -do_insert(struct hashtable *table, uint32_t value)
48.179 -{
48.180 - unsigned int mask, start, i;
48.181 - uint32_t *b;
48.182 - const char *key;
48.183 -
48.184 - key = (char *) table->pool->data + value;
48.185 - mask = table->buckets.alloc - 1;
48.186 - start = hash_string(key) * sizeof(uint32_t);
48.187 -
48.188 - for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
48.189 - b = table->buckets.data + ((start + i) & mask);
48.190 - if (*b == 0) {
48.191 - *b = value;
48.192 - break;
48.193 - }
48.194 - }
48.195 -}
48.196 -
48.197 -static uint32_t
48.198 -add_to_string_pool(struct hashtable *table, const char *key)
48.199 -{
48.200 - int len;
48.201 - char *p;
48.202 -
48.203 - len = strlen(key) + 1;
48.204 - p = array_add(table->pool, len);
48.205 - memcpy(p, key, len);
48.206 -
48.207 - return p - (char *) table->pool->data;
48.208 -}
48.209 -
48.210 -uint32_t
48.211 -hashtable_insert(struct hashtable *table, const char *key)
48.212 -{
48.213 - uint32_t value, *buckets, *b, *end;
48.214 - int alloc;
48.215 -
48.216 - alloc = table->buckets.alloc;
48.217 - array_add(&table->buckets, 4 * sizeof *buckets);
48.218 - if (alloc != table->buckets.alloc) {
48.219 - end = table->buckets.data + alloc;
48.220 - memset(end, 0, table->buckets.alloc - alloc);
48.221 - for (b = table->buckets.data; b < end; b++) {
48.222 - value = *b;
48.223 - if (value != 0) {
48.224 - *b = 0;
48.225 - do_insert(table, value);
48.226 - }
48.227 - }
48.228 - }
48.229 -
48.230 - value = add_to_string_pool(table, key);
48.231 - do_insert (table, value);
48.232 -
48.233 - return value;
48.234 -}
48.235 -
48.236 -uint32_t
48.237 -hashtable_tokenize(struct hashtable *table, const char *string)
48.238 -{
48.239 - uint32_t token;
48.240 -
48.241 - if (string == NULL)
48.242 - string = "";
48.243 -
48.244 - token = hashtable_lookup(table, string);
48.245 - if (token != 0)
48.246 - return token;
48.247 -
48.248 - return hashtable_insert(table, string);
48.249 -}
48.250 -
48.251 -
48.252 -void
48.253 -bitarray_init(struct bitarray *bitarray, int size, int initial_value)
48.254 -{
48.255 - int bytes = ((size + 31) / 32) * 4;
48.256 -
48.257 - bitarray->bits = malloc(bytes);
48.258 - memset(bitarray->bits, initial_value ? 0xff : 0x00, bytes);
48.259 -}
48.260 -
48.261 -void
48.262 -bitarray_release(struct bitarray *bitarray)
48.263 -{
48.264 - free(bitarray->bits);
48.265 -}
48.266 -
48.267 -void
48.268 -bitarray_set(struct bitarray *bitarray, int bit, int value)
48.269 -{
48.270 - if (value)
48.271 - bitarray->bits[bit >> 5] |= 1 << (bit & 31);
48.272 - else
48.273 - bitarray->bits[bit >> 5] &= ~(1 << (bit & 31));
48.274 -}
48.275 -
48.276 -int
48.277 -bitarray_get(struct bitarray *bitarray, int bit)
48.278 -{
48.279 - return (bitarray->bits[bit >> 5] & (1 << (bit & 31))) != 0;
48.280 -}
49.1 --- a/types.h Sun Jun 15 18:16:20 2008 -0400
49.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
49.3 @@ -1,59 +0,0 @@
49.4 -#ifndef _RAZOR_TYPES_H_
49.5 -#define _RAZOR_TYPES_H_
49.6 -
49.7 -#include <stdint.h>
49.8 -
49.9 -struct array {
49.10 - void *data;
49.11 - int size, alloc;
49.12 -};
49.13 -
49.14 -void array_init(struct array *array);
49.15 -void array_release(struct array *array);
49.16 -void *array_add(struct array *array, int size);
49.17 -
49.18 -
49.19 -struct list_head {
49.20 - uint list_ptr : 24;
49.21 - uint flags : 8;
49.22 -};
49.23 -
49.24 -struct list {
49.25 - uint data : 24;
49.26 - uint flags : 8;
49.27 -};
49.28 -
49.29 -void list_set_empty(struct list_head *head);
49.30 -void list_set_ptr(struct list_head *head, uint32_t ptr);
49.31 -void list_set_array(struct list_head *head, struct array *pool, struct array *items, int force_indirect);
49.32 -
49.33 -struct list *list_first(struct list_head *head, struct array *pool);
49.34 -struct list *list_next(struct list *list);
49.35 -
49.36 -void list_remap_pool(struct array *pool, uint32_t *map);
49.37 -void list_remap_head(struct list_head *list, uint32_t *map);
49.38 -
49.39 -
49.40 -struct hashtable {
49.41 - struct array buckets;
49.42 - struct array *pool;
49.43 -};
49.44 -
49.45 -void hashtable_init(struct hashtable *table, struct array *pool);
49.46 -void hashtable_release(struct hashtable *table);
49.47 -uint32_t hashtable_insert(struct hashtable *table, const char *key);
49.48 -uint32_t hashtable_lookup(struct hashtable *table, const char *key);
49.49 -uint32_t hashtable_tokenize(struct hashtable *table, const char *string);
49.50 -
49.51 -
49.52 -struct bitarray {
49.53 - uint32_t *bits;
49.54 -};
49.55 -
49.56 -void bitarray_init(struct bitarray *bitarray, int size, int intial_value);
49.57 -void bitarray_release(struct bitarray *bitarray);
49.58 -void bitarray_set(struct bitarray *bitarray, int bit, int value);
49.59 -int bitarray_get(struct bitarray *bitarray, int bit);
49.60 -
49.61 -
49.62 -#endif /* _RAZOR_TYPES_H_ */
50.1 --- a/util.c Sun Jun 15 18:16:20 2008 -0400
50.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
50.3 @@ -1,167 +0,0 @@
50.4 -#include <limits.h>
50.5 -#include <string.h>
50.6 -#include <sys/stat.h>
50.7 -#include <stdlib.h>
50.8 -#include <stdio.h>
50.9 -#include <stdint.h>
50.10 -#include <unistd.h>
50.11 -
50.12 -#include "razor-internal.h"
50.13 -
50.14 -int
50.15 -razor_create_dir(const char *root, const char *path)
50.16 -{
50.17 - char buffer[PATH_MAX], *p;
50.18 - const char *slash, *next;
50.19 - struct stat buf;
50.20 -
50.21 - /* Create all sub-directories in dir. We know root exists and
50.22 - * is a dir, root does not end in a '/', and path has a
50.23 - * leading '/'. */
50.24 -
50.25 - strcpy(buffer, root);
50.26 - p = buffer + strlen(buffer);
50.27 - slash = path;
50.28 - for (slash = path; *slash != '\0'; slash = next) {
50.29 - next = strchr(slash + 1, '/');
50.30 - if (next == NULL)
50.31 - break;
50.32 -
50.33 - memcpy(p, slash, next - slash);
50.34 - p += next - slash;
50.35 - *p = '\0';
50.36 -
50.37 - if (stat(buffer, &buf) == 0) {
50.38 - if (!S_ISDIR(buf.st_mode)) {
50.39 - fprintf(stderr,
50.40 - "%s exists but is not a directory\n",
50.41 - buffer);
50.42 - return -1;
50.43 - }
50.44 - } else if (mkdir(buffer, 0777) < 0) {
50.45 - fprintf(stderr, "failed to make directory %s: %m\n",
50.46 - buffer);
50.47 - return -1;
50.48 - }
50.49 -
50.50 - /* FIXME: What to do about permissions for dirs we
50.51 - * have to create but are not in the cpio archive? */
50.52 - }
50.53 -
50.54 - return 0;
50.55 -}
50.56 -
50.57 -int
50.58 -razor_write(int fd, const void *data, size_t size)
50.59 -{
50.60 - size_t rest;
50.61 - ssize_t written;
50.62 - const unsigned char *p;
50.63 -
50.64 - rest = size;
50.65 - p = data;
50.66 - while (rest > 0) {
50.67 - written = write(fd, p, rest);
50.68 - if (written < 0) {
50.69 - fprintf(stderr, "write error: %m\n");
50.70 - return -1;
50.71 - }
50.72 - rest -= written;
50.73 - p += written;
50.74 - }
50.75 -
50.76 - return 0;
50.77 -}
50.78 -
50.79 -struct qsort_context {
50.80 - size_t size;
50.81 - razor_compare_with_data_func_t compare;
50.82 - void *data;
50.83 -};
50.84 -
50.85 -static void
50.86 -qsort_swap(void *p1, void *p2, size_t size)
50.87 -{
50.88 - char buffer[size];
50.89 -
50.90 - memcpy(buffer, p1, size);
50.91 - memcpy(p1, p2, size);
50.92 - memcpy(p2, buffer, size);
50.93 -}
50.94 -
50.95 -static void
50.96 -__qsort_with_data(void *base, size_t nelem, uint32_t *map,
50.97 - struct qsort_context *ctx)
50.98 -{
50.99 - void *p, *start, *end, *pivot;
50.100 - uint32_t *mp, *mstart, *mend, tmp;
50.101 - int left, right, result;
50.102 - size_t size = ctx->size;
50.103 -
50.104 - p = base;
50.105 - start = base;
50.106 - end = base + nelem * size;
50.107 - mp = map;
50.108 - mstart = map;
50.109 - mend = map + nelem;
50.110 - pivot = base + (random() % nelem) * size;
50.111 -
50.112 - while (p < end) {
50.113 - result = ctx->compare(p, pivot, ctx->data);
50.114 - if (result < 0) {
50.115 - qsort_swap(p, start, size);
50.116 - tmp = *mp;
50.117 - *mp = *mstart;
50.118 - *mstart = tmp;
50.119 - if (start == pivot)
50.120 - pivot = p;
50.121 - start += size;
50.122 - mstart++;
50.123 - p += size;
50.124 - mp++;
50.125 - } else if (result == 0) {
50.126 - p += size;
50.127 - mp++;
50.128 - } else {
50.129 - end -= size;
50.130 - mend--;
50.131 - qsort_swap(p, end, size);
50.132 - tmp = *mp;
50.133 - *mp = *mend;
50.134 - *mend = tmp;
50.135 - if (end == pivot)
50.136 - pivot = p;
50.137 - }
50.138 - }
50.139 -
50.140 - left = (start - base) / size;
50.141 - right = (base + nelem * size - end) / size;
50.142 - if (left > 1)
50.143 - __qsort_with_data(base, left, map, ctx);
50.144 - if (right > 1)
50.145 - __qsort_with_data(end, right, mend, ctx);
50.146 -}
50.147 -
50.148 -uint32_t *
50.149 -razor_qsort_with_data(void *base, size_t nelem, size_t size,
50.150 - razor_compare_with_data_func_t compare, void *data)
50.151 -{
50.152 - struct qsort_context ctx;
50.153 - uint32_t *map;
50.154 - int i;
50.155 -
50.156 - if (nelem == 0)
50.157 - return NULL;
50.158 -
50.159 - ctx.size = size;
50.160 - ctx.compare = compare;
50.161 - ctx.data = data;
50.162 -
50.163 - map = malloc(nelem * sizeof (uint32_t));
50.164 - for (i = 0; i < nelem; i++)
50.165 - map[i] = i;
50.166 -
50.167 - __qsort_with_data(base, nelem, map, &ctx);
50.168 -
50.169 - return map;
50.170 -}
51.1 --- a/yum.c Sun Jun 15 18:16:20 2008 -0400
51.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51.3 @@ -1,366 +0,0 @@
51.4 -/*
51.5 - * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
51.6 - * Copyright (C) 2008 Red Hat, Inc
51.7 - *
51.8 - * This program is free software; you can redistribute it and/or modify
51.9 - * it under the terms of the GNU General Public License as published by
51.10 - * the Free Software Foundation; either version 2 of the License, or
51.11 - * (at your option) any later version.
51.12 - *
51.13 - * This program is distributed in the hope that it will be useful,
51.14 - * but WITHOUT ANY WARRANTY; without even the implied warranty of
51.15 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51.16 - * GNU General Public License for more details.
51.17 - *
51.18 - * You should have received a copy of the GNU General Public License along
51.19 - * with this program; if not, write to the Free Software Foundation, Inc.,
51.20 - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
51.21 - */
51.22 -
51.23 -#define _GNU_SOURCE
51.24 -
51.25 -#include <string.h>
51.26 -#include <stdio.h>
51.27 -#include <sys/stat.h>
51.28 -#include <sys/mman.h>
51.29 -#include <unistd.h>
51.30 -#include <fcntl.h>
51.31 -#include <errno.h>
51.32 -
51.33 -#include <expat.h>
51.34 -#include <zlib.h>
51.35 -#include "razor.h"
51.36 -
51.37 -/* Import a yum filelist as a razor package set. */
51.38 -
51.39 -enum {
51.40 - YUM_STATE_BEGIN,
51.41 - YUM_STATE_PACKAGE_NAME,
51.42 - YUM_STATE_PACKAGE_ARCH,
51.43 - YUM_STATE_SUMMARY,
51.44 - YUM_STATE_DESCRIPTION,
51.45 - YUM_STATE_URL,
51.46 - YUM_STATE_LICENSE,
51.47 - YUM_STATE_CHECKSUM,
51.48 - YUM_STATE_REQUIRES,
51.49 - YUM_STATE_PROVIDES,
51.50 - YUM_STATE_OBSOLETES,
51.51 - YUM_STATE_CONFLICTS,
51.52 - YUM_STATE_FILE
51.53 -};
51.54 -
51.55 -struct yum_context {
51.56 - XML_Parser primary_parser;
51.57 - XML_Parser filelists_parser;
51.58 - XML_Parser current_parser;
51.59 -
51.60 - struct razor_importer *importer;
51.61 - struct import_property_context *current_property_context;
51.62 - char name[256], arch[64], summary[512], description[4096];
51.63 - char url[256], license[64], buffer[512], *p;
51.64 - char pkgid[128];
51.65 - int state;
51.66 -};
51.67 -
51.68 -static enum razor_version_relation
51.69 -yum_to_razor_flags (const char *flags)
51.70 -{
51.71 - /* FIXME? */
51.72 - if (!flags)
51.73 - return RAZOR_VERSION_EQUAL;
51.74 -
51.75 - if (flags[0] == 'L') {
51.76 - if (flags[1] == 'T')
51.77 - return RAZOR_VERSION_LESS;
51.78 - else
51.79 - return RAZOR_VERSION_LESS_OR_EQUAL;
51.80 - } else if (flags[0] == 'G') {
51.81 - if (flags[1] == 'T')
51.82 - return RAZOR_VERSION_GREATER;
51.83 - else
51.84 - return RAZOR_VERSION_GREATER_OR_EQUAL;
51.85 - } else
51.86 - return RAZOR_VERSION_EQUAL;
51.87 -}
51.88 -
51.89 -static void
51.90 -yum_primary_start_element(void *data, const char *name, const char **atts)
51.91 -{
51.92 - struct yum_context *ctx = data;
51.93 - const char *n, *epoch, *version, *release, *flags;
51.94 - char buffer[128];
51.95 - int i;
51.96 -
51.97 - if (strcmp(name, "name") == 0) {
51.98 - ctx->state = YUM_STATE_PACKAGE_NAME;
51.99 - ctx->p = ctx->name;
51.100 - } else if (strcmp(name, "arch") == 0) {
51.101 - ctx->state = YUM_STATE_PACKAGE_ARCH;
51.102 - ctx->p = ctx->arch;
51.103 - } else if (strcmp(name, "version") == 0) {
51.104 - epoch = NULL;
51.105 - version = NULL;
51.106 - release = NULL;
51.107 - for (i = 0; atts[i]; i += 2) {
51.108 - if (strcmp(atts[i], "epoch") == 0)
51.109 - epoch = atts[i + 1];
51.110 - else if (strcmp(atts[i], "ver") == 0)
51.111 - version = atts[i + 1];
51.112 - else if (strcmp(atts[i], "rel") == 0)
51.113 - release = atts[i + 1];
51.114 - }
51.115 - if (version == NULL || release == NULL) {
51.116 - fprintf(stderr, "invalid version tag, "
51.117 - "missing version or release attribute\n");
51.118 - return;
51.119 - }
51.120 -
51.121 - razor_build_evr(buffer, sizeof buffer, epoch, version, release);
51.122 - razor_importer_begin_package(ctx->importer,
51.123 - ctx->name, buffer, ctx->arch);
51.124 - } else if (strcmp(name, "summary") == 0) {
51.125 - ctx->p = ctx->summary;
51.126 - ctx->state = YUM_STATE_SUMMARY;
51.127 - } else if (strcmp(name, "description") == 0) {
51.128 - ctx->p = ctx->description;
51.129 - ctx->state = YUM_STATE_DESCRIPTION;
51.130 - } else if (strcmp(name, "url") == 0) {
51.131 - ctx->p = ctx->url;
51.132 - ctx->state = YUM_STATE_URL;
51.133 - } else if (strcmp(name, "checksum") == 0) {
51.134 - ctx->p = ctx->pkgid;
51.135 - ctx->state = YUM_STATE_CHECKSUM;
51.136 - } else if (strcmp(name, "rpm:license") == 0) {
51.137 - ctx->p = ctx->license;
51.138 - ctx->state = YUM_STATE_LICENSE;
51.139 - } else if (strcmp(name, "rpm:requires") == 0) {
51.140 - ctx->state = YUM_STATE_REQUIRES;
51.141 - } else if (strcmp(name, "rpm:provides") == 0) {
51.142 - ctx->state = YUM_STATE_PROVIDES;
51.143 - } else if (strcmp(name, "rpm:obsoletes") == 0) {
51.144 - ctx->state = YUM_STATE_OBSOLETES;
51.145 - } else if (strcmp(name, "rpm:conflicts") == 0) {
51.146 - ctx->state = YUM_STATE_CONFLICTS;
51.147 - } else if (strcmp(name, "rpm:entry") == 0 &&
51.148 - ctx->state != YUM_STATE_BEGIN) {
51.149 - n = NULL;
51.150 - epoch = NULL;
51.151 - version = NULL;
51.152 - release = NULL;
51.153 - flags = NULL;
51.154 - for (i = 0; atts[i]; i += 2) {
51.155 - if (strcmp(atts[i], "name") == 0)
51.156 - n = atts[i + 1];
51.157 - else if (strcmp(atts[i], "epoch") == 0)
51.158 - epoch = atts[i + 1];
51.159 - else if (strcmp(atts[i], "ver") == 0)
51.160 - version = atts[i + 1];
51.161 - else if (strcmp(atts[i], "rel") == 0)
51.162 - release = atts[i + 1];
51.163 - else if (strcmp(atts[i], "flags") == 0)
51.164 - flags = atts[i + 1];
51.165 - }
51.166 -
51.167 - if (n == NULL) {
51.168 - fprintf(stderr, "invalid rpm:entry, "
51.169 - "missing name or version attributes\n");
51.170 - return;
51.171 - }
51.172 -
51.173 - razor_build_evr(buffer, sizeof buffer, epoch, version, release);
51.174 - switch (ctx->state) {
51.175 - case YUM_STATE_REQUIRES:
51.176 - razor_importer_add_property(ctx->importer, n,
51.177 - yum_to_razor_flags (flags),
51.178 - buffer,
51.179 - RAZOR_PROPERTY_REQUIRES);
51.180 - break;
51.181 - case YUM_STATE_PROVIDES:
51.182 - razor_importer_add_property(ctx->importer, n,
51.183 - yum_to_razor_flags (flags),
51.184 - buffer,
51.185 - RAZOR_PROPERTY_PROVIDES);
51.186 - break;
51.187 - case YUM_STATE_OBSOLETES:
51.188 - razor_importer_add_property(ctx->importer, n,
51.189 - yum_to_razor_flags (flags),
51.190 - buffer,
51.191 - RAZOR_PROPERTY_OBSOLETES);
51.192 - break;
51.193 - case YUM_STATE_CONFLICTS:
51.194 - razor_importer_add_property(ctx->importer, n,
51.195 - yum_to_razor_flags (flags),
51.196 - buffer,
51.197 - RAZOR_PROPERTY_CONFLICTS);
51.198 - break;
51.199 - }
51.200 - }
51.201 -}
51.202 -
51.203 -static void
51.204 -yum_primary_end_element (void *data, const char *name)
51.205 -{
51.206 - struct yum_context *ctx = data;
51.207 -
51.208 - switch (ctx->state) {
51.209 - case YUM_STATE_PACKAGE_NAME:
51.210 - case YUM_STATE_PACKAGE_ARCH:
51.211 - case YUM_STATE_SUMMARY:
51.212 - case YUM_STATE_DESCRIPTION:
51.213 - case YUM_STATE_URL:
51.214 - case YUM_STATE_LICENSE:
51.215 - case YUM_STATE_CHECKSUM:
51.216 - case YUM_STATE_FILE:
51.217 - ctx->state = YUM_STATE_BEGIN;
51.218 - break;
51.219 - }
51.220 -
51.221 - if (strcmp(name, "package") == 0) {
51.222 - razor_importer_add_details(ctx->importer, ctx->summary,
51.223 - ctx->description, ctx->url,
51.224 - ctx->license);
51.225 -
51.226 - XML_StopParser(ctx->current_parser, XML_TRUE);
51.227 - ctx->current_parser = ctx->filelists_parser;
51.228 - }
51.229 -}
51.230 -
51.231 -static void
51.232 -yum_character_data (void *data, const XML_Char *s, int len)
51.233 -{
51.234 - struct yum_context *ctx = data;
51.235 -
51.236 - switch (ctx->state) {
51.237 - case YUM_STATE_PACKAGE_NAME:
51.238 - case YUM_STATE_PACKAGE_ARCH:
51.239 - case YUM_STATE_SUMMARY:
51.240 - case YUM_STATE_DESCRIPTION:
51.241 - case YUM_STATE_URL:
51.242 - case YUM_STATE_LICENSE:
51.243 - case YUM_STATE_CHECKSUM:
51.244 - case YUM_STATE_FILE:
51.245 - memcpy(ctx->p, s, len);
51.246 - ctx->p += len;
51.247 - *ctx->p = '\0';
51.248 - break;
51.249 - }
51.250 -}
51.251 -
51.252 -static void
51.253 -yum_filelists_start_element(void *data, const char *name, const char **atts)
51.254 -{
51.255 - struct yum_context *ctx = data;
51.256 - const char *pkg, *pkgid;
51.257 - int i;
51.258 -
51.259 - if (strcmp(name, "package") == 0) {
51.260 - pkg = NULL;
51.261 - pkgid = NULL;
51.262 - for (i = 0; atts[i]; i += 2) {
51.263 - if (strcmp(atts[i], "name") == 0)
51.264 - pkg = atts[i + 1];
51.265 - else if (strcmp(atts[i], "pkgid") == 0)
51.266 - pkgid = atts[i + 1];
51.267 - }
51.268 - if (strcmp(pkgid, ctx->pkgid) != 0)
51.269 - fprintf(stderr, "primary.xml and filelists.xml "
51.270 - "mismatch for %s: %s vs %s",
51.271 - pkg, pkgid, ctx->pkgid);
51.272 - } else if (strcmp(name, "file") == 0) {
51.273 - ctx->state = YUM_STATE_FILE;
51.274 - ctx->p = ctx->buffer;
51.275 - }
51.276 -}
51.277 -
51.278 -
51.279 -static void
51.280 -yum_filelists_end_element (void *data, const char *name)
51.281 -{
51.282 - struct yum_context *ctx = data;
51.283 -
51.284 - ctx->state = YUM_STATE_BEGIN;
51.285 - if (strcmp(name, "package") == 0) {
51.286 - XML_StopParser(ctx->current_parser, XML_TRUE);
51.287 - ctx->current_parser = ctx->primary_parser;
51.288 - razor_importer_finish_package(ctx->importer);
51.289 - } else if (strcmp(name, "file") == 0)
51.290 - razor_importer_add_file(ctx->importer, ctx->buffer);
51.291 -
51.292 -}
51.293 -
51.294 -#define XML_BUFFER_SIZE 4096
51.295 -
51.296 -struct razor_set *
51.297 -razor_set_create_from_yum(void)
51.298 -{
51.299 - struct yum_context ctx;
51.300 - void *buf;
51.301 - int len, ret;
51.302 - gzFile primary, filelists;
51.303 - XML_ParsingStatus status;
51.304 -
51.305 - ctx.importer = razor_importer_new();
51.306 - ctx.state = YUM_STATE_BEGIN;
51.307 -
51.308 - ctx.primary_parser = XML_ParserCreate(NULL);
51.309 - XML_SetUserData(ctx.primary_parser, &ctx);
51.310 - XML_SetElementHandler(ctx.primary_parser,
51.311 - yum_primary_start_element,
51.312 - yum_primary_end_element);
51.313 - XML_SetCharacterDataHandler(ctx.primary_parser,
51.314 - yum_character_data);
51.315 -
51.316 - ctx.filelists_parser = XML_ParserCreate(NULL);
51.317 - XML_SetUserData(ctx.filelists_parser, &ctx);
51.318 - XML_SetElementHandler(ctx.filelists_parser,
51.319 - yum_filelists_start_element,
51.320 - yum_filelists_end_element);
51.321 - XML_SetCharacterDataHandler(ctx.filelists_parser,
51.322 - yum_character_data);
51.323 -
51.324 - primary = gzopen("primary.xml.gz", "rb");
51.325 - if (primary == NULL)
51.326 - return NULL;
51.327 - filelists = gzopen("filelists.xml.gz", "rb");
51.328 - if (filelists == NULL)
51.329 - return NULL;
51.330 -
51.331 - ctx.current_parser = ctx.primary_parser;
51.332 -
51.333 - do {
51.334 - XML_GetParsingStatus(ctx.current_parser, &status);
51.335 - switch (status.parsing) {
51.336 - case XML_SUSPENDED:
51.337 - ret = XML_ResumeParser(ctx.current_parser);
51.338 - break;
51.339 - case XML_PARSING:
51.340 - case XML_INITIALIZED:
51.341 - buf = XML_GetBuffer(ctx.current_parser,
51.342 - XML_BUFFER_SIZE);
51.343 - if (ctx.current_parser == ctx.primary_parser)
51.344 - len = gzread(primary, buf, XML_BUFFER_SIZE);
51.345 - else
51.346 - len = gzread(filelists, buf, XML_BUFFER_SIZE);
51.347 - if (len < 0) {
51.348 - fprintf(stderr,
51.349 - "couldn't read input: %s\n",
51.350 - strerror(errno));
51.351 - return NULL;
51.352 - }
51.353 -
51.354 - XML_ParseBuffer(ctx.current_parser, len, len == 0);
51.355 - break;
51.356 - case XML_FINISHED:
51.357 - break;
51.358 - }
51.359 - } while (status.parsing != XML_FINISHED);
51.360 -
51.361 -
51.362 - XML_ParserFree(ctx.primary_parser);
51.363 - XML_ParserFree(ctx.filelists_parser);
51.364 -
51.365 - gzclose(primary);
51.366 - gzclose(filelists);
51.367 -
51.368 - return razor_importer_finish(ctx.importer);
51.369 -}