/[gentoo]/xml/htdocs/proj/en/glep/glep-0025.html
Gentoo

Contents of /xml/htdocs/proj/en/glep/glep-0025.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (hide annotations) (download) (as text)
Sun Oct 14 17:00:15 2007 UTC (6 years, 10 months ago) by antarus
Branch: MAIN
CVS Tags: HEAD
Changes since 1.5: +4 -251 lines
File MIME type: text/html
the canary on 53 went well, changing the rest

1 g2boojum 1.1 <?xml version="1.0" encoding="utf-8" ?>
2     <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
3     <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
4 antarus 1.6
5 g2boojum 1.1 <head>
6     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
7 g2boojum 1.4 <meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
8 g2boojum 1.1 <title>GLEP 25 -- Distfile Patching Support</title>
9 antarus 1.6 <link rel="stylesheet" href="tools/glep.css" type="text/css" />
10 g2boojum 1.1 </head>
11     <body bgcolor="white">
12     <table class="navigation" cellpadding="0" cellspacing="0"
13     width="100%" border="0">
14     <tr><td class="navicon" width="150" height="35">
15     <a href="http://www.gentoo.org/" title="Gentoo Linux Home Page">
16     <img src="http://www.gentoo.org/images/gentoo-new.gif" alt="[Gentoo]"
17     border="0" width="150" height="35" /></a></td>
18     <td class="textlinks" align="left">
19     [<b><a href="http://www.gentoo.org/">Gentoo Linux Home</a></b>]
20 antarus 1.6 [<b><a href="http://www.gentoo.org/proj/en/glep">GLEP Index</a></b>]
21 g2boojum 1.4 [<b><a href="http://www.gentoo.org/proj/en/glep/glep-0025.txt">GLEP Source</a></b>]
22 g2boojum 1.1 </td></tr></table>
23 g2boojum 1.3 <table class="rfc2822 docutils field-list" frame="void" rules="none">
24 g2boojum 1.1 <col class="field-name" />
25     <col class="field-body" />
26     <tbody valign="top">
27     <tr class="field"><th class="field-name">GLEP:</th><td class="field-body">25</td>
28     </tr>
29     <tr class="field"><th class="field-name">Title:</th><td class="field-body">Distfile Patching Support</td>
30     </tr>
31 g2boojum 1.3 <tr class="field"><th class="field-name">Version:</th><td class="field-body">1.3</td>
32 g2boojum 1.1 </tr>
33 g2boojum 1.4 <tr class="field"><th class="field-name">Last-Modified:</th><td class="field-body"><a class="reference" href="http://www.gentoo.org/cgi-bin/viewcvs.cgi/xml/htdocs/proj/en/glep/glep-0025.txt?cvsroot=gentoo">2005/04/01 01:32:19</a></td>
34 g2boojum 1.1 </tr>
35     <tr class="field"><th class="field-name">Author:</th><td class="field-body">Brian Harring &lt;ferringb&#32;&#97;t&#32;gentoo.org&gt;</td>
36     </tr>
37 g2boojum 1.2 <tr class="field"><th class="field-name">Status:</th><td class="field-body">deferred</td>
38 g2boojum 1.1 </tr>
39     <tr class="field"><th class="field-name">Type:</th><td class="field-body">Standards Track</td>
40     </tr>
41 g2boojum 1.4 <tr class="field"><th class="field-name">Content-Type:</th><td class="field-body"><a class="reference" href="glep-0002.html">text/x-rst</a></td>
42 g2boojum 1.1 </tr>
43     <tr class="field"><th class="field-name">Created:</th><td class="field-body">6-Mar-2004</td>
44     </tr>
45 g2boojum 1.2 <tr class="field"><th class="field-name">Post-History:</th><td class="field-body">4-Apr-2004, 11-Nov-2004</td>
46 g2boojum 1.1 </tr>
47     </tbody>
48     </table>
49     <hr />
50 g2boojum 1.4 <div class="contents topic">
51     <p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
52 g2boojum 1.1 <ul class="simple">
53     <li><a class="reference" href="#abstract" id="id7" name="id7">Abstract</a></li>
54 g2boojum 1.2 <li><a class="reference" href="#status" id="id8" name="id8">Status</a></li>
55     <li><a class="reference" href="#motivation" id="id9" name="id9">Motivation</a></li>
56     <li><a class="reference" href="#binary-patches-vs-gnudiff-patches" id="id10" name="id10">Binary patches vs GNUDiff patches</a></li>
57     <li><a class="reference" href="#rationale" id="id11" name="id11">Rationale</a></li>
58     <li><a class="reference" href="#specification" id="id12" name="id12">Specification</a><ul>
59     <li><a class="reference" href="#additions-to-the-tree" id="id13" name="id13">Additions to the tree</a></li>
60     <li><a class="reference" href="#portage-implementation" id="id14" name="id14">Portage Implementation</a><ul>
61     <li><a class="reference" href="#fetching" id="id15" name="id15">Fetching</a></li>
62     <li><a class="reference" href="#reconstruction" id="id16" name="id16">Reconstruction</a></li>
63     <li><a class="reference" href="#compressed-md5sums" id="id17" name="id17">Compressed MD5sums:</a><ul>
64     <li><a class="reference" href="#the-problem-in-detail" id="id18" name="id18">The Problem in Detail</a></li>
65     <li><a class="reference" href="#the-proposed-solution" id="id19" name="id19">The Proposed Solution</a></li>
66 g2boojum 1.1 </ul>
67     </li>
68     </ul>
69     </li>
70 g2boojum 1.2 <li><a class="reference" href="#distfile-mirror-additions" id="id20" name="id20">Distfile Mirror Additions</a></li>
71     <li><a class="reference" href="#patch-creation" id="id21" name="id21">Patch Creation</a></li>
72 g2boojum 1.1 </ul>
73     </li>
74 g2boojum 1.3 <li><a class="reference" href="#backwards-compatibility" id="id22" name="id22">Backwards Compatibility</a></li>
75 g2boojum 1.2 <li><a class="reference" href="#reference-implementation" id="id23" name="id23">Reference Implementation</a></li>
76     <li><a class="reference" href="#references" id="id24" name="id24">References</a></li>
77     <li><a class="reference" href="#copyright" id="id25" name="id25">Copyright</a></li>
78 g2boojum 1.1 </ul>
79     </div>
80 g2boojum 1.4 <div class="section">
81     <h1><a class="toc-backref" href="#id7" id="abstract" name="abstract">Abstract</a></h1>
82 g2boojum 1.1 <p>The intention of this GLEP is to propose the creation of patching support for
83     portage, and iron out the implementation details.</p>
84     </div>
85 g2boojum 1.4 <div class="section">
86     <h1><a class="toc-backref" href="#id8" id="status" name="status">Status</a></h1>
87 g2boojum 1.2 <p>Timed out</p>
88     </div>
89 g2boojum 1.4 <div class="section">
90     <h1><a class="toc-backref" href="#id9" id="motivation" name="motivation">Motivation</a></h1>
91 g2boojum 1.1 <p>Reduce the bandwidth load placed on our mirrors by decreasing the amount of
92     bytes transferred when upgrading between versions. Side benefit of this is to
93     significantly decrease the download requirements for users lacking broadband.</p>
94     </div>
95 g2boojum 1.4 <div class="section">
96     <h1><a class="toc-backref" href="#id10" id="binary-patches-vs-gnudiff-patches" name="binary-patches-vs-gnudiff-patches">Binary patches vs GNUDiff patches</a></h1>
97 g2boojum 1.1 <p>Most people are familiar with diff patches (unified diff for example)- this
98     glep is specifically proposing the use of an actual binary differencer. The
99     reason for this is that diff patches are line based- you change a single
100     character in a line, and the whole line must be included in the patch. Binary
101     differencers work at the byte level- it encodes just that byte. In that
102     respect binary patches are often much more efficient then diff patches.</p>
103     <p>Further, the ability to reverse a unified patch is due to the fact the diff
104     includes <strong>both</strong> the original line, and the modified line. The author isn't
105     aware of any binary differencer that is able to create patches the can be
106     reversed- basically they're unidirectional, the patch that is generated can
107     only be used to upgrade or downgrade the version, not both. The plus side of
108     this limitation is a significantly decreased patch size.</p>
109     <p>The choice of binary patches over diff patches pretty much comes down to the
110     fact they're smaller- example being a kdelibs binary patch for 3.1.4-&gt;3.1.5 is
111     75kb, the equivalent diff patch is 123kb, and is unable to result in a correct
112     md5 <a class="footnote-reference" href="#id4" id="id1" name="id1">[1]</a>.</p>
113     <p>Currently, this glep is proposing only the usage of binary patches- that's not
114     to say (with a fair amount of work) it couldn't be extended to support
115     standard diffs.</p>
116     </div>
117 g2boojum 1.4 <div class="section">
118     <h1><a class="toc-backref" href="#id11" id="rationale" name="rationale">Rationale</a></h1>
119 g2boojum 1.1 <p>The difference between source releases typically isn't very large, especially
120     for minor releases. As an example, kdelibs-3.1.4.tar.bz2 is 10.53 MB, and
121     kdelibs-3.1.5.tar.bz2 is 10.54 MB. A bzip2'ed patch between those versions is
122     75.6 kb <a class="footnote-reference" href="#id5" id="id2" name="id2">[2]</a>, less then 1% the size of 3.1.5's tbz2.</p>
123     </div>
124 g2boojum 1.4 <div class="section">
125     <h1><a class="toc-backref" href="#id12" id="specification" name="specification">Specification</a></h1>
126 g2boojum 1.1 <p>Quite a few sections of gentoo are affected- mirroring, the portage tree, and
127     portage itself.</p>
128 g2boojum 1.4 <div class="section">
129     <h2><a class="toc-backref" href="#id13" id="additions-to-the-tree" name="additions-to-the-tree">Additions to the tree</a></h2>
130 g2boojum 1.1 <p>For adding patch info into the tree, this glep proposes a global patch list
131     (stored in profiles as patches.global), and individual patch lists stored in
132     relevant package directories (named patches). Using the kernel packages as an
133     example, a global list of patches enables us to create a patch once, add an
134     entry, and have all kernel packages benefit from that single entry. Both
135     patches.global, and individual package patch files share the same format:</p>
136     <pre class="literal-block">
137     MD5 md5-value patch-url size MD5 md5-value ref-file size UMD5 md5-value new-file size
138     </pre>
139     <p>For those familiar with digest file layout, this should look familiar.
140     Essentially, chksum type, value, filename, size. The UMD5 chksum type is just
141     the uncompressed md5/size of the file- so if the UMD5 were for a bzip2
142     compressed file, it would be the md5 value/size of the uncompressed file.
143     And an example:</p>
144     <pre class="literal-block">
145     MD5 ccd5411b3558326cbce0306fcae32e26 http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5.patch.bz2 75687 MD5 82c265de78d53c7060a09c5cb1a78942 kdelibs-3.1.4.tar.bz2 10537433 UMD5 0b1908a51e739c07ff5a88e189d2f7a9 kdelibs-3.1.5.tar.bz2 48056320
146     </pre>
147     <p>In the above example, the md5sum of
148     <a class="reference" href="http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5.patch.bz2">http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5.patch.bz2</a> is
149     calculated, compared to the stored value, and then the file size is checked.
150     The one difference is the UMD5 checksum type- the md5 value and the size are
151     specific to the <em>uncompressed</em> file. Continuing, for cases where the patch
152     will reside on one of our mirrors, the patch filename would be sufficient.</p>
153     <p>Finally, note that this is a unidirectional patch- using the above example,
154     kdelibs-3.1.4-3.1.5 can <strong>only</strong> be used to upgrade from 3.1.4 to 3.1.5, not
155     in reverse (originally explained in <a class="reference" href="#binary-patches-vs-gnudiff-patches">Binary patches vs GNUDiff patches</a>).</p>
156     </div>
157 g2boojum 1.4 <div class="section">
158     <h2><a class="toc-backref" href="#id14" id="portage-implementation" name="portage-implementation">Portage Implementation</a></h2>
159 g2boojum 1.1 <p>This glep proposes the patching support should be (at this stage) optional-
160     specifically, enabled via FEATURES=&quot;patching&quot;.</p>
161 g2boojum 1.4 <div class="section">
162     <h3><a class="toc-backref" href="#id15" id="fetching" name="fetching">Fetching</a></h3>
163 g2boojum 1.1 <p>When patching is enabled, the global patch list is read, and the packages
164     patch list is read. From there, portage determines what files could be used
165     as a base for patching to the desired file- further, determining if it's
166     actually worth patching (case where it wouldn't be is when the target file is
167     less then the sum of the patches needed). Any patches to be used are fetched,
168     and md5 verified.</p>
169     </div>
170 g2boojum 1.4 <div class="section">
171     <h3><a class="toc-backref" href="#id16" id="reconstruction" name="reconstruction">Reconstruction</a></h3>
172 g2boojum 1.1 <p>Upon fetching and md5 verification of patch(es), the desired file is
173     reconstructed. Assuming reconstruction didn't return any errors, the target
174     file has its uncompressed md5sum calculated and verified, then is recompressed
175     and the compressed md5sum calculated. At this point, if the compressed md5
176     matches the md5 stored in the tree, then portage transfers the file into
177     distfiles, and continues on it's merry way.</p>
178     <p>If the compressed md5 is different from the tree's value, then the (proposed)
179     md5 database is updated with new compressed md5. Details of this database
180     (and the issue it addresses) follow.</p>
181     </div>
182 g2boojum 1.4 <div class="section">
183     <h3><a class="toc-backref" href="#id17" id="compressed-md5sums" name="compressed-md5sums">Compressed MD5sums:</a></h3>
184 g2boojum 1.1 <p>There will be instances where a file is reconstructed perfectly, recompressed,
185     and the recompressed md5sum differs from what is stored in the tree- the
186     problem is that the md5sum of a compressed file is inherently tied to the
187     compressor version/options used to compress the original source.</p>
188 g2boojum 1.4 <div class="section">
189     <h4><a class="toc-backref" href="#id18" id="the-problem-in-detail" name="the-problem-in-detail">The Problem in Detail</a></h4>
190 g2boojum 1.1 <p>A good example of this problem is related to bzip2 versions used for
191     compression. Between bzip2 0.9x and bzip2 1.x, there was a subtle change in
192     the compressor resulting in a slightly better compression result- end result
193     being a different file, eg a different md5sum. Assuming compressor versions
194     are the same, there also is the issue of what compression level the target
195     source was originally compressed at- was it compressed with -9, -8 or -7?
196     That's just a sampling of the various original settings that must be accounted
197     for, and that's limited to gzip/bzip2; other compressors will add to the
198     number of variables to be accounted for to produce an exact recreation of the
199     compressed md5sum.</p>
200     <p>Tracking the compressor version and options originally used isn't really a
201     valid option- assuming all options were accounted for, clients would still be
202     required to have multiple versions of the same compressor installed just for
203     the sake of recreating a compressed md5sum <em>even though</em> the uncompressed
204     source's md5 has already been verified.</p>
205     </div>
206 g2boojum 1.4 <div class="section">
207     <h4><a class="toc-backref" href="#id19" id="the-proposed-solution" name="the-proposed-solution">The Proposed Solution</a></h4>
208 g2boojum 1.1 <p>The creation of a clientside flatfile/db of valid alternate md5/size pairs
209     would enable portage to handle perfectly reconstructed files, that have a
210     different md5sum due to compression differences. The proposed format is thus:</p>
211     <pre class="literal-block">
212     MD5 md5sum orig-file size MD5 md5sum [ optional new-name ] size
213     </pre>
214     <p>Example:</p>
215     <pre class="literal-block">
216     MD5 984146931906a7d53300b29f58f6a899 OOo_1.0.3_source.tar.bz2 165475319 MD5 0733dd85ed44d88d1eabed704d579721 165444187
217     </pre>
218     <p>An alternate md5/size pair for a file would be added <strong>only</strong> when the
219     uncompressed source's md5/size has been verified, yet upon recompression the
220     md5 differs. For cleansing of older md5/size pairs from this db, a utility
221     would be required- the author suggests the addition of a distfiles-cleaning
222     utility to portage, with the ability to also cleanse old md5/size pairs when
223     the file the pair was created for no longer exists in distfiles.</p>
224     <p>Where to store the database is debatable- /etc/portage or /var/cache/edb are
225     definite options.</p>
226     <p>The reasoning for allowing for an optional new-name is that it provides needed
227     functionality should anyone attempt to extend portage to allow for clients to
228     change the compression used for a source (eg, recompress all gzip files as
229     bzip2). Granted, no such code or attempt has been made, but nothing is lost
230     by leaving the option open should the request/attempt be made.</p>
231     <p>A potential gotcha of adding this support is that in environments where the
232     distfiles directory is shared out to multiple systems, this db must be shared
233     also.</p>
234     </div>
235     </div>
236     </div>
237 g2boojum 1.4 <div class="section">
238     <h2><a class="toc-backref" href="#id20" id="distfile-mirror-additions" name="distfile-mirror-additions">Distfile Mirror Additions</a></h2>
239 g2boojum 1.1 <p>One issue of contention is where these files will actually be stored. As of
240     the writing of this glep, a full distfiles mirror is roughly around 40 gb- a
241     rough estimate by the author places the space requirements for patches for
242     each version at a total of around 4gb. Note this isn't even remotely a hard
243     figure yet, and a better figure is being checked into currently.</p>
244     <p>Regardless of the exact space figure, finding a place to store the patches
245     will be problematic. Expansion of the required mirror space (essentially just
246     swallowing the patches storage requirement) is unlikely, since it was one of
247     the main arguements against the now defunct glep9 attempt <a class="footnote-reference" href="#id5" id="id3" name="id3">[2]</a>. A couple of
248     ideas that have been put forth to handle the additional space requirements are
249     as follows-</p>
250     <p>1) Identification of mirrors willing to handle the extra space requirements-
251     essentially create an additional patch mirror tier.</p>
252     <p>2) Mirroring only a patch for certain package versions, rather then full
253     source. Using kdelibs-3.1.5 as an example, only the patch would be mirrored
254     (rather then the full 10.53 MB source). Downside to this approach is that a
255     user who is downloading kdelibs for the first time would either need to pull
256     it from the original SRC_URI (placing the burden onto the upstream mirror), or
257     pull the 3.1.4 version, and the patch- pulling 63k more then if they had just
258     pulled the full version. The kdelibs 3.1.4/3.1.5 example is something of an
259     optimal case- not all versions will have such miniscule patches.</p>
260     <p>3) A variation on the idea above, essentially mirroring only the patch for
261     the oldest version(s) of a package; eg, kdelibs currently has version 3.05,
262     3.1.5, 3.2.0, and 3.2.1- the mirrors would only carry a patch for 3.05, not
263     full source (think RESTRICT=&quot;fetch&quot;). One plus to this is that patches to
264     downgrade in version are smaller then the patches to upgrade in version- there
265     are exceptions to this, but they're hard to find. A major downside to this
266     approach is A) a user would have to sync up to get the patchlists for that
267     version, B) creation of a set of patches to go backwards in version (see
268     <a class="reference" href="#binary-patches-vs-gnudiff-patches">Binary patches vs GNUDiff patches</a>)..</p>
269     <p>Of the options listed above, the first is the easiest, although the second
270     could be made to work. Feedback and any possible alternatives would be
271     greatly appreciated.</p>
272     </div>
273 g2boojum 1.4 <div class="section">
274     <h2><a class="toc-backref" href="#id21" id="patch-creation" name="patch-creation">Patch Creation</a></h2>
275 g2boojum 1.1 <p>Maintenance of patch lists, and the actual patch creation ought to be managed
276     by a high level script- essentally a dev says &quot;I want a patch between this
277     version, and that version: make it so&quot;, the script churns away
278     creating/updating the patch list, and generating the patch locally. The
279     utility next uploads the new patch to /space/distfiles-local on dev.gentoo.org
280     (exempting if it's not a locally generated patch), and repoman is used to
281     commit the updated patch list.</p>
282     <p>What would be preferable (although possibly wishful thinking), is if hardware
283     could be co-opted for automatic patch generation, rather then forcing it upon
284     the devs- something akin to how files are pulled onto the mirror automatically
285     for new ebuilds.</p>
286     <p>The initial bulk of patches to get will be generated by the author, to ease
287     the transition and offer patches for people to test out.</p>
288     </div>
289     </div>
290 g2boojum 1.4 <div class="section">
291     <h1><a class="toc-backref" href="#id22" id="backwards-compatibility" name="backwards-compatibility">Backwards Compatibility</a></h1>
292 g2boojum 1.1 <p>As noted in <a class="reference" href="#the-proposed-solution">The Proposed Solution</a>, a system using patching and sharing out
293     it's distfiles must share out it's alternate md5 db. Any system that uses the
294     distfiles share must support the alternate md5 db also. If this is considered
295     enough of an issue, it is conceivable to place reconstructed sources with an
296     alternate md5 into a subdirectory of distdir- portage only looks within
297     distdir, unwilling to descend into subdirectories.</p>
298     <p>Also note that <a class="reference" href="#distfile-mirror-additions">Distfile Mirror Additions</a> may add additional backwards
299 g2boojum 1.3 compatibility issues, depending on what solution is accepted.</p>
300 g2boojum 1.1 </div>
301 g2boojum 1.4 <div class="section">
302     <h1><a class="toc-backref" href="#id23" id="reference-implementation" name="reference-implementation">Reference Implementation</a></h1>
303 g2boojum 1.1 <p>TODO</p>
304     </div>
305 g2boojum 1.4 <div class="section">
306     <h1><a class="toc-backref" href="#id24" id="references" name="references">References</a></h1>
307 g2boojum 1.3 <table class="docutils footnote" frame="void" id="id4" rules="none">
308 g2boojum 1.1 <colgroup><col class="label" /><col /></colgroup>
309     <tbody valign="top">
310     <tr><td class="label"><a class="fn-backref" href="#id1" name="id4">[1]</a></td><td><a class="reference" href="http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5">http://dev.gentoo.org/~ferringb/patches/kdelibs-3.1.4-3.1.5</a>.{patch,diff}.bz2.</td></tr>
311     </tbody>
312     </table>
313 g2boojum 1.3 <table class="docutils footnote" frame="void" id="id5" rules="none">
314 g2boojum 1.1 <colgroup><col class="label" /><col /></colgroup>
315     <tbody valign="top">
316 g2boojum 1.4 <tr><td class="label"><a name="id5">[2]</a></td><td><em>(<a class="fn-backref" href="#id2">1</a>, <a class="fn-backref" href="#id3">2</a>)</em> kdelibs-3.1.4-3.1.5.patch.bz2, switching format patch, created via diffball-0.4_pre4 (diffball is available at <a class="reference" href="http://sourceforge.net/projects/diffball">http://sourceforge.net/projects/diffball</a>)
317 g2boojum 1.1 Bzip2 -9 compressed, the patch is 75,687 bytes, uncompressed it is 337,649 bytes. The patch is available at <a class="reference" href="http://dev.gentoo.org/~ferringb/kdelibs-3.1.4-3.1.5.patch.bz2">http://dev.gentoo.org/~ferringb/kdelibs-3.1.4-3.1.5.patch.bz2</a> for those curious.</td></tr>
318     </tbody>
319     </table>
320 g2boojum 1.3 <table class="docutils footnote" frame="void" id="id6" rules="none">
321 g2boojum 1.1 <colgroup><col class="label" /><col /></colgroup>
322     <tbody valign="top">
323 g2boojum 1.4 <tr><td class="label"><a name="id6">[3]</a></td><td>Glep9, 'Gentoo Package Update System'
324 g2boojum 1.1 (<a class="reference" href="http://glep.gentoo.org/glep-0009.html">http://glep.gentoo.org/glep-0009.html</a>)</td></tr>
325     </tbody>
326     </table>
327     </div>
328 g2boojum 1.4 <div class="section">
329     <h1><a class="toc-backref" href="#id25" id="copyright" name="copyright">Copyright</a></h1>
330 g2boojum 1.1 <p>This document has been placed in the public domain.</p>
331     </div>
332 g2boojum 1.3
333 g2boojum 1.1 </div>
334     <div class="footer">
335 g2boojum 1.4 <hr class="footer" />
336 g2boojum 1.1 <a class="reference" href="glep-0025.txt">View document source</a>.
337 antarus 1.6 Generated on: 2007-10-13 13:39 UTC.
338 g2boojum 1.1 Generated by <a class="reference" href="http://docutils.sourceforge.net/">Docutils</a> from <a class="reference" href="http://docutils.sourceforge.net/rst.html">reStructuredText</a> source.
339 g2boojum 1.4
340 g2boojum 1.1 </div>
341     </body>
342     </html>

  ViewVC Help
Powered by ViewVC 1.1.20