6 * Written by Keith Marshall <keithmarshall@users.sourceforge.net>
7 * Copyright (C) 2009, 2010, MinGW Project
10 * Implementation of repository binding for the pkgXmlDocument class.
13 * This is free software. Permission is granted to copy, modify and
14 * redistribute this software, under the provisions of the GNU General
15 * Public License, Version 3, (or, at your option, any later version),
16 * as published by the Free Software Foundation; see the file COPYING
17 * for licensing details.
19 * Note, in particular, that this software is provided "as is", in the
20 * hope that it may prove useful, but WITHOUT WARRANTY OF ANY KIND; not
21 * even an implied WARRANTY OF MERCHANTABILITY, nor of FITNESS FOR ANY
22 * PARTICULAR PURPOSE. Under no circumstances will the author, or the
23 * MinGW Project, accept liability for any damages, however caused,
24 * arising from the use of this software.
36 pkgXmlNode *pkgXmlDocument::BindRepositories( bool force_update )
38 /* Identify the repositories specified in the application profile,
39 * and merge their associated package distribution lists into the
40 * active XML database, which is bound to the profile.
42 pkgXmlNode *dbase = GetRoot();
44 /* Before blindly proceeding, perform a sanity check...
45 * Verify that this XML database defines an application profile,
46 * and that the associated application is "mingw-get"...
48 if( (strcmp( dbase->GetName(), profile_key ) == 0)
49 && (strcmp( dbase->GetPropVal( application_key, "?" ), "mingw-get") == 0) )
51 /* Sanity check passed...
52 * Walk the XML data tree, selecting "repository" specifications...
54 pkgXmlNode *repository = dbase->FindFirstAssociate( repository_key );
55 while( repository != NULL )
57 /* For each "repository" specified, identify its "catalogues"...
59 * FIXME: this requires the "package-lists" to be individually
60 * specified within the locally defined "repository" elements;
61 * it should allow for deduction of these, from a specifically
62 * named "repository-index" file identified via the repository
63 * URI template, and hosted by the download server itself.
65 pkgXmlNode *catalogue = repository->FindFirstAssociate( package_list_key );
66 while( catalogue != NULL )
68 /* ...and for each named "catalogue"...
70 const char *dfile, *dname = catalogue->GetPropVal( catalogue_key, NULL );
71 if( (dname != NULL) && ((dfile = xmlfile( dname )) != NULL) )
73 /* Check for a locally cached copy of the "package-list" file...
75 if( force_update || (access( dfile, F_OK ) != 0) )
77 * When performing an "update", or if no local copy is available...
78 * Force a "sync", to fetch a copy from the public host.
80 SyncRepository( dname, repository );
82 /* We SHOULD now have a locally cached copy of the package-list;
83 * attempt to merge it into the active profile database...
85 pkgXmlDocument merge( dfile );
88 /* We successfully loaded the XML catalogue; refer to its
91 dmh_printf( "Bind repository: %s\n", merge.Value() );
93 if( (pkglist = merge.GetRoot()) != NULL )
95 /* ...read it, selecting each of the "package-collection"
96 * records contained within it...
98 pkglist = pkglist->FindFirstAssociate( package_collection_key );
99 while( pkglist != NULL )
101 /* ...and append a copy of each to the active profile...
103 dbase->LinkEndChild( pkglist->Clone() );
105 /* Move on to the next "package-collection" (if any)
106 * within the current catalogue...
108 pkglist = pkglist->FindNextAssociate( package_collection_key );
113 dmh_notify( DMH_WARNING, "Bind repository: FAILED: %s\n", dfile );
115 /* However we handled it, the XML file's path name in "dfile" was
116 * allocated on the heap; we lose its reference on termination of
117 * this loop, so we must free it to avoid a memory leak.
119 free( (void *)(dfile) );
122 /* A repository may comprise an arbitrary collection of software
123 * catalogues; move on, to process the next catalogue (if any) in
124 * the current repository collection.
126 catalogue = catalogue->FindNextAssociate( package_list_key );
129 /* Similarly, a complete distribution may draw from an arbitrary set
130 * of distinct repositories; move on, to process the next repository
131 * specified (if any).
133 repository = repository->FindNextAssociate( repository_key );
136 /* On successful completion, return a pointer to the root node
137 * of the active XML profile.
142 /* Fall through on total failure to interpret the profile, returning
143 * NULL to indicate failure.
148 /* $RCSfile$: end of file */