summaryrefslogtreecommitdiffstats
path: root/zarb-ml/mageia-sysadm/attachments/20110105
diff options
context:
space:
mode:
authorNicolas Vigier <boklm@mageia.org>2013-04-14 13:46:12 +0000
committerNicolas Vigier <boklm@mageia.org>2013-04-14 13:46:12 +0000
commit1be510f9529cb082f802408b472a77d074b394c0 (patch)
treeb175f9d5fcb107576dabc768e7bd04d4a3e491a0 /zarb-ml/mageia-sysadm/attachments/20110105
parentfa5098cf210b23ab4f419913e28af7b1b07dafb2 (diff)
downloadarchives-master.tar
archives-master.tar.gz
archives-master.tar.bz2
archives-master.tar.xz
archives-master.zip
Add zarb MLs html archivesHEADmaster
Diffstat (limited to 'zarb-ml/mageia-sysadm/attachments/20110105')
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment-0001.html82
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment.html82
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment-0001.html76
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment.html76
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment-0001.html84
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment.html84
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment-0001.html6045
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment.html6045
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment-0001.html2256
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment.html2256
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment-0001.html90
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment.html90
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment-0001.html77
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment.html77
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment-0001.html135
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment.html135
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment-0001.html11434
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment.html11434
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment-0001.html103
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment.html103
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment-0001.html88
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment.html88
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment-0001.html70
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment.html70
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment-0001.html77
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment.html77
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment-0001.html63
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment.html63
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment-0001.html85
-rw-r--r--zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment.html85
30 files changed, 41530 insertions, 0 deletions
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment-0001.html
new file mode 100644
index 000000000..5b2f8a432
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment-0001.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[654] Add ssh key for pterjan.</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>654</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 14:41:16 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>Add ssh key for pterjan.
+He will be helping in the setup of the buildsystem (youri, iurt, ...)</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmanifestscommonpp">puppet/manifests/common.pp</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmanifestscommonpp">Modified: puppet/manifests/common.pp</a>
+===================================================================
+--- puppet/manifests/common.pp 2011-01-05 00:59:39 UTC (rev 653)
++++ puppet/manifests/common.pp 2011-01-05 13:41:16 UTC (rev 654)
+@@ -73,6 +73,12 @@
+ key =&gt; &quot;AAAAB3NzaC1kc3MAAACBAMFaCUsen6ZYH8hsjGK0tlaguduw4YT2KD3TaDEK24ltKzvQ+NDiPRms1zPhTpRL0p0U5QVdIMxm/asAtuiMLMxdmU+Crry6s110mKKY2930ZEk6N4YJ4DbqSiYe2JBmpJVIEJ6Betgn7yZRR2mRM7j134PddAl8BGG+RUvzib7JAAAAFQDzu/G2R+6oe3vjIbbFpOTyR3PAbwAAAIEAmqXAGybY9CVgGChSztPEdvaZ1xOVGJtmxmlWvitWGpu8m5JBf57VhzdpT4Fsf4fiVZ7NWiwPm1DzqNX7xCH7IPLPK0jQSd937xG9Un584CguNB76aEQXv0Yl5VjOrC3DggIEfZ1KLV7GcpOukw0RerxKz99rYAThp6+qzBIrv38AAACBAKhXi7uNlajescWFjiCZ3fpnxdyGAgtKzvlz60mGKwwNyaQCVmPSmYeBI2tg1qk+0I5K6LZUxWkdhuE1UfvAbIrEdwyD8p53dPg1J9DpdQ1KqApeKqLxO02KJtfomuy3cRQXmdfOTovYN7zAu1NCp51uUNTzhIpDHx0MZ6bsWSFv&quot;,
+ user =&gt; &quot;root&quot;
+ }
++
++ ssh_authorized_key { &quot;ssh key pterjan&quot;:
++ type =&gt; &quot;ssh-rsa&quot;,
++ key =&gt; &quot;AAAAB3NzaC1yc2EAAAABIwAAAQEAspyZMl5zAkk5SL45zFvtJF7UhXTRb0bEaZ3nuCC1Ql5wM3GWuftqd5zLH88dCu7ZO/BVh213LZTq/UHb6lI7kWalygk53qtdEx2cywjWFOW23Rg6xybatCEZ2/ZrpGZoBGnu63otAp4h2Nnj/VkOio3pGwD8vavmZ4xPrcECPAwtMPJsYf44Ptu2JdXizi4iY8I0/HKitQ113I4NbDcAiMKbTXSbOfqC+ldcgW3+9xShx/kuMFTKeJOy4LI4GR6gykzkV6+vfnalp24x/SIEjuohBarCRQKo4megHqZOzdMYAHqq0QuNubXURNb0Mvz1sE7Y8AFIxwSfXdQGi5hcQQ==&quot;,
++ user =&gt; &quot;root&quot;
++ }
+ }
+
+ class urpmi_update {
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment.html
new file mode 100644
index 000000000..5b2f8a432
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/07855687/attachment.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[654] Add ssh key for pterjan.</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>654</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 14:41:16 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>Add ssh key for pterjan.
+He will be helping in the setup of the buildsystem (youri, iurt, ...)</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmanifestscommonpp">puppet/manifests/common.pp</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmanifestscommonpp">Modified: puppet/manifests/common.pp</a>
+===================================================================
+--- puppet/manifests/common.pp 2011-01-05 00:59:39 UTC (rev 653)
++++ puppet/manifests/common.pp 2011-01-05 13:41:16 UTC (rev 654)
+@@ -73,6 +73,12 @@
+ key =&gt; &quot;AAAAB3NzaC1kc3MAAACBAMFaCUsen6ZYH8hsjGK0tlaguduw4YT2KD3TaDEK24ltKzvQ+NDiPRms1zPhTpRL0p0U5QVdIMxm/asAtuiMLMxdmU+Crry6s110mKKY2930ZEk6N4YJ4DbqSiYe2JBmpJVIEJ6Betgn7yZRR2mRM7j134PddAl8BGG+RUvzib7JAAAAFQDzu/G2R+6oe3vjIbbFpOTyR3PAbwAAAIEAmqXAGybY9CVgGChSztPEdvaZ1xOVGJtmxmlWvitWGpu8m5JBf57VhzdpT4Fsf4fiVZ7NWiwPm1DzqNX7xCH7IPLPK0jQSd937xG9Un584CguNB76aEQXv0Yl5VjOrC3DggIEfZ1KLV7GcpOukw0RerxKz99rYAThp6+qzBIrv38AAACBAKhXi7uNlajescWFjiCZ3fpnxdyGAgtKzvlz60mGKwwNyaQCVmPSmYeBI2tg1qk+0I5K6LZUxWkdhuE1UfvAbIrEdwyD8p53dPg1J9DpdQ1KqApeKqLxO02KJtfomuy3cRQXmdfOTovYN7zAu1NCp51uUNTzhIpDHx0MZ6bsWSFv&quot;,
+ user =&gt; &quot;root&quot;
+ }
++
++ ssh_authorized_key { &quot;ssh key pterjan&quot;:
++ type =&gt; &quot;ssh-rsa&quot;,
++ key =&gt; &quot;AAAAB3NzaC1yc2EAAAABIwAAAQEAspyZMl5zAkk5SL45zFvtJF7UhXTRb0bEaZ3nuCC1Ql5wM3GWuftqd5zLH88dCu7ZO/BVh213LZTq/UHb6lI7kWalygk53qtdEx2cywjWFOW23Rg6xybatCEZ2/ZrpGZoBGnu63otAp4h2Nnj/VkOio3pGwD8vavmZ4xPrcECPAwtMPJsYf44Ptu2JdXizi4iY8I0/HKitQ113I4NbDcAiMKbTXSbOfqC+ldcgW3+9xShx/kuMFTKeJOy4LI4GR6gykzkV6+vfnalp24x/SIEjuohBarCRQKo4megHqZOzdMYAHqq0QuNubXURNb0Mvz1sE7Y8AFIxwSfXdQGi5hcQQ==&quot;,
++ user =&gt; &quot;root&quot;
++ }
+ }
+
+ class urpmi_update {
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment-0001.html
new file mode 100644
index 000000000..fe00d542c
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment-0001.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[658] - also add identity trunk, while I am on it</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>658</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:09:53 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- also add identity trunk, while I am on it</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulesbindtemplateszonesmageiaorgzone">puppet/modules/bind/templates/zones/mageia.org.zone</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulesbindtemplateszonesmageiaorgzone">Modified: puppet/modules/bind/templates/zones/mageia.org.zone</a>
+===================================================================
+--- puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:52 UTC (rev 657)
++++ puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:53 UTC (rev 658)
+@@ -77,6 +77,7 @@
+ ldap IN CNAME valstar
+
+ identity IN CNAME alamut
++identity-trunk IN CNAME alamut
+ mirrors IN CNAME alamut
+ epoll IN CNAME alamut
+ pgsql IN CNAME alamut
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment.html
new file mode 100644
index 000000000..fe00d542c
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/157b5a6b/attachment.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[658] - also add identity trunk, while I am on it</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>658</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:09:53 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- also add identity trunk, while I am on it</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulesbindtemplateszonesmageiaorgzone">puppet/modules/bind/templates/zones/mageia.org.zone</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulesbindtemplateszonesmageiaorgzone">Modified: puppet/modules/bind/templates/zones/mageia.org.zone</a>
+===================================================================
+--- puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:52 UTC (rev 657)
++++ puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:53 UTC (rev 658)
+@@ -77,6 +77,7 @@
+ ldap IN CNAME valstar
+
+ identity IN CNAME alamut
++identity-trunk IN CNAME alamut
+ mirrors IN CNAME alamut
+ epoll IN CNAME alamut
+ pgsql IN CNAME alamut
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment-0001.html
new file mode 100644
index 000000000..552abf6bf
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment-0001.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[213] - revert commit 196.</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>213</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 21:13:05 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- revert commit 196. The button is near the form because it is related to the
+form, while the link are not. ( ie, we use spatial proximity as a affordance )</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#identityCatDaptrunkrootindextt">identity/CatDap/trunk/root/index.tt</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="identityCatDaptrunkrootindextt">Modified: identity/CatDap/trunk/root/index.tt</a>
+===================================================================
+--- identity/CatDap/trunk/root/index.tt 2011-01-05 15:32:57 UTC (rev 212)
++++ identity/CatDap/trunk/root/index.tt 2011-01-05 20:13:05 UTC (rev 213)
+@@ -10,13 +10,13 @@
+ &lt;label for=&quot;password_&quot;&gt;[% l('Password : ') %]&lt;/label&gt;
+ &lt;input id=&quot;password_&quot; type=&quot;password&quot; name=&quot;password&quot; /&gt;
+ &lt;br /&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; &gt;[% l('Login') %]&lt;/button&gt;
+ &lt;/div&gt;
+ &lt;div id=&quot;login_form_line&quot;&gt;
+ &lt;span&gt;&lt;a href=&quot;/register&quot;&gt;[% l('Register') %]&lt;/a&gt; |
+ @todo [% l('Forgotten password?') %]
+ &lt;!--&lt;a href=&quot;/forgot_password&quot;&gt;[% l('Forgotten password?') %]&lt;/a&gt; --&gt;
+ &lt;/span&gt;
+- &lt;button type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; &gt;[% l('Login') %]&lt;/button&gt;
+ &lt;/div&gt;
+ &lt;/form&gt;
+ &lt;/div&gt;
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment.html
new file mode 100644
index 000000000..552abf6bf
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/2168be7c/attachment.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[213] - revert commit 196.</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>213</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 21:13:05 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- revert commit 196. The button is near the form because it is related to the
+form, while the link are not. ( ie, we use spatial proximity as a affordance )</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#identityCatDaptrunkrootindextt">identity/CatDap/trunk/root/index.tt</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="identityCatDaptrunkrootindextt">Modified: identity/CatDap/trunk/root/index.tt</a>
+===================================================================
+--- identity/CatDap/trunk/root/index.tt 2011-01-05 15:32:57 UTC (rev 212)
++++ identity/CatDap/trunk/root/index.tt 2011-01-05 20:13:05 UTC (rev 213)
+@@ -10,13 +10,13 @@
+ &lt;label for=&quot;password_&quot;&gt;[% l('Password : ') %]&lt;/label&gt;
+ &lt;input id=&quot;password_&quot; type=&quot;password&quot; name=&quot;password&quot; /&gt;
+ &lt;br /&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; &gt;[% l('Login') %]&lt;/button&gt;
+ &lt;/div&gt;
+ &lt;div id=&quot;login_form_line&quot;&gt;
+ &lt;span&gt;&lt;a href=&quot;/register&quot;&gt;[% l('Register') %]&lt;/a&gt; |
+ @todo [% l('Forgotten password?') %]
+ &lt;!--&lt;a href=&quot;/forgot_password&quot;&gt;[% l('Forgotten password?') %]&lt;/a&gt; --&gt;
+ &lt;/span&gt;
+- &lt;button type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; &gt;[% l('Login') %]&lt;/button&gt;
+ &lt;/div&gt;
+ &lt;/form&gt;
+ &lt;/div&gt;
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment-0001.html
new file mode 100644
index 000000000..ca22eaf1b
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment-0001.html
@@ -0,0 +1,6045 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[209] add mandriva version of youri-submit, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/submit/trunk at revision 271600</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>209</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 14:19:06 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add mandriva version of youri-submit, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/submit/trunk at revision 271600</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>build_system/mdv-youri-submit/</li>
+<li>build_system/mdv-youri-submit/branches/</li>
+<li>build_system/mdv-youri-submit/tags/</li>
+<li>build_system/mdv-youri-submit/trunk/</li>
+<li><a href="#build_systemmdvyourisubmittrunkChangeLog">build_system/mdv-youri-submit/trunk/ChangeLog</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkMANIFESTSKIP">build_system/mdv-youri-submit/trunk/MANIFEST.SKIP</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkMakefilePL">build_system/mdv-youri-submit/trunk/Makefile.PL</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkREADME">build_system/mdv-youri-submit/trunk/README</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkTODO">build_system/mdv-youri-submit/trunk/TODO</a></li>
+<li>build_system/mdv-youri-submit/trunk/bin/</li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyouricheckin">build_system/mdv-youri-submit/trunk/bin/youri-check.in</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmit">build_system/mdv-youri-submit/trunk/bin/youri-submit</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmitproxyin">build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmitrestrictedin">build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmitin">build_system/mdv-youri-submit/trunk/bin/youri-submit.in</a></li>
+<li>build_system/mdv-youri-submit/trunk/etc/</li>
+<li>build_system/mdv-youri-submit/trunk/etc/bash_completion.d/</li>
+<li><a href="#build_systemmdvyourisubmittrunketcbash_completiondyourisubmit">build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit</a></li>
+<li><a href="#build_systemmdvyourisubmittrunketcsubmitconf">build_system/mdv-youri-submit/trunk/etc/submit.conf</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/</li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/</li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/</li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionArchivepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionBugzillapm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionCVSpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionCleanpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionDkmsModuleInfopm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionInstallpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionLinkpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionMailpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionMarkreleasepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionRSSpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionRpminfopm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionSendpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionSendcachepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionSignpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionUnpackpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionUpdateMdvDbpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckACLpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckHistorypm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckHostpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckPrecedencepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckQueue_recencypm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckRecencypm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckRpmlintpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckSVNpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckSectionpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckSourcepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckTagpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckTypepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckVersionpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPluginpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostCleanRpmsratepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostGendistribpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostGenhdlist2pm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPreRsyncpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPrepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectArchivepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectCleanpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectInstallpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectMailpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/t/</li>
+<li><a href="#build_systemmdvyourisubmittrunkt00distributiont">build_system/mdv-youri-submit/trunk/t/00distribution.t</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemmdvyourisubmittrunkChangeLog">Added: build_system/mdv-youri-submit/trunk/ChangeLog</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/ChangeLog (rev 0)
++++ build_system/mdv-youri-submit/trunk/ChangeLog 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,606 @@
++2008-02-19 07:50 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: fix &quot;grep_files&quot; handling
++
++2008-02-12 09:42 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: do not make rpmlint errors
++ fatal anymore (asked by fcrozat)
++
++2008-02-08 17:49 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: remove results occurences and
++ update doc
++
++2008-02-08 17:48 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: make all rpmlint errors fatal
++
++2008-02-08 17:44 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: removed unneeded parentheses
++
++2008-02-08 17:44 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: make clear
++ repository/target/define are unused
++
++2008-02-08 17:43 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: use scalar for fd
++
++2008-01-31 16:35 pixel
++
++ * lib/Youri/Submit/Action/Link.pm: also call -&gt;set_arch_changed
++ when linking a noarch file to another arch
++ (this still doesn't explain media/media_info/MD5SUM not being
++ remade, but it
++ can help...)
++
++2007-12-21 14:37 blino
++
++ * bin/youri-submit.in: merge youri-submit into youri-submit.in
++
++2007-12-19 13:43 blino
++
++ * lib/Youri/Submit/Action/Archive.pm: only log main/updates
++ modifications, not contrib/updates or non-free/updates which are
++ legal
++
++2007-12-19 13:37 blino
++
++ * lib/Youri/Submit/Action/Archive.pm: add spuk's debug code for bug
++ 34999
++
++2007-12-17 19:45 blino
++
++ * bin/youri-submit: add an &quot;allow_omitting_packages&quot; global option,
++ to be able to run youri even if no packages are specified on the
++ command line (useful if packages are fetched in pre action)
++
++2007-12-17 19:34 blino
++
++ * bin/youri-submit: improve error messages for pres/posts actions
++ (patch from raoh's copy, probably from warly)
++
++2007-12-17 19:33 blino
++
++ * bin/youri-submit: fix typo about posts actions (patch from raoh's
++ copy, probably from warly)
++
++2007-12-13 15:01 pixel
++
++ * lib/Youri/Submit/Check/Version.pm: - empty {authorized_users}
++ doesn't imply every one is allowed to bypass freeze check!
++ - {authorized_users} should be checked more strictly
++
++2007-12-07 18:26 spuk
++
++ * lib/Youri/Submit/Action/Sendcache.pm: - make Sendcache send debug
++ packages only if explicitly told to, to save space
++
++2007-11-30 19:29 spuk
++
++ * lib/Youri/Submit/Action/UpdateMdvDb.pm: Youri action to update
++ the Mandriva maintainers database.
++
++2007-10-04 20:07 blino
++
++ * lib/Youri/Submit/Check/Host.pm: make host reject message more
++ explicit by print arch (useful when VMware-player for x86_64
++ actually uses i386 as rpm arch...)
++
++2007-09-26 11:21 blino
++
++ * lib/Youri/Submit/Action/Install.pm: improve log message
++
++2007-09-26 11:19 blino
++
++ * lib/Youri/Submit/Action/Install.pm: fix installed filename (oops)
++
++2007-09-26 09:58 blino
++
++ * lib/Youri/Submit/Action/Install.pm: throw exception on failure,
++ not to delete files that can be copied because of lack of space
++ (upstream commit 1398)
++
++2007-09-25 10:49 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: allow to unpack only some
++ files (for release-notes.txt in mandriva-release-common)
++
++2007-09-22 13:11 blino
++
++ * lib/Youri/Submit/Check/Version.pm: allow authorized users to
++ upload everything even during full freeze
++
++2007-08-31 12:51 pixel
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: handle new rpmlint format
++ (not useful at the moment since we still use old rpmlint, but may
++ be useful in
++ the future)
++
++2007-08-31 10:03 blino
++
++ * lib/Youri/Submit/Action/DkmsModuleInfo.pm: adapt to new
++ SOURCEPACKAGE value in prebuilt dkms kernel
++
++2007-08-29 13:21 blino
++
++ * lib/Youri/Submit/Action/DkmsModuleInfo.pm: initial
++ Youri::Submit::Action::DkmsModuleInfo module
++
++2007-08-07 12:50 pixel
++
++ * lib/Youri/Submit/Action/Link.pm: we need the same workaround as
++ done in Action::Install
++
++2007-07-16 09:27 blino
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: remove unused variable
++
++2007-07-08 02:44 spuk
++
++ * lib/Youri/Submit/Check/Recency.pm: - check for newer/current
++ revisions in default section when submitted to another section
++ (bug #30635)
++
++2007-07-02 09:17 pixel
++
++ * lib/Youri/Submit/Action/CVS.pm: drop mdv specific stuff (mdv
++ doesn't use this action anymore)
++
++2007-06-28 07:40 pixel
++
++ * lib/Youri/Submit/Action/Link.pm: do update hdlist for every arch
++ after linking noarch packages (#31638)
++
++2007-06-28 07:37 pixel
++
++ * lib/Youri/Submit/Action/Install.pm: simplify ($arch is not used
++ by -&gt;set_install_dir_changed)
++
++2007-06-23 13:54 pixel
++
++ * lib/Youri/Submit/Action/Mail.pm, lib/Youri/Submit/Reject/Mail.pm:
++ keep raw changelogs to avoid changing the format (backport)
++
++2007-06-23 08:10 spuk
++
++ * lib/Youri/Submit/Check/Recency.pm: - check for newer and same
++ existing revisions in a single pass
++ - use proper get_revisions() instead of get_install_file() hack,
++ as the
++ latter will use the current file name, and thus will fail to
++ check for an
++ existing package revision when submitting, because submitted
++ SRPMs have a
++ different name (&quot;@rev:foobar-...&quot;) than what goes into the
++ repository
++
++2007-06-22 13:51 pixel
++
++ * lib/Youri/Submit/Post/CleanRpmsrate.pm: ensure we don't do
++ anything if nothing changed
++
++2007-06-22 13:41 pixel
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: more atomic generation of
++ MD5SUM
++
++2007-06-22 13:35 pixel
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: - need to redo global
++ MD5SUM. This MD5SUM is mostly obsolete, but is still needed up to
++ 2007.1
++ (and needed even on cooker for existing urpmi.cfg)
++ - don't use --blind. hopefully not needed
++
++2007-06-22 06:45 pixel
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: call genhdlist2 with (new)
++ option --allow-empty-media
++
++2007-06-21 10:13 blino
++
++ * lib/Youri/Submit/Post/CleanRpmsrate.pm: uniquify arch list
++
++2007-06-21 08:16 pixel
++
++ * lib/Youri/Submit/Action/Install.pm,
++ lib/Youri/Submit/Post/Genhdlist2.pm: new action Genhdlist2
++
++2007-06-14 18:23 mrl
++
++ * lib/Youri/Submit/Action/Sendcache.pm: - As this action is unique,
++ avoid too much flexibility and simplify the code.
++ - Use . for hidding temporary files instead of .new suffix.
++
++2007-06-13 18:36 mrl
++
++ * lib/Youri/Submit/Action/Sendcache.pm: - Adapted for working with
++ iurt cache.
++
++2007-06-13 01:48 spuk
++
++ * lib/Youri/Submit/Action/Link.pm: no such 'cd' function, 'chdir'
++ it is...
++
++2007-05-08 06:22 spuk
++
++ * lib/Youri/Submit/Reject/Mail.pm: fixing the Big SVN Breakage:
++ reverting last commit, restoring state as of latest working
++ checkout in ken
++
++2007-05-08 06:06 spuk
++
++ * lib/Youri/Submit/Post/Gendistrib.pm: fixing the Big SVN Breakage:
++ restoring state as of working checkout in ken
++
++2007-05-08 06:00 spuk
++
++ * lib/Youri/Submit/Action/Scp.pm: fixing the Big SVN Breakage:
++ Scp.pm was changed into Send.pm
++
++2007-05-05 06:16 spuk
++
++ * lib/Youri/Submit/Check/Section.pm: Check if package submission
++ was for the correct section.
++
++2007-03-24 11:36 spuk
++
++ * lib/Youri/Submit/Action/Archive.pm: - moved hack for verbosity to
++ start of code, with a remark
++ - removed double $path from debug string
++
++2007-03-15 12:36 mrl
++
++ * lib/Youri/Submit/Check/Version.pm: - Fixed version_freeze mode:
++ do not allow any upload with a different version
++ from what is already present on the repository.
++ - Added an ACL control for maintainers allowed to bypass this
++ restriction as option
++ authorized_users.
++
++2007-03-15 12:32 mrl
++
++ * lib/Youri/Submit/Check/Version.pm: - Improved indentation.
++ - Added some comments regarding possible bugs in freeze modes.
++
++2005-05-24 14:40 Sawyer
++
++ * lib/Youri/Submit/Reject/Mail.pm: LOST
++
++2007-03-10 07:49 spuk
++
++ * lib/Youri/Submit/Action/Archive.pm: The extra '/' was causing the
++ string to not be matched by the regexp below
++ for getting $rep_section and $rep_main_section, in the end making
++ the SRPMs
++ of all other subsections be removed when a newer package was
++ uploaded for any
++ subsection. (#28719)
++
++2007-02-26 10:56 blino
++
++ * lib/Youri/Submit/Post/CleanRpmsrate.pm: initial
++ Post::CleanRpmsrate module
++
++2007-02-14 12:10 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: match rpmlint errors that have
++ no value (such as non-xdg-migrated-menu, the only one we
++ currently use...)
++
++2007-02-09 22:11 blino
++
++ * bin/youri-submit: get -&gt; get_arg
++
++2007-02-09 22:09 blino
++
++ * bin/youri-submit: merge changes from ken/kenobi
++
++2007-02-09 22:09 blino
++
++ * bin/youri-submit: create youri-submit from youri-submit.in
++
++2007-02-09 19:39 blino
++
++ * lib/Youri/Submit/Check/ACL.pm: add section in acl error message
++
++2007-02-09 19:34 blino
++
++ * lib/Youri/Submit/Reject/Mail.pm: do not use packager adress as
++ from, it may be invalid (non-free packages) or not subscribed to
++ maintainers
++
++2007-02-09 18:51 blino
++
++ * lib/Youri/Submit/Reject/Mail.pm: fix changelog in reject mail
++
++2007-02-09 18:50 blino
++
++ * lib/Youri/Submit/Reject/Mail.pm: fix reject mail
++
++2007-02-08 17:28 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: also give directories to &quot;cpio
++ -pdu&quot; to ensure directories are created with same rights
++
++2007-02-08 14:09 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: This action plugin unpack
++ package files somewhere.
++ When unpack_inside_distribution_root is set, dest_directory is
++ relative to the distribution root.
++ When the package is a noarch, the wanted files are unpacked in
++ distribution root of each archs.
++
++ eg:
++ unpack_installer_images:
++ class: Youri::Submit::Action::Unpack
++ options:
++ name: drakx-installer-images
++ source_subdir: /usr/lib*/drakx-installer-images
++ dest_directory: .
++ unpack_inside_distribution_root: 1
++
++2007-01-30 10:02 pixel
++
++ * lib/Youri/Submit/Check/ACL.pm, lib/Youri/Submit/Check/Host.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/SVN.pm,
++ lib/Youri/Submit/Check/Source.pm, lib/Youri/Submit/Check/Type.pm,
++ lib/Youri/Submit/Check/Version.pm, lib/Youri/Submit/Pre/Rsync.pm,
++ lib/Youri/Submit/Reject/Archive.pm,
++ lib/Youri/Submit/Reject/Clean.pm,
++ lib/Youri/Submit/Reject/Install.pm,
++ lib/Youri/Submit/Reject/Mail.pm: fix $Id$ expansion
++
++2007-01-30 10:01 pixel
++
++ * lib/Youri/Submit/Plugin.pm, lib/Youri/Submit/Post.pm,
++ lib/Youri/Submit/Pre.pm, lib/Youri/Submit/Reject.pm: fix pod and
++ $Id$ expansion
++
++2007-01-30 10:00 pixel
++
++ * lib/Youri/Submit/Post.pm: fix pod
++
++2007-01-30 09:59 pixel
++
++ * lib/Youri/Submit/Action/Send.pm: fix pod
++
++2007-01-30 09:58 pixel
++
++ * lib/Youri/Submit/Action/Markrelease.pm,
++ lib/Youri/Submit/Action/Scp.pm: fix pod
++
++2007-01-30 09:49 pixel
++
++ * lib/Youri/Submit/Action/Clean.pm,
++ lib/Youri/Submit/Action/Link.pm,
++ lib/Youri/Submit/Action/Markrelease.pm,
++ lib/Youri/Submit/Action/Rpminfo.pm,
++ lib/Youri/Submit/Action/Scp.pm, lib/Youri/Submit/Action/Send.pm:
++ fix $Id$ expansion
++
++2007-01-26 11:25 blino
++
++ * lib/Youri/Submit/Check/ACL.pm: really match section in ACL
++
++2007-01-26 11:24 blino
++
++ * lib/Youri/Submit/Check/ACL.pm: fix arch ACL matching (and thus
++ allow ACLs to match again)
++
++2006-12-24 10:31 mandrake
++
++ * lib/Youri/Submit/Post.pm, lib/Youri/Submit/Pre.pm,
++ lib/Youri/Submit/Reject.pm: Removing previous pristine/
++ directory.
++
++2006-12-24 03:15 mandrake
++
++ * lib/Youri/Submit/Action.pm: %repsys markrelease
++ version: 1.0
++ release: 0.20061223.3mdv2007.1
++ revision: 101968
++
++ Copying 1.0-0.20061223.3mdv2007.1 to releases/ directory.
++
++2006-10-16 16:05 warly
++
++ * lib/Youri/Submit/Check.pm: merging dev with upstream
++
++2006-11-14 22:01 mrl
++
++ * lib/Youri/Submit/Action/Rpminfo.pm: - Renamed package name tag.
++
++2006-11-14 16:38 mrl
++
++ * lib/Youri/Submit/Action/RpmInfo.pm,
++ lib/Youri/Submit/Action/Rpminfo.pm: - Renamed, due to some
++ enforcement (cfengine?).
++
++2006-11-14 13:23 mrl
++
++ * lib/Youri/Submit/Action/RpmInfo.pm: - Added package summary to
++ .info files.
++
++2006-11-13 12:40 mrl
++
++ * lib/Youri/Submit/Action/RpmInfo.pm: - First version of web
++ interface.
++
++2006-10-31 11:40 mandrake
++
++ * lib/Youri/Submit/Action/Archive.pm: unlink file in Archive for
++ the moment (should be done in clean but the code to detect which
++ packages is obsoleted has to be moved
++
++2006-10-26 11:26 mandrake
++
++ * lib/Youri/Submit/Action/CVS.pm: we perform CVS commit
++ asynchronously
++
++2006-10-26 11:21 mandrake
++
++ * lib/Youri/Submit/Action/Install.pm: rename the rpm to remove the
++ prefix
++
++2006-10-26 11:18 mandrake
++
++ * lib/Youri/Submit/Action/Mail.pm: fix double .
++
++2006-10-26 11:16 mandrake
++
++ * lib/Youri/Submit/Post/Gendistrib.pm: add gendistrib command
++ directly into gendistrib module
++
++2006-10-26 11:14 mandrake
++
++ * lib/Youri/Submit/Pre/Rsync.pm: return correct packages table for
++ groups
++
++2006-10-26 11:10 mandrake
++
++ * lib/Youri/Submit/Reject/Install.pm: get_reject_path seems to be
++ the new name
++
++2006-10-26 11:07 mandrake
++
++ * lib/Youri/Submit/Reject/Mail.pm: $last_change is sometime empty
++
++2006-10-24 11:07 warly
++
++ * bin/youri-submit.in: exit with an error code if an error occured
++ in one group; s/Upload/Submit/; use new structure name from
++ upstream
++
++2006-10-23 11:48 warly
++
++ * lib/Youri/Submit/Check/ACL.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/SVN.pm,
++ lib/Youri/Submit/Check/Source.pm,
++ lib/Youri/Submit/Check/Version.pm: must return an empty value
++
++2006-10-18 12:46 warly
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: remove debug code
++
++2006-10-17 16:10 warly
++
++ * lib/Youri/Submit/Check/ACL.pm: now checks must return the error
++ message
++
++2006-10-17 16:04 warly
++
++ * lib/Youri/Submit/Check/ACL.pm, lib/Youri/Submit/Check/Host.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/SVN.pm,
++ lib/Youri/Submit/Check/Source.pm,
++ lib/Youri/Submit/Check/Version.pm: now checks must return the
++ error message
++
++2006-10-17 15:16 warly
++
++ * lib/Youri/Submit/Action/Clean.pm,
++ lib/Youri/Submit/Action/Link.pm, lib/Youri/Submit/Check/ACL.pm,
++ lib/Youri/Submit/Check/Host.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/SVN.pm, lib/Youri/Submit/Check/Source.pm,
++ lib/Youri/Submit/Check/Type.pm,
++ lib/Youri/Submit/Check/Version.pm, lib/Youri/Submit/Post.pm,
++ lib/Youri/Submit/Pre.pm, lib/Youri/Submit/Reject.pm:
++ s/Upload/Submit/g
++
++2006-10-17 13:53 warly
++
++ * ., ChangeLog, MANIFEST.SKIP, Makefile.PL, README, TODO,
++ bin/youri-submit-proxy.in, bin/youri-submit-restricted.in,
++ bin/youri-submit.in, etc, etc/bash_completion.d,
++ etc/bash_completion.d/youri-submit, etc/submit.conf,
++ lib/Youri/Submit/Plugin.pm, t, t/00distribution.t: merge with
++ upstream
++
++2006-10-16 16:27 warly
++
++ * lib/Youri/Submit/Post/Gendistrib.pm,
++ lib/Youri/Submit/Pre/Rsync.pm,
++ lib/Youri/Submit/Reject/Archive.pm,
++ lib/Youri/Submit/Reject/Clean.pm,
++ lib/Youri/Submit/Reject/Install.pm,
++ lib/Youri/Submit/Reject/Mail.pm: Now the module is Submit and not
++ Upload
++
++2006-10-16 16:26 warly
++
++ * lib/Youri/Submit/Check, lib/Youri/Submit/Check/History.pm,
++ lib/Youri/Submit/Check/Precedence.pm,
++ lib/Youri/Submit/Check/Recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/Tag.pm,
++ lib/Youri/Submit/Check/Type.pm: merging dev with upstream
++
++2006-10-16 16:15 warly
++
++ * lib/Youri/Submit/Post.pm, lib/Youri/Submit/Pre.pm,
++ lib/Youri/Submit/Reject.pm: now plugins are complete abstract
++ classes
++
++2006-10-16 16:08 warly
++
++ * lib/Youri/Submit/Action.pm: merging dev with upstream
++
++2006-10-16 16:05 warly
++
++ * lib/Youri/Submit/Check.pm: merging dev with upstream
++
++2006-10-16 13:03 warly
++
++ * lib/Youri/Submit/Action/Markrelease.pm,
++ lib/Youri/Submit/Action/Scp.pm, lib/Youri/Submit/Action/Send.pm:
++ Now the Module is Submit
++
++2006-10-16 12:57 warly
++
++ * lib/Youri/Submit/Action, lib/Youri/Submit/Action/Archive.pm,
++ lib/Youri/Submit/Action/Bugzilla.pm,
++ lib/Youri/Submit/Action/CVS.pm, lib/Youri/Submit/Action/Clean.pm,
++ lib/Youri/Submit/Action/Install.pm,
++ lib/Youri/Submit/Action/Link.pm, lib/Youri/Submit/Action/Mail.pm,
++ lib/Youri/Submit/Action/RSS.pm, lib/Youri/Submit/Action/Sign.pm:
++ merging dev with upstream
++
++2006-10-16 11:33 warly
++
++ * bin/youri-check.in: add new youri subsections (from upstream)
++
++2006-10-16 11:30 warly
++
++ * lib/Youri/Submit: add new youri subsections (from upstream)
++
++2006-10-16 11:30 warly
++
++ * lib/Youri: add new youri subsections (from upstream)
++
++2006-10-16 11:30 warly
++
++ * lib: add new youri subsections (from upstream)
++
++2006-10-16 11:22 warly
++
++ * bin/youri-submit.in: add new youri subsections (from upstream)
++
++2006-10-16 11:18 warly
++
++ * bin: add new youri subsections (from upstream)
++
++2006-10-16 11:18 warly
++
++ * .: add new youri subsections (from upstream)
++
++2006-04-23 Guillaume Rousse &lt;guillomovitch@zarb.org&gt; 0.9
++ * initial release
+
+<a id="build_systemmdvyourisubmittrunkMANIFESTSKIP">Added: build_system/mdv-youri-submit/trunk/MANIFEST.SKIP</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/MANIFEST.SKIP (rev 0)
++++ build_system/mdv-youri-submit/trunk/MANIFEST.SKIP 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,11 @@
++\.tar\.gz$
++\.SKIP$
++~$
++^pm_to_blib$
++^Makefile$
++^Makefile\.old$
++^bin/youri-submit$
++^bin/youri-submit-restricted$
++^bin/youri-submit-proxy$
++.svn
++blib
+
+<a id="build_systemmdvyourisubmittrunkMakefilePL">Added: build_system/mdv-youri-submit/trunk/Makefile.PL</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/Makefile.PL (rev 0)
++++ build_system/mdv-youri-submit/trunk/Makefile.PL 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,97 @@
++# $Id: Makefile.PL 1723 2006-10-17 13:53:27Z warly $
++use ExtUtils::MakeMaker;
++use Config;
++
++WriteMakefile(
++ NAME =&gt; 'youri-submit',
++ VERSION =&gt; 0.9,
++ AUTHOR =&gt; 'Youri project &lt;youri@zarb.org&gt;',
++ EXE_FILES =&gt; [
++ 'bin/youri-submit',
++ 'bin/youri-submit-restricted',
++ 'bin/youri-submit-proxy'
++ ],
++ PREREQ_PM =&gt; {
++ 'Youri::Config' =&gt; 0,
++ 'Youri::Utils' =&gt; 0,
++ 'Pod::Simple::HTMLBatch' =&gt; 0
++ },
++ PREFIX =&gt; '/usr/local',
++ INSTALLPRIVLIB =&gt; $Config{installprivlib},
++ INSTALLSITELIB =&gt; $Config{installsitelib},
++ INSTALLVENDORLIB =&gt; $Config{installvendorlib},
++ INSTALLMAN3DIR =&gt; $Config{installman3dir},
++ INSTALLSITEMAN3DIR =&gt; $Config{installsiteman3dir},
++ INSTALLVENDORMAN3DIR =&gt; $Config{installvendorman3dir},
++ INSTALLSCRIPT =&gt; '$(PREFIX)/bin',
++ INSTALLSITESCRIPT =&gt; '$(PREFIX)/bin',
++ INSTALLVENDORSCRIPT =&gt; '$(PREFIX)/bin',
++ INSTALLMAN1DIR =&gt; '$(PREFIX)/share/man/man1',
++ INSTALLSITEMAN1DIR =&gt; '$(PREFIX)/share/man/man1',
++ INSTALLVENDORMAN1DIR =&gt; '$(PREFIX)/share/man/man1',
++);
++
++package MY;
++
++sub post_constants {
++ my ($self) = @_;
++ my $sysconfdir = $self-&gt;{ARGS}-&gt;{SYSCONFDIR} || '$(PREFIX)/etc';
++ return &lt;&lt;EOF;
++SYSCONFDIR = $sysconfdir
++EOF
++}
++
++sub top_targets {
++ my ($self) = @_;
++ my $top_targets = $self-&gt;SUPER::top_targets(@_);
++ $top_targets =~ s/all :: pure_all manifypods/all :: pure_all manifypods htmlifypods/;
++ $top_targets .= &lt;&lt;'EOF';
++htmlifypods : $(TO_INST_PM)
++ if [ ! -d blib/html ]; then mkdir blib/html; fi
++ perl -MPod::Simple::HTMLBatch -e Pod::Simple::HTMLBatch::go lib blib/html
++ pod2html &lt; bin/youri-submit &gt; blib/html/youri-submit.html
++ pod2html &lt; bin/youri-submit-restricted &gt; blib/html/youri-submit-restricted.html
++ pod2html &lt; bin/youri-submit-proxy &gt; blib/html/youri-submit-proxy.html
++EOF
++ return $top_targets;
++}
++
++sub install {
++ my ($self) = @_;
++ my $install = $self-&gt;SUPER::install(@_);
++ $install =~ s/install :: all pure_install doc_install/install :: all pure_install doc_install config_install completion_install/;
++ $install .= &lt;&lt;'EOF';
++config_install :
++ install -d -m 755 $(DESTDIR)$(SYSCONFDIR)/youri
++ install -m 644 etc/submit.conf $(DESTDIR)$(SYSCONFDIR)/youri
++
++completion_install :
++ install -d -m 755 $(DESTDIR)$(SYSCONFDIR)/bash_completion.d
++ install -m 644 etc/bash_completion.d/youri-submit $(DESTDIR)$(SYSCONFDIR)/bash_completion.d
++EOF
++ return $install;
++}
++
++sub installbin {
++ my ($self) = @_;
++ my $installbin = $self-&gt;SUPER::installbin(@_);
++ $installbin .= &lt;&lt;'EOF';
++bin/youri-submit : bin/youri-submit.in Makefile
++ perl -p \
++ -e 's|\@sysconfdir\@|$(SYSCONFDIR)|;' \
++ &lt; $&lt; &gt; $@
++
++bin/youri-submit-restricted : bin/youri-submit-restricted.in Makefile
++ perl -p \
++ -e 's|\@sysconfdir\@|$(SYSCONFDIR)|;' \
++ -e 's|\@bindir\@|$(PREFIX)/bin|;' \
++ &lt; $&lt; &gt; $@
++
++bin/youri-submit-proxy : bin/youri-submit-proxy.in Makefile
++ perl -p \
++ -e 's|\@sysconfdir\@|$(SYSCONFDIR)|;' \
++ -e 's|\@bindir\@|$(PREFIX)/bin|;' \
++ &lt; $&lt; &gt; $@
++EOF
++ return $installbin;
++}
+
+<a id="build_systemmdvyourisubmittrunkREADME">Added: build_system/mdv-youri-submit/trunk/README</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/README (rev 0)
++++ build_system/mdv-youri-submit/trunk/README 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,45 @@
++YOURI project
++-------------
++
++YOURI stands for &quot;Youri Offers an Upload &amp; Repository Infrastucture&quot;. It aims
++to build tools making management of a coherent set of packages easier.
++
++Description
++-----------
++Managing a package repository involves many tasks, such as keeping packages
++tree tidy, generating packages indexes, synchronising bug report system,
++running coherency checks, checking for available updates, etc...
++
++Instead of a gazillion project-specific scripts, we aim to provide a generic package-format independant framework, so as to build coherent and robust tools.
++
++Components
++----------
++Available software in this release
++- youri-check allows to check packages
++- youri-upload allows to upload packages
++
++Installation
++------------
++To install, just use:
++perl Makefile.PL
++make
++make test
++
++All standard MakeMaker variables are usable, with the addition of SYSCONFDIR to
++specify configuration files destination.
++
++Copyright and License
++---------------------
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under
++the same terms as Perl itself.
++
++Authors
++-------
++Guillaume Rousse &lt;guillomovitch@zarb.org&gt;,
++Pascal Terjan &lt;pterjan@zarb.org&gt;
++Damien Krotkine &lt;dams@zarb.org&gt;
++Olivier Thauvin &lt;nanardon@zarb.org&gt;
++Ville Skytt\xE4 &lt;ville.skytta@iki.fi&gt;
++
+
+<a id="build_systemmdvyourisubmittrunkTODO">Added: build_system/mdv-youri-submit/trunk/TODO</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/TODO (rev 0)
++++ build_system/mdv-youri-submit/trunk/TODO 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,6 @@
++1.0 Goals
++=========
++
++- svn support
++- automatic bugzilla ticket closing on upload
++- more customizable (template based ?) mail notification
+
+<a id="build_systemmdvyourisubmittrunkbinyouricheckin">Added: build_system/mdv-youri-submit/trunk/bin/youri-check.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-check.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-check.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,395 @@
++#!/usr/bin/perl
++# $Id: youri-check.in 1699 2006-10-16 11:33:58Z warly $
++
++=head1 NAME
++
++youri-check - package check agent
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 SYNOPSIS
++
++youri-check [options] &lt;mode&gt;
++
++Options:
++
++ --config &lt;file&gt; use file &lt;file&gt; as config file
++ --skip-media &lt;media&gt; skip media &lt;media&gt;
++ --skip-plugin &lt;plugin&gt; skip plugin &lt;plugin&gt;
++ --parallel parallel run
++ --verbose verbose run
++ --test test run
++ --help print this help message
++
++=head1 DESCRIPTION
++
++B&lt;youri-check&gt; allows to check packages in a repository.
++
++In input mode, all medias defined in configuration are passed to a list of
++input plugins, each of them storing their result in a persistent resultset. In
++output mode, this resultset is passed to a list of output plugins, each of them
++producing arbitrary effects.
++
++=head1 OPTIONS
++
++=over
++
++=item B&lt;--config&gt; &lt;file&gt;
++
++Use given file as configuration, instead of normal one.
++
++=item B&lt;--skip-media&gt; &lt;media&gt;
++
++Skip media with given identity.
++
++=item B&lt;--skip-plugin&gt; &lt;plugin&gt;
++
++Skip plugin with given identity.
++
++=item B&lt;--parallel&gt;
++
++Run all plugins parallelously
++
++=item B&lt;--verbose&gt;
++
++Produce more verbose output (can be used more than once)
++
++=item B&lt;--test&gt;
++
++Don't perform any modification.
++
++=item B&lt;--help&gt;
++
++Print a brief help message and exits.
++
++=back
++
++=head1 CONFIGURATION
++
++Configuration is read from the first file found among:
++
++=over
++
++=item * the one specified by B&lt;--config&gt; option on command-line
++
++=item * $HOME/.youri/check.conf
++
++=item * @sysconfdir@/youri/check.conf
++
++=back
++
++All additional configuration files specified by B&lt;includes&gt; directive are then
++processed. Then command line options. Any directive overrides prior definition.
++
++=over
++
++=item B&lt;includes&gt; I&lt;files&gt;
++
++Uses space-separated list I&lt;files&gt; as a list of additional configuration files.
++
++=item B&lt;resolver&gt; I&lt;id&gt;
++
++Declare a maintainer resolver object with identity I&lt;id&gt;.
++
++=item B&lt;preferences&gt; I&lt;id&gt;
++
++Declare a maintainer preferences object with identity I&lt;id&gt;.
++
++=item B&lt;resultset&gt; I&lt;id&gt;
++
++Declare a resultset object with identity I&lt;id&gt;.
++
++=item B&lt;medias&gt; I&lt;ids&gt;
++
++Declares a list of media objects with identity taken in space-separated list
++I&lt;ids&gt;.
++
++=item B&lt;inputs&gt; I&lt;ids&gt;
++
++Declares a list of input plugin objects with identity taken in space-separated
++list I&lt;ids&gt;.
++
++=item B&lt;outputs&gt; I&lt;ids&gt;
++
++Declares a list of output plugin objects with identity taken in space-separated
++list I&lt;ids&gt;.
++
++=back
++
++Each object declared in configuration must be fully defined later, using a
++configuration section, starting with bracketed object identity, followed by at
++least a class directive, then any number of additional object-specific
++directives.
++
++Example:
++
++ objects = foo
++
++ [foo]
++ class = Foo::Bar
++ key1 = value1
++ key2 = value2
++
++=head1 SEE ALSO
++
++Youri::Config, for configuration file format.
++
++Each used plugin man page, for available options.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++use Youri::Config;
++use Youri::Utils;
++use Pod::Usage;
++use Net::Config qw/%NetConfig/;
++use DateTime;
++
++my $config = Youri::Config-&gt;new(
++ command_spec =&gt; [
++ 'config=s',
++ 'skip-plugin=s@',
++ 'skip-media=s@',
++ 'parallel!',
++ 'help|h!',
++ 'test|t!',
++ 'verbose|v!'
++ ],
++ file_spec =&gt; [
++ 'includes=s',
++ 'resolver=s',
++ 'preferences=s',
++ 'resultset=s',
++ 'medias=s',
++ 'inputs=s',
++ 'outputs=s'
++ ],
++ directories =&gt; [ '@sysconfdir@', &quot;$ENV{HOME}/.youri&quot; ],
++ file_name =&gt; 'check.conf',
++ caller =&gt; $0,
++);
++
++pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No mode specified, aborting\n&quot;
++) unless @ARGV;
++
++my $mode = $ARGV[0];
++
++# convenient global flags
++my $test = $config-&gt;get('test');
++my $verbose = $config-&gt;get('verbose');
++
++# libnet configuration
++my %netconfig = $config-&gt;get_section('netconfig');
++$NetConfig{$_} = $netconfig{$_} foreach keys %netconfig;
++
++# resultset creation
++my $resultset_id = $config-&gt;get('resultset');
++die &quot;No resultset defined&quot; unless $resultset_id;
++
++report(&quot;Creating resultset $resultset_id&quot;);
++my $resultset = create_instance(
++ 'Youri::Check::Resultset',
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ $config-&gt;get_section($resultset_id)
++);
++
++my $children;
++
++my %skip_plugins = map { $_ =&gt; 1 } @{$config-&gt;get('skip-plugin')};
++
++if ($mode eq 'input') {
++
++ # additional objects
++
++ my $resolver;
++ my $resolver_id = $config-&gt;get('resolver');
++ if ($resolver_id) {
++ report(&quot;Creating maintainer resolver $resolver_id&quot;);
++ eval {
++ $resolver = create_instance(
++ 'Youri::Check::Maintainer::Resolver',
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 1 ? $verbose - 2 : 0,
++ $config-&gt;get_section($resolver_id)
++ );
++ };
++ print STDERR &quot;Failed to create maintainer resolver $resolver_id: $@\n&quot; if $@;
++ }
++
++ my $preferences;
++ my $preferences_id = $config-&gt;get('preferences');
++ if ($preferences_id) {
++ report(&quot;Creating maintainer preferences $preferences_id&quot;);
++ eval {
++ $preferences = create_instance(
++ 'Youri::Check::Maintainer::Preferences',
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 1 ? $verbose - 2 : 0,
++ $config-&gt;get_section($preferences_id)
++ );
++ };
++ print STDERR &quot;Failed to create maintainer preferences $preferences_id: $@\n&quot; if $@;
++ }
++
++ my @medias;
++ my %skip_medias = map { $_ =&gt; 1 } @{$config-&gt;get('skip-media')};
++ foreach my $id (split(/\s+/, $config-&gt;get('medias'))) {
++ next if $skip_medias{$id};
++ report(&quot;Creating media $id&quot;);
++ eval {
++ push(
++ @medias,
++ create_instance(
++ 'Youri::Media',
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ $config-&gt;get_section($id)
++ )
++ );
++ };
++ print STDERR &quot;Failed to create media $id: $@\n&quot; if $@;
++ }
++
++ # prepare resultset
++ $resultset-&gt;reset();
++ $resultset-&gt;set_resolver($resolver);
++
++
++ foreach my $id (split(/\s+/, $config-&gt;get('inputs'))) {
++ next if $skip_plugins{$id};
++ report(&quot;Creating input $id&quot;);
++ my $input;
++ eval {
++ $input = create_instance(
++ 'Youri::Check::Input',
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ resolver =&gt; $resolver,
++ preferences =&gt; $preferences,
++ $config-&gt;get_section($id)
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create input $id: $@\n&quot;;
++ } else {
++ if ($config-&gt;get('parallel')) {
++ # fork
++ my $pid = fork;
++ die &quot;Can't fork: $!&quot; unless defined $pid;
++ if ($pid) {
++ # parent process
++ $children++;
++ next;
++ }
++ }
++ eval {
++ $input-&gt;prepare(@medias);
++ };
++ if ($@) {
++ print STDERR &quot;Failed to prepare input $id: $@\n&quot;;
++ } else {
++ # clone resultset in child process
++ $resultset = $config-&gt;get('parallel') ?
++ $resultset-&gt;clone() :
++ $resultset;
++
++ foreach my $media (@medias) {
++ next if $media-&gt;skip_input($id);
++ my $media_id = $media-&gt;get_id();
++ report(&quot;running input $id on media $media_id&quot;);
++ eval {
++ $input-&gt;run($media, $resultset);
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run input $id on media $media_id: $@\n&quot;;
++ }
++ }
++ }
++ if ($config-&gt;get('parallel')) {
++ # child process
++ exit;
++ }
++ }
++ }
++
++} elsif ($mode eq 'output') {
++
++ foreach my $id (split(/\s+/, $config-&gt;get('outputs'))) {
++ next if $skip_plugins{$id};
++ report(&quot;Creating output $id&quot;);
++ my $output;
++ eval {
++ $output = create_instance(
++ 'Youri::Check::Output',
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ config =&gt; $config,
++ $config-&gt;get_section($id)
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create output $id: $@\n&quot;;
++ } else {
++ if ($config-&gt;get('parallel')) {
++ # fork
++ my $pid = fork;
++ die &quot;Can't fork: $!&quot; unless defined $pid;
++ if ($pid) {
++ # parent process
++ $children++;
++ next;
++ }
++ }
++
++ # clone resultset in child process
++ $resultset = $config-&gt;get('parallel') ?
++ $resultset-&gt;clone() :
++ $resultset;
++
++ report(&quot;running output $id&quot;);
++ eval {
++ $output-&gt;run($resultset);
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run output $id: $@\n&quot;;
++ }
++
++ if ($config-&gt;get('parallel')) {
++ # child process
++ exit;
++ }
++ }
++ }
++} else {
++ die &quot;Invalid mode $mode&quot;;
++}
++
++# wait for all forked processus termination
++while ($children) {
++ wait;
++ $children--;
++}
++
++sub report {
++ my ($message) = @_;
++ print DateTime-&gt;now()-&gt;strftime('[%H:%M:%S] ')
++ if $verbose &gt; 1;
++ print &quot;$message\n&quot;
++ if $verbose &gt; 0;
++}
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-check.in
+___________________________________________________________________
+<a id="svnexecutable">Added: svn:executable</a>
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmit">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,534 @@
++#!/usr/bin/perl
++# $Id: youri-submit 232579 2007-12-17 19:45:47Z blino $
++
++=head1 NAME
++
++youri-submit - package submission tool
++
++=head1 VERSION
++
++Version 2.0
++
++=head1 SYNOPSIS
++
++youri-submit [options] &lt;target&gt; &lt;files&gt;
++
++youri-submit --list &lt;category&gt; [target]
++
++youri-submit --help [category] [item]
++
++Options:
++
++ --config &lt;file&gt; use file &lt;file&gt; as config file
++ --skip-pre &lt;pre&gt; skip pre &lt;pre&gt;
++ --skip-check &lt;check&gt; skip check &lt;check&gt;
++ --skip-action &lt;action&gt; skip action &lt;action&gt;
++ --skip-post &lt;post&gt; skip post &lt;post&gt;
++ --skip-reject &lt;reject&gt; skip reject &lt;reject&gt;
++ --define &lt;key&gt;=&lt;value&gt; pass additional values
++ --clean delete package after success
++ --verbose verbose run
++ --test test run
++ --list &lt;category&gt; list items from given category
++ --help [category] display contextual help
++
++=head1 DESCRIPTION
++
++B&lt;youri-submit&gt; allows to submit packages to a repository.
++
++All packages given on command lines are passed to a list of check plugins,
++depending on given upload target. If none of them fails, all packages are
++passed to a list of action plugins, depending also on given upload target.
++
++=head1 OPTIONS
++
++=over
++
++=item B&lt;--config&gt; I&lt;file&gt;
++
++Use given file as configuration, instead of normal one.
++
++=item B&lt;--skip-pre&gt; I&lt;id&gt;
++
++Skip pre transaction plugin with given identity
++
++=item B&lt;--skip-check&gt; I&lt;id&gt;
++
++Skip check plugin with given identity.
++
++=item B&lt;--skip-action&gt; I&lt;id&gt;
++
++Skip action plugin with given identity.
++
++=item B&lt;--skip-post&gt; I&lt;id&gt;
++
++Skip post transaction plugin with given identity.
++
++=item B&lt;--skip-reject&gt; I&lt;id&gt;
++
++Skip reject action plugin with given identity.
++
++=item B&lt;--define&gt; &lt;key&gt;=&lt;value&gt;
++
++Define additional parameters, to be used by plugins.
++
++=item B&lt;--clean&gt;
++
++Delete submited packages upon successfull submission.
++
++=item B&lt;--verbose&gt;
++
++Produce more verbose output (can be used more than once)
++
++=item B&lt;--test&gt;
++
++Don't perform any modification.
++
++=item B&lt;--list&gt; I&lt;category&gt;
++
++List available items from given category and exits. Category must be either
++B&lt;targets&gt;, B&lt;actions&gt; or B&lt;checks&gt;. A target is needed for the two last ones.
++
++=item B&lt;--help&gt; I&lt;category&gt;
++
++Display help for given category and exits. Category must be either
++B&lt;repository&gt;, B&lt;action&gt; or B&lt;check&gt;. An item is needed for the two last ones.
++If no category given, display standard help.
++
++=back
++
++=head1 CONFIGURATION
++
++Configuration is read from the first file found among:
++
++=over
++
++=item * the one specified by B&lt;--config&gt; option on command-line
++
++=item * $HOME/.youri/submit.conf
++
++=item * /usr/local/etc/youri/submit.conf
++
++=back
++
++The configuration file should be a YAML-format files, with the following
++mandatory top-level directives:
++
++=over
++
++=item B&lt;repository&gt;
++
++The definition of repository plugin to be used.
++
++=item B&lt;targets&gt;
++
++The list of available submission targets, each one being composed from the
++following keys:
++
++=over
++
++=item B&lt;checks&gt;
++
++The list of check plugins to use for this target.
++
++=item B&lt;actions&gt;
++
++The list of action plugins to use for this target.
++
++=back
++
++=item B&lt;checks&gt;
++
++The list of check plugin definitions, indexed by their identity.
++
++=item B&lt;actions&gt;
++
++The list of action plugin definitions, indexed by their identity.
++
++=back
++
++=head1 SEE ALSO
++
++Youri::Config, for additional details about configuration file format.
++
++Each used plugin man page, for available options.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++use Youri::Config;
++use Youri::Utils;
++use Pod::Usage;
++
++my $config = Youri::Config-&gt;new(
++ args =&gt; {
++ 'skip-check' =&gt; '=s@',
++ 'skip-action' =&gt; '=s@',
++ 'define' =&gt; '=s%',
++ 'verbose' =&gt; '|v!',
++ 'clean' =&gt; '!',
++ 'test' =&gt; '|t!',
++ 'list' =&gt; '|l!',
++ 'config' =&gt; '=s',
++ 'skip-prei' =&gt; '=s@',
++ 'skip-post' =&gt; '=s@',
++ 'skip-reject' =&gt; '=s@',
++ },
++ directories =&gt; [ &quot;$ENV{HOME}/.youri&quot;, '/usr/local/etc/youri' ],
++ file =&gt; 'submit.conf',
++);
++
++if ($config-&gt;get_arg('list')) {
++ my $category = $ARGV[0];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No category specified, aborting\n&quot;)
++ unless $category;
++ if ($category eq 'targets') {
++ print join(' ', keys %{$config-&gt;get_param('targets')});
++ } elsif ($category eq 'checks' || $category eq 'actions') {
++ my $target = $ARGV[1];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless $target;
++ if ($category eq 'checks') {
++ my $checks = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{checks};
++ print join(' ', @{$checks}) if $checks;
++ } else {
++ my $actions = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{actions};
++ print join(' ', @{$actions}) if $actions;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ print &quot;\n&quot;;
++ exit 0;
++}
++
++if ($config-&gt;get_arg('help')) {
++ my $category = $ARGV[0];
++ my ($item, $section);
++ if ($category eq 'repository') {
++ $section = $config-&gt;get_param('repository');
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No repository defined, aborting\n&quot;
++ ) unless $section;
++ } elsif ($category eq 'check' || $category eq 'action') {
++ $item = $ARGV[1];
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No item specified, aborting\n&quot;
++ ) unless $item;
++ if ($category eq 'check') {
++ $section = $config-&gt;get_param('checks')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such check $item defined, aborting\n&quot;
++ ) unless $section;
++ } else {
++ $section = $config-&gt;get_param('actions')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such action $item defined, aborting\n&quot;
++ ) unless $section;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ my $file = $section-&gt;{class} . '.pm';
++ $file =~ s/::/\//g;
++ pod2usage(
++ -verbose =&gt; 99,
++ -sections =&gt; 'NAME|DESCRIPTION',
++ -input =&gt; $file,
++ -pathlist =&gt; \@INC
++ );
++}
++
++
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless @ARGV &gt; 0;
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No packages specified, aborting\n&quot;)
++ unless @ARGV &gt; 1 || $config-&gt;get_param('allow_omitting_packages');
++
++# convenient global flags
++my $test = $config-&gt;get_arg('test');
++my $verbose = $config-&gt;get_arg('verbose');
++
++# check target
++my $target = shift @ARGV;
++my $target_conf = $config-&gt;get_param('targets')-&gt;{$target};
++
++# create repository
++my $repository;
++my $repository_conf = $config-&gt;get_param('repository');
++die &quot;No repository declared&quot; unless $repository_conf;
++print &quot;Creating repository\n&quot; if $verbose;
++eval {
++ $repository = create_instance(
++ 'Youri::Repository',
++ $repository_conf,
++ {
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ targets =&gt; [ keys %{$config-&gt;get_param('targets')} ],
++ }
++ );
++};
++die &quot;Failed to create repository: $@\n&quot; if $@;
++
++# perfrom pre action
++my @errors;
++my $pre_packages = [];
++my $skip_pres = $config-&gt;get_arg('skip-pre');
++my %skip_pres = $skip_pres ? map { $_ =&gt; 1 } @{$skip_pres} : ();
++foreach my $id (@{$target_conf-&gt;{pres}}) {
++ next if $skip_pres{$id};
++ print &quot;Creating pre $id\n&quot; if $verbose;
++ my $pre;
++ my $pre_conf = $config-&gt;get_param('pres')-&gt;{$id};
++
++ if (!$pre_conf) {
++ print STDERR &quot;No such pre $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $pre = create_instance(
++ 'Youri::Submit::Pre',
++ $pre_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create pre $id: $@\n&quot;;
++ } else {
++ print &quot;running pre $id\n&quot; if $verbose;
++ my @err = $pre-&gt;run(
++ $pre_packages,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@errors, @err) if $err[0];
++ }
++}
++
++if (@errors) {
++ print &quot;Pre-submission errors, aborting:\n&quot;;
++ foreach my $error (@errors) {
++ print &quot; - $error\n&quot;;
++ }
++ exit(1)
++}
++
++# create packages group
++my $group_error;
++my @packages_group;
++foreach my $group ([ map { { section =&gt; &quot;&quot;, file =&gt; $_ } } @ARGV ], @$pre_packages) {
++ my @packages;
++ foreach my $opt (@$group) {
++ print &quot;Preparing upload for $opt-&gt;{file} in $opt-&gt;{section}\n&quot; if $verbose;
++ $repository-&gt;{packages}{$opt-&gt;{file}}{section} = $opt-&gt;{section};
++ push(
++ @packages,
++ create_instance(
++ 'Youri::Package',
++ {
++ class =&gt; $repository-&gt;get_package_class(),
++ },
++ {
++ file =&gt; $opt-&gt;{file},
++ %$opt
++ },
++ )
++ );
++ }
++ @packages or next;
++
++# check all packages pass all tests
++ my %errors;
++ my $skip_check = $config-&gt;get_arg('skip-check');
++ my %skip_check = $skip_check ? map { $_ =&gt; 1 } @{$skip_check} : ();
++ my @error;
++ foreach my $id (@{$target_conf-&gt;{checks}}) {
++ next if $skip_check{$id};
++ print &quot;Creating check $id\n&quot; if $verbose;
++ my $check;
++ my $check_conf = $config-&gt;get_param('checks')-&gt;{$id};
++
++ if (!$check_conf) {
++ print STDERR &quot;No such check $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $check = create_instance(
++ 'Youri::Submit::Check',
++ $check_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create check $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running check $id on package $package\n&quot; if $verbose;
++ my @errors = $check-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@{$errors{$package}}, @errors) if $errors[0];
++ }
++ }
++ }
++ if (%errors) {
++ print &quot;Submission errors, aborting:\n&quot;;
++ foreach my $package (keys %errors) {
++ print &quot;- $package:\n&quot;;
++ foreach my $error (@{$errors{$package}}) {
++ print &quot; - $error\n&quot;;
++ }
++ }
++ # reject the packages
++ my $skip_rejects = $config-&gt;get_arg('skip-reject');
++ my %skip_rejects = $skip_rejects ? map { $_ =&gt; 1 } @{$skip_rejects} : ();
++ foreach my $id (@{$target_conf-&gt;{rejects}}) {
++ next if $skip_rejects{$id};
++ print &quot;Creating reject $id\n&quot; if $verbose;
++ my $reject;
++ my $reject_conf = $config-&gt;get_param('rejects')-&gt;{$id};
++
++ if (!$reject_conf) {
++ print STDERR &quot;No such reject $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $reject = create_instance(
++ 'Youri::Submit::Reject',
++ $reject_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create reject $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running reject $id on package $package\n&quot; if $verbose;
++ eval {
++ $reject-&gt;run($package, \%errors, $repository, $target, $config-&gt;get_arg('define'));
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++ $group_error = 1;
++ next
++ }
++
++# proceed further
++ my $skip_action = $config-&gt;get_arg('skip-action');
++ my %skip_action = $skip_action ? map { $_ =&gt; 1 } @{$skip_action} : ();
++ foreach my $id (@{$target_conf-&gt;{actions}}) {
++ next if $skip_action{$id};
++ print &quot;Creating action $id\n&quot; if $verbose;
++ my $action;
++ my $action_conf = $config-&gt;get_param('actions')-&gt;{$id};
++
++ if (!$action_conf) {
++ print STDERR &quot;No such action $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $action = create_instance(
++ 'Youri::Submit::Action',
++ $action_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create action $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running action $id on package $package\n&quot; if $verbose;
++ eval {
++ $action-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++
++ if ($config-&gt;get_arg('clean')) {
++ foreach my $package (@packages) {
++ print &quot;cleaning file $package\n&quot; if $verbose;
++ unlink $package-&gt;as_file();
++ }
++ }
++}
++
++# perfrom post action
++my $skip_post = $config-&gt;get_arg('skip-post');
++my %skip_post = $skip_post ? map { $_ =&gt; 1 } @{$skip_post} : ();
++foreach my $id (@{$target_conf-&gt;{posts}}) {
++ next if $skip_post{$id};
++ print &quot;Creating post $id\n&quot; if $verbose;
++ my $post;
++ my $post_conf = $config-&gt;get_param('posts')-&gt;{$id};
++
++ if (!$post_conf) {
++ print STDERR &quot;No such post $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $post = create_instance(
++ 'Youri::Submit::Post',
++ $post_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create post $id: $@\n&quot;;
++ } else {
++ print &quot;running post $id\n&quot; if $verbose;
++ my @err = $post-&gt;run($repository, $target, $config-&gt;get_arg('define'));
++ print STDERR &quot;Error $id: @err\n&quot; if @err
++ }
++}
++
++exit(1) if $group_error;
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmitproxyin">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,77 @@
++#!/usr/bin/perl
++
++=head1 NAME
++
++youri-submit-proxy - proxy wrapper over youri-submit-restricted
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 SYNOPSIS
++
++youri-submit-proxy [options] &lt;target&gt; &lt;files&gt;
++
++=head1 DESCRIPTION
++
++youri-submit-proxy is a proxy wrapper over youri-submit-restricted, intended to
++be used in collaborative work to change uid before calling it through sudo.
++
++=head1 SEE ALSO
++
++youri-submit-restricted(1), youri-submit(1)
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++use Fcntl ':mode';
++use File::Basename;
++
++my ($uid, $gid);
++if (-l $0) {
++ # this is a symlink, get uid and gid from it
++ ($uid, $gid) = (lstat($0))[4, 5];
++} else {
++ ($uid, $gid) = (stat($0))[4, 5];
++}
++my $user = getpwuid($uid) or die &quot;unknown uid $uid&quot;;
++my $prog = '@bindir@/youri-submit-restricted';
++
++my %dirs;
++my @options;
++foreach my $arg (@ARGV) {
++ if (-f $arg) {
++ # push parent dir in list
++ my $parent = dirname($arg);
++ $dirs{$parent}++;
++ }
++ push(@options, $arg);
++}
++
++foreach my $dir (keys %dirs) {
++ # save original perms and gid
++ my ($orig_mode, $orig_gid) = (stat($dir))[2,5];
++ $dirs{$dir} = {
++ mode =&gt; $orig_mode,
++ gid =&gt; $orig_gid
++ };
++ # ensure correct perms and gid
++ chown -1, $gid, $dir;
++ chmod $orig_mode|S_IRGRP|S_IWGRP, $dir;
++}
++
++# call wrapped program
++system('sudo', '-H', '-u', $user, $prog, @options);
++
++foreach my $dir (keys %dirs) {
++ # restore original perms and gid
++ chown -1, $dirs{$dir}-&gt;{gid}, $dir;
++ chmod $dirs{$dir}-&gt;{mode}, $dir;
++}
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmitrestrictedin">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,64 @@
++#!/usr/bin/perl -T
++
++=head1 NAME
++
++youri-submit-restricted - filtering wrapper over youri-submit
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 SYNOPSIS
++
++youri-submit-restricted [options] &lt;target&gt; &lt;files&gt;
++
++=head1 DESCRIPTION
++
++youri-submit-restricted is just a filtering wrapper over youri-submit, intended
++to be used in collaborative work to sanitize environment and options before
++calling it.
++
++=head1 SEE ALSO
++
++youri-submit(1)
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++my $prog = '@bindir@/youri-submit';
++my @prohibited_options = qw/--config --skip-check --skip-action/;
++my %prohibited_options = map { $_ =&gt; 1 } @prohibited_options;
++my @prohibited_envvars = qw/
++ ENV BASH_ENV IFS CDPATH
++ PERLLIB PERL5LIB PERL5OPT PERLIO
++ PERLIO_DEBUG PERL5DB PERL_ENCODING
++ PERL_HASH_SEED PERL_SIGNALS PERL_UNICODE
++/;
++
++my @options;
++while (my $arg = shift @ARGV) {
++ if ($prohibited_options{$arg}) {
++ # drop prohibited options
++ print STDERR &quot;prohibited option $arg, skipping\n&quot;;
++ shift @ARGV;
++ } else {
++ # untaint everything else
++ $arg =~ /(.*)/;
++ push(@options, $1);
++ }
++}
++
++# secure ENV
++$ENV{PATH} = &quot;/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin&quot;;
++delete $ENV{$_} foreach @prohibited_envvars;
++
++# call wrapped program
++system($prog, @options);
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmitin">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,534 @@
++#!/usr/bin/perl
++# $Id: youri-submit.in 232668 2007-12-21 14:37:04Z blino $
++
++=head1 NAME
++
++youri-submit - package submission tool
++
++=head1 VERSION
++
++Version 2.0
++
++=head1 SYNOPSIS
++
++youri-submit [options] &lt;target&gt; &lt;files&gt;
++
++youri-submit --list &lt;category&gt; [target]
++
++youri-submit --help [category] [item]
++
++Options:
++
++ --config &lt;file&gt; use file &lt;file&gt; as config file
++ --skip-pre &lt;pre&gt; skip pre &lt;pre&gt;
++ --skip-check &lt;check&gt; skip check &lt;check&gt;
++ --skip-action &lt;action&gt; skip action &lt;action&gt;
++ --skip-post &lt;post&gt; skip post &lt;post&gt;
++ --skip-reject &lt;reject&gt; skip reject &lt;reject&gt;
++ --define &lt;key&gt;=&lt;value&gt; pass additional values
++ --clean delete package after success
++ --verbose verbose run
++ --test test run
++ --list &lt;category&gt; list items from given category
++ --help [category] display contextual help
++
++=head1 DESCRIPTION
++
++B&lt;youri-submit&gt; allows to submit packages to a repository.
++
++All packages given on command lines are passed to a list of check plugins,
++depending on given upload target. If none of them fails, all packages are
++passed to a list of action plugins, depending also on given upload target.
++
++=head1 OPTIONS
++
++=over
++
++=item B&lt;--config&gt; I&lt;file&gt;
++
++Use given file as configuration, instead of normal one.
++
++=item B&lt;--skip-pre&gt; I&lt;id&gt;
++
++Skip pre transaction plugin with given identity
++
++=item B&lt;--skip-check&gt; I&lt;id&gt;
++
++Skip check plugin with given identity.
++
++=item B&lt;--skip-action&gt; I&lt;id&gt;
++
++Skip action plugin with given identity.
++
++=item B&lt;--skip-post&gt; I&lt;id&gt;
++
++Skip post transaction plugin with given identity.
++
++=item B&lt;--skip-reject&gt; I&lt;id&gt;
++
++Skip reject action plugin with given identity.
++
++=item B&lt;--define&gt; &lt;key&gt;=&lt;value&gt;
++
++Define additional parameters, to be used by plugins.
++
++=item B&lt;--clean&gt;
++
++Delete submited packages upon successfull submission.
++
++=item B&lt;--verbose&gt;
++
++Produce more verbose output (can be used more than once)
++
++=item B&lt;--test&gt;
++
++Don't perform any modification.
++
++=item B&lt;--list&gt; I&lt;category&gt;
++
++List available items from given category and exits. Category must be either
++B&lt;targets&gt;, B&lt;actions&gt; or B&lt;checks&gt;. A target is needed for the two last ones.
++
++=item B&lt;--help&gt; I&lt;category&gt;
++
++Display help for given category and exits. Category must be either
++B&lt;repository&gt;, B&lt;action&gt; or B&lt;check&gt;. An item is needed for the two last ones.
++If no category given, display standard help.
++
++=back
++
++=head1 CONFIGURATION
++
++Configuration is read from the first file found among:
++
++=over
++
++=item * the one specified by B&lt;--config&gt; option on command-line
++
++=item * $HOME/.youri/submit.conf
++
++=item * /usr/local/etc/youri/submit.conf
++
++=back
++
++The configuration file should be a YAML-format files, with the following
++mandatory top-level directives:
++
++=over
++
++=item B&lt;repository&gt;
++
++The definition of repository plugin to be used.
++
++=item B&lt;targets&gt;
++
++The list of available submission targets, each one being composed from the
++following keys:
++
++=over
++
++=item B&lt;checks&gt;
++
++The list of check plugins to use for this target.
++
++=item B&lt;actions&gt;
++
++The list of action plugins to use for this target.
++
++=back
++
++=item B&lt;checks&gt;
++
++The list of check plugin definitions, indexed by their identity.
++
++=item B&lt;actions&gt;
++
++The list of action plugin definitions, indexed by their identity.
++
++=back
++
++=head1 SEE ALSO
++
++Youri::Config, for additional details about configuration file format.
++
++Each used plugin man page, for available options.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++use Youri::Config;
++use Youri::Utils;
++use Pod::Usage;
++
++my $config = Youri::Config-&gt;new(
++ args =&gt; {
++ 'skip-check' =&gt; '=s@',
++ 'skip-action' =&gt; '=s@',
++ 'define' =&gt; '=s%',
++ 'verbose' =&gt; '|v!',
++ 'clean' =&gt; '!',
++ 'test' =&gt; '|t!',
++ 'list' =&gt; '|l!',
++ 'config' =&gt; '=s',
++ 'skip-prei' =&gt; '=s@',
++ 'skip-post' =&gt; '=s@',
++ 'skip-reject' =&gt; '=s@',
++ },
++ directories =&gt; [ &quot;$ENV{HOME}/.youri&quot;, '@sysconfdir@/youri' ],
++ file =&gt; 'submit.conf',
++);
++
++if ($config-&gt;get_arg('list')) {
++ my $category = $ARGV[0];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No category specified, aborting\n&quot;)
++ unless $category;
++ if ($category eq 'targets') {
++ print join(' ', keys %{$config-&gt;get_param('targets')});
++ } elsif ($category eq 'checks' || $category eq 'actions') {
++ my $target = $ARGV[1];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless $target;
++ if ($category eq 'checks') {
++ my $checks = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{checks};
++ print join(' ', @{$checks}) if $checks;
++ } else {
++ my $actions = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{actions};
++ print join(' ', @{$actions}) if $actions;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ print &quot;\n&quot;;
++ exit 0;
++}
++
++if ($config-&gt;get_arg('help')) {
++ my $category = $ARGV[0];
++ my ($item, $section);
++ if ($category eq 'repository') {
++ $section = $config-&gt;get_param('repository');
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No repository defined, aborting\n&quot;
++ ) unless $section;
++ } elsif ($category eq 'check' || $category eq 'action') {
++ $item = $ARGV[1];
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No item specified, aborting\n&quot;
++ ) unless $item;
++ if ($category eq 'check') {
++ $section = $config-&gt;get_param('checks')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such check $item defined, aborting\n&quot;
++ ) unless $section;
++ } else {
++ $section = $config-&gt;get_param('actions')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such action $item defined, aborting\n&quot;
++ ) unless $section;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ my $file = $section-&gt;{class} . '.pm';
++ $file =~ s/::/\//g;
++ pod2usage(
++ -verbose =&gt; 99,
++ -sections =&gt; 'NAME|DESCRIPTION',
++ -input =&gt; $file,
++ -pathlist =&gt; \@INC
++ );
++}
++
++
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless @ARGV &gt; 0;
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No packages specified, aborting\n&quot;)
++ unless @ARGV &gt; 1 || $config-&gt;get_param('allow_omitting_packages');
++
++# convenient global flags
++my $test = $config-&gt;get_arg('test');
++my $verbose = $config-&gt;get_arg('verbose');
++
++# check target
++my $target = shift @ARGV;
++my $target_conf = $config-&gt;get_param('targets')-&gt;{$target};
++
++# create repository
++my $repository;
++my $repository_conf = $config-&gt;get_param('repository');
++die &quot;No repository declared&quot; unless $repository_conf;
++print &quot;Creating repository\n&quot; if $verbose;
++eval {
++ $repository = create_instance(
++ 'Youri::Repository',
++ $repository_conf,
++ {
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ targets =&gt; [ keys %{$config-&gt;get_param('targets')} ],
++ }
++ );
++};
++die &quot;Failed to create repository: $@\n&quot; if $@;
++
++# perfrom pre action
++my @errors;
++my $pre_packages = [];
++my $skip_pres = $config-&gt;get_arg('skip-pre');
++my %skip_pres = $skip_pres ? map { $_ =&gt; 1 } @{$skip_pres} : ();
++foreach my $id (@{$target_conf-&gt;{pres}}) {
++ next if $skip_pres{$id};
++ print &quot;Creating pre $id\n&quot; if $verbose;
++ my $pre;
++ my $pre_conf = $config-&gt;get_param('pres')-&gt;{$id};
++
++ if (!$pre_conf) {
++ print STDERR &quot;No such pre $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $pre = create_instance(
++ 'Youri::Submit::Pre',
++ $pre_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create pre $id: $@\n&quot;;
++ } else {
++ print &quot;running pre $id\n&quot; if $verbose;
++ my @err = $pre-&gt;run(
++ $pre_packages,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@errors, @err) if $err[0];
++ }
++}
++
++if (@errors) {
++ print &quot;Pre-submission errors, aborting:\n&quot;;
++ foreach my $error (@errors) {
++ print &quot; - $error\n&quot;;
++ }
++ exit(1)
++}
++
++# create packages group
++my $group_error;
++my @packages_group;
++foreach my $group ([ map { { section =&gt; &quot;&quot;, file =&gt; $_ } } @ARGV ], @$pre_packages) {
++ my @packages;
++ foreach my $opt (@$group) {
++ print &quot;Preparing upload for $opt-&gt;{file} in $opt-&gt;{section}\n&quot; if $verbose;
++ $repository-&gt;{packages}{$opt-&gt;{file}}{section} = $opt-&gt;{section};
++ push(
++ @packages,
++ create_instance(
++ 'Youri::Package',
++ {
++ class =&gt; $repository-&gt;get_package_class(),
++ },
++ {
++ file =&gt; $opt-&gt;{file},
++ %$opt
++ },
++ )
++ );
++ }
++ @packages or next;
++
++# check all packages pass all tests
++ my %errors;
++ my $skip_check = $config-&gt;get_arg('skip-check');
++ my %skip_check = $skip_check ? map { $_ =&gt; 1 } @{$skip_check} : ();
++ my @error;
++ foreach my $id (@{$target_conf-&gt;{checks}}) {
++ next if $skip_check{$id};
++ print &quot;Creating check $id\n&quot; if $verbose;
++ my $check;
++ my $check_conf = $config-&gt;get_param('checks')-&gt;{$id};
++
++ if (!$check_conf) {
++ print STDERR &quot;No such check $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $check = create_instance(
++ 'Youri::Submit::Check',
++ $check_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create check $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running check $id on package $package\n&quot; if $verbose;
++ my @errors = $check-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@{$errors{$package}}, @errors) if $errors[0];
++ }
++ }
++ }
++ if (%errors) {
++ print &quot;Submission errors, aborting:\n&quot;;
++ foreach my $package (keys %errors) {
++ print &quot;- $package:\n&quot;;
++ foreach my $error (@{$errors{$package}}) {
++ print &quot; - $error\n&quot;;
++ }
++ }
++ # reject the packages
++ my $skip_rejects = $config-&gt;get_arg('skip-reject');
++ my %skip_rejects = $skip_rejects ? map { $_ =&gt; 1 } @{$skip_rejects} : ();
++ foreach my $id (@{$target_conf-&gt;{rejects}}) {
++ next if $skip_rejects{$id};
++ print &quot;Creating reject $id\n&quot; if $verbose;
++ my $reject;
++ my $reject_conf = $config-&gt;get_param('rejects')-&gt;{$id};
++
++ if (!$reject_conf) {
++ print STDERR &quot;No such reject $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $reject = create_instance(
++ 'Youri::Submit::Reject',
++ $reject_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create reject $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running reject $id on package $package\n&quot; if $verbose;
++ eval {
++ $reject-&gt;run($package, \%errors, $repository, $target, $config-&gt;get_arg('define'));
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++ $group_error = 1;
++ next
++ }
++
++# proceed further
++ my $skip_action = $config-&gt;get_arg('skip-action');
++ my %skip_action = $skip_action ? map { $_ =&gt; 1 } @{$skip_action} : ();
++ foreach my $id (@{$target_conf-&gt;{actions}}) {
++ next if $skip_action{$id};
++ print &quot;Creating action $id\n&quot; if $verbose;
++ my $action;
++ my $action_conf = $config-&gt;get_param('actions')-&gt;{$id};
++
++ if (!$action_conf) {
++ print STDERR &quot;No such action $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $action = create_instance(
++ 'Youri::Submit::Action',
++ $action_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create action $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running action $id on package $package\n&quot; if $verbose;
++ eval {
++ $action-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++
++ if ($config-&gt;get_arg('clean')) {
++ foreach my $package (@packages) {
++ print &quot;cleaning file $package\n&quot; if $verbose;
++ unlink $package-&gt;as_file();
++ }
++ }
++}
++
++# perfrom post action
++my $skip_post = $config-&gt;get_arg('skip-post');
++my %skip_post = $skip_post ? map { $_ =&gt; 1 } @{$skip_post} : ();
++foreach my $id (@{$target_conf-&gt;{posts}}) {
++ next if $skip_post{$id};
++ print &quot;Creating post $id\n&quot; if $verbose;
++ my $post;
++ my $post_conf = $config-&gt;get_param('posts')-&gt;{$id};
++
++ if (!$post_conf) {
++ print STDERR &quot;No such post $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $post = create_instance(
++ 'Youri::Submit::Post',
++ $post_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create post $id: $@\n&quot;;
++ } else {
++ print &quot;running post $id\n&quot; if $verbose;
++ my @err = $post-&gt;run($repository, $target, $config-&gt;get_arg('define'));
++ print STDERR &quot;Error $id: @err\n&quot; if @err
++ }
++}
++
++exit(1) if $group_error;
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit.in
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunketcbash_completiondyourisubmit">Added: build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit (rev 0)
++++ build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,60 @@
++# youri-submit completion
++# $Id$
++
++_youri-submit()
++{
++
++ local cur prev config
++
++ COMPREPLY=()
++ cur=${COMP_WORDS[COMP_CWORD]}
++ prev=${COMP_WORDS[COMP_CWORD-1]}
++
++ case &quot;$prev&quot; in
++ --config)
++ _filedir
++ return 0
++ ;;
++ --list)
++ COMPREPLY=( $( compgen -W 'targets checks actions' -- $cur ) )
++ return 0
++ ;;
++ --help)
++ COMPREPLY=( $( compgen -W 'repository check action' -- $cur ) )
++ return 0
++ ;;
++ esac
++
++ if [[ &quot;$cur&quot; == -* ]]; then
++ COMPREPLY=( $( compgen -W '--define --clean -l --list -h --help -t \
++ --test -v --verbose' -- $cur ) )
++ # add dangereous option for main command
++ if [[ ${COMP_WORDS[0]} == youri-submit ]]; then
++ COMPREPLY=( $( compgen -W '${COMPREPLY[@]} --config --skip-check \
++ --skip-action' -- $cur ) )
++ fi
++ else
++ _count_args
++ case $args in
++ 1)
++ _find_config
++ COMPREPLY=( $( compgen -W '$( youri-submit $config --list targets )' -- $cur ) )
++ ;;
++ *)
++ _filedir
++ ;;
++ esac
++ fi
++
++}
++complete -F _youri-submit youri-submit youri-submit-restricted youri-submit-proxy
++
++_find_config()
++{
++ for (( i=1; i &lt; COMP_CWORD; i++ )); do
++ if [[ &quot;${COMP_WORDS[i]}&quot; == --config ]]; then
++ config=&quot;--config ${COMP_WORDS[i+1]}&quot;
++ break
++ fi
++ done
++}
+
+<a id="build_systemmdvyourisubmittrunketcsubmitconf">Added: build_system/mdv-youri-submit/trunk/etc/submit.conf</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/etc/submit.conf (rev 0)
++++ build_system/mdv-youri-submit/trunk/etc/submit.conf 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,134 @@
++# youri-submit sample configuration file
++# $Id: submit.conf 1723 2006-10-17 13:53:27Z warly $
++
++# helper variables
++home: /home/user
++
++# repository definition
++repository:
++ class: Youri::Repository::PLF
++ options:
++ install_root: ${home}/ftp/mandriva
++ version_root: ${home}/cvs
++ archive_root: ${home}/backup/mandriva
++ noarch: i586
++
++# targets definitions
++targets:
++ cooker:
++ checks:
++ - tag
++ - recency
++ - history
++ actions:
++ - sign
++ - install
++ - link
++ - archive
++ - clean
++ - bugzilla
++ - cvs
++ - mail
++ - rss
++
++ 2006.0:
++ checks:
++ - type
++ - tag
++ - recency
++ - history
++ - precedence
++ actions:
++ - sign
++ - install
++ - link
++ - archive
++ - clean
++
++# checks definitions
++checks:
++ tag:
++ class: Youri::Submit::Check::Tag
++ options:
++ tags:
++ release: 'plf$'
++ packager: '&lt;\w+@zarb\.org&gt;$'
++ distribution: '^Mandriva Linux$'
++ vendor: '^Penguin Liberation Front$'
++
++ recency:
++ class: Youri::Submit::Check::Recency
++
++ history:
++ class: Youri::Submit::Check::History
++
++ precedence:
++ class: Youri::Submit::Check::Precedence
++ options:
++ target: cooker
++
++ type:
++ class: Youri::Submit::Check::Type
++ type: binary
++
++# actions definitions
++actions:
++ sign:
++ class: Youri::Submit::Action::Sign
++ options:
++ name: plf@zarb.org
++ path: ${home}/.gnupg
++ passphrase: s3kr3t
++
++ install:
++ class: Youri::Submit::Action::Install
++
++ link:
++ class: Youri::Submit::Action::Link
++
++ archive:
++ class: Youri::Submit::Action::Archive
++
++ clean:
++ class: Youri::Submit::Action::Clean
++
++ mail:
++ class: Youri::Submit::Action::Mail
++ options:
++ mta: /usr/sbin/sendmail
++ to: plf-announce@zarb.org
++ reply_to: plf-discuss@zarb.org
++ from: plf@zarb.org
++ prefix: RPM
++ cc:
++ hot-base: david@dindinx.org bellamy@neverland.net
++ dcgui: mathen@ketelhot.de
++ dclib: mathen@ketelhot.de
++ Video-DVDRip: dvdrip-users@exit1.org
++ hackVideo-DVDRip: dvdrip-users@exit1.org
++ goosnes: tak@bard.sytes.net
++ avidemux: fixounet@free.fr
++ vobcopy: robos@muon.de
++ drip: drip-devel@lists.sourceforge.net
++ libdscaler: vektor@dumbterm.net
++ xawdecode: pingus77@ifrance.com
++
++ rss:
++ class: Youri::Submit::Action::RSS
++ options:
++ file: ${home}/www/changelog.rss
++ title: PLF packages updates
++ link: http://plf.zarb.org/
++ description: ChangeLog for PLF packages
++
++ cvs:
++ class: Youri::Submit::Action::CVS
++
++ bugzilla:
++ class: Youri::Submit::Action::Bugzilla
++ options:
++ host: localhost
++ base: plf_bugs
++ user: plf
++ pass: s3kr3t
++ contact: plf@zarb.org
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionArchivepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,90 @@
++# $Id: Archive.pm 265457 2010-01-28 13:09:30Z pterjan $
++package Youri::Submit::Action::Archive;
++
++=head1 NAME
++
++Youri::Submit::Action::Archive - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # FIXME: workaround for $self-&gt;{_verbose} not being initialized properly
++ $self-&gt;{_verbose} = 1;
++ # all this should be in Mandriva_upload.pm
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ my $main_section = $repository-&gt;_get_main_section($package, $target, $define);
++ print &quot;section $section main_section $main_section\n&quot; if $self-&gt;{_verbose};
++ my $arch = $package-&gt;get_arch();
++ $arch = $self-&gt;{_noarch} if $arch eq 'noarch';
++ my $path = $arch eq 'src' ? &quot;$target/SRPMS&quot; : &quot;$target/$arch/media&quot;;
++ $path = &quot;$repository-&gt;{_install_root}/$path&quot;;
++ $path =~ s,/+,/,g;
++ foreach my $replaced_package (
++ $repository-&gt;get_replaced_packages($package, $target, $define)
++ ) {
++ my $file = $replaced_package-&gt;get_file();
++
++ # trap for debugging bug 34999
++ if ($file =~ /\/[\d.]+\/(main\/updates|.*\/release)/) {
++ my $bugmsg = &quot;BUG#34999 WARNING: trying to remove from a release: $file\n&quot;;
++ open(BUG34999LOG, '&gt;&gt;', &quot;/home/mandrake/bug34999.log&quot;);
++ print $bugmsg;
++ print BUG34999LOG localtime().&quot;: &quot;.$bugmsg;
++ close BUG34999LOG;
++
++ next;
++ }
++
++ my ($rep_section, $rep_main_section) = $file =~ m,$path/(([^/]+)/.*)/[^/]+.rpm,;
++ # We do accept duplicate version for other submedia of the same main media section
++ print &quot;(path '$path') file '$file' section '$rep_section' main_section '$rep_main_section'\n&quot; if $self-&gt;{_verbose};
++ next if $rep_main_section eq $main_section &amp;&amp; $rep_section ne $section;
++ my $dest = $repository-&gt;get_archive_dir($package, $target, $define);
++
++ print &quot;archiving file $file to $dest\n&quot; if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest&quot;)
++ unless -d $dest;
++
++ # install file to new location
++ system(&quot;install -m $self-&gt;{_perms} $file $dest&quot;);
++
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionBugzillapm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,81 @@
++# $Id: Bugzilla.pm 1700 2006-10-16 12:57:42Z warly $
++package Youri::Submit::Action::Bugzilla;
++
++=head1 NAME
++
++Youri::Submit::Action::Bugzilla - Bugzilla synchronisation
++
++=head1 DESCRIPTION
++
++This action plugin ensures synchronisation with Bugzilla.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Bugzilla;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ host =&gt; '',
++ base =&gt; '',
++ user =&gt; '',
++ pass =&gt; '',
++ contact =&gt; '',
++ @_
++ );
++
++ $self-&gt;{_bugzilla} = Youri::Bugzilla-&gt;new(
++ $options{host},
++ $options{base},
++ $options{user},
++ $options{pass}
++ );
++ $self-&gt;{_contact} = $options{contact};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $summary = $package-&gt;get_summary();
++ my $packager = $package-&gt;get_packager();
++ $packager =~ s/.*&lt;(.*)&gt;/$1/;
++
++ if ($self-&gt;{_bugzilla}-&gt;has_package($name)) {
++ my %versions =
++ map { $_ =&gt; 1 }
++ $self-&gt;{_bugzilla}-&gt;get_versions($name);
++ unless ($versions{$version}) {
++ print &quot;adding version $version to bugzilla\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;{_bugzilla}-&gt;add_version($name, $version)
++ unless $self-&gt;{_test};
++ }
++ } else {
++ print &quot;adding package $name to bugzilla\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;{_bugzilla}-&gt;add_package(
++ $name,
++ $summary,
++ $version,
++ $packager,
++ $self-&gt;{_contact}
++ ) unless $self-&gt;{_test};
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionCVSpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,135 @@
++# $Id: CVS.pm 224115 2007-07-02 09:17:15Z pixel $
++package Youri::Submit::Action::CVS;
++
++=head1 NAME
++
++Youri::Submit::Action::CVS - CVS versionning
++
++=head1 DESCRIPTION
++
++This action plugin ensures CVS versionning of package sources.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Cwd;
++use File::Temp qw/tempdir/;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ exclude =&gt; '\.(tar(\.(gz|bz2))?|zip)$',
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_exclude} = $options{exclude};
++ $self-&gt;{_perms} = $options{perms};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++
++ my $root = $repository-&gt;get_version_root();
++ my $path = $repository-&gt;get_version_path($package, $target, $define);
++
++ # remember original directory
++ my $original_dir = cwd();
++
++ # get a safe temporary directory
++ my $dir = tempdir( CLEANUP =&gt; 1 );
++ chdir $dir;
++
++ # first checkout base directory only
++ system(&quot;cvs -Q -d $root co -l $path&quot;);
++
++ # try to checkout package directory
++ my $dest = $path . '/' . $name;
++ system(&quot;cvs -Q -d $root co $dest&quot;);
++
++ # create directory if previous import failed
++ unless (-d $dest) {
++ print &quot;adding directory $dest\n&quot; if $self-&gt;{_verbose};
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest&quot;);
++ system(&quot;cvs -Q -d $root add $dest&quot;);
++ }
++
++ chdir $dest;
++
++ # remove all files
++ unlink grep { -f } glob '*';
++
++ # extract all rpm files locally
++ $package-&gt;extract();
++
++ # remove excluded files
++ if ($self-&gt;{_exclude}) {
++ unlink grep { -f &amp;&amp; /$self-&gt;{_exclude}/ } glob '*';
++ }
++
++ # uncompress all compressed files
++ system(&quot;bunzip2 *.bz2 2&gt;/dev/null&quot;);
++ system(&quot;gunzip *.gz 2&gt;/dev/null&quot;);
++
++ my (@to_remove, @to_add, @to_add_binary);
++ foreach my $line (`cvs -nq update`) {
++ if ($line =~ /^\? (\S+)/) {
++ if (-B $1) {
++ push(@to_add_binary, $1);
++ } else {
++ push(@to_add, $1);
++ }
++ }
++ if ($line =~ /^U (\S+)/) {
++ push(@to_remove, $1);
++ }
++ }
++ if (@to_remove) {
++ my $to_remove = join(' ', @to_remove);
++ print &quot;removing file(s) $to_remove\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q remove $to_remove&quot;);
++ }
++ if (@to_add) {
++ my $to_add = join(' ', @to_add);
++ print &quot;adding text file(s) $to_add\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q add $to_add&quot;);
++ }
++ if (@to_add_binary) {
++ my $to_add_binary = join(' ', @to_add_binary);
++ print &quot;adding binary file(s) $to_add_binary\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q add -kb $to_add_binary&quot;);
++ }
++
++ print &quot;committing current directory\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q commit -m $version-$release&quot;) unless $self-&gt;{_test};
++
++ # tag new release
++ my $tag = &quot;r$version-$release&quot;;
++ $tag =~ s/\./_/g;
++ print &quot;tagging current directory as $tag\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q tag $tag&quot;) unless $self-&gt;{_test};
++
++ # get back to original directory
++ chdir $original_dir;
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionCleanpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,40 @@
++# $Id: Clean.pm 4742 2007-01-30 09:49:58Z pixel $
++package Youri::Submit::Action::Clean;
++
++=head1 NAME
++
++Youri::Submit::Action::Clean - Old revisions cleanup
++
++=head1 DESCRIPTION
++
++This action plugin ensures cleanup of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ foreach my $replaced_package (
++ $repository-&gt;get_replaced_packages($package, $target, $define)
++ ) {
++ my $file = $replaced_package-&gt;as_file();
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionDkmsModuleInfopm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,111 @@
++# $Id$
++package Youri::Submit::Action::DkmsModuleInfo;
++
++=head1 NAME
++
++Youri::Submit::Action::DkmsModuleInfo - extract and commit info from dkms package.
++
++=head1 DESCRIPTION
++
++This action plugin extract modalias and description from dkms packages and commit them
++on a SVN module.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++use File::Temp qw/tempdir/;
++use File::Basename;
++use SVN::Client;
++
++#- inlineed from MDK::Common::Various
++sub chomp_ { my @l = @_; chomp @l; wantarray() ? @l : $l[0] }
++
++sub _init {
++ my ($self, %options) = @_;
++
++ croak &quot;undefined svn module&quot; unless $options{svn_module};
++
++ foreach my $var ('svn_module') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my ($dkms_name) = $package-&gt;get_canonical_name =~ /^dkms-(.*)$/ or return;
++ my $package_name = $package-&gt;get_name;
++ my ($kver) = $package_name =~ /^$dkms_name-kernel-(.*)$/ or return;
++
++ my @files = map { $_-&gt;[0] } $package-&gt;get_files;
++ my @module_files = grep { m!^(/lib/modules/|/var/lib/dkms-binary/).*\.ko(\.gz)?$! } @files
++ or return;
++
++ print &quot;Submit::Action::DkmsModuleInfo: proceeding with $package_name\n&quot; if $self-&gt;{_verbose};
++
++ my $tempdir = tempdir(CLEANUP =&gt; 1);
++ my $file = $package-&gt;as_file;
++ my $cmd = &quot;rpm2cpio $file | (cd $tempdir ; cpio --quiet -id)&quot;;
++ print &quot;Submit::Action::DkmsModuleInfo: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (system($cmd) != 0) {
++ print &quot;Submit::Action::DkmsModuleInfo: failed!\n&quot; if $self-&gt;{_verbose};
++ return;
++ }
++
++ my @fields = qw(description alias);
++
++ my (%modules);
++ foreach my $file (@module_files) {
++ print &quot;Submit::Action::DkmsModuleInfo: extracting $file\n&quot; if $self-&gt;{_verbose};
++ my $module = $file;
++ $module =~ s!.*/!!;
++ $module =~ s!\.ko(\.gz)$!!;
++ $modules{$module}{$_} = [ chomp_(`/sbin/modinfo -F $_ $tempdir$file`) ]
++ foreach @fields;
++ }
++
++ eval {
++ my $svn = SVN::Client-&gt;new();
++ my $dir = $tempdir . '/' . basename($self-&gt;{_svn_module});
++ my $revision = $svn-&gt;checkout($self-&gt;{_svn_module}, $dir, 'HEAD', 0);
++ my $vdir = $dir . '/' . $kver;
++ $svn-&gt;update($vdir, 'HEAD', 0);
++ -d $vdir or $svn-&gt;mkdir($vdir);
++ foreach my $module (keys %modules) {
++ print &quot;Submit::Action::DkmsModuleInfo: adding module $module\n&quot; if $self-&gt;{_verbose};
++ foreach my $field (@fields) {
++ my $file = &quot;$vdir/$module.$field&quot;;
++ $svn-&gt;update($file, 'HEAD', 0);
++ my $exists = -f $file;
++ open(my $fh, &quot;&gt;&quot;, $file);
++ print $fh map { &quot;$_\n&quot; } @{$modules{$module}{$field}};
++ $svn-&gt;add($file, 1) if !$exists;
++ }
++ }
++
++ $svn-&gt;log_msg(sub { $_[0] = \&quot;add dkms info for $dkms_name with kernel $kver&quot; });
++ $svn-&gt;commit($vdir, 0);
++ };
++ if (my $error = $@) {
++ print &quot;Submit::Action::DkmsModuleInfo: commit to svn failed ($error)!\n&quot; if $self-&gt;{_verbose};
++ return;
++ }
++
++ 1;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionInstallpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,74 @@
++# $Id: Install.pm 229772 2007-09-26 11:21:07Z blino $
++package Youri::Submit::Action::Install;
++
++=head1 NAME
++
++Youri::Submit::Action::Install - Package installation
++
++=head1 DESCRIPTION
++
++This action plugin ensures installation of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;as_file();
++ my $rpm = $package-&gt;get_file_name();
++ my $dest = $repository-&gt;get_install_dir($package, $target, $define);
++
++ # FIXME remove prefix this should be done by a function
++ $rpm =~ s/^\d{14}\.\w*\.\w+\.\d+_//;
++ $rpm =~ s/^\@\d+://;
++ print &quot;installing file $file to $dest/$rpm\n&quot; if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ if (! -d $dest) {
++ my $status =
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest&quot;);
++ croak &quot;Unable to create directory $dest: $?&quot; if $status;
++ }
++
++ # install file to new location
++ my $status =
++ system(&quot;install -m $self-&gt;{_perms} $file $dest/$rpm&quot;);
++ croak &quot;Unable to install file $file to $dest/$rpm: $?&quot; if $status;
++
++ my $arch = $package-&gt;get_arch();
++ $repository-&gt;set_arch_changed($target, $arch);
++ $repository-&gt;set_install_dir_changed($dest);
++ }
++ $package-&gt;{_file} = &quot;$dest/$rpm&quot;;
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionLinkpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,80 @@
++# $Id: Link.pm 233641 2008-01-31 16:35:55Z pixel $
++package Youri::Submit::Action::Link;
++
++=head1 NAME
++
++Youri::Submit::Action::Link - Noarch packages linking
++
++=head1 DESCRIPTION
++
++This action plugin ensures linking of noarch packages between arch-specific
++directories.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Cwd;
++use File::Spec;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ symbolic =&gt; 0, # use symbolic linking
++ @_
++ );
++
++ $self-&gt;{_symbolic} = $options{symbolic};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # only needed for noarch packages
++ return unless $package-&gt;get_arch() eq 'noarch';
++
++ my $default_dir = $repository-&gt;get_install_dir($package, $target, $define);
++ my $file = $package-&gt;get_file_name();
++
++ # FIXME remove prefix this should be done by a function
++ $file =~ s/^\d{14}\.\w*\.\w+\.\d+_//;
++ $file =~ s/^\@\d+://;
++
++ foreach my $arch ($repository-&gt;get_extra_arches()) {
++ # compute installation target, forcing arch
++ my $other_dir = $repository-&gt;get_install_dir(
++ $package,
++ $target,
++ $define,
++ { arch =&gt; $arch }
++ );
++
++ if (! $self-&gt;{_test}) {
++ my $current_dir = cwd();
++ chdir $other_dir;
++ my $default_file = File::Spec-&gt;abs2rel($default_dir) . '/' . $file;
++ if ($self-&gt;{_symbolic}) {
++ symlink $default_file, $file;
++ } else {
++ link $default_file, $file;
++ }
++ chdir $current_dir;
++ print &quot;set_install_dir_changed($other_dir) for updated $file\n&quot;;
++ $repository-&gt;set_install_dir_changed($other_dir);
++ $repository-&gt;set_arch_changed($target, $arch);
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionMailpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,131 @@
++# $Id: Mail.pm 223952 2007-06-23 13:54:13Z pixel $
++package Youri::Submit::Action::Mail;
++
++=head1 NAME
++
++Youri::Submit::Action::Mail - Mail notification
++
++=head1 DESCRIPTION
++
++This action plugin ensures mail notification of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use MIME::Entity;
++use Encode qw/from_to/;
++use Carp;
++use Youri::Package;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ mta =&gt; '/usr/sbin/sendmail',
++ to =&gt; '',
++ from =&gt; '',
++ cc =&gt; '',
++ prefix =&gt; '',
++ encoding =&gt; 'quoted-printable',
++ charset =&gt; 'iso-8859-1',
++ @_
++ );
++
++ croak &quot;undefined mail MTA&quot; unless $options{mta};
++ croak &quot;invalid mail MTA $options{mta}&quot; unless -x $options{mta};
++ croak &quot;undefined to&quot; unless $options{to};
++ if ($options{cc}) {
++ croak &quot;cc should be an hashref&quot; unless ref $options{cc} eq 'HASH';
++ }
++ croak &quot;invalid charset $options{charset}&quot;
++ unless Encode::resolve_alias($options{charset});
++
++ $self-&gt;{_mta} = $options{mta};
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_from} = $options{from};
++ $self-&gt;{_cc} = $options{cc};
++ $self-&gt;{_prefix} = $options{prefix};
++ $self-&gt;{_encoding} = $options{encoding};
++ $self-&gt;{_charset} = $options{charset};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $from = $package-&gt;get_packager();
++
++ # force from adress if defined
++ $from =~ s/&lt;.*&gt;/&lt;$self-&gt;{_from}&gt;/ if $self-&gt;{_from};
++
++ my $subject = $self-&gt;get_subject($package, $repository, $target, $define);
++ my $content = $self-&gt;get_content($package, $repository, $target, $define);
++
++ # ensure proper codeset conversion
++ # for informations coming from package
++ my $charset = $repository-&gt;get_package_charset();
++ from_to($content, $charset, $self-&gt;{_charset});
++ from_to($subject, $charset, $self-&gt;{_charset});
++
++ my $mail = MIME::Entity-&gt;build(
++ Type =&gt; 'text/plain',
++ Charset =&gt; $self-&gt;{_charset},
++ Encoding =&gt; $self-&gt;{_encoding},
++ From =&gt; $from,
++ To =&gt; $self-&gt;{_to},
++ Subject =&gt; $subject,
++ Data =&gt; $content,
++ );
++
++ if ($self-&gt;{_cc}) {
++ my $cc = $self-&gt;{_cc}-&gt;{$package-&gt;get_name()};
++ $mail-&gt;head()-&gt;add('cc', $cc) if $cc;
++ }
++
++ if ($self-&gt;{_test}) {
++ $mail-&gt;print(\*STDOUT);
++ } else {
++ open(MAIL, &quot;| $self-&gt;{_mta} -t -oi -oem&quot;) or die &quot;Can't open MTA program: $!&quot;;
++ $mail-&gt;print(\*MAIL);
++ close MAIL;
++ }
++
++}
++
++sub get_subject {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ return
++ ($self-&gt;{_prefix} ? '[' . $self-&gt;{_prefix} . '] ' : '' ) .
++ &quot;$target &quot; . ($section ? &quot;$section &quot; : '' ) .
++ $package-&gt;as_formated_string('%{name}-%{version}-%{release}');
++}
++
++sub get_content {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $information = $package-&gt;get_information();
++ my $last_change = $package-&gt;get_last_change();
++
++ return
++ $information . &quot;\n&quot; .
++ $last_change-&gt;[Youri::Package::CHANGE_AUTHOR] . &quot;:\n&quot; .
++ $last_change-&gt;[Youri::Package::CHANGE_TEXT];
++}
++
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionMarkreleasepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,56 @@
++# $Id: Markrelease.pm 4743 2007-01-30 09:58:30Z pixel $
++package Youri::Submit::Action::Markrelease;
++
++=head1 NAME
++
++Youri::Submit::Action::Markrelease - calls markrelease
++
++=head1 DESCRIPTION
++
++This action plugin calls markrelease
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $package-&gt;is_source or return 1;
++ my $file = $package-&gt;get_file();
++ my $srpm_name = $package-&gt;get_canonical_name;
++
++ if ($repository-&gt;package_in_svn($srpm_name)) {
++ my $svn = $repository-&gt;get_svn_url();
++ my ($rev) = $file =~ /.*\/.*?\@(\d+):/;
++ print &quot;Run repsys markrelease -f $file -r $rev $svn/$srpm_name\n&quot;;
++ # FIXME repsys ask for a username and password
++ # FIXME we should use the key in /var/home/mandrake so that /home/mandrake does not
++ # need to be mounted
++ system('repsys', 'markrelease', '-f', $file, '-r', $rev, &quot;$svn/$srpm_name&quot;);
++ }
++ 1
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionRSSpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,102 @@
++# $Id: RSS.pm 1700 2006-10-16 12:57:42Z warly $
++package Youri::Submit::Action::RSS;
++
++=head1 NAME
++
++Youri::Submit::Action::RSS - RSS notification
++
++=head1 DESCRIPTION
++
++This action plugin ensures RSS notification of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use XML::RSS;
++use Encode qw/from_to/;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ file =&gt; '',
++ title =&gt; '',
++ link =&gt; '',
++ description =&gt; '',
++ charset =&gt; 'iso-8859-1',
++ max_items =&gt; 10,
++ @_
++ );
++
++ croak &quot;undefined rss file&quot; unless $options{file};
++ croak &quot;invalid charset $options{charset}&quot;
++ unless Encode::resolve_alias($options{charset});
++
++ $self-&gt;{_file} = $options{file};
++ $self-&gt;{_title} = $options{title};
++ $self-&gt;{_link} = $options{link};
++ $self-&gt;{_description} = $options{description};
++ $self-&gt;{_charset} = $options{charset};
++ $self-&gt;{_max_items} = $options{max_items};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $subject = $package-&gt;as_formated_string('%{name}-%{version}-%{release}');
++ my $content = $package-&gt;get_information();
++
++ $content =~ s/$/&lt;br\/&gt;/mg;
++
++ # ensure proper codeset conversion
++ # for informations coming from package
++ my $charset = $repository-&gt;get_package_charset();
++ from_to($content, $charset, $self-&gt;{_charset});
++ from_to($subject, $charset, $self-&gt;{_charset});
++
++ my $rss = XML::RSS-&gt;new(
++ encoding =&gt; $self-&gt;{_charset},
++ encode_output =&gt; 1
++ );
++
++ my $file = $self-&gt;{_file};
++ if (-e $file) {
++ $rss-&gt;parsefile($file);
++ splice(@{$rss-&gt;{items}}, $self-&gt;{_max_items})
++ if @{$rss-&gt;{items}} &gt;= $self-&gt;{_max_items};
++ } else {
++ $rss-&gt;channel(
++ title =&gt; $self-&gt;{_title},
++ link =&gt; $self-&gt;{_link},
++ description =&gt; $self-&gt;{_description},
++ language =&gt; 'en'
++ );
++ }
++
++ $rss-&gt;add_item(
++ title =&gt; $subject,
++ description =&gt; $content,
++ mode =&gt; 'insert'
++ );
++
++ if ($self-&gt;{_test}) {
++ print $rss-&gt;as_string();
++ } else {
++ $rss-&gt;save($file);
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionRpminfopm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,69 @@
++# $Id: Rpminfo.pm 4742 2007-01-30 09:49:58Z pixel $
++package Youri::Submit::Action::Rpminfo;
++
++=head1 NAME
++
++Youri::Submit::Action::RpmInfo - Creates .info files
++
++=head1 DESCRIPTION
++
++This action plugin ensures the creation of .info files
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ uphost =&gt; '',
++ user =&gt; '',
++ ssh_key =&gt; '',
++ verbose =&gt; '',
++ @_
++ );
++ croak &quot;undefined upload host&quot; unless $options{uphost};
++ croak &quot;undefined ssh key&quot; unless $options{ssh_key};
++
++ foreach my $var ('perms', 'user', 'uphost', 'ssh_key', 'verbose') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $dest = $repository-&gt;get_upload_dir($package, $target, $define);
++
++ print &quot;Caching rpm information $file on $dest\n&quot; if $self-&gt;{_verbose};
++ my $base = basename ($file);
++ $dest =~ s/\/[0-9]{14}\./\/*./;
++
++ my $cmd = &quot;ssh -i $self-&gt;{_ssh_key} $self-&gt;{_user}\@$self-&gt;{_uphost} \&quot;srpm=`echo /$dest$base`; rpm -q --qf '\%{name}\n\%{epoch}\n\%{version}-\%{release}\n\%{summary}\n' -p \\\$srpm &gt; \\\$srpm.info\&quot;&quot;;
++ print &quot;Submit::Action::RpmInfo: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ if (!system($cmd)) {
++ print &quot;Submit::Action::RpmInfo: rpminfo succeeded!\n&quot;;
++ return 1
++ }
++ print &quot;Submit::Action::RpmInfo: rpminfo failed!\n&quot;;
++ }
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionSendpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,77 @@
++# $Id: Send.pm 4744 2007-01-30 09:59:07Z pixel $
++package Youri::Submit::Action::Send;
++
++=head1 NAME
++
++Youri::Submit::Action::Send - upload package
++
++=head1 DESCRIPTION
++
++This action plugin uploads the package on uphost
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ uphost =&gt; '',
++ user =&gt; '',
++ ssh_key =&gt; '',
++ verbose =&gt; '',
++ keep_svn_release =&gt; '',
++ @_
++ );
++ croak &quot;undefined upload host&quot; unless $options{uphost};
++ croak &quot;undefined ssh key&quot; unless $options{ssh_key};
++
++ foreach my $var ('perms', 'user', 'uphost', 'ssh_key', 'verbose', 'keep_svn_release') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $dest = $repository-&gt;get_upload_dir($package, $target, $define);
++
++ print &quot;Sending file $file to $dest\n&quot; if $self-&gt;{_verbose};
++ my $base;
++ if ($self-&gt;{_keep_svn_release}) {
++ $base = basename($file)
++ } else {
++ ($base) = $file =~ /.*\/(?:@\d+:)?([^\/]*)/
++ }
++
++ my $cmd = &quot;scp -i $self-&gt;{_ssh_key} $file $self-&gt;{_user}\@$self-&gt;{_uphost}:/$dest$base.new&quot;;
++ my $cmd2 = &quot;ssh -i $self-&gt;{_ssh_key} $self-&gt;{_user}\@$self-&gt;{_uphost} \&quot;mv /$dest$base.new /$dest$base\&quot;&quot;;
++ print &quot;Submit::Action::Send: doing $cmd\n$cmd2\n&quot; if 1 || $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ if (!system($cmd)) {
++ if (!system($cmd2)) {
++ print &quot;Submit::Action::Send: upload succeeded!\n&quot;;
++ return 1
++ }
++ }
++ print &quot;Submit::Action::Send: upload failed!\n&quot;;
++ }
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionSendcachepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,81 @@
++# $Id: Sendcache.pm 232350 2007-12-07 18:26:17Z spuk $
++package Youri::Submit::Action::Sendcache;
++
++=head1 NAME
++
++Youri::Submit::Action::Sendcache - upload package to cache
++
++=head1 DESCRIPTION
++
++This action plugin uploads the package on uphost
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ uphost =&gt; '',
++ user =&gt; '',
++ ssh_key =&gt; '',
++ verbose =&gt; '',
++ root =&gt; '',
++ debug_pkgs =&gt; 0,
++ @_
++ );
++ croak &quot;undefined upload host&quot; unless $options{uphost};
++ croak &quot;undefined ssh key&quot; unless $options{ssh_key};
++
++ foreach my $var ('perms', 'user', 'uphost', 'ssh_key', 'verbose', 'root', 'debug_pkgs') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # only cache debug packages if option debug_pkgs is true
++ return if ($package-&gt;is_debug() &amp;&amp; !$self-&gt;{_debug_pkgs});
++
++ my $file = $package-&gt;get_file();
++ my $dest = $repository-&gt;get_upload_dir($package, $target, $define);
++ $dest =~ s!$repository-&gt;{_upload_root}/$repository-&gt;{_queue}!$self-&gt;{_root}!;
++
++ print &quot;Sending file $file to $dest\n&quot; if $self-&gt;{_verbose};
++ my $destfile = &quot;$dest&quot;.basename($file);
++ $destfile =~ s,/[^/_]+_([^/]+)$,/$1,;
++ $destfile =~ s,/@\d+:,/,;
++ my $destfilehidden = $destfile;
++ $destfilehidden =~ s,/([^/]+)$,/.$1,;
++
++ my $cmd = &quot;scp -i $self-&gt;{_ssh_key} $file $self-&gt;{_user}\@$self-&gt;{_uphost}:/$destfilehidden&quot;;
++ my $cmd2 = &quot;ssh -i $self-&gt;{_ssh_key} $self-&gt;{_user}\@$self-&gt;{_uphost} \&quot;mv /$destfilehidden /$destfile\&quot;&quot;;
++ print &quot;Submit::Action::Send: doing $cmd\n$cmd2\n&quot; if 1 || $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ if (!system($cmd)) {
++ if (!system($cmd2)) {
++ print &quot;Submit::Action::Sendcache: upload succeeded!\n&quot;;
++ return 1
++ }
++ }
++ print &quot;Submit::Action::Sendcache: upload failed!\n&quot;;
++ }
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionSignpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,56 @@
++# $Id: Sign.pm 1700 2006-10-16 12:57:42Z warly $
++package Youri::Submit::Action::Sign;
++
++=head1 NAME
++
++Youri::Submit::Action::Sign - GPG signature
++
++=head1 DESCRIPTION
++
++This action plugin ensures GPG signature of packages.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ name =&gt; '',
++ path =&gt; $ENV{HOME} . '/.gnupg',
++ passphrase =&gt; '',
++ @_
++ );
++
++ croak &quot;undefined name&quot; unless $options{name};
++ croak &quot;undefined path&quot; unless $options{path};
++ croak &quot;invalid path $options{path}&quot; unless -d $options{path};
++
++ $self-&gt;{_name} = $options{name};
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_passphrase} = $options{passphrase};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $package-&gt;sign(
++ $self-&gt;{_name},
++ $self-&gt;{_path},
++ $self-&gt;{_passphrase}
++ ) unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionUnpackpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,82 @@
++# $Id: Unpack.pm 115370 2007-01-30 09:59:07Z pixel $
++package Youri::Submit::Action::Unpack;
++
++=head1 NAME
++
++Youri::Submit::Action::Unpack - unpack package files
++
++=head1 DESCRIPTION
++
++This action plugin unpack package files somewhere.
++When unpack_inside_distribution_root is set, dest_directory is relative to the distribution root.
++When the package is a noarch, the wanted files are unpacked in distribution root of each archs.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Temp qw/tempdir/;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my ($self, %options) = @_;
++
++ croak &quot;undefined package name&quot; unless $options{name};
++ croak &quot;undefined source sub directory&quot; unless $options{source_subdir};
++ croak &quot;undefined destination directory&quot; unless $options{dest_directory};
++
++ foreach my $var ('name', 'dest_directory', 'source_subdir', 'grep_files', 'unpack_inside_distribution_root') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $package-&gt;get_name eq $self-&gt;{_name} or return;
++
++ my @dests = $self-&gt;{_unpack_inside_distribution_root} ?
++ (map { &quot;$_/$self-&gt;{_dest_directory}&quot; } $repository-&gt;get_distribution_roots($package, $target))
++ : $self-&gt;{_dest_directory};
++ my $file = $package-&gt;as_file;
++ print &quot;Unpacking rpm $file$self-&gt;{_source_subdir} to @dests\n&quot; if $self-&gt;{_verbose};
++
++ my $tempdir = tempdir(CLEANUP =&gt; 1);
++
++ my $cmd = &quot;rpm2cpio $file | (cd $tempdir ; cpio -id)&quot;;
++ print &quot;Submit::Action::Unpack: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (!$self-&gt;{_test} &amp;&amp; system($cmd) != 0) {
++ print &quot;Submit::Action::Unpack: failed!\n&quot; if $self-&gt;{_verbose};
++ return;
++ }
++
++ foreach my $dest (@dests) {
++ my $find_grep = $self-&gt;{_grep_files} ? &quot;find | grep '$self-&gt;{_grep_files}'&quot; : 'find';
++ my $cmd = &quot;cd $tempdir/$self-&gt;{_source_subdir}; $find_grep | cpio -pdu $dest&quot;;
++ print &quot;Submit::Action::Unpack: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ my @l = glob(&quot;$tempdir/$self-&gt;{_source_subdir}&quot;);
++ if (@l == 1 &amp;&amp; -d $l[0]) {
++ if (system($cmd) != 0) {
++ print &quot;Submit::Action::Unpack: failed!\n&quot; if $self-&gt;{_verbose};
++ }
++ } else {
++ print &quot;Submit::Action::Unpack: directory $self-&gt;{_source_subdir} doesn't exist in package $self-&gt;{_name}\n&quot;;
++ }
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionUpdateMdvDbpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,62 @@
++# $Id$
++package Youri::Submit::Action::UpdateMdvDb;
++
++=head1 NAME
++
++Youri::Submit::Action::UpdateMdvDb - Mandriva maintainers database updater
++
++=head1 DESCRIPTION
++
++This action plugin calls an external script to update last commit info, as
++well as add new packages, in the package maintainers database at
++&lt;http://maint.mandriva.com/&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++
++ # path for mdvdb-updaterep script
++ $self-&gt;{_mdvdb_updaterep} = $options{mdvdb_updaterep};
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # only SRPMs matter
++ return unless $package-&gt;is_source();
++
++ unless ($self-&gt;{_test}) {
++ my $pkg_name = $package-&gt;get_name();
++ my $pkg_media = $repository-&gt;_get_main_section($package, $target, $define);
++ $package-&gt;get_packager() =~ m/(\w[-_.\w]+\@[-_.\w]+)\W/;
++ my $pkg_commiter = $1;
++
++ if (system($self-&gt;{_mdvdb_updaterep}, &quot;update&quot;, $pkg_name, $pkg_media, $pkg_commiter, &quot;youri&quot;)) {
++ print &quot;ERROR: &quot;.$self-&gt;{_mdvdb_updaterep}.&quot; failed for '$pkg_name', '$pkg_media', '$pkg_commiter'.\n&quot;;
++ } else {
++ print &quot;Updated package maintainers DB for '$pkg_name', '$pkg_media', '$pkg_commiter'.\n&quot; if $self-&gt;{_verbose};
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2007, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Base.pm 631 2006-01-26 22:22:23Z guillomovitch $
++package Youri::Submit::Action;
++
++=head1 NAME
++
++Youri::Submit::Action - Abstract action plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines action plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckACLpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,71 @@
++# $Id: ACL.pm 4817 2007-02-09 19:39:05Z blino $
++package Youri::Submit::Check::ACL;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++my $acl;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ acl_file =&gt; '',
++ @_
++ );
++ $acl = get_acl($options{acl_file});
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $file = $package-&gt;get_full_name();
++ my $arch = $package-&gt;get_arch();
++ my $srpm = $package-&gt;get_canonical_name;
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ my $user = $define-&gt;{user};
++ foreach my $t (keys %$acl) {
++ next if $target !~ /$t/;
++ foreach my $acl (@{$acl-&gt;{$t}}) {
++ my ($a, $media, $r, $users) = @$acl;
++ next if $arch !~ $a || $srpm !~ $r || $section !~ $media;
++ if ($user =~ /$users/) {
++ return
++ } else {
++ return &quot;$user is not authorized to upload packages belonging to $srpm in section $section (authorized persons: &quot; . join(', ', split '\|', $users) . &quot;)&quot;;
++ }
++ }
++ }
++ return
++}
++
++sub get_acl {
++ my ($file) = @_;
++ my %acl;
++ open my $f, $file;
++ while (&lt;$f&gt;) {
++ my ($dis, $arch, $media, $regexp, $users) = split ' ';
++ push @{$acl{$dis}}, [ $arch , $media, $regexp, $users ]
++ }
++ \%acl
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckHistorypm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,61 @@
++# $Id: History.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::History;
++
++=head1 NAME
++
++Youri::Submit::Check::History - Non-linear history check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose history does not include last
++available revision one.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Package;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $last_revision =
++ $repository-&gt;get_last_older_revision($package, $target, $define);
++
++ if ($last_revision) {
++ # skip the test if last revision has been produced from another source package, as it occurs during package split/merges
++ return
++ if $last_revision-&gt;get_canonical_name()
++ ne $package-&gt;get_canonical_name();
++
++ my ($last_revision_number) = $last_revision-&gt;get_last_change()-&gt;[Youri::Package::CHANGE_AUTHOR] =~ /(\S+)\s*$/;
++ my %entries =
++ map { $_ =&gt; 1 }
++ map { /(\S+)\s*$/ }
++ map { $_-&gt;[Youri::Package::CHANGE_AUTHOR] }
++ $package-&gt;get_changes();
++ unless ($entries{$last_revision_number}) {
++ push(
++ @errors,
++ &quot;Last changelog entry $last_revision_number from last revision &quot; . $last_revision-&gt;get_full_name() . &quot; missing from current changelog&quot;
++ );
++ }
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckHostpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,63 @@
++# $Id: Host.pm 230850 2007-10-04 20:07:25Z blino $
++package Youri::Submit::Check::Host;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++my $host;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ host_file =&gt; '',
++ @_
++ );
++ $host = get_host($options{host_file})
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $file = $package-&gt;get_file;
++ my $arch = $package-&gt;get_arch;
++ my $buildhost = $package-&gt;as_formated_string('%{buildhost}');
++ foreach my $h (keys %$host) {
++ next if $buildhost !~ $h;
++ if ($arch =~ $host-&gt;{$h}) {
++ return
++ }
++ }
++ &quot;Packages build on host $buildhost are not authorized for arch $arch&quot;;
++}
++
++sub get_host {
++ my ($file) = @_;
++ my %host;
++ open my $f, $file;
++ while (&lt;$f&gt;) {
++ my ($host, $arch) = split ' ';
++ $host{$host} = $arch
++ }
++ \%host
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckPrecedencepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,58 @@
++# $Id: Precedence.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::Precedence;
++
++=head1 NAME
++
++Youri::Submit::Check::Precedence - Release check against another check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose an older revision already exists for
++another upload target.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ _target =&gt; undef, # mandatory targets
++ @_
++ );
++
++ die &quot;undefined target&quot; unless $options{target};
++
++ $self-&gt;{_target} = $options{target};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my @older_revisions =
++ $repository-&gt;get_older_revisions($package, $self-&gt;{_target}, $define);
++ if (@older_revisions) {
++ push(
++ @errors,
++ &quot;Older revisions still exists for $self-&gt;{_target}: &quot; . join(', ', @older_revisions)
++ );
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckQueue_recencypm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,40 @@
++# $Id: Queue_recency.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::Queue_recency;
++
++=head1 NAME
++
++Youri::Submit::Check::Recency - Release check against current target
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose a current or newer revision already
++exists for current upload target.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @newer_revisions =
++ $repository-&gt;get_upload_newer_revisions($package, $target, $define);
++ if (@newer_revisions) {
++ return &quot;Newer revisions already exists for $target in upload queue: &quot; . join(', ', @newer_revisions);
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckRecencypm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,64 @@
++# $Id: Recency.pm 224793 2007-07-08 02:44:48Z spuk $
++package Youri::Submit::Check::Recency;
++
++=head1 NAME
++
++Youri::Submit::Check::Recency - Release check against current target
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose a current or newer revision already
++exists for current upload target.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my @revisions = $repository-&gt;get_revisions($package, $target, $define, undef, sub { return $_[0]-&gt;compare($package) &gt;= 0 });
++ if (@revisions) {
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ push(
++ @errors,
++ &quot;Current or newer revision(s) already exists in $section for $target: &quot; .
++ join(', ', @revisions)
++ );
++ }
++
++ my $defined_section = $define-&gt;{section};
++
++ # if the user provided a section, check also in the default section
++ if ($defined_section) {
++ $define-&gt;{section} = undef;
++ my @default_revisions = $repository-&gt;get_revisions($package, $target, $define, undef, sub { return $_[0]-&gt;compare($package) &gt;= 0 });
++ if (@default_revisions) {
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ push(
++ @errors,
++ &quot;Current or newer revision(s) already exists in $section for $target: &quot; .
++ join(', ', @default_revisions)
++ );
++ }
++ $define-&gt;{section} = $defined_section;
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckRpmlintpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,90 @@
++# $Id: Rpmlint.pm 234384 2008-02-12 09:42:32Z blino $
++package Youri::Submit::Check::Rpmlint;
++
++=head1 NAME
++
++Youri::Submit::Check::Rpmlint - Rpmlint-based check
++
++=head1 DESCRIPTION
++
++This check plugin wraps rpmlint, and reject packages triggering results
++declared as fatal.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Submit::Check::Rpmlint object.
++
++Specific parameters:
++
++=over
++
++=item results $results
++
++List of rpmlint result id considered as fatal.
++
++=item path $path
++
++Path to the rpmlint executable (default: /usr/bin/rpmlint)
++
++=item config $config
++
++Specific rpmlint configuration.
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ results =&gt; undef,
++ path =&gt; '/usr/bin/rpmlint',
++ config =&gt; '',
++ @_
++ );
++
++ croak &quot;no results to check&quot; unless $options{results};
++ croak &quot;fatal should be an arrayref&quot; unless ref $options{results} eq 'ARRAY';
++
++ $self-&gt;{_config} = $options{config};
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_pattern} = '^(?:' . join('|', @{$options{results}}) . ')$';
++}
++
++sub run {
++ my ($self, $package, $_repository, $_target, $_define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $command = &quot;$self-&gt;{_path} -f $self-&gt;{_config} &quot; . $package-&gt;as_file;
++ open(my $RPMLINT, &quot;$command |&quot;) or die &quot;Can't run $command: $!&quot;;
++ while (my $line = &lt;$RPMLINT&gt;) {
++ $line =~ /^[EW]: \S+ (\S+)(.*)$/ # old rpmlint format
++ || $line =~ /^\S+: [EW]: (\S+)(.*)$/ or next; # new rpmlint format
++ my ($id, $value) = ($1, $2);
++ if ($id =~ /$self-&gt;{_pattern}/o) {
++ push(@errors, &quot;$id$value&quot;);
++ }
++ }
++
++ return @errors;
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under
++the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckSVNpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,79 @@
++# $Id: SVN.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::SVN;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ svn =&gt; '',
++ @_
++ );
++ $self-&gt;{_svn} = $options{svn};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ if ($section =~ /\/(testing|backport)$/) {
++ # FIXME, right now ignore packages in SVN for testing and backports
++ # we need to find a clean way to handle them
++ return
++ }
++
++ $package-&gt;is_source or return;
++ my $file = $package-&gt;get_file_name;
++ my $srpm_name = $package-&gt;get_canonical_name;
++ if ($repository-&gt;package_in_svn($srpm_name)) {
++ if ($file !~ /(^|\/|$define-&gt;{prefix}_)@\d+:\Q$srpm_name/) {
++ return &quot;package $srpm_name is in the SVN, the uploaded SRPM must look like @&lt;svn rev&gt;:$srpm_name-&lt;version&gt;-&lt;release&gt;.src.rpm (created with getsrpm-mdk $srpm_name)&quot;;
++ } else {
++ print &quot;Package $file is correct\n&quot;;
++ }
++ }
++ return
++}
++
++sub simple_prompt {
++ my $cred = shift;
++ my $realm = shift;
++ my $default_username = shift;
++ my $may_save = shift;
++ my $pool = shift;
++
++ print &quot;Enter authentication info for realm: $realm\n&quot;;
++ print &quot;Username: &quot;;
++ my $username = &lt;&gt;;
++ chomp($username);
++ $cred-&gt;username($username);
++ print &quot;Password: &quot;;
++ my $password = &lt;&gt;;
++ chomp($password);
++ $cred-&gt;password($password);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckSectionpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,58 @@
++# $Id: Precedence.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::Section;
++
++=head1 NAME
++
++Youri::Submit::Check::Section - Check if package was submitted to the right section
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages which were submitted to a section
++different than the one where an older version already exists.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $submitted_main_section = $repository-&gt;_get_main_section($package, $target, $define);
++
++ # undefine section, so that Repository::_get_section() of Mandriva_upload.pm
++ # finds the section from existing packages
++ my $defined_section = $define-&gt;{section};
++ undef $define-&gt;{section};
++
++ my $old_main_section = $repository-&gt;_get_main_section($package, $target, $define);
++ my @older_revisions = $repository-&gt;get_older_revisions($package, $target, $define);
++
++ # restore defined section
++ $define-&gt;{section} = $defined_section;
++
++ if (@older_revisions &amp;&amp; $submitted_main_section ne $old_main_section) {
++ push(
++ @errors,
++ &quot;Section should be $old_main_section, not $submitted_main_section.&quot;
++ );
++ }
++
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2007, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckSourcepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,45 @@
++# $Id: Source.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::Source;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $file = $package-&gt;as_file();
++ if (!$package-&gt;is_source()) {
++ return &quot;Package $file is not a source rpm&quot;;
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckTagpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,61 @@
++# $Id: Tag.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::Tag;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ tags =&gt; undef, # expected tag values
++ @_
++ );
++
++ croak &quot;no tags to check&quot; unless $options{tags};
++ croak &quot;tag should be an hashref&quot; unless ref $options{tags} eq 'HASH';
++
++ $self-&gt;{_tags} = $options{tags};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ foreach my $tag (keys %{$self-&gt;{_tags}}) {
++ my $value = $package-&gt;get_tag($tag);
++ if ($value !~ /$self-&gt;{_tags}-&gt;{$tag}/) {
++ push(
++ @errors,
++ &quot;invalid value $value for tag $tag&quot;
++ );
++ }
++ }
++
++ return @errors;
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckTypepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,54 @@
++# $Id: Type.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::Type;
++
++=head1 NAME
++
++Youri::Submit::Check::Type - Type check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect type.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ type =&gt; undef, # expected type
++ @_
++ );
++
++ croak &quot;no type to check&quot; unless $options{type};
++ croak &quot;invalid type value&quot; unless $options{type} =~ /^(?:source|binary)$/;
++
++ $self-&gt;{_type} = $options{type};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $type = $package-&gt;get_type();
++ if ($type ne $self-&gt;{_type}) {
++ push(@errors, &quot;invalid type $type&quot;);
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckVersionpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,102 @@
++# $Id: Version.pm 267050 2010-03-23 17:36:49Z nvigier $
++package Youri::Submit::Check::Version;
++
++=head1 NAME
++
++Youri::Submit::Check::Version - Check if older version already exist in cooker (used in freeze period)
++
++=head1 DESCRIPTION
++
++This check plugin rejects new version of packages if they are not mentioned as authorized
++in the configuration file or in a non frozen section.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use URPM;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++
++ foreach my $target (keys %options) {
++ $self-&gt;{$target} = $options{$target}
++ }
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $opt = $self-&gt;{$target};
++ return if $opt-&gt;{mode} eq 'normal';
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ my $name = $package-&gt;get_canonical_name;
++ return if $name =~ /$opt-&gt;{authorized_packages}/;
++ my $arch = $repository-&gt;get_arch($package, $target, $define);
++ return if $arch =~ /$opt-&gt;{authorized_arches}/;
++ if ($opt-&gt;{mode} eq 'version_freeze') {
++ return if $section =~ /$opt-&gt;{authorized_sections}/;
++ my $user = $define-&gt;{user};
++ return if $user =~ /^($opt-&gt;{authorized_users})$/;
++ my ($package_version) = $package =~ /-([^-]+)-[^-]+\.src$/;
++ $define-&gt;{arch} = 'src';
++ my @revisions = $repository-&gt;get_revisions($package, $target, $define, undef,
++ sub {
++ my ($version) = $_[0] =~ /-([^-]+)-[^-]+\.src$/;
++ URPM::ranges_overlap(&quot;== $version&quot;, &quot;&lt; $package_version&quot;)
++ }
++ );
++ $define-&gt;{arch} = '';
++ if (@revisions) {
++ return &quot;FREEZE, package @revisions of different versions exist in $target\n&quot;;
++ }
++ }
++ # FIXME: The following code is not working and must be reviewed.
++ elsif ($opt-&gt;{mode} eq 'freeze') {
++ my $user = $define-&gt;{user};
++ return if (defined($opt-&gt;{authorized_users}) &amp;&amp; $user =~ /^($opt-&gt;{authorized_users})$/);
++ # XXX: So freeze mode really only check for this exceptions?
++ if ($section !~ /$opt-&gt;{authorized_sections}/) {
++ return &quot;FREEZE: repository $target section $section is frozen, you can still submit your packages in testing\nTo do so use your.devel --define section=&lt;section&gt; $target &lt;package 1&gt; &lt;package 2&gt; ... &lt;package n&gt;&quot;;
++ }
++ } else {
++ # FIXME: Calls to get_source_package seems invalid nowadays.
++ # This results on $source having a null content.
++ my $source = $package-&gt;get_source_package;
++ my ($package_version) = $source =~ /-([^-]+)-[^-]+\.src\.rpm$/;
++ $define-&gt;{arch} = 'src';
++ # FIXME: get_revisions now expects the filter as the 5th element, and not the 4th.
++ my @revisions = $repository-&gt;get_revisions($package, $target, $define,
++ sub {
++ # FIXME: Calls to get_source_package seems invalid nowadays.
++ # This results on $source_package having a null content.
++ my $source_package = $_[0]-&gt;get_source_package;
++ my ($version) = $source_package =~ /-([^-]+)-[^-]+\.src\.rpm$/;
++ print STDERR &quot;Found version $version\n&quot;;
++ URPM::ranges_overlap(&quot;== $version&quot;, &quot;&lt; $package_version&quot;)
++ }
++ );
++ $define-&gt;{arch} = '';
++ if (@revisions) {
++ return &quot;FREEZE, package @revisions of different versions exist in $target\n&quot;;
++ }
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, YOURI project
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Base.pm 631 2006-01-26 22:22:23Z guillomovitch $
++package Youri::Submit::Check;
++
++=head1 NAME
++
++Youri::Submit::Check - Abstract check plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines check plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPluginpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,93 @@
++# $Id: Plugin.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Plugin;
++
++=head1 NAME
++
++Youri::Submit::Plugin - Abstract youri-submit plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines youri-submit plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Submit::Plugin object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns plugin identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 run($package, $repository, $target, $define)
++
++Execute action on given L&lt;Youri::Package&gt; object.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item run
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostCleanRpmsratepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,53 @@
++# $Id: CleanRpmsrate.pm 115367 2007-01-30 09:47:04Z pixel $
++package Youri::Submit::Post::CleanRpmsrate;
++
++=head1 NAME
++
++Youri::Submit::Post::CleanRpmsrate - calls clean-rpmsrate
++
++=head1 DESCRIPTION
++
++Calls clean-rpmsrate
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Post/;
++
++#- inlined from MDK::Common::DataStructure
++sub uniq { my %l; $l{$_} = 1 foreach @_; grep { delete $l{$_} } @_ }
++
++sub _init {
++}
++
++sub run {
++ my ($self, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $root = $repository-&gt;get_install_root();
++ my @changed = @{$repository-&gt;get_arch_changed($target)};
++ if (grep { $_ eq 'i586' } @changed) {
++ # x86_64 uses i586 pkgs, so rpmsrate need to be rebuild
++ @changed = uniq(@changed, 'x86_64');
++ }
++ foreach my $arch (@changed) {
++ my $rpmsrate = &quot;$root/$target/$arch/media/media_info/rpmsrate&quot;;
++ my @media = &quot;$root/$target/$arch/media/main/release&quot;;
++ system(&quot;cp&quot;, &quot;$rpmsrate-raw&quot;, &quot;$rpmsrate-new&quot;);
++ system(&quot;clean-rpmsrate&quot;, &quot;$rpmsrate-new&quot;, @media);
++ system(&quot;mv&quot;, &quot;-f&quot;, &quot;$rpmsrate-new&quot;, $rpmsrate);
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2007, Mandriva &lt;blino@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostGendistribpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,66 @@
++# $Id: Gendistrib.pm 115367 2007-01-30 09:47:04Z pixel $
++package Youri::Submit::Post::Gendistrib;
++
++=head1 NAME
++
++Youri::Submit::Post::Gendistrib - calls gendistrib
++
++=head1 DESCRIPTION
++
++Calls gendistrib
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Post/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ user =&gt; '',
++ host =&gt; '',
++ source =&gt; '',
++ destination =&gt; '',
++ @_
++ );
++
++ foreach my $var ('tmpdir', 'command') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++}
++
++sub run {
++ my ($self, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $root = $repository-&gt;get_install_root();
++ (undef, undef, my $hour) = gmtime(time);
++ # during the night, use complete hdlist rebuild
++ my $fast = '--fast';
++ $fast = ''; # blino: don't use fast for now, it might be broken
++ if ($hour &gt; 22 &amp;&amp; $hour &lt; 5) {
++ if ($hour &lt; 4) {
++ $fast = '--blind'
++ } else {
++ $fast = ''
++ }
++ }
++ foreach my $arch (@{$repository-&gt;get_arch_changed($target)}) {
++ my $cmd = &quot;TMPDIR=$self-&gt;{_tmpdir}/$target/$arch time $self-&gt;{_command} --nochkdep --nobadrpm $fast --noclean $root/$target/$arch&quot;;
++ print &quot;$cmd\n&quot;;
++ system($cmd);
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, Mandriva &lt;warly@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostGenhdlist2pm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,82 @@
++# $Id: Gendistrib.pm 115367 2007-01-30 09:47:04Z pixel $
++package Youri::Submit::Post::Genhdlist2;
++
++=head1 NAME
++
++Youri::Submit::Post::Genhdlist2 - calls genhdlist2
++
++=head1 DESCRIPTION
++
++Calls genhdlist2
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Post/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ user =&gt; '',
++ host =&gt; '',
++ source =&gt; '',
++ destination =&gt; '',
++ @_
++ );
++
++ foreach my $var ('command') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++}
++
++sub run {
++ my ($self, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $root = $repository-&gt;get_install_root();
++ my @changed = @{$repository-&gt;get_install_dir_changed($target)};
++ if (!@changed) {
++ print &quot;nothing to do\n&quot;;
++ return;
++ }
++ foreach my $dir (@changed) {
++ my $file_deps = &quot;$dir/../../media_info/file-deps&quot;;
++ my $file_deps_option = -e $file_deps ? &quot;--file-deps $file_deps&quot; : '';
++ my $cmd = &quot;time $self-&gt;{_command} -v --versioned --allow-empty-media $file_deps_option $dir&quot;;
++ print &quot;$cmd\n&quot;;
++ system($cmd) == 0 or print &quot;ERROR: $cmd failed\n&quot;;
++ }
++
++ # need to redo global MD5SUM. This MD5SUM is mostly obsolete, but is still needed up to 2007.1
++ # (and even on cooker for existing urpmi.cfg)
++ foreach my $arch (@{$repository-&gt;get_arch_changed($target)}) {
++ my $dir = &quot;$root/$target/$arch/media/media_info&quot;;
++ my $cmd = &quot;cd $dir ; time md5sum hdlist_* synthesis.*&quot;;
++ print &quot;$cmd\n&quot;;
++ my $m = `$cmd`;
++ open my $f, '&gt;', &quot;$dir/MD5SUM&quot; or die &quot;Can't write $dir/MD5SUM: $!\n&quot;;
++ print $f $m;
++
++ {
++ require MDV::Distribconf::Build;
++ my $distrib = MDV::Distribconf::Build-&gt;new(&quot;$root/$target/$arch&quot;);
++ $distrib-&gt;loadtree or die &quot;$root/$target/$arch does not seem to be a distribution tree\n&quot;;
++ $distrib-&gt;parse_mediacfg;
++ $distrib-&gt;write_version($distrib-&gt;getfullpath(undef, &quot;VERSION&quot;));
++ print &quot;updated $root/$target/$arch/VERSION\n&quot;;
++ }
++ }
++ return;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, Mandriva &lt;warly@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Post.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Post;
++
++=head1 NAME
++
++Youri::Submit::Post - Abstract post plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines post plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPreRsyncpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,87 @@
++# $Id: Rsync.pm 267280 2010-04-01 19:57:53Z bogdano $
++package Youri::Submit::Pre::Rsync;
++
++=head1 NAME
++
++Youri::Submit::Pre::Rsync - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Pre/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ user =&gt; '',
++ host =&gt; '',
++ source =&gt; '',
++ destination =&gt; '',
++ @_
++ );
++
++ foreach my $var ('user', 'host', 'source', 'destination') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++}
++
++sub run {
++ my ($self, $pre_packages, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ if (system(&quot;rsync --exclude '*.new' --exclude '.*' --remove-sent-files -avlPHe 'ssh -xc arcfour' $self-&gt;{_user}\@$self-&gt;{_host}:$self-&gt;{_source}/$target/ $self-&gt;{_destination}/$target/&quot;)) {
++ $self-&gt;{_error} = &quot;Rsync command failed ($!)&quot;;
++ return
++ }
++ my $queue = &quot;$self-&gt;{_destination}/$target&quot;;
++ $self-&gt;{_error} = &quot;Reading queue directory failed&quot;;
++ # now get the packages downloaded
++ my %packages;
++ opendir my $queuedh, &quot;$self-&gt;{_destination}/$target/&quot; or return &quot;Could not open $self-&gt;{_destination}/$target&quot;;
++ opendir my $targetdh, $queue or return &quot;Could not open $queue&quot;;
++ my $idx;
++ foreach my $media (readdir $targetdh) {
++ $media =~ /^\.{1,2}$/ and next;
++ print &quot;$target - $media\n&quot;;
++ if (-d &quot;$queue/$media&quot;) {
++ opendir my $submediadh, &quot;$queue/$media&quot; or return &quot;Could not open $queue/$media&quot;;
++ foreach my $submedia (readdir $submediadh) {
++ $submedia =~ /^\.{1,2}$/ and next;
++ print &quot;$target - $media - $submedia\n&quot;;
++ opendir my $rpmdh, &quot;$queue/$media/$submedia&quot; or return &quot;Could not open $queue/$media/$submedia&quot;;
++ foreach my $rpm (readdir $rpmdh) {
++ $rpm =~ /^\.{1,2}$/ and next;
++ print &quot;$target - $media - $submedia : $rpm\n&quot;;
++ my $file = &quot;$queue/$media/$submedia/$rpm&quot;;
++ $file =~ s/\/+/\//g;
++ if ($rpm =~ /^(\d{14}\.\w+\.\w+\.\d+)_.*\.rpm$/) {
++ push @{$packages{$1}{rpms}}, { section =&gt; &quot;$media/$submedia&quot;, file =&gt; $file };
++ } elsif ($rpm =~ /\.rpm$/) {
++ $idx++;
++ push @{$packages{&quot;independant_$idx&quot;}{rpms}}, { section =&gt; &quot;$media/$submedia&quot;, file =&gt; $file }
++ }
++ }
++ }
++ }
++ }
++ foreach my $key (keys %packages) {
++ push @$pre_packages, $packages{$key}{rpms}
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, Mandriva &lt;warly@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPrepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Pre.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Pre;
++
++=head1 NAME
++
++Youri::Submit::Pre - Abstract pre plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines pre plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectArchivepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,61 @@
++# $Id: Archive.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Reject::Install;
++
++=head1 NAME
++
++Youri::Submit::Action::Archive - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Reject/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $rpm = $package-&gt;get_file_name();
++ my $dest = $repository-&gt;get_reject_dir($package, $target, $define);
++
++ # FIXME remove prefix this should be done by a function
++ $rpm =~ s/^\d{14}\.\w+\.\w+\.\d+_//;
++ print &quot;installing file $file to $dest/$rpm\n&quot; ;#if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest/&quot;)
++ unless -d $dest;
++
++ # install file to new location
++ system(&quot;install -m $self-&gt;{_perms} $file $dest/$rpm&quot;);
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectCleanpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,36 @@
++# $Id: Clean.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Reject::Clean;
++
++=head1 NAME
++
++Youri::Submit::Action::Clean - Old revisions cleanup
++
++=head1 DESCRIPTION
++
++This action plugin ensures cleanup of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Reject/;
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectInstallpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,63 @@
++# $Id: Install.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Reject::Install;
++
++=head1 NAME
++
++Youri::Submit::Action::Archive - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Reject/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++ $self-&gt;{_verbose} = $options{verbose};
++}
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $rpm = $package-&gt;get_file_name();
++ my $dest = $repository-&gt;get_reject_path($package, $target, $define);
++
++ # FIXME remove prefix this should be done by a function
++ $rpm =~ s/^\d{14}\.\w+\.\w+\.\d+_//;
++ print &quot;installing file $file to $dest/$rpm\n&quot; if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest/&quot;)
++ unless -d $dest;
++
++ # install file to new location
++ system(&quot;install -m $self-&gt;{_perms} $file $dest/$rpm&quot;);
++ }
++ $package-&gt;{_file} = &quot;$dest/$rpm&quot;;
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectMailpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,112 @@
++# $Id: Mail.pm 223952 2007-06-23 13:54:13Z pixel $
++package Youri::Submit::Reject::Mail;
++
++=head1 NAME
++
++Youri::Submit::Action::Mail - Mail notification
++
++=head1 DESCRIPTION
++
++This action plugin ensures mail notification of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use MIME::Entity;
++use Encode qw/from_to/;
++use Carp;
++use Youri::Package;
++use base qw/Youri::Submit::Reject/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ mta =&gt; '/usr/sbin/sendmail',
++ to =&gt; '',
++ from =&gt; '',
++ cc =&gt; '',
++ prefix =&gt; '',
++ encoding =&gt; 'quoted-printable',
++ charset =&gt; 'iso-8859-1',
++ @_
++ );
++
++ croak &quot;undefined mail MTA&quot; unless $options{mta};
++ croak &quot;invalid mail MTA $options{mta}&quot; unless -x $options{mta};
++ croak &quot;undefined to&quot; unless $options{to};
++ if ($options{cc}) {
++ croak &quot;cc should be an hashref&quot; unless ref $options{cc} eq 'HASH';
++ }
++ croak &quot;invalid charset $options{charset}&quot;
++ unless Encode::resolve_alias($options{charset});
++
++ $self-&gt;{_mta} = $options{mta};
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_from} = $options{from};
++ $self-&gt;{_cc} = $options{cc};
++ $self-&gt;{_prefix} = $options{prefix};
++ $self-&gt;{_encoding} = $options{encoding};
++ $self-&gt;{_charset} = $options{charset};
++}
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++
++ my $subject =
++ ($self-&gt;{_prefix} ? '[' . $self-&gt;{_prefix} . '] ' : '' ) . ($section ? &quot;$section &quot; : '') .
++ $package-&gt;get_revision_name();
++ my $information = $package-&gt;get_information();
++ my $last_change = $package-&gt;get_last_change();
++ my $author = $last_change-&gt;[Youri::Package::CHANGE_AUTHOR] if $last_change;
++ my $list = $last_change-&gt;[Youri::Package::CHANGE_TEXT] if $last_change;
++ my $content =
++ &quot;Errors: \n\n&quot; . join(&quot;\n&quot;, map {
++ ( &quot;* $_&quot;, (map { &quot; - $_&quot; } @{$errors-&gt;{$_}}), &quot;\n&quot;);
++ } sort(keys %$errors)) . &quot;\n&quot; .
++ $information . &quot;\n&quot; .
++ $author . &quot;:\n$list&quot;;
++
++ # ensure proper codeset conversion
++ # for informations coming from package
++ my $charset = $repository-&gt;get_package_charset();
++ from_to($content, $charset, $self-&gt;{_charset});
++ from_to($subject, $charset, $self-&gt;{_charset});
++
++ my $mail = MIME::Entity-&gt;build(
++ Type =&gt; 'text/plain',
++ Charset =&gt; $self-&gt;{_charset},
++ Encoding =&gt; $self-&gt;{_encoding},
++ From =&gt; $self-&gt;{_from},
++ To =&gt; $self-&gt;{_to},
++ Subject =&gt; $subject,
++ Data =&gt; $content,
++ );
++
++ if ($self-&gt;{_cc}) {
++ my $cc = $self-&gt;{_cc}-&gt;{$package-&gt;get_name()};
++ $mail-&gt;head()-&gt;add('cc', $cc) if $cc;
++ }
++
++ if ($self-&gt;{_test}) {
++ $mail-&gt;print(\*STDOUT);
++ } else {
++ open(MAIL, &quot;| $self-&gt;{_mta} -t -oi -oem&quot;) or die &quot;Can't open MTA program: $!&quot;;
++ $mail-&gt;print(\*MAIL);
++ close MAIL;
++ }
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Reject.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Reject;
++
++=head1 NAME
++
++Youri::Submit::Reject - Abstract reject plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines reject plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunkt00distributiont">Added: build_system/mdv-youri-submit/trunk/t/00distribution.t</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/t/00distribution.t (rev 0)
++++ build_system/mdv-youri-submit/trunk/t/00distribution.t 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,15 @@
++#!/usr/bin/perl
++# $Id: 00distribution.t 1723 2006-10-17 13:53:27Z warly $
++
++use Test::More;
++
++BEGIN {
++ eval {
++ require Test::Distribution;
++ };
++ if($@) {
++ plan skip_all =&gt; 'Test::Distribution not installed';
++ } else {
++ import Test::Distribution only =&gt; [ qw/use pod description/ ];
++ }
++}
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/t/00distribution.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment.html
new file mode 100644
index 000000000..ca22eaf1b
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/2b91b15e/attachment.html
@@ -0,0 +1,6045 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[209] add mandriva version of youri-submit, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/submit/trunk at revision 271600</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>209</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 14:19:06 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add mandriva version of youri-submit, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/submit/trunk at revision 271600</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>build_system/mdv-youri-submit/</li>
+<li>build_system/mdv-youri-submit/branches/</li>
+<li>build_system/mdv-youri-submit/tags/</li>
+<li>build_system/mdv-youri-submit/trunk/</li>
+<li><a href="#build_systemmdvyourisubmittrunkChangeLog">build_system/mdv-youri-submit/trunk/ChangeLog</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkMANIFESTSKIP">build_system/mdv-youri-submit/trunk/MANIFEST.SKIP</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkMakefilePL">build_system/mdv-youri-submit/trunk/Makefile.PL</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkREADME">build_system/mdv-youri-submit/trunk/README</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkTODO">build_system/mdv-youri-submit/trunk/TODO</a></li>
+<li>build_system/mdv-youri-submit/trunk/bin/</li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyouricheckin">build_system/mdv-youri-submit/trunk/bin/youri-check.in</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmit">build_system/mdv-youri-submit/trunk/bin/youri-submit</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmitproxyin">build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmitrestrictedin">build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in</a></li>
+<li><a href="#build_systemmdvyourisubmittrunkbinyourisubmitin">build_system/mdv-youri-submit/trunk/bin/youri-submit.in</a></li>
+<li>build_system/mdv-youri-submit/trunk/etc/</li>
+<li>build_system/mdv-youri-submit/trunk/etc/bash_completion.d/</li>
+<li><a href="#build_systemmdvyourisubmittrunketcbash_completiondyourisubmit">build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit</a></li>
+<li><a href="#build_systemmdvyourisubmittrunketcsubmitconf">build_system/mdv-youri-submit/trunk/etc/submit.conf</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/</li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/</li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/</li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionArchivepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionBugzillapm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionCVSpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionCleanpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionDkmsModuleInfopm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionInstallpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionLinkpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionMailpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionMarkreleasepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionRSSpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionRpminfopm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionSendpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionSendcachepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionSignpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionUnpackpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionUpdateMdvDbpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitActionpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckACLpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckHistorypm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckHostpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckPrecedencepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckQueue_recencypm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckRecencypm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckRpmlintpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckSVNpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckSectionpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckSourcepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckTagpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckTypepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckVersionpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitCheckpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPluginpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostCleanRpmsratepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostGendistribpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostGenhdlist2pm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPostpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPreRsyncpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitPrepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/</li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectArchivepm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectCleanpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectInstallpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectMailpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm</a></li>
+<li><a href="#build_systemmdvyourisubmittrunklibYouriSubmitRejectpm">build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm</a></li>
+<li>build_system/mdv-youri-submit/trunk/t/</li>
+<li><a href="#build_systemmdvyourisubmittrunkt00distributiont">build_system/mdv-youri-submit/trunk/t/00distribution.t</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemmdvyourisubmittrunkChangeLog">Added: build_system/mdv-youri-submit/trunk/ChangeLog</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/ChangeLog (rev 0)
++++ build_system/mdv-youri-submit/trunk/ChangeLog 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,606 @@
++2008-02-19 07:50 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: fix &quot;grep_files&quot; handling
++
++2008-02-12 09:42 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: do not make rpmlint errors
++ fatal anymore (asked by fcrozat)
++
++2008-02-08 17:49 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: remove results occurences and
++ update doc
++
++2008-02-08 17:48 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: make all rpmlint errors fatal
++
++2008-02-08 17:44 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: removed unneeded parentheses
++
++2008-02-08 17:44 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: make clear
++ repository/target/define are unused
++
++2008-02-08 17:43 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: use scalar for fd
++
++2008-01-31 16:35 pixel
++
++ * lib/Youri/Submit/Action/Link.pm: also call -&gt;set_arch_changed
++ when linking a noarch file to another arch
++ (this still doesn't explain media/media_info/MD5SUM not being
++ remade, but it
++ can help...)
++
++2007-12-21 14:37 blino
++
++ * bin/youri-submit.in: merge youri-submit into youri-submit.in
++
++2007-12-19 13:43 blino
++
++ * lib/Youri/Submit/Action/Archive.pm: only log main/updates
++ modifications, not contrib/updates or non-free/updates which are
++ legal
++
++2007-12-19 13:37 blino
++
++ * lib/Youri/Submit/Action/Archive.pm: add spuk's debug code for bug
++ 34999
++
++2007-12-17 19:45 blino
++
++ * bin/youri-submit: add an &quot;allow_omitting_packages&quot; global option,
++ to be able to run youri even if no packages are specified on the
++ command line (useful if packages are fetched in pre action)
++
++2007-12-17 19:34 blino
++
++ * bin/youri-submit: improve error messages for pres/posts actions
++ (patch from raoh's copy, probably from warly)
++
++2007-12-17 19:33 blino
++
++ * bin/youri-submit: fix typo about posts actions (patch from raoh's
++ copy, probably from warly)
++
++2007-12-13 15:01 pixel
++
++ * lib/Youri/Submit/Check/Version.pm: - empty {authorized_users}
++ doesn't imply every one is allowed to bypass freeze check!
++ - {authorized_users} should be checked more strictly
++
++2007-12-07 18:26 spuk
++
++ * lib/Youri/Submit/Action/Sendcache.pm: - make Sendcache send debug
++ packages only if explicitly told to, to save space
++
++2007-11-30 19:29 spuk
++
++ * lib/Youri/Submit/Action/UpdateMdvDb.pm: Youri action to update
++ the Mandriva maintainers database.
++
++2007-10-04 20:07 blino
++
++ * lib/Youri/Submit/Check/Host.pm: make host reject message more
++ explicit by print arch (useful when VMware-player for x86_64
++ actually uses i386 as rpm arch...)
++
++2007-09-26 11:21 blino
++
++ * lib/Youri/Submit/Action/Install.pm: improve log message
++
++2007-09-26 11:19 blino
++
++ * lib/Youri/Submit/Action/Install.pm: fix installed filename (oops)
++
++2007-09-26 09:58 blino
++
++ * lib/Youri/Submit/Action/Install.pm: throw exception on failure,
++ not to delete files that can be copied because of lack of space
++ (upstream commit 1398)
++
++2007-09-25 10:49 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: allow to unpack only some
++ files (for release-notes.txt in mandriva-release-common)
++
++2007-09-22 13:11 blino
++
++ * lib/Youri/Submit/Check/Version.pm: allow authorized users to
++ upload everything even during full freeze
++
++2007-08-31 12:51 pixel
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: handle new rpmlint format
++ (not useful at the moment since we still use old rpmlint, but may
++ be useful in
++ the future)
++
++2007-08-31 10:03 blino
++
++ * lib/Youri/Submit/Action/DkmsModuleInfo.pm: adapt to new
++ SOURCEPACKAGE value in prebuilt dkms kernel
++
++2007-08-29 13:21 blino
++
++ * lib/Youri/Submit/Action/DkmsModuleInfo.pm: initial
++ Youri::Submit::Action::DkmsModuleInfo module
++
++2007-08-07 12:50 pixel
++
++ * lib/Youri/Submit/Action/Link.pm: we need the same workaround as
++ done in Action::Install
++
++2007-07-16 09:27 blino
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: remove unused variable
++
++2007-07-08 02:44 spuk
++
++ * lib/Youri/Submit/Check/Recency.pm: - check for newer/current
++ revisions in default section when submitted to another section
++ (bug #30635)
++
++2007-07-02 09:17 pixel
++
++ * lib/Youri/Submit/Action/CVS.pm: drop mdv specific stuff (mdv
++ doesn't use this action anymore)
++
++2007-06-28 07:40 pixel
++
++ * lib/Youri/Submit/Action/Link.pm: do update hdlist for every arch
++ after linking noarch packages (#31638)
++
++2007-06-28 07:37 pixel
++
++ * lib/Youri/Submit/Action/Install.pm: simplify ($arch is not used
++ by -&gt;set_install_dir_changed)
++
++2007-06-23 13:54 pixel
++
++ * lib/Youri/Submit/Action/Mail.pm, lib/Youri/Submit/Reject/Mail.pm:
++ keep raw changelogs to avoid changing the format (backport)
++
++2007-06-23 08:10 spuk
++
++ * lib/Youri/Submit/Check/Recency.pm: - check for newer and same
++ existing revisions in a single pass
++ - use proper get_revisions() instead of get_install_file() hack,
++ as the
++ latter will use the current file name, and thus will fail to
++ check for an
++ existing package revision when submitting, because submitted
++ SRPMs have a
++ different name (&quot;@rev:foobar-...&quot;) than what goes into the
++ repository
++
++2007-06-22 13:51 pixel
++
++ * lib/Youri/Submit/Post/CleanRpmsrate.pm: ensure we don't do
++ anything if nothing changed
++
++2007-06-22 13:41 pixel
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: more atomic generation of
++ MD5SUM
++
++2007-06-22 13:35 pixel
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: - need to redo global
++ MD5SUM. This MD5SUM is mostly obsolete, but is still needed up to
++ 2007.1
++ (and needed even on cooker for existing urpmi.cfg)
++ - don't use --blind. hopefully not needed
++
++2007-06-22 06:45 pixel
++
++ * lib/Youri/Submit/Post/Genhdlist2.pm: call genhdlist2 with (new)
++ option --allow-empty-media
++
++2007-06-21 10:13 blino
++
++ * lib/Youri/Submit/Post/CleanRpmsrate.pm: uniquify arch list
++
++2007-06-21 08:16 pixel
++
++ * lib/Youri/Submit/Action/Install.pm,
++ lib/Youri/Submit/Post/Genhdlist2.pm: new action Genhdlist2
++
++2007-06-14 18:23 mrl
++
++ * lib/Youri/Submit/Action/Sendcache.pm: - As this action is unique,
++ avoid too much flexibility and simplify the code.
++ - Use . for hidding temporary files instead of .new suffix.
++
++2007-06-13 18:36 mrl
++
++ * lib/Youri/Submit/Action/Sendcache.pm: - Adapted for working with
++ iurt cache.
++
++2007-06-13 01:48 spuk
++
++ * lib/Youri/Submit/Action/Link.pm: no such 'cd' function, 'chdir'
++ it is...
++
++2007-05-08 06:22 spuk
++
++ * lib/Youri/Submit/Reject/Mail.pm: fixing the Big SVN Breakage:
++ reverting last commit, restoring state as of latest working
++ checkout in ken
++
++2007-05-08 06:06 spuk
++
++ * lib/Youri/Submit/Post/Gendistrib.pm: fixing the Big SVN Breakage:
++ restoring state as of working checkout in ken
++
++2007-05-08 06:00 spuk
++
++ * lib/Youri/Submit/Action/Scp.pm: fixing the Big SVN Breakage:
++ Scp.pm was changed into Send.pm
++
++2007-05-05 06:16 spuk
++
++ * lib/Youri/Submit/Check/Section.pm: Check if package submission
++ was for the correct section.
++
++2007-03-24 11:36 spuk
++
++ * lib/Youri/Submit/Action/Archive.pm: - moved hack for verbosity to
++ start of code, with a remark
++ - removed double $path from debug string
++
++2007-03-15 12:36 mrl
++
++ * lib/Youri/Submit/Check/Version.pm: - Fixed version_freeze mode:
++ do not allow any upload with a different version
++ from what is already present on the repository.
++ - Added an ACL control for maintainers allowed to bypass this
++ restriction as option
++ authorized_users.
++
++2007-03-15 12:32 mrl
++
++ * lib/Youri/Submit/Check/Version.pm: - Improved indentation.
++ - Added some comments regarding possible bugs in freeze modes.
++
++2005-05-24 14:40 Sawyer
++
++ * lib/Youri/Submit/Reject/Mail.pm: LOST
++
++2007-03-10 07:49 spuk
++
++ * lib/Youri/Submit/Action/Archive.pm: The extra '/' was causing the
++ string to not be matched by the regexp below
++ for getting $rep_section and $rep_main_section, in the end making
++ the SRPMs
++ of all other subsections be removed when a newer package was
++ uploaded for any
++ subsection. (#28719)
++
++2007-02-26 10:56 blino
++
++ * lib/Youri/Submit/Post/CleanRpmsrate.pm: initial
++ Post::CleanRpmsrate module
++
++2007-02-14 12:10 blino
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: match rpmlint errors that have
++ no value (such as non-xdg-migrated-menu, the only one we
++ currently use...)
++
++2007-02-09 22:11 blino
++
++ * bin/youri-submit: get -&gt; get_arg
++
++2007-02-09 22:09 blino
++
++ * bin/youri-submit: merge changes from ken/kenobi
++
++2007-02-09 22:09 blino
++
++ * bin/youri-submit: create youri-submit from youri-submit.in
++
++2007-02-09 19:39 blino
++
++ * lib/Youri/Submit/Check/ACL.pm: add section in acl error message
++
++2007-02-09 19:34 blino
++
++ * lib/Youri/Submit/Reject/Mail.pm: do not use packager adress as
++ from, it may be invalid (non-free packages) or not subscribed to
++ maintainers
++
++2007-02-09 18:51 blino
++
++ * lib/Youri/Submit/Reject/Mail.pm: fix changelog in reject mail
++
++2007-02-09 18:50 blino
++
++ * lib/Youri/Submit/Reject/Mail.pm: fix reject mail
++
++2007-02-08 17:28 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: also give directories to &quot;cpio
++ -pdu&quot; to ensure directories are created with same rights
++
++2007-02-08 14:09 pixel
++
++ * lib/Youri/Submit/Action/Unpack.pm: This action plugin unpack
++ package files somewhere.
++ When unpack_inside_distribution_root is set, dest_directory is
++ relative to the distribution root.
++ When the package is a noarch, the wanted files are unpacked in
++ distribution root of each archs.
++
++ eg:
++ unpack_installer_images:
++ class: Youri::Submit::Action::Unpack
++ options:
++ name: drakx-installer-images
++ source_subdir: /usr/lib*/drakx-installer-images
++ dest_directory: .
++ unpack_inside_distribution_root: 1
++
++2007-01-30 10:02 pixel
++
++ * lib/Youri/Submit/Check/ACL.pm, lib/Youri/Submit/Check/Host.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/SVN.pm,
++ lib/Youri/Submit/Check/Source.pm, lib/Youri/Submit/Check/Type.pm,
++ lib/Youri/Submit/Check/Version.pm, lib/Youri/Submit/Pre/Rsync.pm,
++ lib/Youri/Submit/Reject/Archive.pm,
++ lib/Youri/Submit/Reject/Clean.pm,
++ lib/Youri/Submit/Reject/Install.pm,
++ lib/Youri/Submit/Reject/Mail.pm: fix $Id$ expansion
++
++2007-01-30 10:01 pixel
++
++ * lib/Youri/Submit/Plugin.pm, lib/Youri/Submit/Post.pm,
++ lib/Youri/Submit/Pre.pm, lib/Youri/Submit/Reject.pm: fix pod and
++ $Id$ expansion
++
++2007-01-30 10:00 pixel
++
++ * lib/Youri/Submit/Post.pm: fix pod
++
++2007-01-30 09:59 pixel
++
++ * lib/Youri/Submit/Action/Send.pm: fix pod
++
++2007-01-30 09:58 pixel
++
++ * lib/Youri/Submit/Action/Markrelease.pm,
++ lib/Youri/Submit/Action/Scp.pm: fix pod
++
++2007-01-30 09:49 pixel
++
++ * lib/Youri/Submit/Action/Clean.pm,
++ lib/Youri/Submit/Action/Link.pm,
++ lib/Youri/Submit/Action/Markrelease.pm,
++ lib/Youri/Submit/Action/Rpminfo.pm,
++ lib/Youri/Submit/Action/Scp.pm, lib/Youri/Submit/Action/Send.pm:
++ fix $Id$ expansion
++
++2007-01-26 11:25 blino
++
++ * lib/Youri/Submit/Check/ACL.pm: really match section in ACL
++
++2007-01-26 11:24 blino
++
++ * lib/Youri/Submit/Check/ACL.pm: fix arch ACL matching (and thus
++ allow ACLs to match again)
++
++2006-12-24 10:31 mandrake
++
++ * lib/Youri/Submit/Post.pm, lib/Youri/Submit/Pre.pm,
++ lib/Youri/Submit/Reject.pm: Removing previous pristine/
++ directory.
++
++2006-12-24 03:15 mandrake
++
++ * lib/Youri/Submit/Action.pm: %repsys markrelease
++ version: 1.0
++ release: 0.20061223.3mdv2007.1
++ revision: 101968
++
++ Copying 1.0-0.20061223.3mdv2007.1 to releases/ directory.
++
++2006-10-16 16:05 warly
++
++ * lib/Youri/Submit/Check.pm: merging dev with upstream
++
++2006-11-14 22:01 mrl
++
++ * lib/Youri/Submit/Action/Rpminfo.pm: - Renamed package name tag.
++
++2006-11-14 16:38 mrl
++
++ * lib/Youri/Submit/Action/RpmInfo.pm,
++ lib/Youri/Submit/Action/Rpminfo.pm: - Renamed, due to some
++ enforcement (cfengine?).
++
++2006-11-14 13:23 mrl
++
++ * lib/Youri/Submit/Action/RpmInfo.pm: - Added package summary to
++ .info files.
++
++2006-11-13 12:40 mrl
++
++ * lib/Youri/Submit/Action/RpmInfo.pm: - First version of web
++ interface.
++
++2006-10-31 11:40 mandrake
++
++ * lib/Youri/Submit/Action/Archive.pm: unlink file in Archive for
++ the moment (should be done in clean but the code to detect which
++ packages is obsoleted has to be moved
++
++2006-10-26 11:26 mandrake
++
++ * lib/Youri/Submit/Action/CVS.pm: we perform CVS commit
++ asynchronously
++
++2006-10-26 11:21 mandrake
++
++ * lib/Youri/Submit/Action/Install.pm: rename the rpm to remove the
++ prefix
++
++2006-10-26 11:18 mandrake
++
++ * lib/Youri/Submit/Action/Mail.pm: fix double .
++
++2006-10-26 11:16 mandrake
++
++ * lib/Youri/Submit/Post/Gendistrib.pm: add gendistrib command
++ directly into gendistrib module
++
++2006-10-26 11:14 mandrake
++
++ * lib/Youri/Submit/Pre/Rsync.pm: return correct packages table for
++ groups
++
++2006-10-26 11:10 mandrake
++
++ * lib/Youri/Submit/Reject/Install.pm: get_reject_path seems to be
++ the new name
++
++2006-10-26 11:07 mandrake
++
++ * lib/Youri/Submit/Reject/Mail.pm: $last_change is sometime empty
++
++2006-10-24 11:07 warly
++
++ * bin/youri-submit.in: exit with an error code if an error occured
++ in one group; s/Upload/Submit/; use new structure name from
++ upstream
++
++2006-10-23 11:48 warly
++
++ * lib/Youri/Submit/Check/ACL.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/SVN.pm,
++ lib/Youri/Submit/Check/Source.pm,
++ lib/Youri/Submit/Check/Version.pm: must return an empty value
++
++2006-10-18 12:46 warly
++
++ * lib/Youri/Submit/Check/Rpmlint.pm: remove debug code
++
++2006-10-17 16:10 warly
++
++ * lib/Youri/Submit/Check/ACL.pm: now checks must return the error
++ message
++
++2006-10-17 16:04 warly
++
++ * lib/Youri/Submit/Check/ACL.pm, lib/Youri/Submit/Check/Host.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/SVN.pm,
++ lib/Youri/Submit/Check/Source.pm,
++ lib/Youri/Submit/Check/Version.pm: now checks must return the
++ error message
++
++2006-10-17 15:16 warly
++
++ * lib/Youri/Submit/Action/Clean.pm,
++ lib/Youri/Submit/Action/Link.pm, lib/Youri/Submit/Check/ACL.pm,
++ lib/Youri/Submit/Check/Host.pm,
++ lib/Youri/Submit/Check/Queue_recency.pm,
++ lib/Youri/Submit/Check/SVN.pm, lib/Youri/Submit/Check/Source.pm,
++ lib/Youri/Submit/Check/Type.pm,
++ lib/Youri/Submit/Check/Version.pm, lib/Youri/Submit/Post.pm,
++ lib/Youri/Submit/Pre.pm, lib/Youri/Submit/Reject.pm:
++ s/Upload/Submit/g
++
++2006-10-17 13:53 warly
++
++ * ., ChangeLog, MANIFEST.SKIP, Makefile.PL, README, TODO,
++ bin/youri-submit-proxy.in, bin/youri-submit-restricted.in,
++ bin/youri-submit.in, etc, etc/bash_completion.d,
++ etc/bash_completion.d/youri-submit, etc/submit.conf,
++ lib/Youri/Submit/Plugin.pm, t, t/00distribution.t: merge with
++ upstream
++
++2006-10-16 16:27 warly
++
++ * lib/Youri/Submit/Post/Gendistrib.pm,
++ lib/Youri/Submit/Pre/Rsync.pm,
++ lib/Youri/Submit/Reject/Archive.pm,
++ lib/Youri/Submit/Reject/Clean.pm,
++ lib/Youri/Submit/Reject/Install.pm,
++ lib/Youri/Submit/Reject/Mail.pm: Now the module is Submit and not
++ Upload
++
++2006-10-16 16:26 warly
++
++ * lib/Youri/Submit/Check, lib/Youri/Submit/Check/History.pm,
++ lib/Youri/Submit/Check/Precedence.pm,
++ lib/Youri/Submit/Check/Recency.pm,
++ lib/Youri/Submit/Check/Rpmlint.pm, lib/Youri/Submit/Check/Tag.pm,
++ lib/Youri/Submit/Check/Type.pm: merging dev with upstream
++
++2006-10-16 16:15 warly
++
++ * lib/Youri/Submit/Post.pm, lib/Youri/Submit/Pre.pm,
++ lib/Youri/Submit/Reject.pm: now plugins are complete abstract
++ classes
++
++2006-10-16 16:08 warly
++
++ * lib/Youri/Submit/Action.pm: merging dev with upstream
++
++2006-10-16 16:05 warly
++
++ * lib/Youri/Submit/Check.pm: merging dev with upstream
++
++2006-10-16 13:03 warly
++
++ * lib/Youri/Submit/Action/Markrelease.pm,
++ lib/Youri/Submit/Action/Scp.pm, lib/Youri/Submit/Action/Send.pm:
++ Now the Module is Submit
++
++2006-10-16 12:57 warly
++
++ * lib/Youri/Submit/Action, lib/Youri/Submit/Action/Archive.pm,
++ lib/Youri/Submit/Action/Bugzilla.pm,
++ lib/Youri/Submit/Action/CVS.pm, lib/Youri/Submit/Action/Clean.pm,
++ lib/Youri/Submit/Action/Install.pm,
++ lib/Youri/Submit/Action/Link.pm, lib/Youri/Submit/Action/Mail.pm,
++ lib/Youri/Submit/Action/RSS.pm, lib/Youri/Submit/Action/Sign.pm:
++ merging dev with upstream
++
++2006-10-16 11:33 warly
++
++ * bin/youri-check.in: add new youri subsections (from upstream)
++
++2006-10-16 11:30 warly
++
++ * lib/Youri/Submit: add new youri subsections (from upstream)
++
++2006-10-16 11:30 warly
++
++ * lib/Youri: add new youri subsections (from upstream)
++
++2006-10-16 11:30 warly
++
++ * lib: add new youri subsections (from upstream)
++
++2006-10-16 11:22 warly
++
++ * bin/youri-submit.in: add new youri subsections (from upstream)
++
++2006-10-16 11:18 warly
++
++ * bin: add new youri subsections (from upstream)
++
++2006-10-16 11:18 warly
++
++ * .: add new youri subsections (from upstream)
++
++2006-04-23 Guillaume Rousse &lt;guillomovitch@zarb.org&gt; 0.9
++ * initial release
+
+<a id="build_systemmdvyourisubmittrunkMANIFESTSKIP">Added: build_system/mdv-youri-submit/trunk/MANIFEST.SKIP</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/MANIFEST.SKIP (rev 0)
++++ build_system/mdv-youri-submit/trunk/MANIFEST.SKIP 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,11 @@
++\.tar\.gz$
++\.SKIP$
++~$
++^pm_to_blib$
++^Makefile$
++^Makefile\.old$
++^bin/youri-submit$
++^bin/youri-submit-restricted$
++^bin/youri-submit-proxy$
++.svn
++blib
+
+<a id="build_systemmdvyourisubmittrunkMakefilePL">Added: build_system/mdv-youri-submit/trunk/Makefile.PL</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/Makefile.PL (rev 0)
++++ build_system/mdv-youri-submit/trunk/Makefile.PL 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,97 @@
++# $Id: Makefile.PL 1723 2006-10-17 13:53:27Z warly $
++use ExtUtils::MakeMaker;
++use Config;
++
++WriteMakefile(
++ NAME =&gt; 'youri-submit',
++ VERSION =&gt; 0.9,
++ AUTHOR =&gt; 'Youri project &lt;youri@zarb.org&gt;',
++ EXE_FILES =&gt; [
++ 'bin/youri-submit',
++ 'bin/youri-submit-restricted',
++ 'bin/youri-submit-proxy'
++ ],
++ PREREQ_PM =&gt; {
++ 'Youri::Config' =&gt; 0,
++ 'Youri::Utils' =&gt; 0,
++ 'Pod::Simple::HTMLBatch' =&gt; 0
++ },
++ PREFIX =&gt; '/usr/local',
++ INSTALLPRIVLIB =&gt; $Config{installprivlib},
++ INSTALLSITELIB =&gt; $Config{installsitelib},
++ INSTALLVENDORLIB =&gt; $Config{installvendorlib},
++ INSTALLMAN3DIR =&gt; $Config{installman3dir},
++ INSTALLSITEMAN3DIR =&gt; $Config{installsiteman3dir},
++ INSTALLVENDORMAN3DIR =&gt; $Config{installvendorman3dir},
++ INSTALLSCRIPT =&gt; '$(PREFIX)/bin',
++ INSTALLSITESCRIPT =&gt; '$(PREFIX)/bin',
++ INSTALLVENDORSCRIPT =&gt; '$(PREFIX)/bin',
++ INSTALLMAN1DIR =&gt; '$(PREFIX)/share/man/man1',
++ INSTALLSITEMAN1DIR =&gt; '$(PREFIX)/share/man/man1',
++ INSTALLVENDORMAN1DIR =&gt; '$(PREFIX)/share/man/man1',
++);
++
++package MY;
++
++sub post_constants {
++ my ($self) = @_;
++ my $sysconfdir = $self-&gt;{ARGS}-&gt;{SYSCONFDIR} || '$(PREFIX)/etc';
++ return &lt;&lt;EOF;
++SYSCONFDIR = $sysconfdir
++EOF
++}
++
++sub top_targets {
++ my ($self) = @_;
++ my $top_targets = $self-&gt;SUPER::top_targets(@_);
++ $top_targets =~ s/all :: pure_all manifypods/all :: pure_all manifypods htmlifypods/;
++ $top_targets .= &lt;&lt;'EOF';
++htmlifypods : $(TO_INST_PM)
++ if [ ! -d blib/html ]; then mkdir blib/html; fi
++ perl -MPod::Simple::HTMLBatch -e Pod::Simple::HTMLBatch::go lib blib/html
++ pod2html &lt; bin/youri-submit &gt; blib/html/youri-submit.html
++ pod2html &lt; bin/youri-submit-restricted &gt; blib/html/youri-submit-restricted.html
++ pod2html &lt; bin/youri-submit-proxy &gt; blib/html/youri-submit-proxy.html
++EOF
++ return $top_targets;
++}
++
++sub install {
++ my ($self) = @_;
++ my $install = $self-&gt;SUPER::install(@_);
++ $install =~ s/install :: all pure_install doc_install/install :: all pure_install doc_install config_install completion_install/;
++ $install .= &lt;&lt;'EOF';
++config_install :
++ install -d -m 755 $(DESTDIR)$(SYSCONFDIR)/youri
++ install -m 644 etc/submit.conf $(DESTDIR)$(SYSCONFDIR)/youri
++
++completion_install :
++ install -d -m 755 $(DESTDIR)$(SYSCONFDIR)/bash_completion.d
++ install -m 644 etc/bash_completion.d/youri-submit $(DESTDIR)$(SYSCONFDIR)/bash_completion.d
++EOF
++ return $install;
++}
++
++sub installbin {
++ my ($self) = @_;
++ my $installbin = $self-&gt;SUPER::installbin(@_);
++ $installbin .= &lt;&lt;'EOF';
++bin/youri-submit : bin/youri-submit.in Makefile
++ perl -p \
++ -e 's|\@sysconfdir\@|$(SYSCONFDIR)|;' \
++ &lt; $&lt; &gt; $@
++
++bin/youri-submit-restricted : bin/youri-submit-restricted.in Makefile
++ perl -p \
++ -e 's|\@sysconfdir\@|$(SYSCONFDIR)|;' \
++ -e 's|\@bindir\@|$(PREFIX)/bin|;' \
++ &lt; $&lt; &gt; $@
++
++bin/youri-submit-proxy : bin/youri-submit-proxy.in Makefile
++ perl -p \
++ -e 's|\@sysconfdir\@|$(SYSCONFDIR)|;' \
++ -e 's|\@bindir\@|$(PREFIX)/bin|;' \
++ &lt; $&lt; &gt; $@
++EOF
++ return $installbin;
++}
+
+<a id="build_systemmdvyourisubmittrunkREADME">Added: build_system/mdv-youri-submit/trunk/README</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/README (rev 0)
++++ build_system/mdv-youri-submit/trunk/README 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,45 @@
++YOURI project
++-------------
++
++YOURI stands for &quot;Youri Offers an Upload &amp; Repository Infrastucture&quot;. It aims
++to build tools making management of a coherent set of packages easier.
++
++Description
++-----------
++Managing a package repository involves many tasks, such as keeping packages
++tree tidy, generating packages indexes, synchronising bug report system,
++running coherency checks, checking for available updates, etc...
++
++Instead of a gazillion project-specific scripts, we aim to provide a generic package-format independant framework, so as to build coherent and robust tools.
++
++Components
++----------
++Available software in this release
++- youri-check allows to check packages
++- youri-upload allows to upload packages
++
++Installation
++------------
++To install, just use:
++perl Makefile.PL
++make
++make test
++
++All standard MakeMaker variables are usable, with the addition of SYSCONFDIR to
++specify configuration files destination.
++
++Copyright and License
++---------------------
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under
++the same terms as Perl itself.
++
++Authors
++-------
++Guillaume Rousse &lt;guillomovitch@zarb.org&gt;,
++Pascal Terjan &lt;pterjan@zarb.org&gt;
++Damien Krotkine &lt;dams@zarb.org&gt;
++Olivier Thauvin &lt;nanardon@zarb.org&gt;
++Ville Skytt\xE4 &lt;ville.skytta@iki.fi&gt;
++
+
+<a id="build_systemmdvyourisubmittrunkTODO">Added: build_system/mdv-youri-submit/trunk/TODO</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/TODO (rev 0)
++++ build_system/mdv-youri-submit/trunk/TODO 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,6 @@
++1.0 Goals
++=========
++
++- svn support
++- automatic bugzilla ticket closing on upload
++- more customizable (template based ?) mail notification
+
+<a id="build_systemmdvyourisubmittrunkbinyouricheckin">Added: build_system/mdv-youri-submit/trunk/bin/youri-check.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-check.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-check.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,395 @@
++#!/usr/bin/perl
++# $Id: youri-check.in 1699 2006-10-16 11:33:58Z warly $
++
++=head1 NAME
++
++youri-check - package check agent
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 SYNOPSIS
++
++youri-check [options] &lt;mode&gt;
++
++Options:
++
++ --config &lt;file&gt; use file &lt;file&gt; as config file
++ --skip-media &lt;media&gt; skip media &lt;media&gt;
++ --skip-plugin &lt;plugin&gt; skip plugin &lt;plugin&gt;
++ --parallel parallel run
++ --verbose verbose run
++ --test test run
++ --help print this help message
++
++=head1 DESCRIPTION
++
++B&lt;youri-check&gt; allows to check packages in a repository.
++
++In input mode, all medias defined in configuration are passed to a list of
++input plugins, each of them storing their result in a persistent resultset. In
++output mode, this resultset is passed to a list of output plugins, each of them
++producing arbitrary effects.
++
++=head1 OPTIONS
++
++=over
++
++=item B&lt;--config&gt; &lt;file&gt;
++
++Use given file as configuration, instead of normal one.
++
++=item B&lt;--skip-media&gt; &lt;media&gt;
++
++Skip media with given identity.
++
++=item B&lt;--skip-plugin&gt; &lt;plugin&gt;
++
++Skip plugin with given identity.
++
++=item B&lt;--parallel&gt;
++
++Run all plugins parallelously
++
++=item B&lt;--verbose&gt;
++
++Produce more verbose output (can be used more than once)
++
++=item B&lt;--test&gt;
++
++Don't perform any modification.
++
++=item B&lt;--help&gt;
++
++Print a brief help message and exits.
++
++=back
++
++=head1 CONFIGURATION
++
++Configuration is read from the first file found among:
++
++=over
++
++=item * the one specified by B&lt;--config&gt; option on command-line
++
++=item * $HOME/.youri/check.conf
++
++=item * @sysconfdir@/youri/check.conf
++
++=back
++
++All additional configuration files specified by B&lt;includes&gt; directive are then
++processed. Then command line options. Any directive overrides prior definition.
++
++=over
++
++=item B&lt;includes&gt; I&lt;files&gt;
++
++Uses space-separated list I&lt;files&gt; as a list of additional configuration files.
++
++=item B&lt;resolver&gt; I&lt;id&gt;
++
++Declare a maintainer resolver object with identity I&lt;id&gt;.
++
++=item B&lt;preferences&gt; I&lt;id&gt;
++
++Declare a maintainer preferences object with identity I&lt;id&gt;.
++
++=item B&lt;resultset&gt; I&lt;id&gt;
++
++Declare a resultset object with identity I&lt;id&gt;.
++
++=item B&lt;medias&gt; I&lt;ids&gt;
++
++Declares a list of media objects with identity taken in space-separated list
++I&lt;ids&gt;.
++
++=item B&lt;inputs&gt; I&lt;ids&gt;
++
++Declares a list of input plugin objects with identity taken in space-separated
++list I&lt;ids&gt;.
++
++=item B&lt;outputs&gt; I&lt;ids&gt;
++
++Declares a list of output plugin objects with identity taken in space-separated
++list I&lt;ids&gt;.
++
++=back
++
++Each object declared in configuration must be fully defined later, using a
++configuration section, starting with bracketed object identity, followed by at
++least a class directive, then any number of additional object-specific
++directives.
++
++Example:
++
++ objects = foo
++
++ [foo]
++ class = Foo::Bar
++ key1 = value1
++ key2 = value2
++
++=head1 SEE ALSO
++
++Youri::Config, for configuration file format.
++
++Each used plugin man page, for available options.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++use Youri::Config;
++use Youri::Utils;
++use Pod::Usage;
++use Net::Config qw/%NetConfig/;
++use DateTime;
++
++my $config = Youri::Config-&gt;new(
++ command_spec =&gt; [
++ 'config=s',
++ 'skip-plugin=s@',
++ 'skip-media=s@',
++ 'parallel!',
++ 'help|h!',
++ 'test|t!',
++ 'verbose|v!'
++ ],
++ file_spec =&gt; [
++ 'includes=s',
++ 'resolver=s',
++ 'preferences=s',
++ 'resultset=s',
++ 'medias=s',
++ 'inputs=s',
++ 'outputs=s'
++ ],
++ directories =&gt; [ '@sysconfdir@', &quot;$ENV{HOME}/.youri&quot; ],
++ file_name =&gt; 'check.conf',
++ caller =&gt; $0,
++);
++
++pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No mode specified, aborting\n&quot;
++) unless @ARGV;
++
++my $mode = $ARGV[0];
++
++# convenient global flags
++my $test = $config-&gt;get('test');
++my $verbose = $config-&gt;get('verbose');
++
++# libnet configuration
++my %netconfig = $config-&gt;get_section('netconfig');
++$NetConfig{$_} = $netconfig{$_} foreach keys %netconfig;
++
++# resultset creation
++my $resultset_id = $config-&gt;get('resultset');
++die &quot;No resultset defined&quot; unless $resultset_id;
++
++report(&quot;Creating resultset $resultset_id&quot;);
++my $resultset = create_instance(
++ 'Youri::Check::Resultset',
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ $config-&gt;get_section($resultset_id)
++);
++
++my $children;
++
++my %skip_plugins = map { $_ =&gt; 1 } @{$config-&gt;get('skip-plugin')};
++
++if ($mode eq 'input') {
++
++ # additional objects
++
++ my $resolver;
++ my $resolver_id = $config-&gt;get('resolver');
++ if ($resolver_id) {
++ report(&quot;Creating maintainer resolver $resolver_id&quot;);
++ eval {
++ $resolver = create_instance(
++ 'Youri::Check::Maintainer::Resolver',
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 1 ? $verbose - 2 : 0,
++ $config-&gt;get_section($resolver_id)
++ );
++ };
++ print STDERR &quot;Failed to create maintainer resolver $resolver_id: $@\n&quot; if $@;
++ }
++
++ my $preferences;
++ my $preferences_id = $config-&gt;get('preferences');
++ if ($preferences_id) {
++ report(&quot;Creating maintainer preferences $preferences_id&quot;);
++ eval {
++ $preferences = create_instance(
++ 'Youri::Check::Maintainer::Preferences',
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 1 ? $verbose - 2 : 0,
++ $config-&gt;get_section($preferences_id)
++ );
++ };
++ print STDERR &quot;Failed to create maintainer preferences $preferences_id: $@\n&quot; if $@;
++ }
++
++ my @medias;
++ my %skip_medias = map { $_ =&gt; 1 } @{$config-&gt;get('skip-media')};
++ foreach my $id (split(/\s+/, $config-&gt;get('medias'))) {
++ next if $skip_medias{$id};
++ report(&quot;Creating media $id&quot;);
++ eval {
++ push(
++ @medias,
++ create_instance(
++ 'Youri::Media',
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ $config-&gt;get_section($id)
++ )
++ );
++ };
++ print STDERR &quot;Failed to create media $id: $@\n&quot; if $@;
++ }
++
++ # prepare resultset
++ $resultset-&gt;reset();
++ $resultset-&gt;set_resolver($resolver);
++
++
++ foreach my $id (split(/\s+/, $config-&gt;get('inputs'))) {
++ next if $skip_plugins{$id};
++ report(&quot;Creating input $id&quot;);
++ my $input;
++ eval {
++ $input = create_instance(
++ 'Youri::Check::Input',
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ resolver =&gt; $resolver,
++ preferences =&gt; $preferences,
++ $config-&gt;get_section($id)
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create input $id: $@\n&quot;;
++ } else {
++ if ($config-&gt;get('parallel')) {
++ # fork
++ my $pid = fork;
++ die &quot;Can't fork: $!&quot; unless defined $pid;
++ if ($pid) {
++ # parent process
++ $children++;
++ next;
++ }
++ }
++ eval {
++ $input-&gt;prepare(@medias);
++ };
++ if ($@) {
++ print STDERR &quot;Failed to prepare input $id: $@\n&quot;;
++ } else {
++ # clone resultset in child process
++ $resultset = $config-&gt;get('parallel') ?
++ $resultset-&gt;clone() :
++ $resultset;
++
++ foreach my $media (@medias) {
++ next if $media-&gt;skip_input($id);
++ my $media_id = $media-&gt;get_id();
++ report(&quot;running input $id on media $media_id&quot;);
++ eval {
++ $input-&gt;run($media, $resultset);
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run input $id on media $media_id: $@\n&quot;;
++ }
++ }
++ }
++ if ($config-&gt;get('parallel')) {
++ # child process
++ exit;
++ }
++ }
++ }
++
++} elsif ($mode eq 'output') {
++
++ foreach my $id (split(/\s+/, $config-&gt;get('outputs'))) {
++ next if $skip_plugins{$id};
++ report(&quot;Creating output $id&quot;);
++ my $output;
++ eval {
++ $output = create_instance(
++ 'Youri::Check::Output',
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ config =&gt; $config,
++ $config-&gt;get_section($id)
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create output $id: $@\n&quot;;
++ } else {
++ if ($config-&gt;get('parallel')) {
++ # fork
++ my $pid = fork;
++ die &quot;Can't fork: $!&quot; unless defined $pid;
++ if ($pid) {
++ # parent process
++ $children++;
++ next;
++ }
++ }
++
++ # clone resultset in child process
++ $resultset = $config-&gt;get('parallel') ?
++ $resultset-&gt;clone() :
++ $resultset;
++
++ report(&quot;running output $id&quot;);
++ eval {
++ $output-&gt;run($resultset);
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run output $id: $@\n&quot;;
++ }
++
++ if ($config-&gt;get('parallel')) {
++ # child process
++ exit;
++ }
++ }
++ }
++} else {
++ die &quot;Invalid mode $mode&quot;;
++}
++
++# wait for all forked processus termination
++while ($children) {
++ wait;
++ $children--;
++}
++
++sub report {
++ my ($message) = @_;
++ print DateTime-&gt;now()-&gt;strftime('[%H:%M:%S] ')
++ if $verbose &gt; 1;
++ print &quot;$message\n&quot;
++ if $verbose &gt; 0;
++}
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-check.in
+___________________________________________________________________
+<a id="svnexecutable">Added: svn:executable</a>
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmit">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,534 @@
++#!/usr/bin/perl
++# $Id: youri-submit 232579 2007-12-17 19:45:47Z blino $
++
++=head1 NAME
++
++youri-submit - package submission tool
++
++=head1 VERSION
++
++Version 2.0
++
++=head1 SYNOPSIS
++
++youri-submit [options] &lt;target&gt; &lt;files&gt;
++
++youri-submit --list &lt;category&gt; [target]
++
++youri-submit --help [category] [item]
++
++Options:
++
++ --config &lt;file&gt; use file &lt;file&gt; as config file
++ --skip-pre &lt;pre&gt; skip pre &lt;pre&gt;
++ --skip-check &lt;check&gt; skip check &lt;check&gt;
++ --skip-action &lt;action&gt; skip action &lt;action&gt;
++ --skip-post &lt;post&gt; skip post &lt;post&gt;
++ --skip-reject &lt;reject&gt; skip reject &lt;reject&gt;
++ --define &lt;key&gt;=&lt;value&gt; pass additional values
++ --clean delete package after success
++ --verbose verbose run
++ --test test run
++ --list &lt;category&gt; list items from given category
++ --help [category] display contextual help
++
++=head1 DESCRIPTION
++
++B&lt;youri-submit&gt; allows to submit packages to a repository.
++
++All packages given on command lines are passed to a list of check plugins,
++depending on given upload target. If none of them fails, all packages are
++passed to a list of action plugins, depending also on given upload target.
++
++=head1 OPTIONS
++
++=over
++
++=item B&lt;--config&gt; I&lt;file&gt;
++
++Use given file as configuration, instead of normal one.
++
++=item B&lt;--skip-pre&gt; I&lt;id&gt;
++
++Skip pre transaction plugin with given identity
++
++=item B&lt;--skip-check&gt; I&lt;id&gt;
++
++Skip check plugin with given identity.
++
++=item B&lt;--skip-action&gt; I&lt;id&gt;
++
++Skip action plugin with given identity.
++
++=item B&lt;--skip-post&gt; I&lt;id&gt;
++
++Skip post transaction plugin with given identity.
++
++=item B&lt;--skip-reject&gt; I&lt;id&gt;
++
++Skip reject action plugin with given identity.
++
++=item B&lt;--define&gt; &lt;key&gt;=&lt;value&gt;
++
++Define additional parameters, to be used by plugins.
++
++=item B&lt;--clean&gt;
++
++Delete submited packages upon successfull submission.
++
++=item B&lt;--verbose&gt;
++
++Produce more verbose output (can be used more than once)
++
++=item B&lt;--test&gt;
++
++Don't perform any modification.
++
++=item B&lt;--list&gt; I&lt;category&gt;
++
++List available items from given category and exits. Category must be either
++B&lt;targets&gt;, B&lt;actions&gt; or B&lt;checks&gt;. A target is needed for the two last ones.
++
++=item B&lt;--help&gt; I&lt;category&gt;
++
++Display help for given category and exits. Category must be either
++B&lt;repository&gt;, B&lt;action&gt; or B&lt;check&gt;. An item is needed for the two last ones.
++If no category given, display standard help.
++
++=back
++
++=head1 CONFIGURATION
++
++Configuration is read from the first file found among:
++
++=over
++
++=item * the one specified by B&lt;--config&gt; option on command-line
++
++=item * $HOME/.youri/submit.conf
++
++=item * /usr/local/etc/youri/submit.conf
++
++=back
++
++The configuration file should be a YAML-format files, with the following
++mandatory top-level directives:
++
++=over
++
++=item B&lt;repository&gt;
++
++The definition of repository plugin to be used.
++
++=item B&lt;targets&gt;
++
++The list of available submission targets, each one being composed from the
++following keys:
++
++=over
++
++=item B&lt;checks&gt;
++
++The list of check plugins to use for this target.
++
++=item B&lt;actions&gt;
++
++The list of action plugins to use for this target.
++
++=back
++
++=item B&lt;checks&gt;
++
++The list of check plugin definitions, indexed by their identity.
++
++=item B&lt;actions&gt;
++
++The list of action plugin definitions, indexed by their identity.
++
++=back
++
++=head1 SEE ALSO
++
++Youri::Config, for additional details about configuration file format.
++
++Each used plugin man page, for available options.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++use Youri::Config;
++use Youri::Utils;
++use Pod::Usage;
++
++my $config = Youri::Config-&gt;new(
++ args =&gt; {
++ 'skip-check' =&gt; '=s@',
++ 'skip-action' =&gt; '=s@',
++ 'define' =&gt; '=s%',
++ 'verbose' =&gt; '|v!',
++ 'clean' =&gt; '!',
++ 'test' =&gt; '|t!',
++ 'list' =&gt; '|l!',
++ 'config' =&gt; '=s',
++ 'skip-prei' =&gt; '=s@',
++ 'skip-post' =&gt; '=s@',
++ 'skip-reject' =&gt; '=s@',
++ },
++ directories =&gt; [ &quot;$ENV{HOME}/.youri&quot;, '/usr/local/etc/youri' ],
++ file =&gt; 'submit.conf',
++);
++
++if ($config-&gt;get_arg('list')) {
++ my $category = $ARGV[0];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No category specified, aborting\n&quot;)
++ unless $category;
++ if ($category eq 'targets') {
++ print join(' ', keys %{$config-&gt;get_param('targets')});
++ } elsif ($category eq 'checks' || $category eq 'actions') {
++ my $target = $ARGV[1];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless $target;
++ if ($category eq 'checks') {
++ my $checks = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{checks};
++ print join(' ', @{$checks}) if $checks;
++ } else {
++ my $actions = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{actions};
++ print join(' ', @{$actions}) if $actions;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ print &quot;\n&quot;;
++ exit 0;
++}
++
++if ($config-&gt;get_arg('help')) {
++ my $category = $ARGV[0];
++ my ($item, $section);
++ if ($category eq 'repository') {
++ $section = $config-&gt;get_param('repository');
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No repository defined, aborting\n&quot;
++ ) unless $section;
++ } elsif ($category eq 'check' || $category eq 'action') {
++ $item = $ARGV[1];
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No item specified, aborting\n&quot;
++ ) unless $item;
++ if ($category eq 'check') {
++ $section = $config-&gt;get_param('checks')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such check $item defined, aborting\n&quot;
++ ) unless $section;
++ } else {
++ $section = $config-&gt;get_param('actions')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such action $item defined, aborting\n&quot;
++ ) unless $section;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ my $file = $section-&gt;{class} . '.pm';
++ $file =~ s/::/\//g;
++ pod2usage(
++ -verbose =&gt; 99,
++ -sections =&gt; 'NAME|DESCRIPTION',
++ -input =&gt; $file,
++ -pathlist =&gt; \@INC
++ );
++}
++
++
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless @ARGV &gt; 0;
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No packages specified, aborting\n&quot;)
++ unless @ARGV &gt; 1 || $config-&gt;get_param('allow_omitting_packages');
++
++# convenient global flags
++my $test = $config-&gt;get_arg('test');
++my $verbose = $config-&gt;get_arg('verbose');
++
++# check target
++my $target = shift @ARGV;
++my $target_conf = $config-&gt;get_param('targets')-&gt;{$target};
++
++# create repository
++my $repository;
++my $repository_conf = $config-&gt;get_param('repository');
++die &quot;No repository declared&quot; unless $repository_conf;
++print &quot;Creating repository\n&quot; if $verbose;
++eval {
++ $repository = create_instance(
++ 'Youri::Repository',
++ $repository_conf,
++ {
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ targets =&gt; [ keys %{$config-&gt;get_param('targets')} ],
++ }
++ );
++};
++die &quot;Failed to create repository: $@\n&quot; if $@;
++
++# perfrom pre action
++my @errors;
++my $pre_packages = [];
++my $skip_pres = $config-&gt;get_arg('skip-pre');
++my %skip_pres = $skip_pres ? map { $_ =&gt; 1 } @{$skip_pres} : ();
++foreach my $id (@{$target_conf-&gt;{pres}}) {
++ next if $skip_pres{$id};
++ print &quot;Creating pre $id\n&quot; if $verbose;
++ my $pre;
++ my $pre_conf = $config-&gt;get_param('pres')-&gt;{$id};
++
++ if (!$pre_conf) {
++ print STDERR &quot;No such pre $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $pre = create_instance(
++ 'Youri::Submit::Pre',
++ $pre_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create pre $id: $@\n&quot;;
++ } else {
++ print &quot;running pre $id\n&quot; if $verbose;
++ my @err = $pre-&gt;run(
++ $pre_packages,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@errors, @err) if $err[0];
++ }
++}
++
++if (@errors) {
++ print &quot;Pre-submission errors, aborting:\n&quot;;
++ foreach my $error (@errors) {
++ print &quot; - $error\n&quot;;
++ }
++ exit(1)
++}
++
++# create packages group
++my $group_error;
++my @packages_group;
++foreach my $group ([ map { { section =&gt; &quot;&quot;, file =&gt; $_ } } @ARGV ], @$pre_packages) {
++ my @packages;
++ foreach my $opt (@$group) {
++ print &quot;Preparing upload for $opt-&gt;{file} in $opt-&gt;{section}\n&quot; if $verbose;
++ $repository-&gt;{packages}{$opt-&gt;{file}}{section} = $opt-&gt;{section};
++ push(
++ @packages,
++ create_instance(
++ 'Youri::Package',
++ {
++ class =&gt; $repository-&gt;get_package_class(),
++ },
++ {
++ file =&gt; $opt-&gt;{file},
++ %$opt
++ },
++ )
++ );
++ }
++ @packages or next;
++
++# check all packages pass all tests
++ my %errors;
++ my $skip_check = $config-&gt;get_arg('skip-check');
++ my %skip_check = $skip_check ? map { $_ =&gt; 1 } @{$skip_check} : ();
++ my @error;
++ foreach my $id (@{$target_conf-&gt;{checks}}) {
++ next if $skip_check{$id};
++ print &quot;Creating check $id\n&quot; if $verbose;
++ my $check;
++ my $check_conf = $config-&gt;get_param('checks')-&gt;{$id};
++
++ if (!$check_conf) {
++ print STDERR &quot;No such check $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $check = create_instance(
++ 'Youri::Submit::Check',
++ $check_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create check $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running check $id on package $package\n&quot; if $verbose;
++ my @errors = $check-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@{$errors{$package}}, @errors) if $errors[0];
++ }
++ }
++ }
++ if (%errors) {
++ print &quot;Submission errors, aborting:\n&quot;;
++ foreach my $package (keys %errors) {
++ print &quot;- $package:\n&quot;;
++ foreach my $error (@{$errors{$package}}) {
++ print &quot; - $error\n&quot;;
++ }
++ }
++ # reject the packages
++ my $skip_rejects = $config-&gt;get_arg('skip-reject');
++ my %skip_rejects = $skip_rejects ? map { $_ =&gt; 1 } @{$skip_rejects} : ();
++ foreach my $id (@{$target_conf-&gt;{rejects}}) {
++ next if $skip_rejects{$id};
++ print &quot;Creating reject $id\n&quot; if $verbose;
++ my $reject;
++ my $reject_conf = $config-&gt;get_param('rejects')-&gt;{$id};
++
++ if (!$reject_conf) {
++ print STDERR &quot;No such reject $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $reject = create_instance(
++ 'Youri::Submit::Reject',
++ $reject_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create reject $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running reject $id on package $package\n&quot; if $verbose;
++ eval {
++ $reject-&gt;run($package, \%errors, $repository, $target, $config-&gt;get_arg('define'));
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++ $group_error = 1;
++ next
++ }
++
++# proceed further
++ my $skip_action = $config-&gt;get_arg('skip-action');
++ my %skip_action = $skip_action ? map { $_ =&gt; 1 } @{$skip_action} : ();
++ foreach my $id (@{$target_conf-&gt;{actions}}) {
++ next if $skip_action{$id};
++ print &quot;Creating action $id\n&quot; if $verbose;
++ my $action;
++ my $action_conf = $config-&gt;get_param('actions')-&gt;{$id};
++
++ if (!$action_conf) {
++ print STDERR &quot;No such action $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $action = create_instance(
++ 'Youri::Submit::Action',
++ $action_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create action $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running action $id on package $package\n&quot; if $verbose;
++ eval {
++ $action-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++
++ if ($config-&gt;get_arg('clean')) {
++ foreach my $package (@packages) {
++ print &quot;cleaning file $package\n&quot; if $verbose;
++ unlink $package-&gt;as_file();
++ }
++ }
++}
++
++# perfrom post action
++my $skip_post = $config-&gt;get_arg('skip-post');
++my %skip_post = $skip_post ? map { $_ =&gt; 1 } @{$skip_post} : ();
++foreach my $id (@{$target_conf-&gt;{posts}}) {
++ next if $skip_post{$id};
++ print &quot;Creating post $id\n&quot; if $verbose;
++ my $post;
++ my $post_conf = $config-&gt;get_param('posts')-&gt;{$id};
++
++ if (!$post_conf) {
++ print STDERR &quot;No such post $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $post = create_instance(
++ 'Youri::Submit::Post',
++ $post_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create post $id: $@\n&quot;;
++ } else {
++ print &quot;running post $id\n&quot; if $verbose;
++ my @err = $post-&gt;run($repository, $target, $config-&gt;get_arg('define'));
++ print STDERR &quot;Error $id: @err\n&quot; if @err
++ }
++}
++
++exit(1) if $group_error;
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmitproxyin">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,77 @@
++#!/usr/bin/perl
++
++=head1 NAME
++
++youri-submit-proxy - proxy wrapper over youri-submit-restricted
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 SYNOPSIS
++
++youri-submit-proxy [options] &lt;target&gt; &lt;files&gt;
++
++=head1 DESCRIPTION
++
++youri-submit-proxy is a proxy wrapper over youri-submit-restricted, intended to
++be used in collaborative work to change uid before calling it through sudo.
++
++=head1 SEE ALSO
++
++youri-submit-restricted(1), youri-submit(1)
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++use Fcntl ':mode';
++use File::Basename;
++
++my ($uid, $gid);
++if (-l $0) {
++ # this is a symlink, get uid and gid from it
++ ($uid, $gid) = (lstat($0))[4, 5];
++} else {
++ ($uid, $gid) = (stat($0))[4, 5];
++}
++my $user = getpwuid($uid) or die &quot;unknown uid $uid&quot;;
++my $prog = '@bindir@/youri-submit-restricted';
++
++my %dirs;
++my @options;
++foreach my $arg (@ARGV) {
++ if (-f $arg) {
++ # push parent dir in list
++ my $parent = dirname($arg);
++ $dirs{$parent}++;
++ }
++ push(@options, $arg);
++}
++
++foreach my $dir (keys %dirs) {
++ # save original perms and gid
++ my ($orig_mode, $orig_gid) = (stat($dir))[2,5];
++ $dirs{$dir} = {
++ mode =&gt; $orig_mode,
++ gid =&gt; $orig_gid
++ };
++ # ensure correct perms and gid
++ chown -1, $gid, $dir;
++ chmod $orig_mode|S_IRGRP|S_IWGRP, $dir;
++}
++
++# call wrapped program
++system('sudo', '-H', '-u', $user, $prog, @options);
++
++foreach my $dir (keys %dirs) {
++ # restore original perms and gid
++ chown -1, $dirs{$dir}-&gt;{gid}, $dir;
++ chmod $dirs{$dir}-&gt;{mode}, $dir;
++}
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit-proxy.in
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmitrestrictedin">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,64 @@
++#!/usr/bin/perl -T
++
++=head1 NAME
++
++youri-submit-restricted - filtering wrapper over youri-submit
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 SYNOPSIS
++
++youri-submit-restricted [options] &lt;target&gt; &lt;files&gt;
++
++=head1 DESCRIPTION
++
++youri-submit-restricted is just a filtering wrapper over youri-submit, intended
++to be used in collaborative work to sanitize environment and options before
++calling it.
++
++=head1 SEE ALSO
++
++youri-submit(1)
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++my $prog = '@bindir@/youri-submit';
++my @prohibited_options = qw/--config --skip-check --skip-action/;
++my %prohibited_options = map { $_ =&gt; 1 } @prohibited_options;
++my @prohibited_envvars = qw/
++ ENV BASH_ENV IFS CDPATH
++ PERLLIB PERL5LIB PERL5OPT PERLIO
++ PERLIO_DEBUG PERL5DB PERL_ENCODING
++ PERL_HASH_SEED PERL_SIGNALS PERL_UNICODE
++/;
++
++my @options;
++while (my $arg = shift @ARGV) {
++ if ($prohibited_options{$arg}) {
++ # drop prohibited options
++ print STDERR &quot;prohibited option $arg, skipping\n&quot;;
++ shift @ARGV;
++ } else {
++ # untaint everything else
++ $arg =~ /(.*)/;
++ push(@options, $1);
++ }
++}
++
++# secure ENV
++$ENV{PATH} = &quot;/sbin:/usr/sbin:/bin:/usr/bin:/usr/X11R6/bin&quot;;
++delete $ENV{$_} foreach @prohibited_envvars;
++
++# call wrapped program
++system($prog, @options);
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit-restricted.in
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunkbinyourisubmitin">Added: build_system/mdv-youri-submit/trunk/bin/youri-submit.in</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/bin/youri-submit.in (rev 0)
++++ build_system/mdv-youri-submit/trunk/bin/youri-submit.in 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,534 @@
++#!/usr/bin/perl
++# $Id: youri-submit.in 232668 2007-12-21 14:37:04Z blino $
++
++=head1 NAME
++
++youri-submit - package submission tool
++
++=head1 VERSION
++
++Version 2.0
++
++=head1 SYNOPSIS
++
++youri-submit [options] &lt;target&gt; &lt;files&gt;
++
++youri-submit --list &lt;category&gt; [target]
++
++youri-submit --help [category] [item]
++
++Options:
++
++ --config &lt;file&gt; use file &lt;file&gt; as config file
++ --skip-pre &lt;pre&gt; skip pre &lt;pre&gt;
++ --skip-check &lt;check&gt; skip check &lt;check&gt;
++ --skip-action &lt;action&gt; skip action &lt;action&gt;
++ --skip-post &lt;post&gt; skip post &lt;post&gt;
++ --skip-reject &lt;reject&gt; skip reject &lt;reject&gt;
++ --define &lt;key&gt;=&lt;value&gt; pass additional values
++ --clean delete package after success
++ --verbose verbose run
++ --test test run
++ --list &lt;category&gt; list items from given category
++ --help [category] display contextual help
++
++=head1 DESCRIPTION
++
++B&lt;youri-submit&gt; allows to submit packages to a repository.
++
++All packages given on command lines are passed to a list of check plugins,
++depending on given upload target. If none of them fails, all packages are
++passed to a list of action plugins, depending also on given upload target.
++
++=head1 OPTIONS
++
++=over
++
++=item B&lt;--config&gt; I&lt;file&gt;
++
++Use given file as configuration, instead of normal one.
++
++=item B&lt;--skip-pre&gt; I&lt;id&gt;
++
++Skip pre transaction plugin with given identity
++
++=item B&lt;--skip-check&gt; I&lt;id&gt;
++
++Skip check plugin with given identity.
++
++=item B&lt;--skip-action&gt; I&lt;id&gt;
++
++Skip action plugin with given identity.
++
++=item B&lt;--skip-post&gt; I&lt;id&gt;
++
++Skip post transaction plugin with given identity.
++
++=item B&lt;--skip-reject&gt; I&lt;id&gt;
++
++Skip reject action plugin with given identity.
++
++=item B&lt;--define&gt; &lt;key&gt;=&lt;value&gt;
++
++Define additional parameters, to be used by plugins.
++
++=item B&lt;--clean&gt;
++
++Delete submited packages upon successfull submission.
++
++=item B&lt;--verbose&gt;
++
++Produce more verbose output (can be used more than once)
++
++=item B&lt;--test&gt;
++
++Don't perform any modification.
++
++=item B&lt;--list&gt; I&lt;category&gt;
++
++List available items from given category and exits. Category must be either
++B&lt;targets&gt;, B&lt;actions&gt; or B&lt;checks&gt;. A target is needed for the two last ones.
++
++=item B&lt;--help&gt; I&lt;category&gt;
++
++Display help for given category and exits. Category must be either
++B&lt;repository&gt;, B&lt;action&gt; or B&lt;check&gt;. An item is needed for the two last ones.
++If no category given, display standard help.
++
++=back
++
++=head1 CONFIGURATION
++
++Configuration is read from the first file found among:
++
++=over
++
++=item * the one specified by B&lt;--config&gt; option on command-line
++
++=item * $HOME/.youri/submit.conf
++
++=item * /usr/local/etc/youri/submit.conf
++
++=back
++
++The configuration file should be a YAML-format files, with the following
++mandatory top-level directives:
++
++=over
++
++=item B&lt;repository&gt;
++
++The definition of repository plugin to be used.
++
++=item B&lt;targets&gt;
++
++The list of available submission targets, each one being composed from the
++following keys:
++
++=over
++
++=item B&lt;checks&gt;
++
++The list of check plugins to use for this target.
++
++=item B&lt;actions&gt;
++
++The list of action plugins to use for this target.
++
++=back
++
++=item B&lt;checks&gt;
++
++The list of check plugin definitions, indexed by their identity.
++
++=item B&lt;actions&gt;
++
++The list of action plugin definitions, indexed by their identity.
++
++=back
++
++=head1 SEE ALSO
++
++Youri::Config, for additional details about configuration file format.
++
++Each used plugin man page, for available options.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++use strict;
++use warnings;
++
++use Youri::Config;
++use Youri::Utils;
++use Pod::Usage;
++
++my $config = Youri::Config-&gt;new(
++ args =&gt; {
++ 'skip-check' =&gt; '=s@',
++ 'skip-action' =&gt; '=s@',
++ 'define' =&gt; '=s%',
++ 'verbose' =&gt; '|v!',
++ 'clean' =&gt; '!',
++ 'test' =&gt; '|t!',
++ 'list' =&gt; '|l!',
++ 'config' =&gt; '=s',
++ 'skip-prei' =&gt; '=s@',
++ 'skip-post' =&gt; '=s@',
++ 'skip-reject' =&gt; '=s@',
++ },
++ directories =&gt; [ &quot;$ENV{HOME}/.youri&quot;, '@sysconfdir@/youri' ],
++ file =&gt; 'submit.conf',
++);
++
++if ($config-&gt;get_arg('list')) {
++ my $category = $ARGV[0];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No category specified, aborting\n&quot;)
++ unless $category;
++ if ($category eq 'targets') {
++ print join(' ', keys %{$config-&gt;get_param('targets')});
++ } elsif ($category eq 'checks' || $category eq 'actions') {
++ my $target = $ARGV[1];
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless $target;
++ if ($category eq 'checks') {
++ my $checks = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{checks};
++ print join(' ', @{$checks}) if $checks;
++ } else {
++ my $actions = $config-&gt;get_param('targets')-&gt;{$target}-&gt;{actions};
++ print join(' ', @{$actions}) if $actions;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ print &quot;\n&quot;;
++ exit 0;
++}
++
++if ($config-&gt;get_arg('help')) {
++ my $category = $ARGV[0];
++ my ($item, $section);
++ if ($category eq 'repository') {
++ $section = $config-&gt;get_param('repository');
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No repository defined, aborting\n&quot;
++ ) unless $section;
++ } elsif ($category eq 'check' || $category eq 'action') {
++ $item = $ARGV[1];
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No item specified, aborting\n&quot;
++ ) unless $item;
++ if ($category eq 'check') {
++ $section = $config-&gt;get_param('checks')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such check $item defined, aborting\n&quot;
++ ) unless $section;
++ } else {
++ $section = $config-&gt;get_param('actions')-&gt;{$item};
++ pod2usage(
++ -verbose =&gt; 0,
++ -message =&gt; &quot;No such action $item defined, aborting\n&quot;
++ ) unless $section;
++ }
++ } else {
++ pod2usage(-verbose =&gt; 0, -message =&gt; &quot;Invalid category $category, aborting\n&quot;)
++ }
++ my $file = $section-&gt;{class} . '.pm';
++ $file =~ s/::/\//g;
++ pod2usage(
++ -verbose =&gt; 99,
++ -sections =&gt; 'NAME|DESCRIPTION',
++ -input =&gt; $file,
++ -pathlist =&gt; \@INC
++ );
++}
++
++
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No target specified, aborting\n&quot;)
++ unless @ARGV &gt; 0;
++pod2usage(-verbose =&gt; 0, -message =&gt; &quot;No packages specified, aborting\n&quot;)
++ unless @ARGV &gt; 1 || $config-&gt;get_param('allow_omitting_packages');
++
++# convenient global flags
++my $test = $config-&gt;get_arg('test');
++my $verbose = $config-&gt;get_arg('verbose');
++
++# check target
++my $target = shift @ARGV;
++my $target_conf = $config-&gt;get_param('targets')-&gt;{$target};
++
++# create repository
++my $repository;
++my $repository_conf = $config-&gt;get_param('repository');
++die &quot;No repository declared&quot; unless $repository_conf;
++print &quot;Creating repository\n&quot; if $verbose;
++eval {
++ $repository = create_instance(
++ 'Youri::Repository',
++ $repository_conf,
++ {
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ targets =&gt; [ keys %{$config-&gt;get_param('targets')} ],
++ }
++ );
++};
++die &quot;Failed to create repository: $@\n&quot; if $@;
++
++# perfrom pre action
++my @errors;
++my $pre_packages = [];
++my $skip_pres = $config-&gt;get_arg('skip-pre');
++my %skip_pres = $skip_pres ? map { $_ =&gt; 1 } @{$skip_pres} : ();
++foreach my $id (@{$target_conf-&gt;{pres}}) {
++ next if $skip_pres{$id};
++ print &quot;Creating pre $id\n&quot; if $verbose;
++ my $pre;
++ my $pre_conf = $config-&gt;get_param('pres')-&gt;{$id};
++
++ if (!$pre_conf) {
++ print STDERR &quot;No such pre $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $pre = create_instance(
++ 'Youri::Submit::Pre',
++ $pre_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create pre $id: $@\n&quot;;
++ } else {
++ print &quot;running pre $id\n&quot; if $verbose;
++ my @err = $pre-&gt;run(
++ $pre_packages,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@errors, @err) if $err[0];
++ }
++}
++
++if (@errors) {
++ print &quot;Pre-submission errors, aborting:\n&quot;;
++ foreach my $error (@errors) {
++ print &quot; - $error\n&quot;;
++ }
++ exit(1)
++}
++
++# create packages group
++my $group_error;
++my @packages_group;
++foreach my $group ([ map { { section =&gt; &quot;&quot;, file =&gt; $_ } } @ARGV ], @$pre_packages) {
++ my @packages;
++ foreach my $opt (@$group) {
++ print &quot;Preparing upload for $opt-&gt;{file} in $opt-&gt;{section}\n&quot; if $verbose;
++ $repository-&gt;{packages}{$opt-&gt;{file}}{section} = $opt-&gt;{section};
++ push(
++ @packages,
++ create_instance(
++ 'Youri::Package',
++ {
++ class =&gt; $repository-&gt;get_package_class(),
++ },
++ {
++ file =&gt; $opt-&gt;{file},
++ %$opt
++ },
++ )
++ );
++ }
++ @packages or next;
++
++# check all packages pass all tests
++ my %errors;
++ my $skip_check = $config-&gt;get_arg('skip-check');
++ my %skip_check = $skip_check ? map { $_ =&gt; 1 } @{$skip_check} : ();
++ my @error;
++ foreach my $id (@{$target_conf-&gt;{checks}}) {
++ next if $skip_check{$id};
++ print &quot;Creating check $id\n&quot; if $verbose;
++ my $check;
++ my $check_conf = $config-&gt;get_param('checks')-&gt;{$id};
++
++ if (!$check_conf) {
++ print STDERR &quot;No such check $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $check = create_instance(
++ 'Youri::Submit::Check',
++ $check_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create check $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running check $id on package $package\n&quot; if $verbose;
++ my @errors = $check-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ push(@{$errors{$package}}, @errors) if $errors[0];
++ }
++ }
++ }
++ if (%errors) {
++ print &quot;Submission errors, aborting:\n&quot;;
++ foreach my $package (keys %errors) {
++ print &quot;- $package:\n&quot;;
++ foreach my $error (@{$errors{$package}}) {
++ print &quot; - $error\n&quot;;
++ }
++ }
++ # reject the packages
++ my $skip_rejects = $config-&gt;get_arg('skip-reject');
++ my %skip_rejects = $skip_rejects ? map { $_ =&gt; 1 } @{$skip_rejects} : ();
++ foreach my $id (@{$target_conf-&gt;{rejects}}) {
++ next if $skip_rejects{$id};
++ print &quot;Creating reject $id\n&quot; if $verbose;
++ my $reject;
++ my $reject_conf = $config-&gt;get_param('rejects')-&gt;{$id};
++
++ if (!$reject_conf) {
++ print STDERR &quot;No such reject $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $reject = create_instance(
++ 'Youri::Submit::Reject',
++ $reject_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create reject $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running reject $id on package $package\n&quot; if $verbose;
++ eval {
++ $reject-&gt;run($package, \%errors, $repository, $target, $config-&gt;get_arg('define'));
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++ $group_error = 1;
++ next
++ }
++
++# proceed further
++ my $skip_action = $config-&gt;get_arg('skip-action');
++ my %skip_action = $skip_action ? map { $_ =&gt; 1 } @{$skip_action} : ();
++ foreach my $id (@{$target_conf-&gt;{actions}}) {
++ next if $skip_action{$id};
++ print &quot;Creating action $id\n&quot; if $verbose;
++ my $action;
++ my $action_conf = $config-&gt;get_param('actions')-&gt;{$id};
++
++ if (!$action_conf) {
++ print STDERR &quot;No such action $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $action = create_instance(
++ 'Youri::Submit::Action',
++ $action_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create action $id: $@\n&quot;;
++ } else {
++ foreach my $package (@packages) {
++ print &quot;running action $id on package $package\n&quot; if $verbose;
++ eval {
++ $action-&gt;run(
++ $package,
++ $repository,
++ $target,
++ $config-&gt;get_arg('define')
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to run action $id on package $package: $@\n&quot;;
++ }
++ }
++ }
++ }
++
++ if ($config-&gt;get_arg('clean')) {
++ foreach my $package (@packages) {
++ print &quot;cleaning file $package\n&quot; if $verbose;
++ unlink $package-&gt;as_file();
++ }
++ }
++}
++
++# perfrom post action
++my $skip_post = $config-&gt;get_arg('skip-post');
++my %skip_post = $skip_post ? map { $_ =&gt; 1 } @{$skip_post} : ();
++foreach my $id (@{$target_conf-&gt;{posts}}) {
++ next if $skip_post{$id};
++ print &quot;Creating post $id\n&quot; if $verbose;
++ my $post;
++ my $post_conf = $config-&gt;get_param('posts')-&gt;{$id};
++
++ if (!$post_conf) {
++ print STDERR &quot;No such post $id, skipping\n&quot;;
++ next;
++ }
++ eval {
++ $post = create_instance(
++ 'Youri::Submit::Post',
++ $post_conf,
++ {
++ id =&gt; $id,
++ test =&gt; $test,
++ verbose =&gt; $verbose &gt; 0 ? $verbose - 1 : 0,
++ }
++ );
++ };
++ if ($@) {
++ print STDERR &quot;Failed to create post $id: $@\n&quot;;
++ } else {
++ print &quot;running post $id\n&quot; if $verbose;
++ my @err = $post-&gt;run($repository, $target, $config-&gt;get_arg('define'));
++ print STDERR &quot;Error $id: @err\n&quot; if @err
++ }
++}
++
++exit(1) if $group_error;
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/bin/youri-submit.in
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyourisubmittrunketcbash_completiondyourisubmit">Added: build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit (rev 0)
++++ build_system/mdv-youri-submit/trunk/etc/bash_completion.d/youri-submit 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,60 @@
++# youri-submit completion
++# $Id$
++
++_youri-submit()
++{
++
++ local cur prev config
++
++ COMPREPLY=()
++ cur=${COMP_WORDS[COMP_CWORD]}
++ prev=${COMP_WORDS[COMP_CWORD-1]}
++
++ case &quot;$prev&quot; in
++ --config)
++ _filedir
++ return 0
++ ;;
++ --list)
++ COMPREPLY=( $( compgen -W 'targets checks actions' -- $cur ) )
++ return 0
++ ;;
++ --help)
++ COMPREPLY=( $( compgen -W 'repository check action' -- $cur ) )
++ return 0
++ ;;
++ esac
++
++ if [[ &quot;$cur&quot; == -* ]]; then
++ COMPREPLY=( $( compgen -W '--define --clean -l --list -h --help -t \
++ --test -v --verbose' -- $cur ) )
++ # add dangereous option for main command
++ if [[ ${COMP_WORDS[0]} == youri-submit ]]; then
++ COMPREPLY=( $( compgen -W '${COMPREPLY[@]} --config --skip-check \
++ --skip-action' -- $cur ) )
++ fi
++ else
++ _count_args
++ case $args in
++ 1)
++ _find_config
++ COMPREPLY=( $( compgen -W '$( youri-submit $config --list targets )' -- $cur ) )
++ ;;
++ *)
++ _filedir
++ ;;
++ esac
++ fi
++
++}
++complete -F _youri-submit youri-submit youri-submit-restricted youri-submit-proxy
++
++_find_config()
++{
++ for (( i=1; i &lt; COMP_CWORD; i++ )); do
++ if [[ &quot;${COMP_WORDS[i]}&quot; == --config ]]; then
++ config=&quot;--config ${COMP_WORDS[i+1]}&quot;
++ break
++ fi
++ done
++}
+
+<a id="build_systemmdvyourisubmittrunketcsubmitconf">Added: build_system/mdv-youri-submit/trunk/etc/submit.conf</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/etc/submit.conf (rev 0)
++++ build_system/mdv-youri-submit/trunk/etc/submit.conf 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,134 @@
++# youri-submit sample configuration file
++# $Id: submit.conf 1723 2006-10-17 13:53:27Z warly $
++
++# helper variables
++home: /home/user
++
++# repository definition
++repository:
++ class: Youri::Repository::PLF
++ options:
++ install_root: ${home}/ftp/mandriva
++ version_root: ${home}/cvs
++ archive_root: ${home}/backup/mandriva
++ noarch: i586
++
++# targets definitions
++targets:
++ cooker:
++ checks:
++ - tag
++ - recency
++ - history
++ actions:
++ - sign
++ - install
++ - link
++ - archive
++ - clean
++ - bugzilla
++ - cvs
++ - mail
++ - rss
++
++ 2006.0:
++ checks:
++ - type
++ - tag
++ - recency
++ - history
++ - precedence
++ actions:
++ - sign
++ - install
++ - link
++ - archive
++ - clean
++
++# checks definitions
++checks:
++ tag:
++ class: Youri::Submit::Check::Tag
++ options:
++ tags:
++ release: 'plf$'
++ packager: '&lt;\w+@zarb\.org&gt;$'
++ distribution: '^Mandriva Linux$'
++ vendor: '^Penguin Liberation Front$'
++
++ recency:
++ class: Youri::Submit::Check::Recency
++
++ history:
++ class: Youri::Submit::Check::History
++
++ precedence:
++ class: Youri::Submit::Check::Precedence
++ options:
++ target: cooker
++
++ type:
++ class: Youri::Submit::Check::Type
++ type: binary
++
++# actions definitions
++actions:
++ sign:
++ class: Youri::Submit::Action::Sign
++ options:
++ name: plf@zarb.org
++ path: ${home}/.gnupg
++ passphrase: s3kr3t
++
++ install:
++ class: Youri::Submit::Action::Install
++
++ link:
++ class: Youri::Submit::Action::Link
++
++ archive:
++ class: Youri::Submit::Action::Archive
++
++ clean:
++ class: Youri::Submit::Action::Clean
++
++ mail:
++ class: Youri::Submit::Action::Mail
++ options:
++ mta: /usr/sbin/sendmail
++ to: plf-announce@zarb.org
++ reply_to: plf-discuss@zarb.org
++ from: plf@zarb.org
++ prefix: RPM
++ cc:
++ hot-base: david@dindinx.org bellamy@neverland.net
++ dcgui: mathen@ketelhot.de
++ dclib: mathen@ketelhot.de
++ Video-DVDRip: dvdrip-users@exit1.org
++ hackVideo-DVDRip: dvdrip-users@exit1.org
++ goosnes: tak@bard.sytes.net
++ avidemux: fixounet@free.fr
++ vobcopy: robos@muon.de
++ drip: drip-devel@lists.sourceforge.net
++ libdscaler: vektor@dumbterm.net
++ xawdecode: pingus77@ifrance.com
++
++ rss:
++ class: Youri::Submit::Action::RSS
++ options:
++ file: ${home}/www/changelog.rss
++ title: PLF packages updates
++ link: http://plf.zarb.org/
++ description: ChangeLog for PLF packages
++
++ cvs:
++ class: Youri::Submit::Action::CVS
++
++ bugzilla:
++ class: Youri::Submit::Action::Bugzilla
++ options:
++ host: localhost
++ base: plf_bugs
++ user: plf
++ pass: s3kr3t
++ contact: plf@zarb.org
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionArchivepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Archive.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,90 @@
++# $Id: Archive.pm 265457 2010-01-28 13:09:30Z pterjan $
++package Youri::Submit::Action::Archive;
++
++=head1 NAME
++
++Youri::Submit::Action::Archive - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # FIXME: workaround for $self-&gt;{_verbose} not being initialized properly
++ $self-&gt;{_verbose} = 1;
++ # all this should be in Mandriva_upload.pm
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ my $main_section = $repository-&gt;_get_main_section($package, $target, $define);
++ print &quot;section $section main_section $main_section\n&quot; if $self-&gt;{_verbose};
++ my $arch = $package-&gt;get_arch();
++ $arch = $self-&gt;{_noarch} if $arch eq 'noarch';
++ my $path = $arch eq 'src' ? &quot;$target/SRPMS&quot; : &quot;$target/$arch/media&quot;;
++ $path = &quot;$repository-&gt;{_install_root}/$path&quot;;
++ $path =~ s,/+,/,g;
++ foreach my $replaced_package (
++ $repository-&gt;get_replaced_packages($package, $target, $define)
++ ) {
++ my $file = $replaced_package-&gt;get_file();
++
++ # trap for debugging bug 34999
++ if ($file =~ /\/[\d.]+\/(main\/updates|.*\/release)/) {
++ my $bugmsg = &quot;BUG#34999 WARNING: trying to remove from a release: $file\n&quot;;
++ open(BUG34999LOG, '&gt;&gt;', &quot;/home/mandrake/bug34999.log&quot;);
++ print $bugmsg;
++ print BUG34999LOG localtime().&quot;: &quot;.$bugmsg;
++ close BUG34999LOG;
++
++ next;
++ }
++
++ my ($rep_section, $rep_main_section) = $file =~ m,$path/(([^/]+)/.*)/[^/]+.rpm,;
++ # We do accept duplicate version for other submedia of the same main media section
++ print &quot;(path '$path') file '$file' section '$rep_section' main_section '$rep_main_section'\n&quot; if $self-&gt;{_verbose};
++ next if $rep_main_section eq $main_section &amp;&amp; $rep_section ne $section;
++ my $dest = $repository-&gt;get_archive_dir($package, $target, $define);
++
++ print &quot;archiving file $file to $dest\n&quot; if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest&quot;)
++ unless -d $dest;
++
++ # install file to new location
++ system(&quot;install -m $self-&gt;{_perms} $file $dest&quot;);
++
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionBugzillapm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Bugzilla.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,81 @@
++# $Id: Bugzilla.pm 1700 2006-10-16 12:57:42Z warly $
++package Youri::Submit::Action::Bugzilla;
++
++=head1 NAME
++
++Youri::Submit::Action::Bugzilla - Bugzilla synchronisation
++
++=head1 DESCRIPTION
++
++This action plugin ensures synchronisation with Bugzilla.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Bugzilla;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ host =&gt; '',
++ base =&gt; '',
++ user =&gt; '',
++ pass =&gt; '',
++ contact =&gt; '',
++ @_
++ );
++
++ $self-&gt;{_bugzilla} = Youri::Bugzilla-&gt;new(
++ $options{host},
++ $options{base},
++ $options{user},
++ $options{pass}
++ );
++ $self-&gt;{_contact} = $options{contact};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $summary = $package-&gt;get_summary();
++ my $packager = $package-&gt;get_packager();
++ $packager =~ s/.*&lt;(.*)&gt;/$1/;
++
++ if ($self-&gt;{_bugzilla}-&gt;has_package($name)) {
++ my %versions =
++ map { $_ =&gt; 1 }
++ $self-&gt;{_bugzilla}-&gt;get_versions($name);
++ unless ($versions{$version}) {
++ print &quot;adding version $version to bugzilla\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;{_bugzilla}-&gt;add_version($name, $version)
++ unless $self-&gt;{_test};
++ }
++ } else {
++ print &quot;adding package $name to bugzilla\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;{_bugzilla}-&gt;add_package(
++ $name,
++ $summary,
++ $version,
++ $packager,
++ $self-&gt;{_contact}
++ ) unless $self-&gt;{_test};
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionCVSpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/CVS.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,135 @@
++# $Id: CVS.pm 224115 2007-07-02 09:17:15Z pixel $
++package Youri::Submit::Action::CVS;
++
++=head1 NAME
++
++Youri::Submit::Action::CVS - CVS versionning
++
++=head1 DESCRIPTION
++
++This action plugin ensures CVS versionning of package sources.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Cwd;
++use File::Temp qw/tempdir/;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ exclude =&gt; '\.(tar(\.(gz|bz2))?|zip)$',
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_exclude} = $options{exclude};
++ $self-&gt;{_perms} = $options{perms};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++
++ my $root = $repository-&gt;get_version_root();
++ my $path = $repository-&gt;get_version_path($package, $target, $define);
++
++ # remember original directory
++ my $original_dir = cwd();
++
++ # get a safe temporary directory
++ my $dir = tempdir( CLEANUP =&gt; 1 );
++ chdir $dir;
++
++ # first checkout base directory only
++ system(&quot;cvs -Q -d $root co -l $path&quot;);
++
++ # try to checkout package directory
++ my $dest = $path . '/' . $name;
++ system(&quot;cvs -Q -d $root co $dest&quot;);
++
++ # create directory if previous import failed
++ unless (-d $dest) {
++ print &quot;adding directory $dest\n&quot; if $self-&gt;{_verbose};
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest&quot;);
++ system(&quot;cvs -Q -d $root add $dest&quot;);
++ }
++
++ chdir $dest;
++
++ # remove all files
++ unlink grep { -f } glob '*';
++
++ # extract all rpm files locally
++ $package-&gt;extract();
++
++ # remove excluded files
++ if ($self-&gt;{_exclude}) {
++ unlink grep { -f &amp;&amp; /$self-&gt;{_exclude}/ } glob '*';
++ }
++
++ # uncompress all compressed files
++ system(&quot;bunzip2 *.bz2 2&gt;/dev/null&quot;);
++ system(&quot;gunzip *.gz 2&gt;/dev/null&quot;);
++
++ my (@to_remove, @to_add, @to_add_binary);
++ foreach my $line (`cvs -nq update`) {
++ if ($line =~ /^\? (\S+)/) {
++ if (-B $1) {
++ push(@to_add_binary, $1);
++ } else {
++ push(@to_add, $1);
++ }
++ }
++ if ($line =~ /^U (\S+)/) {
++ push(@to_remove, $1);
++ }
++ }
++ if (@to_remove) {
++ my $to_remove = join(' ', @to_remove);
++ print &quot;removing file(s) $to_remove\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q remove $to_remove&quot;);
++ }
++ if (@to_add) {
++ my $to_add = join(' ', @to_add);
++ print &quot;adding text file(s) $to_add\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q add $to_add&quot;);
++ }
++ if (@to_add_binary) {
++ my $to_add_binary = join(' ', @to_add_binary);
++ print &quot;adding binary file(s) $to_add_binary\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q add -kb $to_add_binary&quot;);
++ }
++
++ print &quot;committing current directory\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q commit -m $version-$release&quot;) unless $self-&gt;{_test};
++
++ # tag new release
++ my $tag = &quot;r$version-$release&quot;;
++ $tag =~ s/\./_/g;
++ print &quot;tagging current directory as $tag\n&quot; if $self-&gt;{_verbose};
++ system(&quot;cvs -Q tag $tag&quot;) unless $self-&gt;{_test};
++
++ # get back to original directory
++ chdir $original_dir;
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionCleanpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Clean.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,40 @@
++# $Id: Clean.pm 4742 2007-01-30 09:49:58Z pixel $
++package Youri::Submit::Action::Clean;
++
++=head1 NAME
++
++Youri::Submit::Action::Clean - Old revisions cleanup
++
++=head1 DESCRIPTION
++
++This action plugin ensures cleanup of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ foreach my $replaced_package (
++ $repository-&gt;get_replaced_packages($package, $target, $define)
++ ) {
++ my $file = $replaced_package-&gt;as_file();
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionDkmsModuleInfopm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/DkmsModuleInfo.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,111 @@
++# $Id$
++package Youri::Submit::Action::DkmsModuleInfo;
++
++=head1 NAME
++
++Youri::Submit::Action::DkmsModuleInfo - extract and commit info from dkms package.
++
++=head1 DESCRIPTION
++
++This action plugin extract modalias and description from dkms packages and commit them
++on a SVN module.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++use File::Temp qw/tempdir/;
++use File::Basename;
++use SVN::Client;
++
++#- inlineed from MDK::Common::Various
++sub chomp_ { my @l = @_; chomp @l; wantarray() ? @l : $l[0] }
++
++sub _init {
++ my ($self, %options) = @_;
++
++ croak &quot;undefined svn module&quot; unless $options{svn_module};
++
++ foreach my $var ('svn_module') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my ($dkms_name) = $package-&gt;get_canonical_name =~ /^dkms-(.*)$/ or return;
++ my $package_name = $package-&gt;get_name;
++ my ($kver) = $package_name =~ /^$dkms_name-kernel-(.*)$/ or return;
++
++ my @files = map { $_-&gt;[0] } $package-&gt;get_files;
++ my @module_files = grep { m!^(/lib/modules/|/var/lib/dkms-binary/).*\.ko(\.gz)?$! } @files
++ or return;
++
++ print &quot;Submit::Action::DkmsModuleInfo: proceeding with $package_name\n&quot; if $self-&gt;{_verbose};
++
++ my $tempdir = tempdir(CLEANUP =&gt; 1);
++ my $file = $package-&gt;as_file;
++ my $cmd = &quot;rpm2cpio $file | (cd $tempdir ; cpio --quiet -id)&quot;;
++ print &quot;Submit::Action::DkmsModuleInfo: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (system($cmd) != 0) {
++ print &quot;Submit::Action::DkmsModuleInfo: failed!\n&quot; if $self-&gt;{_verbose};
++ return;
++ }
++
++ my @fields = qw(description alias);
++
++ my (%modules);
++ foreach my $file (@module_files) {
++ print &quot;Submit::Action::DkmsModuleInfo: extracting $file\n&quot; if $self-&gt;{_verbose};
++ my $module = $file;
++ $module =~ s!.*/!!;
++ $module =~ s!\.ko(\.gz)$!!;
++ $modules{$module}{$_} = [ chomp_(`/sbin/modinfo -F $_ $tempdir$file`) ]
++ foreach @fields;
++ }
++
++ eval {
++ my $svn = SVN::Client-&gt;new();
++ my $dir = $tempdir . '/' . basename($self-&gt;{_svn_module});
++ my $revision = $svn-&gt;checkout($self-&gt;{_svn_module}, $dir, 'HEAD', 0);
++ my $vdir = $dir . '/' . $kver;
++ $svn-&gt;update($vdir, 'HEAD', 0);
++ -d $vdir or $svn-&gt;mkdir($vdir);
++ foreach my $module (keys %modules) {
++ print &quot;Submit::Action::DkmsModuleInfo: adding module $module\n&quot; if $self-&gt;{_verbose};
++ foreach my $field (@fields) {
++ my $file = &quot;$vdir/$module.$field&quot;;
++ $svn-&gt;update($file, 'HEAD', 0);
++ my $exists = -f $file;
++ open(my $fh, &quot;&gt;&quot;, $file);
++ print $fh map { &quot;$_\n&quot; } @{$modules{$module}{$field}};
++ $svn-&gt;add($file, 1) if !$exists;
++ }
++ }
++
++ $svn-&gt;log_msg(sub { $_[0] = \&quot;add dkms info for $dkms_name with kernel $kver&quot; });
++ $svn-&gt;commit($vdir, 0);
++ };
++ if (my $error = $@) {
++ print &quot;Submit::Action::DkmsModuleInfo: commit to svn failed ($error)!\n&quot; if $self-&gt;{_verbose};
++ return;
++ }
++
++ 1;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionInstallpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Install.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,74 @@
++# $Id: Install.pm 229772 2007-09-26 11:21:07Z blino $
++package Youri::Submit::Action::Install;
++
++=head1 NAME
++
++Youri::Submit::Action::Install - Package installation
++
++=head1 DESCRIPTION
++
++This action plugin ensures installation of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;as_file();
++ my $rpm = $package-&gt;get_file_name();
++ my $dest = $repository-&gt;get_install_dir($package, $target, $define);
++
++ # FIXME remove prefix this should be done by a function
++ $rpm =~ s/^\d{14}\.\w*\.\w+\.\d+_//;
++ $rpm =~ s/^\@\d+://;
++ print &quot;installing file $file to $dest/$rpm\n&quot; if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ if (! -d $dest) {
++ my $status =
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest&quot;);
++ croak &quot;Unable to create directory $dest: $?&quot; if $status;
++ }
++
++ # install file to new location
++ my $status =
++ system(&quot;install -m $self-&gt;{_perms} $file $dest/$rpm&quot;);
++ croak &quot;Unable to install file $file to $dest/$rpm: $?&quot; if $status;
++
++ my $arch = $package-&gt;get_arch();
++ $repository-&gt;set_arch_changed($target, $arch);
++ $repository-&gt;set_install_dir_changed($dest);
++ }
++ $package-&gt;{_file} = &quot;$dest/$rpm&quot;;
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionLinkpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Link.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,80 @@
++# $Id: Link.pm 233641 2008-01-31 16:35:55Z pixel $
++package Youri::Submit::Action::Link;
++
++=head1 NAME
++
++Youri::Submit::Action::Link - Noarch packages linking
++
++=head1 DESCRIPTION
++
++This action plugin ensures linking of noarch packages between arch-specific
++directories.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Cwd;
++use File::Spec;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ symbolic =&gt; 0, # use symbolic linking
++ @_
++ );
++
++ $self-&gt;{_symbolic} = $options{symbolic};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # only needed for noarch packages
++ return unless $package-&gt;get_arch() eq 'noarch';
++
++ my $default_dir = $repository-&gt;get_install_dir($package, $target, $define);
++ my $file = $package-&gt;get_file_name();
++
++ # FIXME remove prefix this should be done by a function
++ $file =~ s/^\d{14}\.\w*\.\w+\.\d+_//;
++ $file =~ s/^\@\d+://;
++
++ foreach my $arch ($repository-&gt;get_extra_arches()) {
++ # compute installation target, forcing arch
++ my $other_dir = $repository-&gt;get_install_dir(
++ $package,
++ $target,
++ $define,
++ { arch =&gt; $arch }
++ );
++
++ if (! $self-&gt;{_test}) {
++ my $current_dir = cwd();
++ chdir $other_dir;
++ my $default_file = File::Spec-&gt;abs2rel($default_dir) . '/' . $file;
++ if ($self-&gt;{_symbolic}) {
++ symlink $default_file, $file;
++ } else {
++ link $default_file, $file;
++ }
++ chdir $current_dir;
++ print &quot;set_install_dir_changed($other_dir) for updated $file\n&quot;;
++ $repository-&gt;set_install_dir_changed($other_dir);
++ $repository-&gt;set_arch_changed($target, $arch);
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionMailpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Mail.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,131 @@
++# $Id: Mail.pm 223952 2007-06-23 13:54:13Z pixel $
++package Youri::Submit::Action::Mail;
++
++=head1 NAME
++
++Youri::Submit::Action::Mail - Mail notification
++
++=head1 DESCRIPTION
++
++This action plugin ensures mail notification of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use MIME::Entity;
++use Encode qw/from_to/;
++use Carp;
++use Youri::Package;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ mta =&gt; '/usr/sbin/sendmail',
++ to =&gt; '',
++ from =&gt; '',
++ cc =&gt; '',
++ prefix =&gt; '',
++ encoding =&gt; 'quoted-printable',
++ charset =&gt; 'iso-8859-1',
++ @_
++ );
++
++ croak &quot;undefined mail MTA&quot; unless $options{mta};
++ croak &quot;invalid mail MTA $options{mta}&quot; unless -x $options{mta};
++ croak &quot;undefined to&quot; unless $options{to};
++ if ($options{cc}) {
++ croak &quot;cc should be an hashref&quot; unless ref $options{cc} eq 'HASH';
++ }
++ croak &quot;invalid charset $options{charset}&quot;
++ unless Encode::resolve_alias($options{charset});
++
++ $self-&gt;{_mta} = $options{mta};
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_from} = $options{from};
++ $self-&gt;{_cc} = $options{cc};
++ $self-&gt;{_prefix} = $options{prefix};
++ $self-&gt;{_encoding} = $options{encoding};
++ $self-&gt;{_charset} = $options{charset};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $from = $package-&gt;get_packager();
++
++ # force from adress if defined
++ $from =~ s/&lt;.*&gt;/&lt;$self-&gt;{_from}&gt;/ if $self-&gt;{_from};
++
++ my $subject = $self-&gt;get_subject($package, $repository, $target, $define);
++ my $content = $self-&gt;get_content($package, $repository, $target, $define);
++
++ # ensure proper codeset conversion
++ # for informations coming from package
++ my $charset = $repository-&gt;get_package_charset();
++ from_to($content, $charset, $self-&gt;{_charset});
++ from_to($subject, $charset, $self-&gt;{_charset});
++
++ my $mail = MIME::Entity-&gt;build(
++ Type =&gt; 'text/plain',
++ Charset =&gt; $self-&gt;{_charset},
++ Encoding =&gt; $self-&gt;{_encoding},
++ From =&gt; $from,
++ To =&gt; $self-&gt;{_to},
++ Subject =&gt; $subject,
++ Data =&gt; $content,
++ );
++
++ if ($self-&gt;{_cc}) {
++ my $cc = $self-&gt;{_cc}-&gt;{$package-&gt;get_name()};
++ $mail-&gt;head()-&gt;add('cc', $cc) if $cc;
++ }
++
++ if ($self-&gt;{_test}) {
++ $mail-&gt;print(\*STDOUT);
++ } else {
++ open(MAIL, &quot;| $self-&gt;{_mta} -t -oi -oem&quot;) or die &quot;Can't open MTA program: $!&quot;;
++ $mail-&gt;print(\*MAIL);
++ close MAIL;
++ }
++
++}
++
++sub get_subject {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ return
++ ($self-&gt;{_prefix} ? '[' . $self-&gt;{_prefix} . '] ' : '' ) .
++ &quot;$target &quot; . ($section ? &quot;$section &quot; : '' ) .
++ $package-&gt;as_formated_string('%{name}-%{version}-%{release}');
++}
++
++sub get_content {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $information = $package-&gt;get_information();
++ my $last_change = $package-&gt;get_last_change();
++
++ return
++ $information . &quot;\n&quot; .
++ $last_change-&gt;[Youri::Package::CHANGE_AUTHOR] . &quot;:\n&quot; .
++ $last_change-&gt;[Youri::Package::CHANGE_TEXT];
++}
++
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionMarkreleasepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Markrelease.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,56 @@
++# $Id: Markrelease.pm 4743 2007-01-30 09:58:30Z pixel $
++package Youri::Submit::Action::Markrelease;
++
++=head1 NAME
++
++Youri::Submit::Action::Markrelease - calls markrelease
++
++=head1 DESCRIPTION
++
++This action plugin calls markrelease
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $package-&gt;is_source or return 1;
++ my $file = $package-&gt;get_file();
++ my $srpm_name = $package-&gt;get_canonical_name;
++
++ if ($repository-&gt;package_in_svn($srpm_name)) {
++ my $svn = $repository-&gt;get_svn_url();
++ my ($rev) = $file =~ /.*\/.*?\@(\d+):/;
++ print &quot;Run repsys markrelease -f $file -r $rev $svn/$srpm_name\n&quot;;
++ # FIXME repsys ask for a username and password
++ # FIXME we should use the key in /var/home/mandrake so that /home/mandrake does not
++ # need to be mounted
++ system('repsys', 'markrelease', '-f', $file, '-r', $rev, &quot;$svn/$srpm_name&quot;);
++ }
++ 1
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionRSSpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/RSS.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,102 @@
++# $Id: RSS.pm 1700 2006-10-16 12:57:42Z warly $
++package Youri::Submit::Action::RSS;
++
++=head1 NAME
++
++Youri::Submit::Action::RSS - RSS notification
++
++=head1 DESCRIPTION
++
++This action plugin ensures RSS notification of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use XML::RSS;
++use Encode qw/from_to/;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ file =&gt; '',
++ title =&gt; '',
++ link =&gt; '',
++ description =&gt; '',
++ charset =&gt; 'iso-8859-1',
++ max_items =&gt; 10,
++ @_
++ );
++
++ croak &quot;undefined rss file&quot; unless $options{file};
++ croak &quot;invalid charset $options{charset}&quot;
++ unless Encode::resolve_alias($options{charset});
++
++ $self-&gt;{_file} = $options{file};
++ $self-&gt;{_title} = $options{title};
++ $self-&gt;{_link} = $options{link};
++ $self-&gt;{_description} = $options{description};
++ $self-&gt;{_charset} = $options{charset};
++ $self-&gt;{_max_items} = $options{max_items};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $package-&gt;is_source();
++
++ my $subject = $package-&gt;as_formated_string('%{name}-%{version}-%{release}');
++ my $content = $package-&gt;get_information();
++
++ $content =~ s/$/&lt;br\/&gt;/mg;
++
++ # ensure proper codeset conversion
++ # for informations coming from package
++ my $charset = $repository-&gt;get_package_charset();
++ from_to($content, $charset, $self-&gt;{_charset});
++ from_to($subject, $charset, $self-&gt;{_charset});
++
++ my $rss = XML::RSS-&gt;new(
++ encoding =&gt; $self-&gt;{_charset},
++ encode_output =&gt; 1
++ );
++
++ my $file = $self-&gt;{_file};
++ if (-e $file) {
++ $rss-&gt;parsefile($file);
++ splice(@{$rss-&gt;{items}}, $self-&gt;{_max_items})
++ if @{$rss-&gt;{items}} &gt;= $self-&gt;{_max_items};
++ } else {
++ $rss-&gt;channel(
++ title =&gt; $self-&gt;{_title},
++ link =&gt; $self-&gt;{_link},
++ description =&gt; $self-&gt;{_description},
++ language =&gt; 'en'
++ );
++ }
++
++ $rss-&gt;add_item(
++ title =&gt; $subject,
++ description =&gt; $content,
++ mode =&gt; 'insert'
++ );
++
++ if ($self-&gt;{_test}) {
++ print $rss-&gt;as_string();
++ } else {
++ $rss-&gt;save($file);
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionRpminfopm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Rpminfo.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,69 @@
++# $Id: Rpminfo.pm 4742 2007-01-30 09:49:58Z pixel $
++package Youri::Submit::Action::Rpminfo;
++
++=head1 NAME
++
++Youri::Submit::Action::RpmInfo - Creates .info files
++
++=head1 DESCRIPTION
++
++This action plugin ensures the creation of .info files
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ uphost =&gt; '',
++ user =&gt; '',
++ ssh_key =&gt; '',
++ verbose =&gt; '',
++ @_
++ );
++ croak &quot;undefined upload host&quot; unless $options{uphost};
++ croak &quot;undefined ssh key&quot; unless $options{ssh_key};
++
++ foreach my $var ('perms', 'user', 'uphost', 'ssh_key', 'verbose') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $dest = $repository-&gt;get_upload_dir($package, $target, $define);
++
++ print &quot;Caching rpm information $file on $dest\n&quot; if $self-&gt;{_verbose};
++ my $base = basename ($file);
++ $dest =~ s/\/[0-9]{14}\./\/*./;
++
++ my $cmd = &quot;ssh -i $self-&gt;{_ssh_key} $self-&gt;{_user}\@$self-&gt;{_uphost} \&quot;srpm=`echo /$dest$base`; rpm -q --qf '\%{name}\n\%{epoch}\n\%{version}-\%{release}\n\%{summary}\n' -p \\\$srpm &gt; \\\$srpm.info\&quot;&quot;;
++ print &quot;Submit::Action::RpmInfo: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ if (!system($cmd)) {
++ print &quot;Submit::Action::RpmInfo: rpminfo succeeded!\n&quot;;
++ return 1
++ }
++ print &quot;Submit::Action::RpmInfo: rpminfo failed!\n&quot;;
++ }
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionSendpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Send.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,77 @@
++# $Id: Send.pm 4744 2007-01-30 09:59:07Z pixel $
++package Youri::Submit::Action::Send;
++
++=head1 NAME
++
++Youri::Submit::Action::Send - upload package
++
++=head1 DESCRIPTION
++
++This action plugin uploads the package on uphost
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ uphost =&gt; '',
++ user =&gt; '',
++ ssh_key =&gt; '',
++ verbose =&gt; '',
++ keep_svn_release =&gt; '',
++ @_
++ );
++ croak &quot;undefined upload host&quot; unless $options{uphost};
++ croak &quot;undefined ssh key&quot; unless $options{ssh_key};
++
++ foreach my $var ('perms', 'user', 'uphost', 'ssh_key', 'verbose', 'keep_svn_release') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $dest = $repository-&gt;get_upload_dir($package, $target, $define);
++
++ print &quot;Sending file $file to $dest\n&quot; if $self-&gt;{_verbose};
++ my $base;
++ if ($self-&gt;{_keep_svn_release}) {
++ $base = basename($file)
++ } else {
++ ($base) = $file =~ /.*\/(?:@\d+:)?([^\/]*)/
++ }
++
++ my $cmd = &quot;scp -i $self-&gt;{_ssh_key} $file $self-&gt;{_user}\@$self-&gt;{_uphost}:/$dest$base.new&quot;;
++ my $cmd2 = &quot;ssh -i $self-&gt;{_ssh_key} $self-&gt;{_user}\@$self-&gt;{_uphost} \&quot;mv /$dest$base.new /$dest$base\&quot;&quot;;
++ print &quot;Submit::Action::Send: doing $cmd\n$cmd2\n&quot; if 1 || $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ if (!system($cmd)) {
++ if (!system($cmd2)) {
++ print &quot;Submit::Action::Send: upload succeeded!\n&quot;;
++ return 1
++ }
++ }
++ print &quot;Submit::Action::Send: upload failed!\n&quot;;
++ }
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionSendcachepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sendcache.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,81 @@
++# $Id: Sendcache.pm 232350 2007-12-07 18:26:17Z spuk $
++package Youri::Submit::Action::Sendcache;
++
++=head1 NAME
++
++Youri::Submit::Action::Sendcache - upload package to cache
++
++=head1 DESCRIPTION
++
++This action plugin uploads the package on uphost
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ uphost =&gt; '',
++ user =&gt; '',
++ ssh_key =&gt; '',
++ verbose =&gt; '',
++ root =&gt; '',
++ debug_pkgs =&gt; 0,
++ @_
++ );
++ croak &quot;undefined upload host&quot; unless $options{uphost};
++ croak &quot;undefined ssh key&quot; unless $options{ssh_key};
++
++ foreach my $var ('perms', 'user', 'uphost', 'ssh_key', 'verbose', 'root', 'debug_pkgs') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # only cache debug packages if option debug_pkgs is true
++ return if ($package-&gt;is_debug() &amp;&amp; !$self-&gt;{_debug_pkgs});
++
++ my $file = $package-&gt;get_file();
++ my $dest = $repository-&gt;get_upload_dir($package, $target, $define);
++ $dest =~ s!$repository-&gt;{_upload_root}/$repository-&gt;{_queue}!$self-&gt;{_root}!;
++
++ print &quot;Sending file $file to $dest\n&quot; if $self-&gt;{_verbose};
++ my $destfile = &quot;$dest&quot;.basename($file);
++ $destfile =~ s,/[^/_]+_([^/]+)$,/$1,;
++ $destfile =~ s,/@\d+:,/,;
++ my $destfilehidden = $destfile;
++ $destfilehidden =~ s,/([^/]+)$,/.$1,;
++
++ my $cmd = &quot;scp -i $self-&gt;{_ssh_key} $file $self-&gt;{_user}\@$self-&gt;{_uphost}:/$destfilehidden&quot;;
++ my $cmd2 = &quot;ssh -i $self-&gt;{_ssh_key} $self-&gt;{_user}\@$self-&gt;{_uphost} \&quot;mv /$destfilehidden /$destfile\&quot;&quot;;
++ print &quot;Submit::Action::Send: doing $cmd\n$cmd2\n&quot; if 1 || $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ if (!system($cmd)) {
++ if (!system($cmd2)) {
++ print &quot;Submit::Action::Sendcache: upload succeeded!\n&quot;;
++ return 1
++ }
++ }
++ print &quot;Submit::Action::Sendcache: upload failed!\n&quot;;
++ }
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionSignpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Sign.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,56 @@
++# $Id: Sign.pm 1700 2006-10-16 12:57:42Z warly $
++package Youri::Submit::Action::Sign;
++
++=head1 NAME
++
++Youri::Submit::Action::Sign - GPG signature
++
++=head1 DESCRIPTION
++
++This action plugin ensures GPG signature of packages.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ name =&gt; '',
++ path =&gt; $ENV{HOME} . '/.gnupg',
++ passphrase =&gt; '',
++ @_
++ );
++
++ croak &quot;undefined name&quot; unless $options{name};
++ croak &quot;undefined path&quot; unless $options{path};
++ croak &quot;invalid path $options{path}&quot; unless -d $options{path};
++
++ $self-&gt;{_name} = $options{name};
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_passphrase} = $options{passphrase};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $package-&gt;sign(
++ $self-&gt;{_name},
++ $self-&gt;{_path},
++ $self-&gt;{_passphrase}
++ ) unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionUnpackpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/Unpack.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,82 @@
++# $Id: Unpack.pm 115370 2007-01-30 09:59:07Z pixel $
++package Youri::Submit::Action::Unpack;
++
++=head1 NAME
++
++Youri::Submit::Action::Unpack - unpack package files
++
++=head1 DESCRIPTION
++
++This action plugin unpack package files somewhere.
++When unpack_inside_distribution_root is set, dest_directory is relative to the distribution root.
++When the package is a noarch, the wanted files are unpacked in distribution root of each archs.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Temp qw/tempdir/;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my ($self, %options) = @_;
++
++ croak &quot;undefined package name&quot; unless $options{name};
++ croak &quot;undefined source sub directory&quot; unless $options{source_subdir};
++ croak &quot;undefined destination directory&quot; unless $options{dest_directory};
++
++ foreach my $var ('name', 'dest_directory', 'source_subdir', 'grep_files', 'unpack_inside_distribution_root') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $package-&gt;get_name eq $self-&gt;{_name} or return;
++
++ my @dests = $self-&gt;{_unpack_inside_distribution_root} ?
++ (map { &quot;$_/$self-&gt;{_dest_directory}&quot; } $repository-&gt;get_distribution_roots($package, $target))
++ : $self-&gt;{_dest_directory};
++ my $file = $package-&gt;as_file;
++ print &quot;Unpacking rpm $file$self-&gt;{_source_subdir} to @dests\n&quot; if $self-&gt;{_verbose};
++
++ my $tempdir = tempdir(CLEANUP =&gt; 1);
++
++ my $cmd = &quot;rpm2cpio $file | (cd $tempdir ; cpio -id)&quot;;
++ print &quot;Submit::Action::Unpack: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (!$self-&gt;{_test} &amp;&amp; system($cmd) != 0) {
++ print &quot;Submit::Action::Unpack: failed!\n&quot; if $self-&gt;{_verbose};
++ return;
++ }
++
++ foreach my $dest (@dests) {
++ my $find_grep = $self-&gt;{_grep_files} ? &quot;find | grep '$self-&gt;{_grep_files}'&quot; : 'find';
++ my $cmd = &quot;cd $tempdir/$self-&gt;{_source_subdir}; $find_grep | cpio -pdu $dest&quot;;
++ print &quot;Submit::Action::Unpack: doing $cmd\n&quot; if $self-&gt;{_verbose};
++ if (!$self-&gt;{_test}) {
++ my @l = glob(&quot;$tempdir/$self-&gt;{_source_subdir}&quot;);
++ if (@l == 1 &amp;&amp; -d $l[0]) {
++ if (system($cmd) != 0) {
++ print &quot;Submit::Action::Unpack: failed!\n&quot; if $self-&gt;{_verbose};
++ }
++ } else {
++ print &quot;Submit::Action::Unpack: directory $self-&gt;{_source_subdir} doesn't exist in package $self-&gt;{_name}\n&quot;;
++ }
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionUpdateMdvDbpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action/UpdateMdvDb.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,62 @@
++# $Id$
++package Youri::Submit::Action::UpdateMdvDb;
++
++=head1 NAME
++
++Youri::Submit::Action::UpdateMdvDb - Mandriva maintainers database updater
++
++=head1 DESCRIPTION
++
++This action plugin calls an external script to update last commit info, as
++well as add new packages, in the package maintainers database at
++&lt;http://maint.mandriva.com/&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Action/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++
++ # path for mdvdb-updaterep script
++ $self-&gt;{_mdvdb_updaterep} = $options{mdvdb_updaterep};
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # only SRPMs matter
++ return unless $package-&gt;is_source();
++
++ unless ($self-&gt;{_test}) {
++ my $pkg_name = $package-&gt;get_name();
++ my $pkg_media = $repository-&gt;_get_main_section($package, $target, $define);
++ $package-&gt;get_packager() =~ m/(\w[-_.\w]+\@[-_.\w]+)\W/;
++ my $pkg_commiter = $1;
++
++ if (system($self-&gt;{_mdvdb_updaterep}, &quot;update&quot;, $pkg_name, $pkg_media, $pkg_commiter, &quot;youri&quot;)) {
++ print &quot;ERROR: &quot;.$self-&gt;{_mdvdb_updaterep}.&quot; failed for '$pkg_name', '$pkg_media', '$pkg_commiter'.\n&quot;;
++ } else {
++ print &quot;Updated package maintainers DB for '$pkg_name', '$pkg_media', '$pkg_commiter'.\n&quot; if $self-&gt;{_verbose};
++ }
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2007, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitActionpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Action.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Base.pm 631 2006-01-26 22:22:23Z guillomovitch $
++package Youri::Submit::Action;
++
++=head1 NAME
++
++Youri::Submit::Action - Abstract action plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines action plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckACLpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/ACL.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,71 @@
++# $Id: ACL.pm 4817 2007-02-09 19:39:05Z blino $
++package Youri::Submit::Check::ACL;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++my $acl;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ acl_file =&gt; '',
++ @_
++ );
++ $acl = get_acl($options{acl_file});
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $file = $package-&gt;get_full_name();
++ my $arch = $package-&gt;get_arch();
++ my $srpm = $package-&gt;get_canonical_name;
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ my $user = $define-&gt;{user};
++ foreach my $t (keys %$acl) {
++ next if $target !~ /$t/;
++ foreach my $acl (@{$acl-&gt;{$t}}) {
++ my ($a, $media, $r, $users) = @$acl;
++ next if $arch !~ $a || $srpm !~ $r || $section !~ $media;
++ if ($user =~ /$users/) {
++ return
++ } else {
++ return &quot;$user is not authorized to upload packages belonging to $srpm in section $section (authorized persons: &quot; . join(', ', split '\|', $users) . &quot;)&quot;;
++ }
++ }
++ }
++ return
++}
++
++sub get_acl {
++ my ($file) = @_;
++ my %acl;
++ open my $f, $file;
++ while (&lt;$f&gt;) {
++ my ($dis, $arch, $media, $regexp, $users) = split ' ';
++ push @{$acl{$dis}}, [ $arch , $media, $regexp, $users ]
++ }
++ \%acl
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckHistorypm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/History.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,61 @@
++# $Id: History.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::History;
++
++=head1 NAME
++
++Youri::Submit::Check::History - Non-linear history check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose history does not include last
++available revision one.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Package;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $last_revision =
++ $repository-&gt;get_last_older_revision($package, $target, $define);
++
++ if ($last_revision) {
++ # skip the test if last revision has been produced from another source package, as it occurs during package split/merges
++ return
++ if $last_revision-&gt;get_canonical_name()
++ ne $package-&gt;get_canonical_name();
++
++ my ($last_revision_number) = $last_revision-&gt;get_last_change()-&gt;[Youri::Package::CHANGE_AUTHOR] =~ /(\S+)\s*$/;
++ my %entries =
++ map { $_ =&gt; 1 }
++ map { /(\S+)\s*$/ }
++ map { $_-&gt;[Youri::Package::CHANGE_AUTHOR] }
++ $package-&gt;get_changes();
++ unless ($entries{$last_revision_number}) {
++ push(
++ @errors,
++ &quot;Last changelog entry $last_revision_number from last revision &quot; . $last_revision-&gt;get_full_name() . &quot; missing from current changelog&quot;
++ );
++ }
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckHostpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Host.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,63 @@
++# $Id: Host.pm 230850 2007-10-04 20:07:25Z blino $
++package Youri::Submit::Check::Host;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++my $host;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ host_file =&gt; '',
++ @_
++ );
++ $host = get_host($options{host_file})
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $file = $package-&gt;get_file;
++ my $arch = $package-&gt;get_arch;
++ my $buildhost = $package-&gt;as_formated_string('%{buildhost}');
++ foreach my $h (keys %$host) {
++ next if $buildhost !~ $h;
++ if ($arch =~ $host-&gt;{$h}) {
++ return
++ }
++ }
++ &quot;Packages build on host $buildhost are not authorized for arch $arch&quot;;
++}
++
++sub get_host {
++ my ($file) = @_;
++ my %host;
++ open my $f, $file;
++ while (&lt;$f&gt;) {
++ my ($host, $arch) = split ' ';
++ $host{$host} = $arch
++ }
++ \%host
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckPrecedencepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Precedence.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,58 @@
++# $Id: Precedence.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::Precedence;
++
++=head1 NAME
++
++Youri::Submit::Check::Precedence - Release check against another check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose an older revision already exists for
++another upload target.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ _target =&gt; undef, # mandatory targets
++ @_
++ );
++
++ die &quot;undefined target&quot; unless $options{target};
++
++ $self-&gt;{_target} = $options{target};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my @older_revisions =
++ $repository-&gt;get_older_revisions($package, $self-&gt;{_target}, $define);
++ if (@older_revisions) {
++ push(
++ @errors,
++ &quot;Older revisions still exists for $self-&gt;{_target}: &quot; . join(', ', @older_revisions)
++ );
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckQueue_recencypm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Queue_recency.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,40 @@
++# $Id: Queue_recency.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::Queue_recency;
++
++=head1 NAME
++
++Youri::Submit::Check::Recency - Release check against current target
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose a current or newer revision already
++exists for current upload target.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @newer_revisions =
++ $repository-&gt;get_upload_newer_revisions($package, $target, $define);
++ if (@newer_revisions) {
++ return &quot;Newer revisions already exists for $target in upload queue: &quot; . join(', ', @newer_revisions);
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckRecencypm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Recency.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,64 @@
++# $Id: Recency.pm 224793 2007-07-08 02:44:48Z spuk $
++package Youri::Submit::Check::Recency;
++
++=head1 NAME
++
++Youri::Submit::Check::Recency - Release check against current target
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages whose a current or newer revision already
++exists for current upload target.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my @revisions = $repository-&gt;get_revisions($package, $target, $define, undef, sub { return $_[0]-&gt;compare($package) &gt;= 0 });
++ if (@revisions) {
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ push(
++ @errors,
++ &quot;Current or newer revision(s) already exists in $section for $target: &quot; .
++ join(', ', @revisions)
++ );
++ }
++
++ my $defined_section = $define-&gt;{section};
++
++ # if the user provided a section, check also in the default section
++ if ($defined_section) {
++ $define-&gt;{section} = undef;
++ my @default_revisions = $repository-&gt;get_revisions($package, $target, $define, undef, sub { return $_[0]-&gt;compare($package) &gt;= 0 });
++ if (@default_revisions) {
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ push(
++ @errors,
++ &quot;Current or newer revision(s) already exists in $section for $target: &quot; .
++ join(', ', @default_revisions)
++ );
++ }
++ $define-&gt;{section} = $defined_section;
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckRpmlintpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Rpmlint.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,90 @@
++# $Id: Rpmlint.pm 234384 2008-02-12 09:42:32Z blino $
++package Youri::Submit::Check::Rpmlint;
++
++=head1 NAME
++
++Youri::Submit::Check::Rpmlint - Rpmlint-based check
++
++=head1 DESCRIPTION
++
++This check plugin wraps rpmlint, and reject packages triggering results
++declared as fatal.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Submit::Check::Rpmlint object.
++
++Specific parameters:
++
++=over
++
++=item results $results
++
++List of rpmlint result id considered as fatal.
++
++=item path $path
++
++Path to the rpmlint executable (default: /usr/bin/rpmlint)
++
++=item config $config
++
++Specific rpmlint configuration.
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ results =&gt; undef,
++ path =&gt; '/usr/bin/rpmlint',
++ config =&gt; '',
++ @_
++ );
++
++ croak &quot;no results to check&quot; unless $options{results};
++ croak &quot;fatal should be an arrayref&quot; unless ref $options{results} eq 'ARRAY';
++
++ $self-&gt;{_config} = $options{config};
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_pattern} = '^(?:' . join('|', @{$options{results}}) . ')$';
++}
++
++sub run {
++ my ($self, $package, $_repository, $_target, $_define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $command = &quot;$self-&gt;{_path} -f $self-&gt;{_config} &quot; . $package-&gt;as_file;
++ open(my $RPMLINT, &quot;$command |&quot;) or die &quot;Can't run $command: $!&quot;;
++ while (my $line = &lt;$RPMLINT&gt;) {
++ $line =~ /^[EW]: \S+ (\S+)(.*)$/ # old rpmlint format
++ || $line =~ /^\S+: [EW]: (\S+)(.*)$/ or next; # new rpmlint format
++ my ($id, $value) = ($1, $2);
++ if ($id =~ /$self-&gt;{_pattern}/o) {
++ push(@errors, &quot;$id$value&quot;);
++ }
++ }
++
++ return @errors;
++}
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under
++the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckSVNpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/SVN.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,79 @@
++# $Id: SVN.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::SVN;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ svn =&gt; '',
++ @_
++ );
++ $self-&gt;{_svn} = $options{svn};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ if ($section =~ /\/(testing|backport)$/) {
++ # FIXME, right now ignore packages in SVN for testing and backports
++ # we need to find a clean way to handle them
++ return
++ }
++
++ $package-&gt;is_source or return;
++ my $file = $package-&gt;get_file_name;
++ my $srpm_name = $package-&gt;get_canonical_name;
++ if ($repository-&gt;package_in_svn($srpm_name)) {
++ if ($file !~ /(^|\/|$define-&gt;{prefix}_)@\d+:\Q$srpm_name/) {
++ return &quot;package $srpm_name is in the SVN, the uploaded SRPM must look like @&lt;svn rev&gt;:$srpm_name-&lt;version&gt;-&lt;release&gt;.src.rpm (created with getsrpm-mdk $srpm_name)&quot;;
++ } else {
++ print &quot;Package $file is correct\n&quot;;
++ }
++ }
++ return
++}
++
++sub simple_prompt {
++ my $cred = shift;
++ my $realm = shift;
++ my $default_username = shift;
++ my $may_save = shift;
++ my $pool = shift;
++
++ print &quot;Enter authentication info for realm: $realm\n&quot;;
++ print &quot;Username: &quot;;
++ my $username = &lt;&gt;;
++ chomp($username);
++ $cred-&gt;username($username);
++ print &quot;Password: &quot;;
++ my $password = &lt;&gt;;
++ chomp($password);
++ $cred-&gt;password($password);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckSectionpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Section.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,58 @@
++# $Id: Precedence.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::Section;
++
++=head1 NAME
++
++Youri::Submit::Check::Section - Check if package was submitted to the right section
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages which were submitted to a section
++different than the one where an older version already exists.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $submitted_main_section = $repository-&gt;_get_main_section($package, $target, $define);
++
++ # undefine section, so that Repository::_get_section() of Mandriva_upload.pm
++ # finds the section from existing packages
++ my $defined_section = $define-&gt;{section};
++ undef $define-&gt;{section};
++
++ my $old_main_section = $repository-&gt;_get_main_section($package, $target, $define);
++ my @older_revisions = $repository-&gt;get_older_revisions($package, $target, $define);
++
++ # restore defined section
++ $define-&gt;{section} = $defined_section;
++
++ if (@older_revisions &amp;&amp; $submitted_main_section ne $old_main_section) {
++ push(
++ @errors,
++ &quot;Section should be $old_main_section, not $submitted_main_section.&quot;
++ );
++ }
++
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2007, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckSourcepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Source.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,45 @@
++# $Id: Source.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::Source;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $file = $package-&gt;as_file();
++ if (!$package-&gt;is_source()) {
++ return &quot;Package $file is not a source rpm&quot;;
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckTagpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Tag.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,61 @@
++# $Id: Tag.pm 1707 2006-10-16 16:26:42Z warly $
++package Youri::Submit::Check::Tag;
++
++=head1 NAME
++
++Youri::Submit::Check::Tag - Incorrect tag values check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect tag values, based on regular
++expressions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ tags =&gt; undef, # expected tag values
++ @_
++ );
++
++ croak &quot;no tags to check&quot; unless $options{tags};
++ croak &quot;tag should be an hashref&quot; unless ref $options{tags} eq 'HASH';
++
++ $self-&gt;{_tags} = $options{tags};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ foreach my $tag (keys %{$self-&gt;{_tags}}) {
++ my $value = $package-&gt;get_tag($tag);
++ if ($value !~ /$self-&gt;{_tags}-&gt;{$tag}/) {
++ push(
++ @errors,
++ &quot;invalid value $value for tag $tag&quot;
++ );
++ }
++ }
++
++ return @errors;
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckTypepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Type.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,54 @@
++# $Id: Type.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Check::Type;
++
++=head1 NAME
++
++Youri::Submit::Check::Type - Type check
++
++=head1 DESCRIPTION
++
++This check plugin rejects packages with incorrect type.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ type =&gt; undef, # expected type
++ @_
++ );
++
++ croak &quot;no type to check&quot; unless $options{type};
++ croak &quot;invalid type value&quot; unless $options{type} =~ /^(?:source|binary)$/;
++
++ $self-&gt;{_type} = $options{type};
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @errors;
++
++ my $type = $package-&gt;get_type();
++ if ($type ne $self-&gt;{_type}) {
++ push(@errors, &quot;invalid type $type&quot;);
++ }
++
++ return @errors;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckVersionpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check/Version.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,102 @@
++# $Id: Version.pm 267050 2010-03-23 17:36:49Z nvigier $
++package Youri::Submit::Check::Version;
++
++=head1 NAME
++
++Youri::Submit::Check::Version - Check if older version already exist in cooker (used in freeze period)
++
++=head1 DESCRIPTION
++
++This check plugin rejects new version of packages if they are not mentioned as authorized
++in the configuration file or in a non frozen section.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use URPM;
++use base qw/Youri::Submit::Check/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++
++ foreach my $target (keys %options) {
++ $self-&gt;{$target} = $options{$target}
++ }
++}
++
++sub run {
++ my ($self, $package, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $opt = $self-&gt;{$target};
++ return if $opt-&gt;{mode} eq 'normal';
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++ my $name = $package-&gt;get_canonical_name;
++ return if $name =~ /$opt-&gt;{authorized_packages}/;
++ my $arch = $repository-&gt;get_arch($package, $target, $define);
++ return if $arch =~ /$opt-&gt;{authorized_arches}/;
++ if ($opt-&gt;{mode} eq 'version_freeze') {
++ return if $section =~ /$opt-&gt;{authorized_sections}/;
++ my $user = $define-&gt;{user};
++ return if $user =~ /^($opt-&gt;{authorized_users})$/;
++ my ($package_version) = $package =~ /-([^-]+)-[^-]+\.src$/;
++ $define-&gt;{arch} = 'src';
++ my @revisions = $repository-&gt;get_revisions($package, $target, $define, undef,
++ sub {
++ my ($version) = $_[0] =~ /-([^-]+)-[^-]+\.src$/;
++ URPM::ranges_overlap(&quot;== $version&quot;, &quot;&lt; $package_version&quot;)
++ }
++ );
++ $define-&gt;{arch} = '';
++ if (@revisions) {
++ return &quot;FREEZE, package @revisions of different versions exist in $target\n&quot;;
++ }
++ }
++ # FIXME: The following code is not working and must be reviewed.
++ elsif ($opt-&gt;{mode} eq 'freeze') {
++ my $user = $define-&gt;{user};
++ return if (defined($opt-&gt;{authorized_users}) &amp;&amp; $user =~ /^($opt-&gt;{authorized_users})$/);
++ # XXX: So freeze mode really only check for this exceptions?
++ if ($section !~ /$opt-&gt;{authorized_sections}/) {
++ return &quot;FREEZE: repository $target section $section is frozen, you can still submit your packages in testing\nTo do so use your.devel --define section=&lt;section&gt; $target &lt;package 1&gt; &lt;package 2&gt; ... &lt;package n&gt;&quot;;
++ }
++ } else {
++ # FIXME: Calls to get_source_package seems invalid nowadays.
++ # This results on $source having a null content.
++ my $source = $package-&gt;get_source_package;
++ my ($package_version) = $source =~ /-([^-]+)-[^-]+\.src\.rpm$/;
++ $define-&gt;{arch} = 'src';
++ # FIXME: get_revisions now expects the filter as the 5th element, and not the 4th.
++ my @revisions = $repository-&gt;get_revisions($package, $target, $define,
++ sub {
++ # FIXME: Calls to get_source_package seems invalid nowadays.
++ # This results on $source_package having a null content.
++ my $source_package = $_[0]-&gt;get_source_package;
++ my ($version) = $source_package =~ /-([^-]+)-[^-]+\.src\.rpm$/;
++ print STDERR &quot;Found version $version\n&quot;;
++ URPM::ranges_overlap(&quot;== $version&quot;, &quot;&lt; $package_version&quot;)
++ }
++ );
++ $define-&gt;{arch} = '';
++ if (@revisions) {
++ return &quot;FREEZE, package @revisions of different versions exist in $target\n&quot;;
++ }
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, YOURI project
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitCheckpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Check.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Base.pm 631 2006-01-26 22:22:23Z guillomovitch $
++package Youri::Submit::Check;
++
++=head1 NAME
++
++Youri::Submit::Check - Abstract check plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines check plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPluginpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Plugin.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,93 @@
++# $Id: Plugin.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Plugin;
++
++=head1 NAME
++
++Youri::Submit::Plugin - Abstract youri-submit plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines youri-submit plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Submit::Plugin object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns plugin identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 run($package, $repository, $target, $define)
++
++Execute action on given L&lt;Youri::Package&gt; object.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item run
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostCleanRpmsratepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/CleanRpmsrate.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,53 @@
++# $Id: CleanRpmsrate.pm 115367 2007-01-30 09:47:04Z pixel $
++package Youri::Submit::Post::CleanRpmsrate;
++
++=head1 NAME
++
++Youri::Submit::Post::CleanRpmsrate - calls clean-rpmsrate
++
++=head1 DESCRIPTION
++
++Calls clean-rpmsrate
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Post/;
++
++#- inlined from MDK::Common::DataStructure
++sub uniq { my %l; $l{$_} = 1 foreach @_; grep { delete $l{$_} } @_ }
++
++sub _init {
++}
++
++sub run {
++ my ($self, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $root = $repository-&gt;get_install_root();
++ my @changed = @{$repository-&gt;get_arch_changed($target)};
++ if (grep { $_ eq 'i586' } @changed) {
++ # x86_64 uses i586 pkgs, so rpmsrate need to be rebuild
++ @changed = uniq(@changed, 'x86_64');
++ }
++ foreach my $arch (@changed) {
++ my $rpmsrate = &quot;$root/$target/$arch/media/media_info/rpmsrate&quot;;
++ my @media = &quot;$root/$target/$arch/media/main/release&quot;;
++ system(&quot;cp&quot;, &quot;$rpmsrate-raw&quot;, &quot;$rpmsrate-new&quot;);
++ system(&quot;clean-rpmsrate&quot;, &quot;$rpmsrate-new&quot;, @media);
++ system(&quot;mv&quot;, &quot;-f&quot;, &quot;$rpmsrate-new&quot;, $rpmsrate);
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2007, Mandriva &lt;blino@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostGendistribpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Gendistrib.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,66 @@
++# $Id: Gendistrib.pm 115367 2007-01-30 09:47:04Z pixel $
++package Youri::Submit::Post::Gendistrib;
++
++=head1 NAME
++
++Youri::Submit::Post::Gendistrib - calls gendistrib
++
++=head1 DESCRIPTION
++
++Calls gendistrib
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Post/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ user =&gt; '',
++ host =&gt; '',
++ source =&gt; '',
++ destination =&gt; '',
++ @_
++ );
++
++ foreach my $var ('tmpdir', 'command') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++}
++
++sub run {
++ my ($self, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $root = $repository-&gt;get_install_root();
++ (undef, undef, my $hour) = gmtime(time);
++ # during the night, use complete hdlist rebuild
++ my $fast = '--fast';
++ $fast = ''; # blino: don't use fast for now, it might be broken
++ if ($hour &gt; 22 &amp;&amp; $hour &lt; 5) {
++ if ($hour &lt; 4) {
++ $fast = '--blind'
++ } else {
++ $fast = ''
++ }
++ }
++ foreach my $arch (@{$repository-&gt;get_arch_changed($target)}) {
++ my $cmd = &quot;TMPDIR=$self-&gt;{_tmpdir}/$target/$arch time $self-&gt;{_command} --nochkdep --nobadrpm $fast --noclean $root/$target/$arch&quot;;
++ print &quot;$cmd\n&quot;;
++ system($cmd);
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, Mandriva &lt;warly@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostGenhdlist2pm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post/Genhdlist2.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,82 @@
++# $Id: Gendistrib.pm 115367 2007-01-30 09:47:04Z pixel $
++package Youri::Submit::Post::Genhdlist2;
++
++=head1 NAME
++
++Youri::Submit::Post::Genhdlist2 - calls genhdlist2
++
++=head1 DESCRIPTION
++
++Calls genhdlist2
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Post/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ user =&gt; '',
++ host =&gt; '',
++ source =&gt; '',
++ destination =&gt; '',
++ @_
++ );
++
++ foreach my $var ('command') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++}
++
++sub run {
++ my ($self, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $root = $repository-&gt;get_install_root();
++ my @changed = @{$repository-&gt;get_install_dir_changed($target)};
++ if (!@changed) {
++ print &quot;nothing to do\n&quot;;
++ return;
++ }
++ foreach my $dir (@changed) {
++ my $file_deps = &quot;$dir/../../media_info/file-deps&quot;;
++ my $file_deps_option = -e $file_deps ? &quot;--file-deps $file_deps&quot; : '';
++ my $cmd = &quot;time $self-&gt;{_command} -v --versioned --allow-empty-media $file_deps_option $dir&quot;;
++ print &quot;$cmd\n&quot;;
++ system($cmd) == 0 or print &quot;ERROR: $cmd failed\n&quot;;
++ }
++
++ # need to redo global MD5SUM. This MD5SUM is mostly obsolete, but is still needed up to 2007.1
++ # (and even on cooker for existing urpmi.cfg)
++ foreach my $arch (@{$repository-&gt;get_arch_changed($target)}) {
++ my $dir = &quot;$root/$target/$arch/media/media_info&quot;;
++ my $cmd = &quot;cd $dir ; time md5sum hdlist_* synthesis.*&quot;;
++ print &quot;$cmd\n&quot;;
++ my $m = `$cmd`;
++ open my $f, '&gt;', &quot;$dir/MD5SUM&quot; or die &quot;Can't write $dir/MD5SUM: $!\n&quot;;
++ print $f $m;
++
++ {
++ require MDV::Distribconf::Build;
++ my $distrib = MDV::Distribconf::Build-&gt;new(&quot;$root/$target/$arch&quot;);
++ $distrib-&gt;loadtree or die &quot;$root/$target/$arch does not seem to be a distribution tree\n&quot;;
++ $distrib-&gt;parse_mediacfg;
++ $distrib-&gt;write_version($distrib-&gt;getfullpath(undef, &quot;VERSION&quot;));
++ print &quot;updated $root/$target/$arch/VERSION\n&quot;;
++ }
++ }
++ return;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, Mandriva &lt;warly@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
++
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPostpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Post.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Post.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Post;
++
++=head1 NAME
++
++Youri::Submit::Post - Abstract post plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines post plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPreRsyncpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre/Rsync.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,87 @@
++# $Id: Rsync.pm 267280 2010-04-01 19:57:53Z bogdano $
++package Youri::Submit::Pre::Rsync;
++
++=head1 NAME
++
++Youri::Submit::Pre::Rsync - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Pre/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ user =&gt; '',
++ host =&gt; '',
++ source =&gt; '',
++ destination =&gt; '',
++ @_
++ );
++
++ foreach my $var ('user', 'host', 'source', 'destination') {
++ $self-&gt;{&quot;_$var&quot;} = $options{$var};
++ }
++}
++
++sub run {
++ my ($self, $pre_packages, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ if (system(&quot;rsync --exclude '*.new' --exclude '.*' --remove-sent-files -avlPHe 'ssh -xc arcfour' $self-&gt;{_user}\@$self-&gt;{_host}:$self-&gt;{_source}/$target/ $self-&gt;{_destination}/$target/&quot;)) {
++ $self-&gt;{_error} = &quot;Rsync command failed ($!)&quot;;
++ return
++ }
++ my $queue = &quot;$self-&gt;{_destination}/$target&quot;;
++ $self-&gt;{_error} = &quot;Reading queue directory failed&quot;;
++ # now get the packages downloaded
++ my %packages;
++ opendir my $queuedh, &quot;$self-&gt;{_destination}/$target/&quot; or return &quot;Could not open $self-&gt;{_destination}/$target&quot;;
++ opendir my $targetdh, $queue or return &quot;Could not open $queue&quot;;
++ my $idx;
++ foreach my $media (readdir $targetdh) {
++ $media =~ /^\.{1,2}$/ and next;
++ print &quot;$target - $media\n&quot;;
++ if (-d &quot;$queue/$media&quot;) {
++ opendir my $submediadh, &quot;$queue/$media&quot; or return &quot;Could not open $queue/$media&quot;;
++ foreach my $submedia (readdir $submediadh) {
++ $submedia =~ /^\.{1,2}$/ and next;
++ print &quot;$target - $media - $submedia\n&quot;;
++ opendir my $rpmdh, &quot;$queue/$media/$submedia&quot; or return &quot;Could not open $queue/$media/$submedia&quot;;
++ foreach my $rpm (readdir $rpmdh) {
++ $rpm =~ /^\.{1,2}$/ and next;
++ print &quot;$target - $media - $submedia : $rpm\n&quot;;
++ my $file = &quot;$queue/$media/$submedia/$rpm&quot;;
++ $file =~ s/\/+/\//g;
++ if ($rpm =~ /^(\d{14}\.\w+\.\w+\.\d+)_.*\.rpm$/) {
++ push @{$packages{$1}{rpms}}, { section =&gt; &quot;$media/$submedia&quot;, file =&gt; $file };
++ } elsif ($rpm =~ /\.rpm$/) {
++ $idx++;
++ push @{$packages{&quot;independant_$idx&quot;}{rpms}}, { section =&gt; &quot;$media/$submedia&quot;, file =&gt; $file }
++ }
++ }
++ }
++ }
++ }
++ foreach my $key (keys %packages) {
++ push @$pre_packages, $packages{$key}{rpms}
++ }
++ return
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, Mandriva &lt;warly@mandriva.com&gt;
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitPrepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Pre.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Pre.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Pre;
++
++=head1 NAME
++
++Youri::Submit::Pre - Abstract pre plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines pre plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectArchivepm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Archive.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,61 @@
++# $Id: Archive.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Reject::Install;
++
++=head1 NAME
++
++Youri::Submit::Action::Archive - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Reject/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++
++ return $self;
++}
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $rpm = $package-&gt;get_file_name();
++ my $dest = $repository-&gt;get_reject_dir($package, $target, $define);
++
++ # FIXME remove prefix this should be done by a function
++ $rpm =~ s/^\d{14}\.\w+\.\w+\.\d+_//;
++ print &quot;installing file $file to $dest/$rpm\n&quot; ;#if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest/&quot;)
++ unless -d $dest;
++
++ # install file to new location
++ system(&quot;install -m $self-&gt;{_perms} $file $dest/$rpm&quot;);
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectCleanpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Clean.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,36 @@
++# $Id: Clean.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Reject::Clean;
++
++=head1 NAME
++
++Youri::Submit::Action::Clean - Old revisions cleanup
++
++=head1 DESCRIPTION
++
++This action plugin ensures cleanup of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Reject/;
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectInstallpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Install.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,63 @@
++# $Id: Install.pm 4747 2007-01-30 10:02:41Z pixel $
++package Youri::Submit::Reject::Install;
++
++=head1 NAME
++
++Youri::Submit::Action::Archive - Old revisions archiving
++
++=head1 DESCRIPTION
++
++This action plugin ensures archiving of old package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Reject/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ perms =&gt; 644,
++ @_
++ );
++
++ $self-&gt;{_perms} = $options{perms};
++ $self-&gt;{_verbose} = $options{verbose};
++}
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $file = $package-&gt;get_file();
++ my $rpm = $package-&gt;get_file_name();
++ my $dest = $repository-&gt;get_reject_path($package, $target, $define);
++
++ # FIXME remove prefix this should be done by a function
++ $rpm =~ s/^\d{14}\.\w+\.\w+\.\d+_//;
++ print &quot;installing file $file to $dest/$rpm\n&quot; if $self-&gt;{_verbose};
++
++ unless ($self-&gt;{_test}) {
++ # create destination dir if needed
++ system(&quot;install -d -m &quot; . ($self-&gt;{_perms} + 111) . &quot; $dest/&quot;)
++ unless -d $dest;
++
++ # install file to new location
++ system(&quot;install -m $self-&gt;{_perms} $file $dest/$rpm&quot;);
++ }
++ $package-&gt;{_file} = &quot;$dest/$rpm&quot;;
++ print &quot;deleting file $file\n&quot; if $self-&gt;{_verbose};
++ unlink $file unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectMailpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject/Mail.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,112 @@
++# $Id: Mail.pm 223952 2007-06-23 13:54:13Z pixel $
++package Youri::Submit::Reject::Mail;
++
++=head1 NAME
++
++Youri::Submit::Action::Mail - Mail notification
++
++=head1 DESCRIPTION
++
++This action plugin ensures mail notification of new package revisions.
++
++=cut
++
++use warnings;
++use strict;
++use MIME::Entity;
++use Encode qw/from_to/;
++use Carp;
++use Youri::Package;
++use base qw/Youri::Submit::Reject/;
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ mta =&gt; '/usr/sbin/sendmail',
++ to =&gt; '',
++ from =&gt; '',
++ cc =&gt; '',
++ prefix =&gt; '',
++ encoding =&gt; 'quoted-printable',
++ charset =&gt; 'iso-8859-1',
++ @_
++ );
++
++ croak &quot;undefined mail MTA&quot; unless $options{mta};
++ croak &quot;invalid mail MTA $options{mta}&quot; unless -x $options{mta};
++ croak &quot;undefined to&quot; unless $options{to};
++ if ($options{cc}) {
++ croak &quot;cc should be an hashref&quot; unless ref $options{cc} eq 'HASH';
++ }
++ croak &quot;invalid charset $options{charset}&quot;
++ unless Encode::resolve_alias($options{charset});
++
++ $self-&gt;{_mta} = $options{mta};
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_from} = $options{from};
++ $self-&gt;{_cc} = $options{cc};
++ $self-&gt;{_prefix} = $options{prefix};
++ $self-&gt;{_encoding} = $options{encoding};
++ $self-&gt;{_charset} = $options{charset};
++}
++
++sub run {
++ my ($self, $package, $errors, $repository, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $section = $repository-&gt;_get_section($package, $target, $define);
++
++ my $subject =
++ ($self-&gt;{_prefix} ? '[' . $self-&gt;{_prefix} . '] ' : '' ) . ($section ? &quot;$section &quot; : '') .
++ $package-&gt;get_revision_name();
++ my $information = $package-&gt;get_information();
++ my $last_change = $package-&gt;get_last_change();
++ my $author = $last_change-&gt;[Youri::Package::CHANGE_AUTHOR] if $last_change;
++ my $list = $last_change-&gt;[Youri::Package::CHANGE_TEXT] if $last_change;
++ my $content =
++ &quot;Errors: \n\n&quot; . join(&quot;\n&quot;, map {
++ ( &quot;* $_&quot;, (map { &quot; - $_&quot; } @{$errors-&gt;{$_}}), &quot;\n&quot;);
++ } sort(keys %$errors)) . &quot;\n&quot; .
++ $information . &quot;\n&quot; .
++ $author . &quot;:\n$list&quot;;
++
++ # ensure proper codeset conversion
++ # for informations coming from package
++ my $charset = $repository-&gt;get_package_charset();
++ from_to($content, $charset, $self-&gt;{_charset});
++ from_to($subject, $charset, $self-&gt;{_charset});
++
++ my $mail = MIME::Entity-&gt;build(
++ Type =&gt; 'text/plain',
++ Charset =&gt; $self-&gt;{_charset},
++ Encoding =&gt; $self-&gt;{_encoding},
++ From =&gt; $self-&gt;{_from},
++ To =&gt; $self-&gt;{_to},
++ Subject =&gt; $subject,
++ Data =&gt; $content,
++ );
++
++ if ($self-&gt;{_cc}) {
++ my $cc = $self-&gt;{_cc}-&gt;{$package-&gt;get_name()};
++ $mail-&gt;head()-&gt;add('cc', $cc) if $cc;
++ }
++
++ if ($self-&gt;{_test}) {
++ $mail-&gt;print(\*STDOUT);
++ } else {
++ open(MAIL, &quot;| $self-&gt;{_mta} -t -oi -oem&quot;) or die &quot;Can't open MTA program: $!&quot;;
++ $mail-&gt;print(\*MAIL);
++ close MAIL;
++ }
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunklibYouriSubmitRejectpm">Added: build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm (rev 0)
++++ build_system/mdv-youri-submit/trunk/lib/Youri/Submit/Reject.pm 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,27 @@
++# $Id: Reject.pm 4746 2007-01-30 10:01:14Z pixel $
++package Youri::Submit::Reject;
++
++=head1 NAME
++
++Youri::Submit::Reject - Abstract reject plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines reject plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base qw/Youri::Submit::Plugin/;
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2006, Mandriva
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyourisubmittrunkt00distributiont">Added: build_system/mdv-youri-submit/trunk/t/00distribution.t</a>
+===================================================================
+--- build_system/mdv-youri-submit/trunk/t/00distribution.t (rev 0)
++++ build_system/mdv-youri-submit/trunk/t/00distribution.t 2011-01-05 13:19:06 UTC (rev 209)
+@@ -0,0 +1,15 @@
++#!/usr/bin/perl
++# $Id: 00distribution.t 1723 2006-10-17 13:53:27Z warly $
++
++use Test::More;
++
++BEGIN {
++ eval {
++ require Test::Distribution;
++ };
++ if($@) {
++ plan skip_all =&gt; 'Test::Distribution not installed';
++ } else {
++ import Test::Distribution only =&gt; [ qw/use pod description/ ];
++ }
++}
+
+
+Property changes on: build_system/mdv-youri-submit/trunk/t/00distribution.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment-0001.html
new file mode 100644
index 000000000..49d5e4185
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment-0001.html
@@ -0,0 +1,2256 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[212] - merge trunk ( for good this time )</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>212</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 16:32:57 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- merge trunk ( for good this time )</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#identityCatDapbranchesliveMakefilePL">identity/CatDap/branches/live/Makefile.PL</a></li>
+<li><a href="#identityCatDapbrancheslivecatdapyml">identity/CatDap/branches/live/catdap.yml</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControllerRootpm">identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControlleradminpm">identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControllerregisterpm">identity/CatDap/branches/live/lib/CatDap/Controller/register.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControlleruserpm">identity/CatDap/branches/live/lib/CatDap/Controller/user.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapI18Nafpo">identity/CatDap/branches/live/lib/CatDap/I18N/af.po</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapI18Nfrpo">identity/CatDap/branches/live/lib/CatDap/I18N/fr.po</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapI18Nmessagespot">identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDappm">identity/CatDap/branches/live/lib/CatDap.pm</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccounttt">identity/CatDap/branches/live/root/admin/account.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_addoctt">identity/CatDap/branches/live/root/admin/account_addoc.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_grouptt">identity/CatDap/branches/live/root/admin/account_group.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_modifytt">identity/CatDap/branches/live/root/admin/account_modify.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_promotett">identity/CatDap/branches/live/root/admin/account_promote.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadmingrouptt">identity/CatDap/branches/live/root/admin/group.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadmingroup_modifytt">identity/CatDap/branches/live/root/admin/group_modify.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminindextt">identity/CatDap/branches/live/root/admin/index.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootemailactivationtt">identity/CatDap/branches/live/root/email/activation.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootemailadminpasswordtt">identity/CatDap/branches/live/root/email/admin/password.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootindextt">identity/CatDap/branches/live/root/index.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootregisterchecktt">identity/CatDap/branches/live/root/register/check.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootregisterindextt">identity/CatDap/branches/live/root/register/index.tt</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatefooter">identity/CatDap/branches/live/root/template/footer</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplateheader">identity/CatDap/branches/live/root/template/header</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatehtml">identity/CatDap/branches/live/root/template/html</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatepre">identity/CatDap/branches/live/root/template/pre</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatewrapper">identity/CatDap/branches/live/root/template/wrapper</a></li>
+<li><a href="#identityCatDapbranchesliverootuserindextt">identity/CatDap/branches/live/root/user/index.tt</a></li>
+</ul>
+
+<h3>Property Changed</h3>
+<ul>
+<li><a href="#identityCatDapbrancheslive">identity/CatDap/branches/live/</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+
+<a id="identityCatDapbrancheslive">Property changes on: identity/CatDap/branches/live</a>
+___________________________________________________________________
+<a id="svnmergeinfo">Modified: svn:mergeinfo</a>
+ - /identity/CatDap/trunk:64,66-68,210
+ + /identity/CatDap/trunk:64,66-68,140-211
+
+<a id="identityCatDapbranchesliveMakefilePL">Modified: identity/CatDap/branches/live/Makefile.PL</a>
+===================================================================
+--- identity/CatDap/branches/live/Makefile.PL 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/Makefile.PL 2011-01-05 15:32:57 UTC (rev 212)
+@@ -13,6 +13,7 @@
+ requires 'Catalyst::Plugin::ConfigLoader';
+ requires 'Catalyst::Plugin::Static::Simple';
+ requires 'Catalyst::Plugin::I18N';
++requires 'Catalyst::Plugin::Unicode::Encoding';
+ requires 'Catalyst::Plugin::Authentication';
+ requires 'Catalyst::Plugin::Authentication::Store::LDAP';
+ requires 'Catalyst::Plugin::Captcha';
+
+<a id="identityCatDapbrancheslivecatdapyml">Modified: identity/CatDap/branches/live/catdap.yml</a>
+===================================================================
+--- identity/CatDap/branches/live/catdap.yml 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/catdap.yml 2011-01-05 15:32:57 UTC (rev 212)
+@@ -11,6 +11,7 @@
+ default_view: Web
+
+ organisation: Mageia
++project_url: http://www.mageia.org/
+ apptitle: Mageia Identity Management
+ emailfrom: noreply@mageia.org
+
+@@ -20,6 +21,8 @@
+ password: FIXME
+ host: ldap.mageia.org
+ start_tls: 1
++ options:
++ inet6: 1
+
+ # dn and password should not be required here, we rebind with credentials
+ # from the authenticated user using Model::LDAP::FromAuthentication
+@@ -28,6 +31,10 @@
+ host: ldap.mageia.org
+ start_tls: 1
+
++register:
++ login_blacklist:
++ - apache
++
+ authentication:
+ default_realm: ldap
+ realms:
+@@ -39,8 +46,10 @@
+ store:
+ class: LDAP
+ ldap_server: 'ldap.mageia.org'
++ ldap_server_options:
++ inet6: 1
+ start_tls: 1
+- binddn: cn=catdap,ou=System Accounts,dc=mageai,dc=org
++ binddn: cn=catdap,ou=System Accounts,dc=mageia,dc=org
+ bindpw: FIXME
+ user_basedn: &quot;ou=people,dc=mageia,dc=org&quot;
+ user_filter: '(&amp;(objectClass=inetOrgPerson)(uid=%s))'
+
+<a id="identityCatDapbrancheslivelibCatDapControllerRootpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -28,7 +28,11 @@
+
+ sub index :Path :Args(0) {
+ my ( $self, $c ) = @_;
+-
++ # if user is defined, redirect to /user and let the /user page handle the authentication
++ if (defined $c-&gt;user) {
++ $c-&gt;log-&gt;debug('Redirecting to /user');
++ $c-&gt;res-&gt;redirect('/user');
++ }
+ # Hello World
+ #$c-&gt;response-&gt;body( $c-&gt;welcome_message );
+ }
+
+<a id="identityCatDapbrancheslivelibCatDapControlleradminpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -47,7 +47,17 @@
+ my $password;
+ my $mesg;
+ my $dn;
+- my $keyprefix = sprintf( &quot;%02x%02x%02x&quot;, split /\./, $c-&gt;req-&gt;address );
++
++ # TODO merge this code with the one in user.pm
++ my $keyprefix;
++ if ($c-&gt;req-&gt;address =~ m/:/) {
++ my $address = $c-&gt;req-&gt;address;
++ $address =~ s/\[\]://;
++ $keyprefix = sprintf( &quot;%06x&quot;, $address &gt;&gt; 104 ); # if we shift right 104 bits from 128 we have 24 bits left or 3 bytes.
++ }
++ else {
++ $keyprefix = sprintf( &quot;%02x%02x%02x&quot;, split /\./, $c-&gt;req-&gt;address );
++ }
+ if ( !defined $c-&gt;user or not $c-&gt;req-&gt;cookie('key') ) {
+ $c-&gt;detach('/user/login')
+ if ( not $c-&gt;req-&gt;param('username')
+
+<a id="identityCatDapbrancheslivelibCatDapControllerregisterpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/register.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/register.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/register.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -51,6 +51,20 @@
+ if (! $c-&gt;validate_captcha($c-&gt;req-&gt;param('validate'))){
+ push @errors, $c-&gt;loc('Incorrect validation text, please try again');
+ }
++
++ if ( ! open( my $etcpasswd, &quot;/etc/passwd&quot;)) {
++ push @errors, $c-&gt;loc('Cannot check /etc/passwd, please warn system administrators');
++ } else {
++ if ( grep { /^$username:/ } &lt;$etcpasswd&gt; ) {
++ push @errors, $c-&gt;loc('Invalid username, already used by system');
++ }
++ close($etcpasswd);
++ }
++
++ if ( grep /^$username$/, @{${$c-&gt;config}{'register'}{'login_blacklist'}}) {
++ push @errors, $c-&gt;loc('Username is not authorized to be used');
++ }
++
+ if ($c-&gt;request-&gt;params-&gt;{gn} !~ /^\p{IsAlnum}+$/) {
+ push @errors, $c-&gt;loc(
+ 'The first name supplied contains illegal characters'
+@@ -108,7 +122,8 @@
+ push @errors,$mesg-&gt;error;
+ $c-&gt;log-&gt;info( sprintf(&quot;Creating DN $dn failed: %s&quot;, $mesg-&gt;error) );
+ $c-&gt;stash(errors =&gt; \@errors);
+- #$c-&gt;stash(template =&gt; 'register/index.tt');
++ $c-&gt;stash(template =&gt; 'register/index.tt');
++ return ;
+ }
+
+ $c-&gt;stash(
+
+<a id="identityCatDapbrancheslivelibCatDapControlleruserpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/user.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/user.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/user.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -55,7 +55,7 @@
+ my $mesg;
+ my $dn;
+ my @errors;
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ if (! defined $c-&gt;user or not $c-&gt;req-&gt;cookie('key')) {
+ if (not $c-&gt;req-&gt;param('password')) {
+ push @errors,$c-&gt;loc('Your session has expired');
+@@ -112,6 +112,22 @@
+
+ }
+
++sub get_keyprefix : Private {
++ my ( $self, $c ) = @_;
++ my $keyprefix;
++ if ($c-&gt;req-&gt;address =~ m/:/) {
++ my $address = $c-&gt;req-&gt;address;
++ $address =~ s/\[\]://;
++
++ # if we shift right 104 bits from 128 we have 24 bits left or 3 bytes.
++ $keyprefix = sprintf( &quot;%06x&quot;, $address &gt;&gt; 104 );
++ }
++ else {
++ $keyprefix = sprintf( &quot;%02x%02x%02x&quot;, split /\./, $c-&gt;req-&gt;address );
++ }
++ return $keyprefix;
++}
++
+ =head2 index
+
+ =cut
+@@ -293,7 +309,7 @@
+ } else {
+
+ # re-encrypt the new password and forward to user view
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ my $key = $c-&gt;req-&gt;cookie('key')-&gt;value;
+ $cipher = Crypt::CBC-&gt;new( -key =&gt; $keyprefix . $key,
+ -cipher =&gt; 'Blowfish'
+@@ -321,7 +337,7 @@
+ $c-&gt;res-&gt;redirect('/user');
+ }
+ # cache password for next request with form data
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ my $key = Data::UUID-&gt;new-&gt;create_str();
+ $cipher = Crypt::CBC-&gt;new( -key =&gt; $keyprefix . $key,
+ -cipher =&gt; 'Blowfish'
+@@ -338,7 +354,7 @@
+ }
+
+ #Re-authenticate user
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ my $key = $c-&gt;req-&gt;cookie('key')-&gt;value;
+ $cipher = Crypt::CBC-&gt;new( -key =&gt; $keyprefix . $key,
+ -cipher =&gt; 'Blowfish'
+
+<a id="identityCatDapbrancheslivelibCatDapI18Nafpo">Modified: identity/CatDap/branches/live/lib/CatDap/I18N/af.po</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/I18N/af.po 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/I18N/af.po 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,45 +1,78 @@
+-#: lib/CatDap/Controller/register.pm:119
++#: lib/CatDap/Controller/register.pm:133
+ msgid &quot;Activation&quot;
+ msgstr &quot;Aktivering&quot;
+
+-#: root/user/index.tt:28 root/user/index.tt:8
++#: root/admin/account_addoc.tt:28 root/admin/account_modify.tt:24
++#: root/admin/group_modify.tt:18 root/user/index.tt:19 root/user/index.tt:46
+ msgid &quot;Add&quot;
+ msgstr &quot;Voeg by&quot;
+
++#: root/admin/account_modify.tt:85
++msgid &quot;Add ObjectClass&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:47
++msgid &quot;Add attribute&quot;
++msgstr &quot;&quot;
++
++#. (oc, dn)
++#: root/admin/account_addoc.tt:1
++msgid &quot;Adding objectclass %1 to dn %2&quot;
++msgstr &quot;&quot;
++
+ #: lib/CatDap/Controller/register.pm:49
+ msgid &quot;Addresses do not match&quot;
+ msgstr &quot;Die addresse verskil&quot;
+
+-#: lib/CatDap/Controller/register.pm:75
++#: lib/CatDap/Controller/register.pm:89
+ msgid &quot;An account already exists with this email address&quot;
+ msgstr &quot;'n Rekening met hierde epos adres bestaan reeds&quot;
+
+-#: lib/CatDap/Controller/register.pm:80
++#: lib/CatDap/Controller/register.pm:94
+ msgid &quot;An account already exists with this username&quot;
+ msgstr &quot;'n Rekening met hierdie gebruikersnaam bestaan reeds&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/admin.pm:529
++#: lib/CatDap/Controller/register.pm:145
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process f you entered the correct email address: %1&quot;
++&quot;the password recovery process if you entered the correct email address. &quot;
++&quot;Errors %1&quot;
+ msgstr &quot;&quot;
+ &quot;Daar was 'n fout met die stuur van die aktiverings epos, maar jou rekening &quot;
+ &quot;is geskep. Probeer die wagwoord herwinnings proses as die epos adres korrek &quot;
+-&quot;was: %1&quot;
++&quot;was. Foute: %1&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/register.pm:131
++#: lib/CatDap/Controller/admin.pm:539
++#, fuzzy
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process if you entered the correct email address. &quot;
+-&quot;Errors %1&quot;
++&quot;the password recovery process if you entered the correct email address: %1&quot;
+ msgstr &quot;&quot;
+ &quot;Daar was 'n fout met die stuur van die aktiverings epos, maar jou rekening &quot;
+ &quot;is geskep. Probeer die wagwoord herwinnings proses as die epos adres korrek &quot;
+-&quot;was. Foute: %1&quot;
++&quot;was: %1&quot;
+
+-#: root/user/firstlogin.tt:14 root/user/password.tt:18
++#. ($errors)
++#: lib/CatDap/Controller/forgot_password.pm:105
++msgid &quot;An error occured sending the email, please try again later. Errors %1&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:9 root/admin/account_modify.tt:8
++#: root/admin/group_modify.tt:5 root/user/index.tt:4
++msgid &quot;Attribute&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/register.pm:56
++msgid &quot;Cannot check /etc/passwd, please warn system administrators&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:29
++msgid &quot;Captcha&quot;
++msgstr &quot;&quot;
++
++#: root/user/firstlogin.tt:14 root/user/password.tt:19
+ msgid &quot;Change&quot;
+ msgstr &quot;Verander&quot;
+
+@@ -51,7 +84,12 @@
+ msgid &quot;Check your mail for activation instructions.&quot;
+ msgstr &quot;Kyk jou epos vir aktiverings instruksies.&quot;
+
+-#: root/register/index.tt:34
++#: root/forgot_password/complete.tt:5
++#, fuzzy
++msgid &quot;Check your mail for password reset instructions.&quot;
++msgstr &quot;Kyk jou epos vir aktiverings instruksies.&quot;
++
++#: root/register/index.tt:24
+ msgid &quot;Confirm Email address&quot;
+ msgstr &quot;Bevestig epos adres&quot;
+
+@@ -62,10 +100,11 @@
+ #. (cn)
+ #. (entry.cn)
+ #: root/email/activation.tt:1 root/email/admin/password.tt:1
++#: root/email/forgot_password.tt:1
+ msgid &quot;Dear %1,&quot;
+ msgstr &quot;Liewe %1,&quot;
+
+-#: root/user/index.tt:9
++#: root/admin/account_modify.tt:27 root/user/index.tt:22
+ msgid &quot;Delete&quot;
+ msgstr &quot;Vee uit&quot;
+
+@@ -73,18 +112,75 @@
+ msgid &quot;Edit&quot;
+ msgstr &quot;Wysig&quot;
+
+-#: root/register/index.tt:30
++#: root/admin/account.tt:33 root/admin/account.tt:8
++#: root/admin/account_promote.tt:6 root/register/index.tt:20
++msgid &quot;Email&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:11 root/register/index.tt:21
+ msgid &quot;Email address&quot;
+ msgstr &quot;Epos adres&quot;
+
+-#: root/register/index.tt:22
++#: root/forgot_password/complete.tt:1
++msgid &quot;Email sent.&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:2
++#, fuzzy
++msgid &quot;Enter new password.&quot;
++msgstr &quot;Verander wagwoord&quot;
++
++#: root/register/index.tt:32
++msgid &quot;Enter text&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:34 root/admin/account_promote.tt:7
++#, fuzzy
++msgid &quot;First Name&quot;
++msgstr &quot;Voornaam&quot;
++
++#: root/register/index.tt:13
+ msgid &quot;First name&quot;
+ msgstr &quot;Voornaam&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:94
++#, fuzzy
++msgid &quot;Forgot password&quot;
++msgstr &quot;Huidige wagwoord&quot;
++
++#: root/forgot_password/index.tt:5
++msgid &quot;Forgot your password?&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:17 root/index.tt:18
++#, fuzzy
++msgid &quot;Forgotten password?&quot;
++msgstr &quot;Huidige wagwoord&quot;
++
++#: root/admin/account.tt:36 root/admin/account.tt:9
++#: root/admin/account_promote.tt:9
++msgid &quot;Full Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:27
++msgid &quot;Group Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:9
++#, fuzzy
++msgid &quot;Group name&quot;
++msgstr &quot;Voornaam&quot;
++
++#: root/admin/account_modify.tt:2
++msgid &quot;Groups&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:48
+ #: lib/CatDap/Controller/register.pm:52
+ msgid &quot;Incorrect validation text, please try again&quot;
+ msgstr &quot;Inkorrekte teks van die prentjie, probeer weer&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:45
+ #: lib/CatDap/Controller/register.pm:46
+ msgid &quot;Invalid email address&quot;
+ msgstr &quot;Ongeldige epos adres&quot;
+@@ -93,39 +189,69 @@
+ msgid &quot;Invalid username&quot;
+ msgstr &quot;Ongeldige gebruikersnaam&quot;
+
+-#: root/template/header:12 root/user/fake.tt:3
++#: lib/CatDap/Controller/register.pm:59
++msgid &quot;Invalid username, already used by system&quot;
++msgstr &quot;&quot;
++
++#: root/template/header:10 root/user/fake.tt:3
+ msgid &quot;Log out&quot;
+ msgstr &quot;Teken uit&quot;
+
+-#: root/index.tt:1 root/index.tt:17
++#: root/index.tt:1 root/index.tt:13
+ msgid &quot;Login&quot;
+ msgstr &quot;Teken in&quot;
+
+-#: root/user/firstlogin.tt:5 root/user/password.tt:9
++#: root/forgot_password/confirm.tt:8 root/user/firstlogin.tt:5
++#: root/user/password.tt:10
+ msgid &quot;New Password&quot;
+ msgstr &quot;Nuwe Wagwoord&quot;
+
+-#: lib/CatDap/Controller/user.pm:273
++#: lib/CatDap/Controller/user.pm:296
+ msgid &quot;New passwords dont match&quot;
+ msgstr &quot;Nuwe wagwoorde verskil&quot;
+
+-#: root/index.tt:11
++#: root/forgot_password/complete.tt:4
++#, fuzzy
++msgid &quot;Operation was successful.&quot;
++msgstr &quot;Registrasie was suksesvol.&quot;
++
++#: root/index.tt:10
+ msgid &quot;Password&quot;
+ msgstr &quot;Wagwoord&quot;
+
+-#: lib/CatDap/Controller/user.pm:267
++#: lib/CatDap/Controller/user.pm:290
+ msgid &quot;Password incorrect&quot;
+ msgstr &quot;Wagwoord inkorrek&quot;
+
+-#: lib/CatDap/Controller/admin.pm:532
++#: lib/CatDap/Controller/admin.pm:542
+ msgid &quot;Password reset and email sent&quot;
+ msgstr &quot;Wagwoord is herstel en epos gestuur&quot;
+
++#: root/register/index.tt:12
++msgid &quot;Personal Information&quot;
++msgstr &quot;&quot;
++
+ #: root/email/admin/password.tt:5
+ msgid &quot;Please click below to change your password&quot;
+ msgstr &quot;Volg die skakel onder en verander jou wagwoord&quot;
+
+-#: root/index.tt:18 root/register/index.tt:43 root/register/index.tt:6
++#: root/admin/index.tt:1
++msgid &quot;Please use the menus above.&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:25
++msgid &quot;Primary group&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:71
++msgid &quot;Promote&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:62
++msgid &quot;Promote user to posixAccount with primary group:&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:16 root/register/index.tt:3 root/register/index.tt:35
+ msgid &quot;Register&quot;
+ msgstr &quot;Registreer&quot;
+
+@@ -137,35 +263,95 @@
+ msgid &quot;Registration was successful.&quot;
+ msgstr &quot;Registrasie was suksesvol.&quot;
+
+-#: root/user/firstlogin.tt:9 root/user/password.tt:13
++#: root/forgot_password/confirm.tt:11 root/user/firstlogin.tt:10
++#: root/user/password.tt:15
+ msgid &quot;Repeat New Password&quot;
+ msgstr &quot;Herhaal Nuwe Wagwoord&quot;
+
+-#: root/register/index.tt:26
++#: root/admin/account_modify.tt:1
++#, fuzzy
++msgid &quot;Reset password&quot;
++msgstr &quot;Huidige wagwoord&quot;
++
++#: root/admin/account.tt:22
++msgid &quot;Search&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:4 root/admin/group.tt:5
++msgid &quot;Search by&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:4
++msgid &quot;Select&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:18
++#, fuzzy
++msgid &quot;Send me my password&quot;
++msgstr &quot;Verander wagwoord&quot;
++
++#: root/forgot_password/confirm.tt:16
++#, fuzzy
++msgid &quot;Set new password&quot;
++msgstr &quot;Herhaal Nuwe Wagwoord&quot;
++
++#: root/register/check.tt:1
++msgid &quot;Success&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:10 root/admin/account.tt:35
++#: root/admin/account_promote.tt:8 root/register/index.tt:16
+ msgid &quot;Surname&quot;
+ msgstr &quot;Van&quot;
+
+-#: lib/CatDap/Controller/register.pm:56
++#: lib/CatDap/Controller/register.pm:70
+ msgid &quot;The first name supplied contains illegal characters&quot;
+ msgstr &quot;Die verskafte noemnaam sluit ongeldige karakters in&quot;
+
+-#: lib/CatDap/Controller/register.pm:61
++#: lib/CatDap/Controller/register.pm:75
+ msgid &quot;The surname supplied contains illegal characters&quot;
+ msgstr &quot;Die verskafte van sluit ondeldige karakters in&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:66
++msgid &quot;This email address is not bound to an account&quot;
++msgstr &quot;&quot;
++
+ #: root/email/activation.tt:3
+ msgid &quot;To activate your account, please follow the link below.&quot;
+ msgstr &quot;Om U rekening te aktiveer, volg asseblief die volgende skakel.&quot;
+
+-#: root/user/index.tt:13
++#: root/email/forgot_password.tt:3
++#, fuzzy
++msgid &quot;To reset your password, please follow the link below.&quot;
++msgstr &quot;Om U rekening te aktiveer, volg asseblief die volgende skakel.&quot;
++
++#: root/admin/account_modify.tt:35 root/user/index.tt:29
+ msgid &quot;Update&quot;
+ msgstr &quot;Opdateer&quot;
+
+-#: root/index.tt:7 root/register/index.tt:18
++#: root/admin/account.tt:32 root/admin/account.tt:7
++#: root/admin/account_promote.tt:5 root/index.tt:6 root/register/index.tt:7
++#: root/register/index.tt:8
+ msgid &quot;Username&quot;
+ msgstr &quot;Gebruikersnaam&quot;
+
++#: lib/CatDap/Controller/register.pm:65
++msgid &quot;Username is not authorized to be used&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:10 root/admin/account_modify.tt:9
++#: root/admin/group_modify.tt:6 root/user/index.tt:4
++msgid &quot;Value&quot;
++msgstr &quot;&quot;
++
+ #. (c.config.organisation)
++#: root/email/forgot_password.tt:2
++msgid &quot;&quot;
++&quot;Your %1 account has been requested to change the password. If you did not do &quot;
++&quot;this, or you do not want to change your password; you can just do nothing.&quot;
++msgstr &quot;&quot;
++
++#. (c.config.organisation)
+ #: root/email/activation.tt:2
+ msgid &quot;Your %1 account has been successfully created, but requires activation.&quot;
+ msgstr &quot;Jou %1 rekening is suksesvol geskep, maar aktivering is benodig&quot;
+@@ -179,14 +365,42 @@
+ msgid &quot;Your session has expired&quot;
+ msgstr &quot;Jou sessie het verstrek&quot;
+
+-#: root/index.tt:17
+-msgid &quot;or&quot;
+-msgstr &quot;of&quot;
++#: root/admin/account.tt:15 root/admin/group.tt:15
++msgid &quot;contains&quot;
++msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/admin.pm:516
++#: root/admin/group_modify.tt:14
++#, fuzzy
++msgid &quot;delete&quot;
++msgstr &quot;Vee uit&quot;
++
++#: root/admin/account.tt:17 root/admin/group.tt:17
++msgid &quot;greater than or equal to&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:16 root/admin/group.tt:16
++msgid &quot;is exactly&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:18 root/admin/group.tt:18
++msgid &quot;less than&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:10
++msgid &quot;member&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/admin.pm:526
+ msgid &quot;password reset&quot;
+ msgstr &quot;Wagwoord herstelling&quot;
+
++#: root/admin/account_modify.tt:53
++msgid &quot;with value&quot;
++msgstr &quot;&quot;
++
++#~ msgid &quot;or&quot;
++#~ msgstr &quot;of&quot;
++
+ #~ msgid &quot;Repeat&quot;
+ #~ msgstr &quot;Herhaal&quot;
+
+
+<a id="identityCatDapbrancheslivelibCatDapI18Nfrpo">Modified: identity/CatDap/branches/live/lib/CatDap/I18N/fr.po</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/I18N/fr.po 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/I18N/fr.po 2011-01-05 15:32:57 UTC (rev 212)
+@@ -5,98 +5,202 @@
+ #
+ msgid &quot;&quot;
+ msgstr &quot;&quot;
+-&quot;Project-Id-Version: PACKAGE VERSION\n&quot;
++&quot;Project-Id-Version: Catdap\n&quot;
+ &quot;POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n&quot;
+-&quot;PO-Revision-Date: 2010-10-19 21:07+0100\n&quot;
++&quot;PO-Revision-Date: 2010-11-04 21:09+0100\n&quot;
+ &quot;Last-Translator: Michael Scherer &lt;misc@zarb.org&gt;\n&quot;
+-&quot;Language-Team: LANGUAGE &lt;LL@li.org&gt;\n&quot;
++&quot;Language-Team: LANGUAGE &lt;mageia-i18n@mageia.org&gt;\n&quot;
++&quot;Language: \n&quot;
+ &quot;MIME-Version: 1.0\n&quot;
+ &quot;Content-Type: text/plain; charset=UTF-8\n&quot;
+ &quot;Content-Transfer-Encoding: 8bit\n&quot;
++&quot;X-Poedit-Language: French\n&quot;
++&quot;X-Poedit-Country: FRANCE\n&quot;
++&quot;X-Poedit-SourceCharset: utf-8\n&quot;
+
+-#: lib/CatDap/Controller/register.pm:119
++#: lib/CatDap/Controller/register.pm:133
+ msgid &quot;Activation&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Activation&quot;
+
+-#: root/user/index.tt:28 root/user/index.tt:8
++#: root/admin/account_addoc.tt:28 root/admin/account_modify.tt:24
++#: root/admin/group_modify.tt:18 root/user/index.tt:19 root/user/index.tt:46
+ msgid &quot;Add&quot;
++msgstr &quot;Ajouter&quot;
++
++#: root/admin/account_modify.tt:85
++msgid &quot;Add ObjectClass&quot;
+ msgstr &quot;&quot;
+
++#: root/admin/account_modify.tt:47
++msgid &quot;Add attribute&quot;
++msgstr &quot;&quot;
++
++#. (oc, dn)
++#: root/admin/account_addoc.tt:1
++msgid &quot;Adding objectclass %1 to dn %2&quot;
++msgstr &quot;&quot;
++
+ #: lib/CatDap/Controller/register.pm:49
+ msgid &quot;Addresses do not match&quot;
+ msgstr &quot;Les adresses ne correspondent pas&quot;
+
+-#: lib/CatDap/Controller/register.pm:75
++#: lib/CatDap/Controller/register.pm:89
+ msgid &quot;An account already exists with this email address&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Un compte existe déjà avec cet email&quot;
+
+-#: lib/CatDap/Controller/register.pm:80
++#: lib/CatDap/Controller/register.pm:94
+ msgid &quot;An account already exists with this username&quot;
+ msgstr &quot;Un compte existe déjà pour ce nom d'utilisateur&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/admin.pm:529
++#: lib/CatDap/Controller/register.pm:145
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process f you entered the correct email address: %1&quot;
++&quot;the password recovery process if you entered the correct email address. &quot;
++&quot;Errors %1&quot;
+ msgstr &quot;&quot;
++&quot;Une erreur est arrivé lors de l'envoi du mail, mais votre compte a été crée. &quot;
++&quot;Vous pouvez utiliser la fonction de réinitialisation du mot de passe si &quot;
++&quot;votre adresse est correcte. Erreurs %1&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/register.pm:131
++#: lib/CatDap/Controller/admin.pm:539
++#, fuzzy
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process if you entered the correct email address. &quot;
+-&quot;Errors %1&quot;
++&quot;the password recovery process if you entered the correct email address: %1&quot;
+ msgstr &quot;&quot;
++&quot;Une erreur est arrivé lors de l'envoi du mail, mais votre compte a été crée. &quot;
++&quot;Vous pouvez utiliser la fonction de réinitialisation du mot de passe si &quot;
++&quot;votre adresse est correcte : %1&quot;
+
+-#: root/user/firstlogin.tt:14 root/user/password.tt:18
+-msgid &quot;Change&quot;
++#. ($errors)
++#: lib/CatDap/Controller/forgot_password.pm:105
++msgid &quot;An error occured sending the email, please try again later. Errors %1&quot;
+ msgstr &quot;&quot;
+
++#: root/admin/account_addoc.tt:9 root/admin/account_modify.tt:8
++#: root/admin/group_modify.tt:5 root/user/index.tt:4
++msgid &quot;Attribute&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/register.pm:56
++msgid &quot;Cannot check /etc/passwd, please warn system administrators&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:29
++msgid &quot;Captcha&quot;
++msgstr &quot;&quot;
++
++#: root/user/firstlogin.tt:14 root/user/password.tt:19
++msgid &quot;Change&quot;
++msgstr &quot;Changer&quot;
++
+ #: root/user/fake.tt:2
+-#, fuzzy
+ msgid &quot;Change password&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;Changer le mot de passe&quot;
+
+ #: root/register/complete.tt:5
+ msgid &quot;Check your mail for activation instructions.&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Vérifier votre boite mail pour les instructions d'activation&quot;
+
+-#: root/register/index.tt:34
++#: root/forgot_password/complete.tt:5
++#, fuzzy
++msgid &quot;Check your mail for password reset instructions.&quot;
++msgstr &quot;Vérifier votre boite mail pour les instructions d'activation&quot;
++
++#: root/register/index.tt:24
+ msgid &quot;Confirm Email address&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Confirmer l'adresse email&quot;
+
+ #: root/user/password.tt:5
+ msgid &quot;Current password&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Mot de passe actuel&quot;
+
+ #. (cn)
+ #. (entry.cn)
+ #: root/email/activation.tt:1 root/email/admin/password.tt:1
+-#, fuzzy
++#: root/email/forgot_password.tt:1
+ msgid &quot;Dear %1,&quot;
+-msgstr &quot;Cher(e)&quot;
++msgstr &quot;Cher(e) %1,&quot;
+
+-#: root/user/index.tt:9
++#: root/admin/account_modify.tt:27 root/user/index.tt:22
+ msgid &quot;Delete&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Supprimer&quot;
+
+ #: root/user/fake.tt:1
+ msgid &quot;Edit&quot;
++msgstr &quot;Éditer&quot;
++
++#: root/admin/account.tt:33 root/admin/account.tt:8
++#: root/admin/account_promote.tt:6 root/register/index.tt:20
++msgid &quot;Email&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:30
++#: root/forgot_password/index.tt:11 root/register/index.tt:21
+ msgid &quot;Email address&quot;
+-msgstr &quot;Adresse de messagerie&quot;
++msgstr &quot;Adresse email&quot;
+
+-#: root/register/index.tt:22
++#: root/forgot_password/complete.tt:1
++msgid &quot;Email sent.&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:2
++#, fuzzy
++msgid &quot;Enter new password.&quot;
++msgstr &quot;Changer le mot de passe&quot;
++
++#: root/register/index.tt:32
++msgid &quot;Enter text&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:34 root/admin/account_promote.tt:7
++#, fuzzy
++msgid &quot;First Name&quot;
++msgstr &quot;Prénom&quot;
++
++#: root/register/index.tt:13
+ msgid &quot;First name&quot;
+ msgstr &quot;Prénom&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:94
++#, fuzzy
++msgid &quot;Forgot password&quot;
++msgstr &quot;Mot de passe actuel&quot;
++
++#: root/forgot_password/index.tt:5
++msgid &quot;Forgot your password?&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:17 root/index.tt:18
++#, fuzzy
++msgid &quot;Forgotten password?&quot;
++msgstr &quot;Mot de passe actuel&quot;
++
++#: root/admin/account.tt:36 root/admin/account.tt:9
++#: root/admin/account_promote.tt:9
++msgid &quot;Full Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:27
++msgid &quot;Group Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:9
++#, fuzzy
++msgid &quot;Group name&quot;
++msgstr &quot;Prénom&quot;
++
++#: root/admin/account_modify.tt:2
++msgid &quot;Groups&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:48
+ #: lib/CatDap/Controller/register.pm:52
+ msgid &quot;Incorrect validation text, please try again&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Texte de validation incorrect, merci de tester à nouveau&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:45
+ #: lib/CatDap/Controller/register.pm:46
+ msgid &quot;Invalid email address&quot;
+ msgstr &quot;Adresse mail invalide&quot;
+@@ -105,105 +209,218 @@
+ msgid &quot;Invalid username&quot;
+ msgstr &quot;Nom d'utilisateur invalide&quot;
+
+-#: root/template/header:12 root/user/fake.tt:3
+-msgid &quot;Log out&quot;
++#: lib/CatDap/Controller/register.pm:59
++msgid &quot;Invalid username, already used by system&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:1 root/index.tt:17
++#: root/template/header:10 root/user/fake.tt:3
++msgid &quot;Log out&quot;
++msgstr &quot;Se déconnecter&quot;
++
++#: root/index.tt:1 root/index.tt:13
+ msgid &quot;Login&quot;
+ msgstr &quot;Login&quot;
+
+-#: root/user/firstlogin.tt:5 root/user/password.tt:9
+-#, fuzzy
++#: root/forgot_password/confirm.tt:8 root/user/firstlogin.tt:5
++#: root/user/password.tt:10
+ msgid &quot;New Password&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;Nouveau mot de passe&quot;
+
+-#: lib/CatDap/Controller/user.pm:273
+-#, fuzzy
++#: lib/CatDap/Controller/user.pm:296
+ msgid &quot;New passwords dont match&quot;
+-msgstr &quot;Les adresses ne correspondent pas&quot;
++msgstr &quot;Les mot de passes ne correspondent pas&quot;
+
+-#: root/index.tt:11
++#: root/forgot_password/complete.tt:4
++#, fuzzy
++msgid &quot;Operation was successful.&quot;
++msgstr &quot;L'enregistrement a réussi&quot;
++
++#: root/index.tt:10
+ msgid &quot;Password&quot;
+ msgstr &quot;Mot de passe&quot;
+
+-#: lib/CatDap/Controller/user.pm:267
+-#, fuzzy
++#: lib/CatDap/Controller/user.pm:290
+ msgid &quot;Password incorrect&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;Mot de passe incorrect&quot;
+
+-#: lib/CatDap/Controller/admin.pm:532
++#: lib/CatDap/Controller/admin.pm:542
+ msgid &quot;Password reset and email sent&quot;
++msgstr &quot;Mot de passe réinitialiser, email envoyé&quot;
++
++#: root/register/index.tt:12
++msgid &quot;Personal Information&quot;
+ msgstr &quot;&quot;
+
+ #: root/email/admin/password.tt:5
+ msgid &quot;Please click below to change your password&quot;
++msgstr &quot;Cliquer ici pour changer votre mot de passe&quot;
++
++#: root/admin/index.tt:1
++msgid &quot;Please use the menus above.&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:18 root/register/index.tt:43 root/register/index.tt:6
++#: root/admin/account_promote.tt:25
++msgid &quot;Primary group&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:71
++msgid &quot;Promote&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:62
++msgid &quot;Promote user to posixAccount with primary group:&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:16 root/register/index.tt:3 root/register/index.tt:35
+ msgid &quot;Register&quot;
+ msgstr &quot;S'enregistrer&quot;
+
+ #: root/register/complete.tt:1
+ msgid &quot;Registration completed&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Enregistrement terminé&quot;
+
+ #: root/register/complete.tt:4
+ msgid &quot;Registration was successful.&quot;
+-msgstr &quot;&quot;
++msgstr &quot;L'enregistrement a réussi&quot;
+
+-#: root/user/firstlogin.tt:9 root/user/password.tt:13
++#: root/forgot_password/confirm.tt:11 root/user/firstlogin.tt:10
++#: root/user/password.tt:15
+ msgid &quot;Repeat New Password&quot;
++msgstr &quot;Répéter le nouveau de passe&quot;
++
++#: root/admin/account_modify.tt:1
++#, fuzzy
++msgid &quot;Reset password&quot;
++msgstr &quot;Mot de passe actuel&quot;
++
++#: root/admin/account.tt:22
++msgid &quot;Search&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:26
++#: root/admin/account.tt:4 root/admin/group.tt:5
++msgid &quot;Search by&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:4
++msgid &quot;Select&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:18
++#, fuzzy
++msgid &quot;Send me my password&quot;
++msgstr &quot;Changer le mot de passe&quot;
++
++#: root/forgot_password/confirm.tt:16
++#, fuzzy
++msgid &quot;Set new password&quot;
++msgstr &quot;Répéter le nouveau de passe&quot;
++
++#: root/register/check.tt:1
++msgid &quot;Success&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:10 root/admin/account.tt:35
++#: root/admin/account_promote.tt:8 root/register/index.tt:16
+ msgid &quot;Surname&quot;
+-msgstr &quot;Surnom&quot;
++msgstr &quot;Nom&quot;
+
+-#: lib/CatDap/Controller/register.pm:56
++#: lib/CatDap/Controller/register.pm:70
+ msgid &quot;The first name supplied contains illegal characters&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Le prénom proposé contient des caractères interdits&quot;
+
+-#: lib/CatDap/Controller/register.pm:61
++#: lib/CatDap/Controller/register.pm:75
+ msgid &quot;The surname supplied contains illegal characters&quot;
++msgstr &quot;Le nom proposé contient des caractères interdits&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:66
++msgid &quot;This email address is not bound to an account&quot;
+ msgstr &quot;&quot;
+
+ #: root/email/activation.tt:3
+-#, fuzzy
+ msgid &quot;To activate your account, please follow the link below.&quot;
+ msgstr &quot;Pour activer votre compte, merci de suivre le lien ci dessous.&quot;
+
+-#: root/user/index.tt:13
++#: root/email/forgot_password.tt:3
++#, fuzzy
++msgid &quot;To reset your password, please follow the link below.&quot;
++msgstr &quot;Pour activer votre compte, merci de suivre le lien ci dessous.&quot;
++
++#: root/admin/account_modify.tt:35 root/user/index.tt:29
+ msgid &quot;Update&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Mettre à jour&quot;
+
+-#: root/index.tt:7 root/register/index.tt:18
++#: root/admin/account.tt:32 root/admin/account.tt:7
++#: root/admin/account_promote.tt:5 root/index.tt:6 root/register/index.tt:7
++#: root/register/index.tt:8
+ msgid &quot;Username&quot;
+ msgstr &quot;Nom d'utilisateur&quot;
+
++#: lib/CatDap/Controller/register.pm:65
++msgid &quot;Username is not authorized to be used&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:10 root/admin/account_modify.tt:9
++#: root/admin/group_modify.tt:6 root/user/index.tt:4
++msgid &quot;Value&quot;
++msgstr &quot;&quot;
++
+ #. (c.config.organisation)
++#: root/email/forgot_password.tt:2
++msgid &quot;&quot;
++&quot;Your %1 account has been requested to change the password. If you did not do &quot;
++&quot;this, or you do not want to change your password; you can just do nothing.&quot;
++msgstr &quot;&quot;
++
++#. (c.config.organisation)
+ #: root/email/activation.tt:2
+ msgid &quot;Your %1 account has been successfully created, but requires activation.&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Votre compte %1 a été crée mais requiert d'être activé&quot;
+
+ #. (c.user.username)
+ #: root/email/admin/password.tt:3
+ msgid &quot;Your password was reset by %1&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Votre mot de passe a été réinitialisé par %1&quot;
+
+ #: lib/CatDap/Controller/user.pm:61
+ msgid &quot;Your session has expired&quot;
++msgstr &quot;Votre session a expiré&quot;
++
++#: root/admin/account.tt:15 root/admin/group.tt:15
++msgid &quot;contains&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:17
+-msgid &quot;or&quot;
+-msgstr &quot;ou&quot;
++#: root/admin/group_modify.tt:14
++#, fuzzy
++msgid &quot;delete&quot;
++msgstr &quot;Supprimer&quot;
+
+-#: lib/CatDap/Controller/admin.pm:516
+-#, fuzzy
++#: root/admin/account.tt:17 root/admin/group.tt:17
++msgid &quot;greater than or equal to&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:16 root/admin/group.tt:16
++msgid &quot;is exactly&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:18 root/admin/group.tt:18
++msgid &quot;less than&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:10
++msgid &quot;member&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/admin.pm:526
+ msgid &quot;password reset&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;réinitialisation du mot de passe&quot;
+
++#: root/admin/account_modify.tt:53
++msgid &quot;with value&quot;
++msgstr &quot;&quot;
++
++#~ msgid &quot;or&quot;
++#~ msgstr &quot;ou&quot;
++
+ #~ msgid &quot;Mageia Identity Activation&quot;
+ #~ msgstr &quot;Activation de l'identité Mageia&quot;
+
+
+<a id="identityCatDapbrancheslivelibCatDapI18Nmessagespot">Modified: identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot 2011-01-05 15:32:57 UTC (rev 212)
+@@ -15,37 +15,67 @@
+ &quot;Content-Type: text/plain; charset=CHARSET\n&quot;
+ &quot;Content-Transfer-Encoding: 8bit\n&quot;
+
+-#: lib/CatDap/Controller/register.pm:119
++#: lib/CatDap/Controller/register.pm:133
+ msgid &quot;Activation&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/index.tt:28 root/user/index.tt:8
++#: root/admin/account_addoc.tt:28 root/admin/account_modify.tt:24 root/admin/group_modify.tt:18 root/user/index.tt:19 root/user/index.tt:46
+ msgid &quot;Add&quot;
+ msgstr &quot;&quot;
+
++#: root/admin/account_modify.tt:85
++msgid &quot;Add ObjectClass&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:47
++msgid &quot;Add attribute&quot;
++msgstr &quot;&quot;
++
++#. (oc, dn)
++#: root/admin/account_addoc.tt:1
++msgid &quot;Adding objectclass %1 to dn %2&quot;
++msgstr &quot;&quot;
++
+ #: lib/CatDap/Controller/register.pm:49
+ msgid &quot;Addresses do not match&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:75
++#: lib/CatDap/Controller/register.pm:89
+ msgid &quot;An account already exists with this email address&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:80
++#: lib/CatDap/Controller/register.pm:94
+ msgid &quot;An account already exists with this username&quot;
+ msgstr &quot;&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/admin.pm:529
+-msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process f you entered the correct email address: %1&quot;
++#: lib/CatDap/Controller/register.pm:145
++msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process if you entered the correct email address. Errors %1&quot;
+ msgstr &quot;&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/register.pm:131
+-msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process if you entered the correct email address. Errors %1&quot;
++#: lib/CatDap/Controller/admin.pm:539
++msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process if you entered the correct email address: %1&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/firstlogin.tt:14 root/user/password.tt:18
++#. ($errors)
++#: lib/CatDap/Controller/forgot_password.pm:105
++msgid &quot;An error occured sending the email, please try again later. Errors %1&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:9 root/admin/account_modify.tt:8 root/admin/group_modify.tt:5 root/user/index.tt:4
++msgid &quot;Attribute&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/register.pm:56
++msgid &quot;Cannot check /etc/passwd, please warn system administrators&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:29
++msgid &quot;Captcha&quot;
++msgstr &quot;&quot;
++
++#: root/user/firstlogin.tt:14 root/user/password.tt:19
+ msgid &quot;Change&quot;
+ msgstr &quot;&quot;
+
+@@ -57,7 +87,11 @@
+ msgid &quot;Check your mail for activation instructions.&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:34
++#: root/forgot_password/complete.tt:5
++msgid &quot;Check your mail for password reset instructions.&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:24
+ msgid &quot;Confirm Email address&quot;
+ msgstr &quot;&quot;
+
+@@ -67,11 +101,11 @@
+
+ #. (cn)
+ #. (entry.cn)
+-#: root/email/activation.tt:1 root/email/admin/password.tt:1
++#: root/email/activation.tt:1 root/email/admin/password.tt:1 root/email/forgot_password.tt:1
+ msgid &quot;Dear %1,&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/index.tt:9
++#: root/admin/account_modify.tt:27 root/user/index.tt:22
+ msgid &quot;Delete&quot;
+ msgstr &quot;&quot;
+
+@@ -79,19 +113,67 @@
+ msgid &quot;Edit&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:30
++#: root/admin/account.tt:33 root/admin/account.tt:8 root/admin/account_promote.tt:6 root/register/index.tt:20
++msgid &quot;Email&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:11 root/register/index.tt:21
+ msgid &quot;Email address&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:22
++#: root/forgot_password/complete.tt:1
++msgid &quot;Email sent.&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:2
++msgid &quot;Enter new password.&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:32
++msgid &quot;Enter text&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:34 root/admin/account_promote.tt:7
++msgid &quot;First Name&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:13
+ msgid &quot;First name&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:52
++#: lib/CatDap/Controller/forgot_password.pm:94
++msgid &quot;Forgot password&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:5
++msgid &quot;Forgot your password?&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:17 root/index.tt:18
++msgid &quot;Forgotten password?&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:36 root/admin/account.tt:9 root/admin/account_promote.tt:9
++msgid &quot;Full Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:27
++msgid &quot;Group Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:9
++msgid &quot;Group name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:2
++msgid &quot;Groups&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:48 lib/CatDap/Controller/register.pm:52
+ msgid &quot;Incorrect validation text, please try again&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:46
++#: lib/CatDap/Controller/forgot_password.pm:45 lib/CatDap/Controller/register.pm:46
+ msgid &quot;Invalid email address&quot;
+ msgstr &quot;&quot;
+
+@@ -99,39 +181,67 @@
+ msgid &quot;Invalid username&quot;
+ msgstr &quot;&quot;
+
+-#: root/template/header:12 root/user/fake.tt:3
++#: lib/CatDap/Controller/register.pm:59
++msgid &quot;Invalid username, already used by system&quot;
++msgstr &quot;&quot;
++
++#: root/template/header:10 root/user/fake.tt:3
+ msgid &quot;Log out&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:1 root/index.tt:17
++#: root/index.tt:1 root/index.tt:13
+ msgid &quot;Login&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/firstlogin.tt:5 root/user/password.tt:9
++#: root/forgot_password/confirm.tt:8 root/user/firstlogin.tt:5 root/user/password.tt:10
+ msgid &quot;New Password&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/user.pm:273
++#: lib/CatDap/Controller/user.pm:296
+ msgid &quot;New passwords dont match&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:11
++#: root/forgot_password/complete.tt:4
++msgid &quot;Operation was successful.&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:10
+ msgid &quot;Password&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/user.pm:267
++#: lib/CatDap/Controller/user.pm:290
+ msgid &quot;Password incorrect&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/admin.pm:532
++#: lib/CatDap/Controller/admin.pm:542
+ msgid &quot;Password reset and email sent&quot;
+ msgstr &quot;&quot;
+
++#: root/register/index.tt:12
++msgid &quot;Personal Information&quot;
++msgstr &quot;&quot;
++
+ #: root/email/admin/password.tt:5
+ msgid &quot;Please click below to change your password&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:18 root/register/index.tt:43 root/register/index.tt:6
++#: root/admin/index.tt:1
++msgid &quot;Please use the menus above.&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:25
++msgid &quot;Primary group&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:71
++msgid &quot;Promote&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:62
++msgid &quot;Promote user to posixAccount with primary group:&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:16 root/register/index.tt:3 root/register/index.tt:35
+ msgid &quot;Register&quot;
+ msgstr &quot;&quot;
+
+@@ -143,35 +253,84 @@
+ msgid &quot;Registration was successful.&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/firstlogin.tt:9 root/user/password.tt:13
++#: root/forgot_password/confirm.tt:11 root/user/firstlogin.tt:10 root/user/password.tt:15
+ msgid &quot;Repeat New Password&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:26
++#: root/admin/account_modify.tt:1
++msgid &quot;Reset password&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:22
++msgid &quot;Search&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:4 root/admin/group.tt:5
++msgid &quot;Search by&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:4
++msgid &quot;Select&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:18
++msgid &quot;Send me my password&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:16
++msgid &quot;Set new password&quot;
++msgstr &quot;&quot;
++
++#: root/register/check.tt:1
++msgid &quot;Success&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:10 root/admin/account.tt:35 root/admin/account_promote.tt:8 root/register/index.tt:16
+ msgid &quot;Surname&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:56
++#: lib/CatDap/Controller/register.pm:70
+ msgid &quot;The first name supplied contains illegal characters&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:61
++#: lib/CatDap/Controller/register.pm:75
+ msgid &quot;The surname supplied contains illegal characters&quot;
+ msgstr &quot;&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:66
++msgid &quot;This email address is not bound to an account&quot;
++msgstr &quot;&quot;
++
+ #: root/email/activation.tt:3
+ msgid &quot;To activate your account, please follow the link below.&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/index.tt:13
++#: root/email/forgot_password.tt:3
++msgid &quot;To reset your password, please follow the link below.&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:35 root/user/index.tt:29
+ msgid &quot;Update&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:7 root/register/index.tt:18
++#: root/admin/account.tt:32 root/admin/account.tt:7 root/admin/account_promote.tt:5 root/index.tt:6 root/register/index.tt:7 root/register/index.tt:8
+ msgid &quot;Username&quot;
+ msgstr &quot;&quot;
+
++#: lib/CatDap/Controller/register.pm:65
++msgid &quot;Username is not authorized to be used&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:10 root/admin/account_modify.tt:9 root/admin/group_modify.tt:6 root/user/index.tt:4
++msgid &quot;Value&quot;
++msgstr &quot;&quot;
++
+ #. (c.config.organisation)
++#: root/email/forgot_password.tt:2
++msgid &quot;Your %1 account has been requested to change the password. If you did not do this, or you do not want to change your password; you can just do nothing.&quot;
++msgstr &quot;&quot;
++
++#. (c.config.organisation)
+ #: root/email/activation.tt:2
+ msgid &quot;Your %1 account has been successfully created, but requires activation.&quot;
+ msgstr &quot;&quot;
+@@ -185,10 +344,34 @@
+ msgid &quot;Your session has expired&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:17
+-msgid &quot;or&quot;
++#: root/admin/account.tt:15 root/admin/group.tt:15
++msgid &quot;contains&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/admin.pm:516
++#: root/admin/group_modify.tt:14
++msgid &quot;delete&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:17 root/admin/group.tt:17
++msgid &quot;greater than or equal to&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:16 root/admin/group.tt:16
++msgid &quot;is exactly&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:18 root/admin/group.tt:18
++msgid &quot;less than&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:10
++msgid &quot;member&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/admin.pm:526
+ msgid &quot;password reset&quot;
+ msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:53
++msgid &quot;with value&quot;
++msgstr &quot;&quot;
+
+<a id="identityCatDapbrancheslivelibCatDappm">Modified: identity/CatDap/branches/live/lib/CatDap.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -22,6 +22,7 @@
+ Authentication
+ Authorization::Roles
+ I18N
++ Unicode::Encoding
+ /;
+
+ extends 'Catalyst';
+
+<a id="identityCatDapbranchesliverootadminaccounttt">Modified: identity/CatDap/branches/live/root/admin/account.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,24 +1,25 @@
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;table&gt;
+ &lt;tr&gt;
+- &lt;td&gt;Search by&lt;/td&gt;
++ &lt;td&gt;[% l('Search by') %]&lt;/td&gt;
+ &lt;td&gt;
+ &lt;select name=&quot;attribute&quot;&gt;
+- &lt;option value=&quot;uid&quot;&gt;Username&lt;/option&gt;
+- &lt;option value=&quot;mail&quot;&gt;Email&lt;/option&gt;
+- &lt;option value=&quot;cn&quot;&gt;Full Name&lt;/option&gt;
+- &lt;option value=&quot;sn&quot;&gt;Surname&lt;/option&gt;
++ &lt;option value=&quot;uid&quot;&gt;[% l('Username') %]&lt;/option&gt;
++ &lt;option value=&quot;mail&quot;&gt;[% l('Email') %]&lt;/option&gt;
++ &lt;option value=&quot;cn&quot;&gt;[% l('Full Name') %]&lt;/option&gt;
++ &lt;option value=&quot;sn&quot;&gt;[% l('Surname') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td&gt;
+ &lt;!-- td&gt;
+ &lt;select name=&quot;matchtype&quot;&gt;
+- &lt;option value=&quot;substring&quot;&gt;contains&lt;/option&gt;
+- &lt;option value=&quot;exact&quot;&gt;is exactly&lt;/option&gt;
+- &lt;option value=&quot;gte&quot;&gt;greater than or equal to&lt;/option&gt;
+- &lt;option value=&quot;lt&quot;&gt;less than&lt;/option&gt;
++ &lt;option value=&quot;substring&quot;&gt;[% l('contains') %]&lt;/option&gt;
++ &lt;option value=&quot;exact&quot;&gt;[% l('is exactly') %]&lt;/option&gt;
++ &lt;option value=&quot;gte&quot;&gt;[% l('greater than or equal to') %]&lt;/option&gt;
++ &lt;option value=&quot;lt&quot;&gt;[% l('less than') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td --&gt;
+- &lt;td&gt;&lt;input name=&quot;value&quot; value=&quot;&quot; /&gt;&lt;/td&gt;
++ &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;value&quot; value=&quot;&quot; /&gt;&lt;/td&gt;
++ &lt;td&gt;&lt;button type=&quot;submit&quot; value=&quot;[% l('Search') %]&quot;&gt;[% l('Search') %]&lt;/button&gt;&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;/table&gt;
+ &lt;/form&gt;
+@@ -28,11 +29,11 @@
+ [% IF entries %]
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Username&lt;/th&gt;
+- &lt;th&gt;Email&lt;/th&gt;
+- &lt;th&gt;First Name&lt;/th&gt;
+- &lt;th&gt;Surname&lt;/td&gt;
+- &lt;th&gt;Full Name&lt;/td&gt;
++ &lt;th&gt;[% l('Username') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Email') %]&lt;/th&gt;
++ &lt;th&gt;[% l('First Name') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Surname') %]&lt;/td&gt;
++ &lt;th&gt;[% l('Full Name') %]&lt;/td&gt;
+ &lt;/tr&gt;
+ [% FOREACH entry IN entries %]
+ &lt;tr&gt;
+
+<a id="identityCatDapbranchesliverootadminaccount_addoctt">Modified: identity/CatDap/branches/live/root/admin/account_addoc.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_addoc.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_addoc.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,4 @@
+-Adding objectclass [% oc %] to dn [% dn %]
++[% l('Adding objectclass [_1] to dn [_2]', oc, dn) %]
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type=&quot;hidden&quot; name=&quot;dn&quot; value=&quot;[% dn %]&quot; /&gt;
+@@ -6,8 +6,8 @@
+ &lt;input type=&quot;hidden&quot; name=&quot;objectclass&quot; value=&quot;[% oc %]&quot; /&gt;
+ &lt;table&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Attribute&lt;/th&gt;
+- &lt;th&gt;Value&lt;/th&gt;
++ &lt;th&gt;[% l('Attribute') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Value') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH attr IN must %]
+ [% IF attr != &quot;objectClass&quot; %]
+@@ -25,6 +25,6 @@
+ &lt;/tr&gt;
+ [% END %]
+ &lt;/table&gt;
+- &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Add&quot; /&gt;&lt;/p&gt;
++ &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot; /&gt;&lt;/p&gt;
+
+ &lt;/form&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootadminaccount_grouptt">Modified: identity/CatDap/branches/live/root/admin/account_group.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_group.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_group.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,4 @@
+-&lt;h2&gt;Add user [% uid %] to a new group&lt;/h2&gt;
++&lt;h2&gt;[% l('Add user [_1] to a new group, uid) %]&lt;/h2&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type='hidden' name='uid' value='[% uid %]' /&gt;
+@@ -8,12 +8,12 @@
+ &lt;option value='[% group.cn %]'&gt;[% group.cn %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type='submit' value='Add' /&gt;
++ &lt;input type='submit' value='[% l('Add') %]' /&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+
+-&lt;h2&gt;Delete user [% uid %] from an existing group:&lt;/h2&gt;
++&lt;h2&gt;[% l('Delete user [_1] from an existing group:', uid) %] &lt;/h2&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type='hidden' name='uid' value='[% uid %]' /&gt;
+@@ -23,7 +23,7 @@
+ &lt;option value='[% group.cn %]'&gt;[% group.cn %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type='submit' value='Delete' /&gt;
++ &lt;input type='submit' value='[% l('Delete') %]' /&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootadminaccount_modifytt">Modified: identity/CatDap/branches/live/root/admin/account_modify.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_modify.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_modify.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,12 +1,12 @@
+-&lt;a href=&quot;[% c.uri_for('/admin/password') %]/[% uid %]&quot;&gt;Reset password&lt;/a&gt;
+-&lt;a href=&quot;[% c.uri_for('/admin/account_group') %]/[% uid %]&quot;&gt;Groups&lt;/a&gt;
++&lt;a href=&quot;[% c.uri_for('/admin/password') %]/[% uid %]&quot;&gt;[% l('Reset password') %]&lt;/a&gt;
++&lt;a href=&quot;[% c.uri_for('/admin/account_group') %]/[% uid %]&quot;&gt;[% l('Groups') %]&lt;/a&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type='hidden' name='operation' value='replace' /&gt;
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Attribute&lt;/th&gt;
+- &lt;th&gt;Value&lt;/th&gt;
++ &lt;th&gt;[% l('Attribute') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Value') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH attr IN values %]
+ &lt;tr&gt;
+@@ -21,10 +21,10 @@
+ &lt;br/&gt;
+ [% END %]
+ [% IF attr.addable AND attr.editable %]
+- &lt;a href=&quot;[% c.uri_for('/admin/account_edit') %]/add/[% attr.name %]&quot;&gt;Add&lt;/a&gt;
++ &lt;a href=&quot;[% c.uri_for('/admin/account_edit') %]/add/[% attr.name %]&quot;&gt;[% l('Add') %]&lt;/a&gt;
+ [% END %]
+ [% IF attr.removable AND attr.editable %]
+- &lt;a href=&quot;[% c.uri_for('/admin/account_modifydel') %]/[% uid %]/[% attr.name %]/[% val %]&quot;&gt;Delete&lt;/a&gt;
++ &lt;a href=&quot;[% c.uri_for('/admin/account_modifydel') %]/[% uid %]/[% attr.name %]/[% val %]&quot;&gt;[% l('Delete') %]&lt;/a&gt;
+ [% END %]
+ [% END %]
+ &lt;/td&gt;
+@@ -32,7 +32,7 @@
+ [% END %]
+ &lt;tr&gt;
+ &lt;td colspan=2 align=center&gt;
+- &lt;input type='Submit' value='Update'&gt;
++ &lt;input type='Submit' value='[% l('Update') %]'&gt;
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;/table&gt;
+@@ -44,13 +44,13 @@
+ &lt;input type=&quot;hidden&quot; name=&quot;operation&quot; value=&quot;add&quot; /&gt;
+
+ &lt;p&gt;
+- Add attribute
++ [% l('Add attribute') %]
+ &lt;select name='attribute'&gt;
+ [% FOREACH attr IN may %]
+ &lt;option value=&quot;[% attr %]&quot;&gt;[% attr %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- with value
++ [% l('with value') %]
+ &lt;input name=&quot;value&quot; value=&quot;&quot; /&gt;
+ &lt;input type=&quot;submit&quot; value=&quot;Add&quot; /&gt;
+ &lt;/p&gt;
+@@ -59,7 +59,7 @@
+ &lt;hr /&gt;
+
+ [% IF groups %]
+-&lt;p&gt;Promote user to posixAccount with primary group: &lt;/p&gt;
++&lt;p&gt;[% l('Promote user to posixAccount with primary group:') %] &lt;/p&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;[% c.uri_for('/admin/account_promote') %]&quot;&gt;
+ &lt;input type=&quot;hidden&quot; name=&quot;dn&quot; value=&quot;[% dn %]&quot; /&gt;
+@@ -68,7 +68,7 @@
+ &lt;option value=&quot;[% group.gidNumber %]&quot;&gt;[% group.name %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type=&quot;submit&quot; value=&quot;Promote&quot; /&gt;
++ &lt;input type=&quot;submit&quot; value=&quot;[% l('Promote') %]&quot; /&gt;
+ &lt;/form&gt;
+ [% END %]
+
+@@ -82,7 +82,7 @@
+ &lt;option value='[% oc %]'&gt;[% oc %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type=&quot;submit&quot; value=&quot;Add ObjectClass&quot; /&gt;
++ &lt;input type=&quot;submit&quot; value=&quot;[% l('Add ObjectClass') %]&quot; /&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootadminaccount_promotett">Modified: identity/CatDap/branches/live/root/admin/account_promote.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_promote.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_promote.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,12 +1,12 @@
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Select&lt;/th&gt;
+- &lt;th&gt;Username&lt;/th&gt;
+- &lt;th&gt;Email&lt;/th&gt;
+- &lt;th&gt;First Name&lt;/th&gt;
+- &lt;th&gt;Surname&lt;/td&gt;
+- &lt;th&gt;Full Name&lt;/td&gt;
++ &lt;th&gt;[% l('Select') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Username') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Email') %]&lt;/th&gt;
++ &lt;th&gt;[% l('First Name') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Surname') %]&lt;/td&gt;
++ &lt;th&gt;[% l('Full Name') %]&lt;/td&gt;
+ &lt;/tr&gt;
+ [% FOREACH entry IN entries %]
+ &lt;tr&gt;
+@@ -22,7 +22,7 @@
+
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;td&gt;Primary group&lt;/td&gt;
++ &lt;td&gt;[% l('Primary group') %]&lt;/td&gt;
+ &lt;td&gt;
+ &lt;select name=&quot;gid&quot;&gt;
+ [% FOREACH group IN groups %]
+
+<a id="identityCatDapbranchesliverootadmingrouptt">Modified: identity/CatDap/branches/live/root/admin/group.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/group.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/group.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -2,20 +2,20 @@
+ &lt;table&gt;
+ &lt;tr&gt;
+ &lt;td&gt;
+-Search by
++[% l('Search by') %]
+ &lt;/td&gt;
+ &lt;td&gt;
+ &lt;select name=&quot;attribute&quot;&gt;
+-&lt;option value=&quot;cn&quot;&gt;Group name&lt;/option&gt;
+-&lt;option value=&quot;member&quot;&gt;member&lt;/option&gt;
++&lt;option value=&quot;cn&quot;&gt;[% l('Group name') %]&lt;/option&gt;
++&lt;option value=&quot;member&quot;&gt;[% l('member') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td&gt;
+ &lt;!-- td&gt;
+ &lt;select name=&quot;matchtype&quot;&gt;
+-&lt;option value=&quot;substring&quot;&gt;contains&lt;/option&gt;
+-&lt;option value=&quot;exact&quot;&gt;is exactly&lt;/option&gt;
+-&lt;option value=&quot;gte&quot;&gt;greater than or equal to&lt;/option&gt;
+-&lt;option value=&quot;lt&quot;&gt;less than&lt;/option&gt;
++&lt;option value=&quot;substring&quot;&gt;[% l('contains') %]&lt;/option&gt;
++&lt;option value=&quot;exact&quot;&gt;[% l('is exactly') %]&lt;/option&gt;
++&lt;option value=&quot;gte&quot;&gt;[% l('greater than or equal to') %]&lt;/option&gt;
++&lt;option value=&quot;lt&quot;&gt;[% l('less than') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td --&gt;
+ &lt;td&gt;&lt;input name='value'&gt;&lt;/td&gt;
+@@ -24,7 +24,7 @@
+ [% IF entries %]
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+-&lt;th&gt;Group Name&lt;/th&gt;
++&lt;th&gt;[% l('Group Name') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH entry IN entries %]
+ &lt;tr&gt;
+
+<a id="identityCatDapbranchesliverootadmingroup_modifytt">Modified: identity/CatDap/branches/live/root/admin/group_modify.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/group_modify.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/group_modify.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -2,8 +2,8 @@
+ &lt;input type='hidden' name='dn' value='[% group.dn %]'&gt;
+ &lt;table&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Attribute&lt;/th&gt;
+- &lt;th&gt;Value&lt;/th&gt;
++ &lt;th&gt;[% l('Attribute') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Value') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH attr IN group.attributes %]
+ &lt;tr&gt;
+@@ -11,11 +11,11 @@
+ &lt;td&gt;
+ [% FOREACH value IN group.get_value(attr) %]
+ [% value %]
+- &lt;a href=&quot;[% c.uri_for('/admin/group_modify') %]/delete/[% group.dn %]/[% attr %]/[% value %]&quot;&gt;delete&lt;/a&gt;
++ &lt;a href=&quot;[% c.uri_for('/admin/group_modify') %]/delete/[% group.dn %]/[% attr %]/[% value %]&quot;&gt;[% l('delete') %]&lt;/a&gt;
+ &lt;br/&gt;
+ [% END %]
+ &lt;input name=&quot;[% attr %]&quot; value=&quot;&quot; /&gt;
+- &lt;input type=&quot;submit&quot; value=&quot;Add&quot; /&gt;
++ &lt;input type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot; /&gt;
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ [% END %]
+
+<a id="identityCatDapbranchesliverootadminindextt">Modified: identity/CatDap/branches/live/root/admin/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1 +1 @@
+-&lt;p&gt;Please use the menus above.&lt;/p&gt;
+\ No newline at end of file
++&lt;p&gt;[% l('Please use the menus above.') %]&lt;/p&gt;
+
+<a id="identityCatDapbranchesliverootemailactivationtt">Modified: identity/CatDap/branches/live/root/email/activation.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/email/activation.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/email/activation.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -4,4 +4,4 @@
+ [% url %]
+
+ --
+-http://mageia.org/
+\ No newline at end of file
++[% c.config.project_url %]
+
+<a id="identityCatDapbranchesliverootemailadminpasswordtt">Modified: identity/CatDap/branches/live/root/email/admin/password.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/email/admin/password.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/email/admin/password.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -7,4 +7,4 @@
+ [% url %]
+
+ --
+-http://mageia.org/
+\ No newline at end of file
++[% c.config.project_url %]
+
+<a id="identityCatDapbranchesliverootindextt">Modified: identity/CatDap/branches/live/root/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,21 +1,22 @@
+ &lt;h1&gt;[% l('Login') %]&lt;/h1&gt;
+
++&lt;div id=&quot;login_form&quot;&gt;
+ &lt;form method=&quot;post&quot; action=&quot;/user&quot;&gt;
++ &lt;div id=&quot;login_form_inputs&quot;&gt;
++ &lt;label for=&quot;username_&quot;&gt;[% l('Username : ') %]&lt;/label&gt;
++ &lt;input id=&quot;username_&quot; type=&quot;text&quot; name=&quot;username&quot; value=&quot;[% c.user.username %]&quot; /&gt;
++ &lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;username_&quot;&gt;[% l('Username') %]&lt;/label&gt;
+- &lt;input id=&quot;username_&quot; type=&quot;text&quot; name=&quot;username&quot; value=&quot;[% c.user.username %]&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;
+- &lt;label for=&quot;password_&quot;&gt;[% l('Password') %]&lt;/label&gt;
+- &lt;input id=&quot;password_&quot; type=&quot;password&quot; name=&quot;password&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; /&gt;
+- [% l('or') %]
+- &lt;a href=&quot;/register&quot;&gt;[% l('Register') %]&lt;/a&gt;&lt;/p&gt;
+-
+- &lt;p&gt;@todo [% l('Forgotten password?') %]&lt;/p&gt;
+-
++ &lt;label for=&quot;password_&quot;&gt;[% l('Password : ') %]&lt;/label&gt;
++ &lt;input id=&quot;password_&quot; type=&quot;password&quot; name=&quot;password&quot; /&gt;
++ &lt;br /&gt;
++ &lt;/div&gt;
++ &lt;div id=&quot;login_form_line&quot;&gt;
++ &lt;span&gt;&lt;a href=&quot;/register&quot;&gt;[% l('Register') %]&lt;/a&gt; |
++ @todo [% l('Forgotten password?') %]
++ &lt;!--&lt;a href=&quot;/forgot_password&quot;&gt;[% l('Forgotten password?') %]&lt;/a&gt; --&gt;
++ &lt;/span&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; &gt;[% l('Login') %]&lt;/button&gt;
++ &lt;/div&gt;
+ &lt;/form&gt;
++&lt;/div&gt;
+
+<a id="identityCatDapbranchesliverootregisterchecktt">Modified: identity/CatDap/branches/live/root/register/check.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/register/check.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/register/check.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,4 @@
+-&lt;h2&gt;Success&lt;/h2&gt;
++&lt;h2&gt;[% l('Success') %]&lt;/h2&gt;
+ &lt;p&gt;
+ [% message %]
+ &lt;/p&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootregisterindextt">Modified: identity/CatDap/branches/live/root/register/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/register/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/register/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,48 +1,37 @@
+-[% MACRO l(text, args) BLOCK;
+- c.localize(text, args);
+-END; %]
+
+
+ &lt;h2&gt;[% l('Register') %]&lt;/h2&gt;
+
+-&lt;p class=&quot;error&quot;&gt;
+- [% FOREACH error IN errors %]
+- [% error %]&lt;br/&gt;
+- [% END %]
+-&lt;/p&gt;
+-
++&lt;div id=&quot;input_form&quot;&gt;
+ &lt;form method=&quot;post&quot; action=&quot;/register/check&quot;&gt;
++ &lt;h3&gt;[% l('Username') %]&lt;/h3&gt;
++ &lt;label for=&quot;uid_&quot;&gt;[% l('Username') %]&lt;/label&gt;&lt;br /&gt;
++ &lt;input id=&quot;uid_&quot; type=&quot;text&quot; name=&quot;uid&quot; value=&quot;[% c.request.params.uid %]&quot; /&gt;&lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;uid_&quot;&gt;[% l('Username') %]&lt;/label&gt;
+- &lt;input id=&quot;uid_&quot; type=&quot;text&quot; name=&quot;uid&quot; value=&quot;[% c.request.params.uid %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;p&gt;
++ &lt;h3&gt;[% l('Personal Information') %]&lt;/h3&gt;
++ &lt;label for=&quot;gn_&quot;&gt;[% l('First name') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;gn_&quot; type=&quot;text&quot; name=&quot;gn&quot; value=&quot;[% c.request.params.gn %]&quot; /&gt;&lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;gn_&quot;&gt;[% l('First name') %]&lt;/label&gt;
+- &lt;input id=&quot;gn_&quot; type=&quot;text&quot; name=&quot;gn&quot; value=&quot;[% c.request.params.gn %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;label for=&quot;sn_&quot;&gt;[% l('Surname') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;sn_&quot; type=&quot;text&quot; name=&quot;sn&quot; value=&quot;[% c.request.params.sn %]&quot; /&gt;&lt;br /&gt;
++ &lt;/p&gt;
++ &lt;p&gt;
++ &lt;h3&gt;[% l('Email') %]&lt;/h3&gt;
++ &lt;label for=&quot;mail1_&quot;&gt;[% l('Email address') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;mail1_&quot; type=&quot;text&quot; name=&quot;mail1&quot; value=&quot;[% c.request.params.mail1 %]&quot; /&gt;&lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;sn_&quot;&gt;[% l('Surname') %]&lt;/label&gt;
+- &lt;input id=&quot;sn_&quot; type=&quot;text&quot; name=&quot;sn&quot; value=&quot;[% c.request.params.sn %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;label for=&quot;mail2_&quot;&gt;[% l('Confirm Email address') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;mail2_&quot; type=&quot;text&quot; name=&quot;mail2&quot; value=&quot;[% c.request.params.mail2 %]&quot; /&gt;&lt;br /&gt;
++ &lt;/p&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;mail1_&quot;&gt;[% l('Email address') %]&lt;/label&gt;
+- &lt;input id=&quot;mail1_&quot; type=&quot;text&quot; name=&quot;mail1&quot; value=&quot;[% c.request.params.mail1 %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;p&gt;
++ &lt;h3&gt;[% l('Captcha') %]&lt;/h3&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;mail2_&quot;&gt;[% l('Confirm Email address') %]&lt;/label&gt;
+- &lt;input id=&quot;mail2_&quot; type=&quot;text&quot; name=&quot;mail2&quot; value=&quot;[% c.request.params.mail2 %]&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;
+- &lt;img src=&quot;/register/captcha&quot; /&gt;
+- &lt;input type=&quot;text&quot; name=&quot;validate&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;[% l('Register') %]&quot; /&gt;&lt;/p&gt;
+-
+-&lt;/form&gt;
+\ No newline at end of file
++ &lt;img src=&quot;/register/captcha&quot; /&gt;&lt;br /&gt;
++ &lt;label for=&quot;test&quot;&gt;[% l('Enter text') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input type=&quot;text&quot; name=&quot;validate&quot; /&gt;&lt;br/&gt;
++ &lt;/p&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Register') %]&quot;&gt;[% l('Register') %]&lt;/button&gt;
++&lt;/form&gt;
++&lt;/div&gt;
+
+<a id="identityCatDapbranchesliveroottemplatefooter">Modified: identity/CatDap/branches/live/root/template/footer</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/footer 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/footer 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,5 @@
+-&lt;p&gt;2010 &lt;a href=&quot;http://mageia.org/&quot;&gt;Mageia.org&lt;/a&gt;
++&lt;div class=&quot;hnav&quot;&gt;
++&lt;div align=center&gt;&lt;p&gt;2010 &lt;a href=&quot;http://mageia.org/&quot;&gt;Mageia.org&lt;/a&gt;
+ | &lt;a href=&quot;http://mageia.org/policies/privacy/&quot;&gt;Privacy policy&lt;/a&gt;
+ | &lt;a href=&quot;http://mageia.org/faq/accounts/&quot;&gt;Mageia user accounts FAQ&lt;/a&gt;
+- &lt;/p&gt;
+\ No newline at end of file
++&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
+
+<a id="identityCatDapbranchesliveroottemplateheader">Modified: identity/CatDap/branches/live/root/template/header</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/header 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/header 2011-01-05 15:32:57 UTC (rev 212)
+@@ -8,8 +8,6 @@
+ [% IF c.user.username %]
+ &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;[% c.uri_for(&quot;/user&quot;) %]&quot;&gt;[% c.user.username %]&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
+ &lt;li&gt;&lt;a href=&quot;/user/logout&quot;&gt;[% l('Log out') %]&lt;/a&gt;&lt;/li&gt;
+- [% ELSE %]
+- &lt;li&gt;&lt;a href=&quot;/&quot;&gt;[% l('Login') %]&lt;/a&gt;&lt;/li&gt;
+ [% END %]
+ &lt;/ul&gt;
+ &lt;/div&gt;
+
+<a id="identityCatDapbranchesliveroottemplatehtml">Modified: identity/CatDap/branches/live/root/template/html</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/html 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/html 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,17 +1,17 @@
+ &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+ &lt;!DOCTYPE html&gt;
+-&lt;html lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
++&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
+ &lt;head&gt;
+ &lt;meta charset=&quot;utf-8&quot; /&gt;
+ &lt;title&gt;[% template.title or site.title or c.config.apptitle %]&lt;/title&gt;
+- &lt;meta content=&quot;description&quot; value=&quot;Mageia.org online user account panel&quot; /&gt;
+- &lt;meta content=&quot;keywords&quot; value=&quot;mageia, user, account, password&quot; /&gt;
+- &lt;meta content=&quot;robots&quot; value=&quot;index,nofollow&quot; /&gt;
+- &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/reset-fonts-grids.css&quot;&gt;
+- &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/base-min.css&quot;&gt;
++ &lt;meta name=&quot;description&quot; content=&quot;Mageia.org online user account panel&quot; /&gt;
++ &lt;meta name=&quot;keywords&quot; content=&quot;mageia, user, account, password&quot; /&gt;
++ &lt;meta name=&quot;robots&quot; content=&quot;index,nofollow&quot; /&gt;
++ &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/reset-fonts-grids.css&quot; /&gt;
++ &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/base-min.css&quot; /&gt;
+ &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/ttsite.css&quot; /&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ [% content %]
+ &lt;/body&gt;
+-&lt;/html&gt;
+\ No newline at end of file
++&lt;/html&gt;
+
+<a id="identityCatDapbranchesliveroottemplatepre">Modified: identity/CatDap/branches/live/root/template/pre</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/pre 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/pre 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,3 +1,3 @@
+-[% MACRO l(text, args) BLOCK;
++[%- MACRO l(text, args) BLOCK;
+ c.localize(text, args);
+-END; %]
++END; -%]
+
+<a id="identityCatDapbranchesliveroottemplatewrapper">Modified: identity/CatDap/branches/live/root/template/wrapper</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/wrapper 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/wrapper 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,7 +1,4 @@
+-[% MACRO l(text, args) BLOCK;
+- c.localize(text, args);
+-END; %]
+-[% IF template.name.match('\.(css|js|txt)');
++[%- IF template.name.match('\.(css|js|txt)');
+ debug(&quot;Passing page through as text: $template.name&quot;);
+ content;
+ ELSE;
+
+<a id="identityCatDapbranchesliverootuserindextt">Modified: identity/CatDap/branches/live/root/user/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/user/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/user/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,30 +1,34 @@
++&lt;div id=&quot;input_form&quot;&gt;
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+- &lt;table border=0&gt;
+- &lt;tr&gt;&lt;th&gt;Attribute&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;
++ &lt;table&gt;
++ &lt;tr&gt;&lt;th&gt;[% l('Attribute') %]&lt;/th&gt;&lt;th&gt;[% l('Value') %]&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;/tr&gt;
+ [% FOREACH attr IN values %]
+ &lt;tr&gt;
+ &lt;td&gt;[% attr.name %]&lt;/td&gt;
+ &lt;td&gt;
+ [% FOREACH val IN attr.values %]
+- [% IF attr.editable %]&lt;input type=hidden name=&quot;[% attr.name %]_old&quot; value=&quot;[% val %]&quot;&gt;
+- &lt;input name=&quot;[% attr.name %]_new&quot; value=&quot;[% val %]&quot;&gt;
++ [% IF attr.editable %]&lt;input type=&quot;hidden&quot; name=&quot;[% attr.name %]_old&quot; value=&quot;[% val %]&quot; /&gt;
++ &lt;input name=&quot;[% attr.name %]_new&quot; value=&quot;[% val %]&quot; /&gt;
+ [% ELSE %]
+ [% val %]
+ &lt;br/&gt;
+ [% END %]
++ &lt;/td&gt;
++ &lt;td&gt;
+ [% IF attr.addable AND attr.editable %]
+- &lt;a href=&quot;/user/add/[% attr.name %]&quot;&gt;[% l('Add') %]&lt;/a&gt;
++ &lt;button type=&quot;button&quot; onclick=&quot;location='/user/add/[% attr.name %]'&quot;&gt;[% l('Add') %]&lt;/button&gt;
+ [% END %]
+ [% IF attr.removable AND attr.editable %]
+- &lt;a href=&quot;/user/delete/[% attr.name %]/[% val %]&quot;&gt;[% l('Delete') %]&lt;/a&gt;
++ &lt;button type=&quot;button&quot; onclick=&quot;location='/user/delete/[% attr.name %]/[% val %]'&quot;&gt;[% l('Delete') %]&lt;/button&gt;
+ [% END %]
+ [% END %]
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ [% END %]
++ &lt;tr&gt;
++ &lt;td colspan=&quot;3&quot; style=&quot;text-align:center;&quot;&gt;&lt;button type=&quot;Submit&quot; value=&quot;[% l('Update') %]&quot;&gt;[% l('Update') %]&lt;/button&gt;&lt;/td&gt;
++ &lt;/tr&gt;
+ &lt;/table&gt;
+-
+- &lt;p&gt;&lt;input type=&quot;Submit&quot; value=&quot;[% l('Update') %]&quot; /&gt;&lt;/p&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+@@ -35,9 +39,11 @@
+ [% FOREACH attr IN may %]
+ &lt;option value=&quot;[% attr %]&quot;&gt;[% attr %]&lt;/option&gt;
+ [% END %]
++ &lt;/select&gt;
+
+ &lt;input name=&quot;value&quot; value=&quot;&quot; /&gt;
+
+- &lt;input type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot; /&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot;&gt;[% l('Add') %]&lt;/button&gt;
+ &lt;/p&gt;
+ &lt;/form&gt;
++&lt;/div&gt;
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment.html
new file mode 100644
index 000000000..49d5e4185
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/307f41b8/attachment.html
@@ -0,0 +1,2256 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[212] - merge trunk ( for good this time )</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>212</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 16:32:57 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- merge trunk ( for good this time )</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#identityCatDapbranchesliveMakefilePL">identity/CatDap/branches/live/Makefile.PL</a></li>
+<li><a href="#identityCatDapbrancheslivecatdapyml">identity/CatDap/branches/live/catdap.yml</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControllerRootpm">identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControlleradminpm">identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControllerregisterpm">identity/CatDap/branches/live/lib/CatDap/Controller/register.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapControlleruserpm">identity/CatDap/branches/live/lib/CatDap/Controller/user.pm</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapI18Nafpo">identity/CatDap/branches/live/lib/CatDap/I18N/af.po</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapI18Nfrpo">identity/CatDap/branches/live/lib/CatDap/I18N/fr.po</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDapI18Nmessagespot">identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot</a></li>
+<li><a href="#identityCatDapbrancheslivelibCatDappm">identity/CatDap/branches/live/lib/CatDap.pm</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccounttt">identity/CatDap/branches/live/root/admin/account.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_addoctt">identity/CatDap/branches/live/root/admin/account_addoc.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_grouptt">identity/CatDap/branches/live/root/admin/account_group.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_modifytt">identity/CatDap/branches/live/root/admin/account_modify.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminaccount_promotett">identity/CatDap/branches/live/root/admin/account_promote.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadmingrouptt">identity/CatDap/branches/live/root/admin/group.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadmingroup_modifytt">identity/CatDap/branches/live/root/admin/group_modify.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootadminindextt">identity/CatDap/branches/live/root/admin/index.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootemailactivationtt">identity/CatDap/branches/live/root/email/activation.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootemailadminpasswordtt">identity/CatDap/branches/live/root/email/admin/password.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootindextt">identity/CatDap/branches/live/root/index.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootregisterchecktt">identity/CatDap/branches/live/root/register/check.tt</a></li>
+<li><a href="#identityCatDapbranchesliverootregisterindextt">identity/CatDap/branches/live/root/register/index.tt</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatefooter">identity/CatDap/branches/live/root/template/footer</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplateheader">identity/CatDap/branches/live/root/template/header</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatehtml">identity/CatDap/branches/live/root/template/html</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatepre">identity/CatDap/branches/live/root/template/pre</a></li>
+<li><a href="#identityCatDapbranchesliveroottemplatewrapper">identity/CatDap/branches/live/root/template/wrapper</a></li>
+<li><a href="#identityCatDapbranchesliverootuserindextt">identity/CatDap/branches/live/root/user/index.tt</a></li>
+</ul>
+
+<h3>Property Changed</h3>
+<ul>
+<li><a href="#identityCatDapbrancheslive">identity/CatDap/branches/live/</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+
+<a id="identityCatDapbrancheslive">Property changes on: identity/CatDap/branches/live</a>
+___________________________________________________________________
+<a id="svnmergeinfo">Modified: svn:mergeinfo</a>
+ - /identity/CatDap/trunk:64,66-68,210
+ + /identity/CatDap/trunk:64,66-68,140-211
+
+<a id="identityCatDapbranchesliveMakefilePL">Modified: identity/CatDap/branches/live/Makefile.PL</a>
+===================================================================
+--- identity/CatDap/branches/live/Makefile.PL 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/Makefile.PL 2011-01-05 15:32:57 UTC (rev 212)
+@@ -13,6 +13,7 @@
+ requires 'Catalyst::Plugin::ConfigLoader';
+ requires 'Catalyst::Plugin::Static::Simple';
+ requires 'Catalyst::Plugin::I18N';
++requires 'Catalyst::Plugin::Unicode::Encoding';
+ requires 'Catalyst::Plugin::Authentication';
+ requires 'Catalyst::Plugin::Authentication::Store::LDAP';
+ requires 'Catalyst::Plugin::Captcha';
+
+<a id="identityCatDapbrancheslivecatdapyml">Modified: identity/CatDap/branches/live/catdap.yml</a>
+===================================================================
+--- identity/CatDap/branches/live/catdap.yml 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/catdap.yml 2011-01-05 15:32:57 UTC (rev 212)
+@@ -11,6 +11,7 @@
+ default_view: Web
+
+ organisation: Mageia
++project_url: http://www.mageia.org/
+ apptitle: Mageia Identity Management
+ emailfrom: noreply@mageia.org
+
+@@ -20,6 +21,8 @@
+ password: FIXME
+ host: ldap.mageia.org
+ start_tls: 1
++ options:
++ inet6: 1
+
+ # dn and password should not be required here, we rebind with credentials
+ # from the authenticated user using Model::LDAP::FromAuthentication
+@@ -28,6 +31,10 @@
+ host: ldap.mageia.org
+ start_tls: 1
+
++register:
++ login_blacklist:
++ - apache
++
+ authentication:
+ default_realm: ldap
+ realms:
+@@ -39,8 +46,10 @@
+ store:
+ class: LDAP
+ ldap_server: 'ldap.mageia.org'
++ ldap_server_options:
++ inet6: 1
+ start_tls: 1
+- binddn: cn=catdap,ou=System Accounts,dc=mageai,dc=org
++ binddn: cn=catdap,ou=System Accounts,dc=mageia,dc=org
+ bindpw: FIXME
+ user_basedn: &quot;ou=people,dc=mageia,dc=org&quot;
+ user_filter: '(&amp;(objectClass=inetOrgPerson)(uid=%s))'
+
+<a id="identityCatDapbrancheslivelibCatDapControllerRootpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/Root.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -28,7 +28,11 @@
+
+ sub index :Path :Args(0) {
+ my ( $self, $c ) = @_;
+-
++ # if user is defined, redirect to /user and let the /user page handle the authentication
++ if (defined $c-&gt;user) {
++ $c-&gt;log-&gt;debug('Redirecting to /user');
++ $c-&gt;res-&gt;redirect('/user');
++ }
+ # Hello World
+ #$c-&gt;response-&gt;body( $c-&gt;welcome_message );
+ }
+
+<a id="identityCatDapbrancheslivelibCatDapControlleradminpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/admin.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -47,7 +47,17 @@
+ my $password;
+ my $mesg;
+ my $dn;
+- my $keyprefix = sprintf( &quot;%02x%02x%02x&quot;, split /\./, $c-&gt;req-&gt;address );
++
++ # TODO merge this code with the one in user.pm
++ my $keyprefix;
++ if ($c-&gt;req-&gt;address =~ m/:/) {
++ my $address = $c-&gt;req-&gt;address;
++ $address =~ s/\[\]://;
++ $keyprefix = sprintf( &quot;%06x&quot;, $address &gt;&gt; 104 ); # if we shift right 104 bits from 128 we have 24 bits left or 3 bytes.
++ }
++ else {
++ $keyprefix = sprintf( &quot;%02x%02x%02x&quot;, split /\./, $c-&gt;req-&gt;address );
++ }
+ if ( !defined $c-&gt;user or not $c-&gt;req-&gt;cookie('key') ) {
+ $c-&gt;detach('/user/login')
+ if ( not $c-&gt;req-&gt;param('username')
+
+<a id="identityCatDapbrancheslivelibCatDapControllerregisterpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/register.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/register.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/register.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -51,6 +51,20 @@
+ if (! $c-&gt;validate_captcha($c-&gt;req-&gt;param('validate'))){
+ push @errors, $c-&gt;loc('Incorrect validation text, please try again');
+ }
++
++ if ( ! open( my $etcpasswd, &quot;/etc/passwd&quot;)) {
++ push @errors, $c-&gt;loc('Cannot check /etc/passwd, please warn system administrators');
++ } else {
++ if ( grep { /^$username:/ } &lt;$etcpasswd&gt; ) {
++ push @errors, $c-&gt;loc('Invalid username, already used by system');
++ }
++ close($etcpasswd);
++ }
++
++ if ( grep /^$username$/, @{${$c-&gt;config}{'register'}{'login_blacklist'}}) {
++ push @errors, $c-&gt;loc('Username is not authorized to be used');
++ }
++
+ if ($c-&gt;request-&gt;params-&gt;{gn} !~ /^\p{IsAlnum}+$/) {
+ push @errors, $c-&gt;loc(
+ 'The first name supplied contains illegal characters'
+@@ -108,7 +122,8 @@
+ push @errors,$mesg-&gt;error;
+ $c-&gt;log-&gt;info( sprintf(&quot;Creating DN $dn failed: %s&quot;, $mesg-&gt;error) );
+ $c-&gt;stash(errors =&gt; \@errors);
+- #$c-&gt;stash(template =&gt; 'register/index.tt');
++ $c-&gt;stash(template =&gt; 'register/index.tt');
++ return ;
+ }
+
+ $c-&gt;stash(
+
+<a id="identityCatDapbrancheslivelibCatDapControlleruserpm">Modified: identity/CatDap/branches/live/lib/CatDap/Controller/user.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/Controller/user.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/Controller/user.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -55,7 +55,7 @@
+ my $mesg;
+ my $dn;
+ my @errors;
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ if (! defined $c-&gt;user or not $c-&gt;req-&gt;cookie('key')) {
+ if (not $c-&gt;req-&gt;param('password')) {
+ push @errors,$c-&gt;loc('Your session has expired');
+@@ -112,6 +112,22 @@
+
+ }
+
++sub get_keyprefix : Private {
++ my ( $self, $c ) = @_;
++ my $keyprefix;
++ if ($c-&gt;req-&gt;address =~ m/:/) {
++ my $address = $c-&gt;req-&gt;address;
++ $address =~ s/\[\]://;
++
++ # if we shift right 104 bits from 128 we have 24 bits left or 3 bytes.
++ $keyprefix = sprintf( &quot;%06x&quot;, $address &gt;&gt; 104 );
++ }
++ else {
++ $keyprefix = sprintf( &quot;%02x%02x%02x&quot;, split /\./, $c-&gt;req-&gt;address );
++ }
++ return $keyprefix;
++}
++
+ =head2 index
+
+ =cut
+@@ -293,7 +309,7 @@
+ } else {
+
+ # re-encrypt the new password and forward to user view
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ my $key = $c-&gt;req-&gt;cookie('key')-&gt;value;
+ $cipher = Crypt::CBC-&gt;new( -key =&gt; $keyprefix . $key,
+ -cipher =&gt; 'Blowfish'
+@@ -321,7 +337,7 @@
+ $c-&gt;res-&gt;redirect('/user');
+ }
+ # cache password for next request with form data
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ my $key = Data::UUID-&gt;new-&gt;create_str();
+ $cipher = Crypt::CBC-&gt;new( -key =&gt; $keyprefix . $key,
+ -cipher =&gt; 'Blowfish'
+@@ -338,7 +354,7 @@
+ }
+
+ #Re-authenticate user
+- my $keyprefix = sprintf(&quot;%02x%02x%02x&quot;,split /\./,$c-&gt;req-&gt;address);
++ my $keyprefix = $self-&gt;get_keyprefix($c);
+ my $key = $c-&gt;req-&gt;cookie('key')-&gt;value;
+ $cipher = Crypt::CBC-&gt;new( -key =&gt; $keyprefix . $key,
+ -cipher =&gt; 'Blowfish'
+
+<a id="identityCatDapbrancheslivelibCatDapI18Nafpo">Modified: identity/CatDap/branches/live/lib/CatDap/I18N/af.po</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/I18N/af.po 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/I18N/af.po 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,45 +1,78 @@
+-#: lib/CatDap/Controller/register.pm:119
++#: lib/CatDap/Controller/register.pm:133
+ msgid &quot;Activation&quot;
+ msgstr &quot;Aktivering&quot;
+
+-#: root/user/index.tt:28 root/user/index.tt:8
++#: root/admin/account_addoc.tt:28 root/admin/account_modify.tt:24
++#: root/admin/group_modify.tt:18 root/user/index.tt:19 root/user/index.tt:46
+ msgid &quot;Add&quot;
+ msgstr &quot;Voeg by&quot;
+
++#: root/admin/account_modify.tt:85
++msgid &quot;Add ObjectClass&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:47
++msgid &quot;Add attribute&quot;
++msgstr &quot;&quot;
++
++#. (oc, dn)
++#: root/admin/account_addoc.tt:1
++msgid &quot;Adding objectclass %1 to dn %2&quot;
++msgstr &quot;&quot;
++
+ #: lib/CatDap/Controller/register.pm:49
+ msgid &quot;Addresses do not match&quot;
+ msgstr &quot;Die addresse verskil&quot;
+
+-#: lib/CatDap/Controller/register.pm:75
++#: lib/CatDap/Controller/register.pm:89
+ msgid &quot;An account already exists with this email address&quot;
+ msgstr &quot;'n Rekening met hierde epos adres bestaan reeds&quot;
+
+-#: lib/CatDap/Controller/register.pm:80
++#: lib/CatDap/Controller/register.pm:94
+ msgid &quot;An account already exists with this username&quot;
+ msgstr &quot;'n Rekening met hierdie gebruikersnaam bestaan reeds&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/admin.pm:529
++#: lib/CatDap/Controller/register.pm:145
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process f you entered the correct email address: %1&quot;
++&quot;the password recovery process if you entered the correct email address. &quot;
++&quot;Errors %1&quot;
+ msgstr &quot;&quot;
+ &quot;Daar was 'n fout met die stuur van die aktiverings epos, maar jou rekening &quot;
+ &quot;is geskep. Probeer die wagwoord herwinnings proses as die epos adres korrek &quot;
+-&quot;was: %1&quot;
++&quot;was. Foute: %1&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/register.pm:131
++#: lib/CatDap/Controller/admin.pm:539
++#, fuzzy
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process if you entered the correct email address. &quot;
+-&quot;Errors %1&quot;
++&quot;the password recovery process if you entered the correct email address: %1&quot;
+ msgstr &quot;&quot;
+ &quot;Daar was 'n fout met die stuur van die aktiverings epos, maar jou rekening &quot;
+ &quot;is geskep. Probeer die wagwoord herwinnings proses as die epos adres korrek &quot;
+-&quot;was. Foute: %1&quot;
++&quot;was: %1&quot;
+
+-#: root/user/firstlogin.tt:14 root/user/password.tt:18
++#. ($errors)
++#: lib/CatDap/Controller/forgot_password.pm:105
++msgid &quot;An error occured sending the email, please try again later. Errors %1&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:9 root/admin/account_modify.tt:8
++#: root/admin/group_modify.tt:5 root/user/index.tt:4
++msgid &quot;Attribute&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/register.pm:56
++msgid &quot;Cannot check /etc/passwd, please warn system administrators&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:29
++msgid &quot;Captcha&quot;
++msgstr &quot;&quot;
++
++#: root/user/firstlogin.tt:14 root/user/password.tt:19
+ msgid &quot;Change&quot;
+ msgstr &quot;Verander&quot;
+
+@@ -51,7 +84,12 @@
+ msgid &quot;Check your mail for activation instructions.&quot;
+ msgstr &quot;Kyk jou epos vir aktiverings instruksies.&quot;
+
+-#: root/register/index.tt:34
++#: root/forgot_password/complete.tt:5
++#, fuzzy
++msgid &quot;Check your mail for password reset instructions.&quot;
++msgstr &quot;Kyk jou epos vir aktiverings instruksies.&quot;
++
++#: root/register/index.tt:24
+ msgid &quot;Confirm Email address&quot;
+ msgstr &quot;Bevestig epos adres&quot;
+
+@@ -62,10 +100,11 @@
+ #. (cn)
+ #. (entry.cn)
+ #: root/email/activation.tt:1 root/email/admin/password.tt:1
++#: root/email/forgot_password.tt:1
+ msgid &quot;Dear %1,&quot;
+ msgstr &quot;Liewe %1,&quot;
+
+-#: root/user/index.tt:9
++#: root/admin/account_modify.tt:27 root/user/index.tt:22
+ msgid &quot;Delete&quot;
+ msgstr &quot;Vee uit&quot;
+
+@@ -73,18 +112,75 @@
+ msgid &quot;Edit&quot;
+ msgstr &quot;Wysig&quot;
+
+-#: root/register/index.tt:30
++#: root/admin/account.tt:33 root/admin/account.tt:8
++#: root/admin/account_promote.tt:6 root/register/index.tt:20
++msgid &quot;Email&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:11 root/register/index.tt:21
+ msgid &quot;Email address&quot;
+ msgstr &quot;Epos adres&quot;
+
+-#: root/register/index.tt:22
++#: root/forgot_password/complete.tt:1
++msgid &quot;Email sent.&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:2
++#, fuzzy
++msgid &quot;Enter new password.&quot;
++msgstr &quot;Verander wagwoord&quot;
++
++#: root/register/index.tt:32
++msgid &quot;Enter text&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:34 root/admin/account_promote.tt:7
++#, fuzzy
++msgid &quot;First Name&quot;
++msgstr &quot;Voornaam&quot;
++
++#: root/register/index.tt:13
+ msgid &quot;First name&quot;
+ msgstr &quot;Voornaam&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:94
++#, fuzzy
++msgid &quot;Forgot password&quot;
++msgstr &quot;Huidige wagwoord&quot;
++
++#: root/forgot_password/index.tt:5
++msgid &quot;Forgot your password?&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:17 root/index.tt:18
++#, fuzzy
++msgid &quot;Forgotten password?&quot;
++msgstr &quot;Huidige wagwoord&quot;
++
++#: root/admin/account.tt:36 root/admin/account.tt:9
++#: root/admin/account_promote.tt:9
++msgid &quot;Full Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:27
++msgid &quot;Group Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:9
++#, fuzzy
++msgid &quot;Group name&quot;
++msgstr &quot;Voornaam&quot;
++
++#: root/admin/account_modify.tt:2
++msgid &quot;Groups&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:48
+ #: lib/CatDap/Controller/register.pm:52
+ msgid &quot;Incorrect validation text, please try again&quot;
+ msgstr &quot;Inkorrekte teks van die prentjie, probeer weer&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:45
+ #: lib/CatDap/Controller/register.pm:46
+ msgid &quot;Invalid email address&quot;
+ msgstr &quot;Ongeldige epos adres&quot;
+@@ -93,39 +189,69 @@
+ msgid &quot;Invalid username&quot;
+ msgstr &quot;Ongeldige gebruikersnaam&quot;
+
+-#: root/template/header:12 root/user/fake.tt:3
++#: lib/CatDap/Controller/register.pm:59
++msgid &quot;Invalid username, already used by system&quot;
++msgstr &quot;&quot;
++
++#: root/template/header:10 root/user/fake.tt:3
+ msgid &quot;Log out&quot;
+ msgstr &quot;Teken uit&quot;
+
+-#: root/index.tt:1 root/index.tt:17
++#: root/index.tt:1 root/index.tt:13
+ msgid &quot;Login&quot;
+ msgstr &quot;Teken in&quot;
+
+-#: root/user/firstlogin.tt:5 root/user/password.tt:9
++#: root/forgot_password/confirm.tt:8 root/user/firstlogin.tt:5
++#: root/user/password.tt:10
+ msgid &quot;New Password&quot;
+ msgstr &quot;Nuwe Wagwoord&quot;
+
+-#: lib/CatDap/Controller/user.pm:273
++#: lib/CatDap/Controller/user.pm:296
+ msgid &quot;New passwords dont match&quot;
+ msgstr &quot;Nuwe wagwoorde verskil&quot;
+
+-#: root/index.tt:11
++#: root/forgot_password/complete.tt:4
++#, fuzzy
++msgid &quot;Operation was successful.&quot;
++msgstr &quot;Registrasie was suksesvol.&quot;
++
++#: root/index.tt:10
+ msgid &quot;Password&quot;
+ msgstr &quot;Wagwoord&quot;
+
+-#: lib/CatDap/Controller/user.pm:267
++#: lib/CatDap/Controller/user.pm:290
+ msgid &quot;Password incorrect&quot;
+ msgstr &quot;Wagwoord inkorrek&quot;
+
+-#: lib/CatDap/Controller/admin.pm:532
++#: lib/CatDap/Controller/admin.pm:542
+ msgid &quot;Password reset and email sent&quot;
+ msgstr &quot;Wagwoord is herstel en epos gestuur&quot;
+
++#: root/register/index.tt:12
++msgid &quot;Personal Information&quot;
++msgstr &quot;&quot;
++
+ #: root/email/admin/password.tt:5
+ msgid &quot;Please click below to change your password&quot;
+ msgstr &quot;Volg die skakel onder en verander jou wagwoord&quot;
+
+-#: root/index.tt:18 root/register/index.tt:43 root/register/index.tt:6
++#: root/admin/index.tt:1
++msgid &quot;Please use the menus above.&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:25
++msgid &quot;Primary group&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:71
++msgid &quot;Promote&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:62
++msgid &quot;Promote user to posixAccount with primary group:&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:16 root/register/index.tt:3 root/register/index.tt:35
+ msgid &quot;Register&quot;
+ msgstr &quot;Registreer&quot;
+
+@@ -137,35 +263,95 @@
+ msgid &quot;Registration was successful.&quot;
+ msgstr &quot;Registrasie was suksesvol.&quot;
+
+-#: root/user/firstlogin.tt:9 root/user/password.tt:13
++#: root/forgot_password/confirm.tt:11 root/user/firstlogin.tt:10
++#: root/user/password.tt:15
+ msgid &quot;Repeat New Password&quot;
+ msgstr &quot;Herhaal Nuwe Wagwoord&quot;
+
+-#: root/register/index.tt:26
++#: root/admin/account_modify.tt:1
++#, fuzzy
++msgid &quot;Reset password&quot;
++msgstr &quot;Huidige wagwoord&quot;
++
++#: root/admin/account.tt:22
++msgid &quot;Search&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:4 root/admin/group.tt:5
++msgid &quot;Search by&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:4
++msgid &quot;Select&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:18
++#, fuzzy
++msgid &quot;Send me my password&quot;
++msgstr &quot;Verander wagwoord&quot;
++
++#: root/forgot_password/confirm.tt:16
++#, fuzzy
++msgid &quot;Set new password&quot;
++msgstr &quot;Herhaal Nuwe Wagwoord&quot;
++
++#: root/register/check.tt:1
++msgid &quot;Success&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:10 root/admin/account.tt:35
++#: root/admin/account_promote.tt:8 root/register/index.tt:16
+ msgid &quot;Surname&quot;
+ msgstr &quot;Van&quot;
+
+-#: lib/CatDap/Controller/register.pm:56
++#: lib/CatDap/Controller/register.pm:70
+ msgid &quot;The first name supplied contains illegal characters&quot;
+ msgstr &quot;Die verskafte noemnaam sluit ongeldige karakters in&quot;
+
+-#: lib/CatDap/Controller/register.pm:61
++#: lib/CatDap/Controller/register.pm:75
+ msgid &quot;The surname supplied contains illegal characters&quot;
+ msgstr &quot;Die verskafte van sluit ondeldige karakters in&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:66
++msgid &quot;This email address is not bound to an account&quot;
++msgstr &quot;&quot;
++
+ #: root/email/activation.tt:3
+ msgid &quot;To activate your account, please follow the link below.&quot;
+ msgstr &quot;Om U rekening te aktiveer, volg asseblief die volgende skakel.&quot;
+
+-#: root/user/index.tt:13
++#: root/email/forgot_password.tt:3
++#, fuzzy
++msgid &quot;To reset your password, please follow the link below.&quot;
++msgstr &quot;Om U rekening te aktiveer, volg asseblief die volgende skakel.&quot;
++
++#: root/admin/account_modify.tt:35 root/user/index.tt:29
+ msgid &quot;Update&quot;
+ msgstr &quot;Opdateer&quot;
+
+-#: root/index.tt:7 root/register/index.tt:18
++#: root/admin/account.tt:32 root/admin/account.tt:7
++#: root/admin/account_promote.tt:5 root/index.tt:6 root/register/index.tt:7
++#: root/register/index.tt:8
+ msgid &quot;Username&quot;
+ msgstr &quot;Gebruikersnaam&quot;
+
++#: lib/CatDap/Controller/register.pm:65
++msgid &quot;Username is not authorized to be used&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:10 root/admin/account_modify.tt:9
++#: root/admin/group_modify.tt:6 root/user/index.tt:4
++msgid &quot;Value&quot;
++msgstr &quot;&quot;
++
+ #. (c.config.organisation)
++#: root/email/forgot_password.tt:2
++msgid &quot;&quot;
++&quot;Your %1 account has been requested to change the password. If you did not do &quot;
++&quot;this, or you do not want to change your password; you can just do nothing.&quot;
++msgstr &quot;&quot;
++
++#. (c.config.organisation)
+ #: root/email/activation.tt:2
+ msgid &quot;Your %1 account has been successfully created, but requires activation.&quot;
+ msgstr &quot;Jou %1 rekening is suksesvol geskep, maar aktivering is benodig&quot;
+@@ -179,14 +365,42 @@
+ msgid &quot;Your session has expired&quot;
+ msgstr &quot;Jou sessie het verstrek&quot;
+
+-#: root/index.tt:17
+-msgid &quot;or&quot;
+-msgstr &quot;of&quot;
++#: root/admin/account.tt:15 root/admin/group.tt:15
++msgid &quot;contains&quot;
++msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/admin.pm:516
++#: root/admin/group_modify.tt:14
++#, fuzzy
++msgid &quot;delete&quot;
++msgstr &quot;Vee uit&quot;
++
++#: root/admin/account.tt:17 root/admin/group.tt:17
++msgid &quot;greater than or equal to&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:16 root/admin/group.tt:16
++msgid &quot;is exactly&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:18 root/admin/group.tt:18
++msgid &quot;less than&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:10
++msgid &quot;member&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/admin.pm:526
+ msgid &quot;password reset&quot;
+ msgstr &quot;Wagwoord herstelling&quot;
+
++#: root/admin/account_modify.tt:53
++msgid &quot;with value&quot;
++msgstr &quot;&quot;
++
++#~ msgid &quot;or&quot;
++#~ msgstr &quot;of&quot;
++
+ #~ msgid &quot;Repeat&quot;
+ #~ msgstr &quot;Herhaal&quot;
+
+
+<a id="identityCatDapbrancheslivelibCatDapI18Nfrpo">Modified: identity/CatDap/branches/live/lib/CatDap/I18N/fr.po</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/I18N/fr.po 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/I18N/fr.po 2011-01-05 15:32:57 UTC (rev 212)
+@@ -5,98 +5,202 @@
+ #
+ msgid &quot;&quot;
+ msgstr &quot;&quot;
+-&quot;Project-Id-Version: PACKAGE VERSION\n&quot;
++&quot;Project-Id-Version: Catdap\n&quot;
+ &quot;POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n&quot;
+-&quot;PO-Revision-Date: 2010-10-19 21:07+0100\n&quot;
++&quot;PO-Revision-Date: 2010-11-04 21:09+0100\n&quot;
+ &quot;Last-Translator: Michael Scherer &lt;misc@zarb.org&gt;\n&quot;
+-&quot;Language-Team: LANGUAGE &lt;LL@li.org&gt;\n&quot;
++&quot;Language-Team: LANGUAGE &lt;mageia-i18n@mageia.org&gt;\n&quot;
++&quot;Language: \n&quot;
+ &quot;MIME-Version: 1.0\n&quot;
+ &quot;Content-Type: text/plain; charset=UTF-8\n&quot;
+ &quot;Content-Transfer-Encoding: 8bit\n&quot;
++&quot;X-Poedit-Language: French\n&quot;
++&quot;X-Poedit-Country: FRANCE\n&quot;
++&quot;X-Poedit-SourceCharset: utf-8\n&quot;
+
+-#: lib/CatDap/Controller/register.pm:119
++#: lib/CatDap/Controller/register.pm:133
+ msgid &quot;Activation&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Activation&quot;
+
+-#: root/user/index.tt:28 root/user/index.tt:8
++#: root/admin/account_addoc.tt:28 root/admin/account_modify.tt:24
++#: root/admin/group_modify.tt:18 root/user/index.tt:19 root/user/index.tt:46
+ msgid &quot;Add&quot;
++msgstr &quot;Ajouter&quot;
++
++#: root/admin/account_modify.tt:85
++msgid &quot;Add ObjectClass&quot;
+ msgstr &quot;&quot;
+
++#: root/admin/account_modify.tt:47
++msgid &quot;Add attribute&quot;
++msgstr &quot;&quot;
++
++#. (oc, dn)
++#: root/admin/account_addoc.tt:1
++msgid &quot;Adding objectclass %1 to dn %2&quot;
++msgstr &quot;&quot;
++
+ #: lib/CatDap/Controller/register.pm:49
+ msgid &quot;Addresses do not match&quot;
+ msgstr &quot;Les adresses ne correspondent pas&quot;
+
+-#: lib/CatDap/Controller/register.pm:75
++#: lib/CatDap/Controller/register.pm:89
+ msgid &quot;An account already exists with this email address&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Un compte existe déjà avec cet email&quot;
+
+-#: lib/CatDap/Controller/register.pm:80
++#: lib/CatDap/Controller/register.pm:94
+ msgid &quot;An account already exists with this username&quot;
+ msgstr &quot;Un compte existe déjà pour ce nom d'utilisateur&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/admin.pm:529
++#: lib/CatDap/Controller/register.pm:145
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process f you entered the correct email address: %1&quot;
++&quot;the password recovery process if you entered the correct email address. &quot;
++&quot;Errors %1&quot;
+ msgstr &quot;&quot;
++&quot;Une erreur est arrivé lors de l'envoi du mail, mais votre compte a été crée. &quot;
++&quot;Vous pouvez utiliser la fonction de réinitialisation du mot de passe si &quot;
++&quot;votre adresse est correcte. Erreurs %1&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/register.pm:131
++#: lib/CatDap/Controller/admin.pm:539
++#, fuzzy
+ msgid &quot;&quot;
+ &quot;An error occured sending the email, but your account was created. Please try &quot;
+-&quot;the password recovery process if you entered the correct email address. &quot;
+-&quot;Errors %1&quot;
++&quot;the password recovery process if you entered the correct email address: %1&quot;
+ msgstr &quot;&quot;
++&quot;Une erreur est arrivé lors de l'envoi du mail, mais votre compte a été crée. &quot;
++&quot;Vous pouvez utiliser la fonction de réinitialisation du mot de passe si &quot;
++&quot;votre adresse est correcte : %1&quot;
+
+-#: root/user/firstlogin.tt:14 root/user/password.tt:18
+-msgid &quot;Change&quot;
++#. ($errors)
++#: lib/CatDap/Controller/forgot_password.pm:105
++msgid &quot;An error occured sending the email, please try again later. Errors %1&quot;
+ msgstr &quot;&quot;
+
++#: root/admin/account_addoc.tt:9 root/admin/account_modify.tt:8
++#: root/admin/group_modify.tt:5 root/user/index.tt:4
++msgid &quot;Attribute&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/register.pm:56
++msgid &quot;Cannot check /etc/passwd, please warn system administrators&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:29
++msgid &quot;Captcha&quot;
++msgstr &quot;&quot;
++
++#: root/user/firstlogin.tt:14 root/user/password.tt:19
++msgid &quot;Change&quot;
++msgstr &quot;Changer&quot;
++
+ #: root/user/fake.tt:2
+-#, fuzzy
+ msgid &quot;Change password&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;Changer le mot de passe&quot;
+
+ #: root/register/complete.tt:5
+ msgid &quot;Check your mail for activation instructions.&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Vérifier votre boite mail pour les instructions d'activation&quot;
+
+-#: root/register/index.tt:34
++#: root/forgot_password/complete.tt:5
++#, fuzzy
++msgid &quot;Check your mail for password reset instructions.&quot;
++msgstr &quot;Vérifier votre boite mail pour les instructions d'activation&quot;
++
++#: root/register/index.tt:24
+ msgid &quot;Confirm Email address&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Confirmer l'adresse email&quot;
+
+ #: root/user/password.tt:5
+ msgid &quot;Current password&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Mot de passe actuel&quot;
+
+ #. (cn)
+ #. (entry.cn)
+ #: root/email/activation.tt:1 root/email/admin/password.tt:1
+-#, fuzzy
++#: root/email/forgot_password.tt:1
+ msgid &quot;Dear %1,&quot;
+-msgstr &quot;Cher(e)&quot;
++msgstr &quot;Cher(e) %1,&quot;
+
+-#: root/user/index.tt:9
++#: root/admin/account_modify.tt:27 root/user/index.tt:22
+ msgid &quot;Delete&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Supprimer&quot;
+
+ #: root/user/fake.tt:1
+ msgid &quot;Edit&quot;
++msgstr &quot;Éditer&quot;
++
++#: root/admin/account.tt:33 root/admin/account.tt:8
++#: root/admin/account_promote.tt:6 root/register/index.tt:20
++msgid &quot;Email&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:30
++#: root/forgot_password/index.tt:11 root/register/index.tt:21
+ msgid &quot;Email address&quot;
+-msgstr &quot;Adresse de messagerie&quot;
++msgstr &quot;Adresse email&quot;
+
+-#: root/register/index.tt:22
++#: root/forgot_password/complete.tt:1
++msgid &quot;Email sent.&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:2
++#, fuzzy
++msgid &quot;Enter new password.&quot;
++msgstr &quot;Changer le mot de passe&quot;
++
++#: root/register/index.tt:32
++msgid &quot;Enter text&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:34 root/admin/account_promote.tt:7
++#, fuzzy
++msgid &quot;First Name&quot;
++msgstr &quot;Prénom&quot;
++
++#: root/register/index.tt:13
+ msgid &quot;First name&quot;
+ msgstr &quot;Prénom&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:94
++#, fuzzy
++msgid &quot;Forgot password&quot;
++msgstr &quot;Mot de passe actuel&quot;
++
++#: root/forgot_password/index.tt:5
++msgid &quot;Forgot your password?&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:17 root/index.tt:18
++#, fuzzy
++msgid &quot;Forgotten password?&quot;
++msgstr &quot;Mot de passe actuel&quot;
++
++#: root/admin/account.tt:36 root/admin/account.tt:9
++#: root/admin/account_promote.tt:9
++msgid &quot;Full Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:27
++msgid &quot;Group Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:9
++#, fuzzy
++msgid &quot;Group name&quot;
++msgstr &quot;Prénom&quot;
++
++#: root/admin/account_modify.tt:2
++msgid &quot;Groups&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:48
+ #: lib/CatDap/Controller/register.pm:52
+ msgid &quot;Incorrect validation text, please try again&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Texte de validation incorrect, merci de tester à nouveau&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:45
+ #: lib/CatDap/Controller/register.pm:46
+ msgid &quot;Invalid email address&quot;
+ msgstr &quot;Adresse mail invalide&quot;
+@@ -105,105 +209,218 @@
+ msgid &quot;Invalid username&quot;
+ msgstr &quot;Nom d'utilisateur invalide&quot;
+
+-#: root/template/header:12 root/user/fake.tt:3
+-msgid &quot;Log out&quot;
++#: lib/CatDap/Controller/register.pm:59
++msgid &quot;Invalid username, already used by system&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:1 root/index.tt:17
++#: root/template/header:10 root/user/fake.tt:3
++msgid &quot;Log out&quot;
++msgstr &quot;Se déconnecter&quot;
++
++#: root/index.tt:1 root/index.tt:13
+ msgid &quot;Login&quot;
+ msgstr &quot;Login&quot;
+
+-#: root/user/firstlogin.tt:5 root/user/password.tt:9
+-#, fuzzy
++#: root/forgot_password/confirm.tt:8 root/user/firstlogin.tt:5
++#: root/user/password.tt:10
+ msgid &quot;New Password&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;Nouveau mot de passe&quot;
+
+-#: lib/CatDap/Controller/user.pm:273
+-#, fuzzy
++#: lib/CatDap/Controller/user.pm:296
+ msgid &quot;New passwords dont match&quot;
+-msgstr &quot;Les adresses ne correspondent pas&quot;
++msgstr &quot;Les mot de passes ne correspondent pas&quot;
+
+-#: root/index.tt:11
++#: root/forgot_password/complete.tt:4
++#, fuzzy
++msgid &quot;Operation was successful.&quot;
++msgstr &quot;L'enregistrement a réussi&quot;
++
++#: root/index.tt:10
+ msgid &quot;Password&quot;
+ msgstr &quot;Mot de passe&quot;
+
+-#: lib/CatDap/Controller/user.pm:267
+-#, fuzzy
++#: lib/CatDap/Controller/user.pm:290
+ msgid &quot;Password incorrect&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;Mot de passe incorrect&quot;
+
+-#: lib/CatDap/Controller/admin.pm:532
++#: lib/CatDap/Controller/admin.pm:542
+ msgid &quot;Password reset and email sent&quot;
++msgstr &quot;Mot de passe réinitialiser, email envoyé&quot;
++
++#: root/register/index.tt:12
++msgid &quot;Personal Information&quot;
+ msgstr &quot;&quot;
+
+ #: root/email/admin/password.tt:5
+ msgid &quot;Please click below to change your password&quot;
++msgstr &quot;Cliquer ici pour changer votre mot de passe&quot;
++
++#: root/admin/index.tt:1
++msgid &quot;Please use the menus above.&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:18 root/register/index.tt:43 root/register/index.tt:6
++#: root/admin/account_promote.tt:25
++msgid &quot;Primary group&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:71
++msgid &quot;Promote&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:62
++msgid &quot;Promote user to posixAccount with primary group:&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:16 root/register/index.tt:3 root/register/index.tt:35
+ msgid &quot;Register&quot;
+ msgstr &quot;S'enregistrer&quot;
+
+ #: root/register/complete.tt:1
+ msgid &quot;Registration completed&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Enregistrement terminé&quot;
+
+ #: root/register/complete.tt:4
+ msgid &quot;Registration was successful.&quot;
+-msgstr &quot;&quot;
++msgstr &quot;L'enregistrement a réussi&quot;
+
+-#: root/user/firstlogin.tt:9 root/user/password.tt:13
++#: root/forgot_password/confirm.tt:11 root/user/firstlogin.tt:10
++#: root/user/password.tt:15
+ msgid &quot;Repeat New Password&quot;
++msgstr &quot;Répéter le nouveau de passe&quot;
++
++#: root/admin/account_modify.tt:1
++#, fuzzy
++msgid &quot;Reset password&quot;
++msgstr &quot;Mot de passe actuel&quot;
++
++#: root/admin/account.tt:22
++msgid &quot;Search&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:26
++#: root/admin/account.tt:4 root/admin/group.tt:5
++msgid &quot;Search by&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:4
++msgid &quot;Select&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:18
++#, fuzzy
++msgid &quot;Send me my password&quot;
++msgstr &quot;Changer le mot de passe&quot;
++
++#: root/forgot_password/confirm.tt:16
++#, fuzzy
++msgid &quot;Set new password&quot;
++msgstr &quot;Répéter le nouveau de passe&quot;
++
++#: root/register/check.tt:1
++msgid &quot;Success&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:10 root/admin/account.tt:35
++#: root/admin/account_promote.tt:8 root/register/index.tt:16
+ msgid &quot;Surname&quot;
+-msgstr &quot;Surnom&quot;
++msgstr &quot;Nom&quot;
+
+-#: lib/CatDap/Controller/register.pm:56
++#: lib/CatDap/Controller/register.pm:70
+ msgid &quot;The first name supplied contains illegal characters&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Le prénom proposé contient des caractères interdits&quot;
+
+-#: lib/CatDap/Controller/register.pm:61
++#: lib/CatDap/Controller/register.pm:75
+ msgid &quot;The surname supplied contains illegal characters&quot;
++msgstr &quot;Le nom proposé contient des caractères interdits&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:66
++msgid &quot;This email address is not bound to an account&quot;
+ msgstr &quot;&quot;
+
+ #: root/email/activation.tt:3
+-#, fuzzy
+ msgid &quot;To activate your account, please follow the link below.&quot;
+ msgstr &quot;Pour activer votre compte, merci de suivre le lien ci dessous.&quot;
+
+-#: root/user/index.tt:13
++#: root/email/forgot_password.tt:3
++#, fuzzy
++msgid &quot;To reset your password, please follow the link below.&quot;
++msgstr &quot;Pour activer votre compte, merci de suivre le lien ci dessous.&quot;
++
++#: root/admin/account_modify.tt:35 root/user/index.tt:29
+ msgid &quot;Update&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Mettre à jour&quot;
+
+-#: root/index.tt:7 root/register/index.tt:18
++#: root/admin/account.tt:32 root/admin/account.tt:7
++#: root/admin/account_promote.tt:5 root/index.tt:6 root/register/index.tt:7
++#: root/register/index.tt:8
+ msgid &quot;Username&quot;
+ msgstr &quot;Nom d'utilisateur&quot;
+
++#: lib/CatDap/Controller/register.pm:65
++msgid &quot;Username is not authorized to be used&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:10 root/admin/account_modify.tt:9
++#: root/admin/group_modify.tt:6 root/user/index.tt:4
++msgid &quot;Value&quot;
++msgstr &quot;&quot;
++
+ #. (c.config.organisation)
++#: root/email/forgot_password.tt:2
++msgid &quot;&quot;
++&quot;Your %1 account has been requested to change the password. If you did not do &quot;
++&quot;this, or you do not want to change your password; you can just do nothing.&quot;
++msgstr &quot;&quot;
++
++#. (c.config.organisation)
+ #: root/email/activation.tt:2
+ msgid &quot;Your %1 account has been successfully created, but requires activation.&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Votre compte %1 a été crée mais requiert d'être activé&quot;
+
+ #. (c.user.username)
+ #: root/email/admin/password.tt:3
+ msgid &quot;Your password was reset by %1&quot;
+-msgstr &quot;&quot;
++msgstr &quot;Votre mot de passe a été réinitialisé par %1&quot;
+
+ #: lib/CatDap/Controller/user.pm:61
+ msgid &quot;Your session has expired&quot;
++msgstr &quot;Votre session a expiré&quot;
++
++#: root/admin/account.tt:15 root/admin/group.tt:15
++msgid &quot;contains&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:17
+-msgid &quot;or&quot;
+-msgstr &quot;ou&quot;
++#: root/admin/group_modify.tt:14
++#, fuzzy
++msgid &quot;delete&quot;
++msgstr &quot;Supprimer&quot;
+
+-#: lib/CatDap/Controller/admin.pm:516
+-#, fuzzy
++#: root/admin/account.tt:17 root/admin/group.tt:17
++msgid &quot;greater than or equal to&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:16 root/admin/group.tt:16
++msgid &quot;is exactly&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:18 root/admin/group.tt:18
++msgid &quot;less than&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:10
++msgid &quot;member&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/admin.pm:526
+ msgid &quot;password reset&quot;
+-msgstr &quot;Mot de passe&quot;
++msgstr &quot;réinitialisation du mot de passe&quot;
+
++#: root/admin/account_modify.tt:53
++msgid &quot;with value&quot;
++msgstr &quot;&quot;
++
++#~ msgid &quot;or&quot;
++#~ msgstr &quot;ou&quot;
++
+ #~ msgid &quot;Mageia Identity Activation&quot;
+ #~ msgstr &quot;Activation de l'identité Mageia&quot;
+
+
+<a id="identityCatDapbrancheslivelibCatDapI18Nmessagespot">Modified: identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap/I18N/messages.pot 2011-01-05 15:32:57 UTC (rev 212)
+@@ -15,37 +15,67 @@
+ &quot;Content-Type: text/plain; charset=CHARSET\n&quot;
+ &quot;Content-Transfer-Encoding: 8bit\n&quot;
+
+-#: lib/CatDap/Controller/register.pm:119
++#: lib/CatDap/Controller/register.pm:133
+ msgid &quot;Activation&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/index.tt:28 root/user/index.tt:8
++#: root/admin/account_addoc.tt:28 root/admin/account_modify.tt:24 root/admin/group_modify.tt:18 root/user/index.tt:19 root/user/index.tt:46
+ msgid &quot;Add&quot;
+ msgstr &quot;&quot;
+
++#: root/admin/account_modify.tt:85
++msgid &quot;Add ObjectClass&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:47
++msgid &quot;Add attribute&quot;
++msgstr &quot;&quot;
++
++#. (oc, dn)
++#: root/admin/account_addoc.tt:1
++msgid &quot;Adding objectclass %1 to dn %2&quot;
++msgstr &quot;&quot;
++
+ #: lib/CatDap/Controller/register.pm:49
+ msgid &quot;Addresses do not match&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:75
++#: lib/CatDap/Controller/register.pm:89
+ msgid &quot;An account already exists with this email address&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:80
++#: lib/CatDap/Controller/register.pm:94
+ msgid &quot;An account already exists with this username&quot;
+ msgstr &quot;&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/admin.pm:529
+-msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process f you entered the correct email address: %1&quot;
++#: lib/CatDap/Controller/register.pm:145
++msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process if you entered the correct email address. Errors %1&quot;
+ msgstr &quot;&quot;
+
+ #. ($errors)
+-#: lib/CatDap/Controller/register.pm:131
+-msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process if you entered the correct email address. Errors %1&quot;
++#: lib/CatDap/Controller/admin.pm:539
++msgid &quot;An error occured sending the email, but your account was created. Please try the password recovery process if you entered the correct email address: %1&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/firstlogin.tt:14 root/user/password.tt:18
++#. ($errors)
++#: lib/CatDap/Controller/forgot_password.pm:105
++msgid &quot;An error occured sending the email, please try again later. Errors %1&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:9 root/admin/account_modify.tt:8 root/admin/group_modify.tt:5 root/user/index.tt:4
++msgid &quot;Attribute&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/register.pm:56
++msgid &quot;Cannot check /etc/passwd, please warn system administrators&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:29
++msgid &quot;Captcha&quot;
++msgstr &quot;&quot;
++
++#: root/user/firstlogin.tt:14 root/user/password.tt:19
+ msgid &quot;Change&quot;
+ msgstr &quot;&quot;
+
+@@ -57,7 +87,11 @@
+ msgid &quot;Check your mail for activation instructions.&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:34
++#: root/forgot_password/complete.tt:5
++msgid &quot;Check your mail for password reset instructions.&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:24
+ msgid &quot;Confirm Email address&quot;
+ msgstr &quot;&quot;
+
+@@ -67,11 +101,11 @@
+
+ #. (cn)
+ #. (entry.cn)
+-#: root/email/activation.tt:1 root/email/admin/password.tt:1
++#: root/email/activation.tt:1 root/email/admin/password.tt:1 root/email/forgot_password.tt:1
+ msgid &quot;Dear %1,&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/index.tt:9
++#: root/admin/account_modify.tt:27 root/user/index.tt:22
+ msgid &quot;Delete&quot;
+ msgstr &quot;&quot;
+
+@@ -79,19 +113,67 @@
+ msgid &quot;Edit&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:30
++#: root/admin/account.tt:33 root/admin/account.tt:8 root/admin/account_promote.tt:6 root/register/index.tt:20
++msgid &quot;Email&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:11 root/register/index.tt:21
+ msgid &quot;Email address&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:22
++#: root/forgot_password/complete.tt:1
++msgid &quot;Email sent.&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:2
++msgid &quot;Enter new password.&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:32
++msgid &quot;Enter text&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:34 root/admin/account_promote.tt:7
++msgid &quot;First Name&quot;
++msgstr &quot;&quot;
++
++#: root/register/index.tt:13
+ msgid &quot;First name&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:52
++#: lib/CatDap/Controller/forgot_password.pm:94
++msgid &quot;Forgot password&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:5
++msgid &quot;Forgot your password?&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:17 root/index.tt:18
++msgid &quot;Forgotten password?&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:36 root/admin/account.tt:9 root/admin/account_promote.tt:9
++msgid &quot;Full Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:27
++msgid &quot;Group Name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:9
++msgid &quot;Group name&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:2
++msgid &quot;Groups&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/forgot_password.pm:48 lib/CatDap/Controller/register.pm:52
+ msgid &quot;Incorrect validation text, please try again&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:46
++#: lib/CatDap/Controller/forgot_password.pm:45 lib/CatDap/Controller/register.pm:46
+ msgid &quot;Invalid email address&quot;
+ msgstr &quot;&quot;
+
+@@ -99,39 +181,67 @@
+ msgid &quot;Invalid username&quot;
+ msgstr &quot;&quot;
+
+-#: root/template/header:12 root/user/fake.tt:3
++#: lib/CatDap/Controller/register.pm:59
++msgid &quot;Invalid username, already used by system&quot;
++msgstr &quot;&quot;
++
++#: root/template/header:10 root/user/fake.tt:3
+ msgid &quot;Log out&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:1 root/index.tt:17
++#: root/index.tt:1 root/index.tt:13
+ msgid &quot;Login&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/firstlogin.tt:5 root/user/password.tt:9
++#: root/forgot_password/confirm.tt:8 root/user/firstlogin.tt:5 root/user/password.tt:10
+ msgid &quot;New Password&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/user.pm:273
++#: lib/CatDap/Controller/user.pm:296
+ msgid &quot;New passwords dont match&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:11
++#: root/forgot_password/complete.tt:4
++msgid &quot;Operation was successful.&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:10
+ msgid &quot;Password&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/user.pm:267
++#: lib/CatDap/Controller/user.pm:290
+ msgid &quot;Password incorrect&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/admin.pm:532
++#: lib/CatDap/Controller/admin.pm:542
+ msgid &quot;Password reset and email sent&quot;
+ msgstr &quot;&quot;
+
++#: root/register/index.tt:12
++msgid &quot;Personal Information&quot;
++msgstr &quot;&quot;
++
+ #: root/email/admin/password.tt:5
+ msgid &quot;Please click below to change your password&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:18 root/register/index.tt:43 root/register/index.tt:6
++#: root/admin/index.tt:1
++msgid &quot;Please use the menus above.&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:25
++msgid &quot;Primary group&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:71
++msgid &quot;Promote&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:62
++msgid &quot;Promote user to posixAccount with primary group:&quot;
++msgstr &quot;&quot;
++
++#: root/index.tt:16 root/register/index.tt:3 root/register/index.tt:35
+ msgid &quot;Register&quot;
+ msgstr &quot;&quot;
+
+@@ -143,35 +253,84 @@
+ msgid &quot;Registration was successful.&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/firstlogin.tt:9 root/user/password.tt:13
++#: root/forgot_password/confirm.tt:11 root/user/firstlogin.tt:10 root/user/password.tt:15
+ msgid &quot;Repeat New Password&quot;
+ msgstr &quot;&quot;
+
+-#: root/register/index.tt:26
++#: root/admin/account_modify.tt:1
++msgid &quot;Reset password&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:22
++msgid &quot;Search&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:4 root/admin/group.tt:5
++msgid &quot;Search by&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_promote.tt:4
++msgid &quot;Select&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/index.tt:18
++msgid &quot;Send me my password&quot;
++msgstr &quot;&quot;
++
++#: root/forgot_password/confirm.tt:16
++msgid &quot;Set new password&quot;
++msgstr &quot;&quot;
++
++#: root/register/check.tt:1
++msgid &quot;Success&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:10 root/admin/account.tt:35 root/admin/account_promote.tt:8 root/register/index.tt:16
+ msgid &quot;Surname&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:56
++#: lib/CatDap/Controller/register.pm:70
+ msgid &quot;The first name supplied contains illegal characters&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/register.pm:61
++#: lib/CatDap/Controller/register.pm:75
+ msgid &quot;The surname supplied contains illegal characters&quot;
+ msgstr &quot;&quot;
+
++#: lib/CatDap/Controller/forgot_password.pm:66
++msgid &quot;This email address is not bound to an account&quot;
++msgstr &quot;&quot;
++
+ #: root/email/activation.tt:3
+ msgid &quot;To activate your account, please follow the link below.&quot;
+ msgstr &quot;&quot;
+
+-#: root/user/index.tt:13
++#: root/email/forgot_password.tt:3
++msgid &quot;To reset your password, please follow the link below.&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:35 root/user/index.tt:29
+ msgid &quot;Update&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:7 root/register/index.tt:18
++#: root/admin/account.tt:32 root/admin/account.tt:7 root/admin/account_promote.tt:5 root/index.tt:6 root/register/index.tt:7 root/register/index.tt:8
+ msgid &quot;Username&quot;
+ msgstr &quot;&quot;
+
++#: lib/CatDap/Controller/register.pm:65
++msgid &quot;Username is not authorized to be used&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account_addoc.tt:10 root/admin/account_modify.tt:9 root/admin/group_modify.tt:6 root/user/index.tt:4
++msgid &quot;Value&quot;
++msgstr &quot;&quot;
++
+ #. (c.config.organisation)
++#: root/email/forgot_password.tt:2
++msgid &quot;Your %1 account has been requested to change the password. If you did not do this, or you do not want to change your password; you can just do nothing.&quot;
++msgstr &quot;&quot;
++
++#. (c.config.organisation)
+ #: root/email/activation.tt:2
+ msgid &quot;Your %1 account has been successfully created, but requires activation.&quot;
+ msgstr &quot;&quot;
+@@ -185,10 +344,34 @@
+ msgid &quot;Your session has expired&quot;
+ msgstr &quot;&quot;
+
+-#: root/index.tt:17
+-msgid &quot;or&quot;
++#: root/admin/account.tt:15 root/admin/group.tt:15
++msgid &quot;contains&quot;
+ msgstr &quot;&quot;
+
+-#: lib/CatDap/Controller/admin.pm:516
++#: root/admin/group_modify.tt:14
++msgid &quot;delete&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:17 root/admin/group.tt:17
++msgid &quot;greater than or equal to&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:16 root/admin/group.tt:16
++msgid &quot;is exactly&quot;
++msgstr &quot;&quot;
++
++#: root/admin/account.tt:18 root/admin/group.tt:18
++msgid &quot;less than&quot;
++msgstr &quot;&quot;
++
++#: root/admin/group.tt:10
++msgid &quot;member&quot;
++msgstr &quot;&quot;
++
++#: lib/CatDap/Controller/admin.pm:526
+ msgid &quot;password reset&quot;
+ msgstr &quot;&quot;
++
++#: root/admin/account_modify.tt:53
++msgid &quot;with value&quot;
++msgstr &quot;&quot;
+
+<a id="identityCatDapbrancheslivelibCatDappm">Modified: identity/CatDap/branches/live/lib/CatDap.pm</a>
+===================================================================
+--- identity/CatDap/branches/live/lib/CatDap.pm 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/lib/CatDap.pm 2011-01-05 15:32:57 UTC (rev 212)
+@@ -22,6 +22,7 @@
+ Authentication
+ Authorization::Roles
+ I18N
++ Unicode::Encoding
+ /;
+
+ extends 'Catalyst';
+
+<a id="identityCatDapbranchesliverootadminaccounttt">Modified: identity/CatDap/branches/live/root/admin/account.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,24 +1,25 @@
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;table&gt;
+ &lt;tr&gt;
+- &lt;td&gt;Search by&lt;/td&gt;
++ &lt;td&gt;[% l('Search by') %]&lt;/td&gt;
+ &lt;td&gt;
+ &lt;select name=&quot;attribute&quot;&gt;
+- &lt;option value=&quot;uid&quot;&gt;Username&lt;/option&gt;
+- &lt;option value=&quot;mail&quot;&gt;Email&lt;/option&gt;
+- &lt;option value=&quot;cn&quot;&gt;Full Name&lt;/option&gt;
+- &lt;option value=&quot;sn&quot;&gt;Surname&lt;/option&gt;
++ &lt;option value=&quot;uid&quot;&gt;[% l('Username') %]&lt;/option&gt;
++ &lt;option value=&quot;mail&quot;&gt;[% l('Email') %]&lt;/option&gt;
++ &lt;option value=&quot;cn&quot;&gt;[% l('Full Name') %]&lt;/option&gt;
++ &lt;option value=&quot;sn&quot;&gt;[% l('Surname') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td&gt;
+ &lt;!-- td&gt;
+ &lt;select name=&quot;matchtype&quot;&gt;
+- &lt;option value=&quot;substring&quot;&gt;contains&lt;/option&gt;
+- &lt;option value=&quot;exact&quot;&gt;is exactly&lt;/option&gt;
+- &lt;option value=&quot;gte&quot;&gt;greater than or equal to&lt;/option&gt;
+- &lt;option value=&quot;lt&quot;&gt;less than&lt;/option&gt;
++ &lt;option value=&quot;substring&quot;&gt;[% l('contains') %]&lt;/option&gt;
++ &lt;option value=&quot;exact&quot;&gt;[% l('is exactly') %]&lt;/option&gt;
++ &lt;option value=&quot;gte&quot;&gt;[% l('greater than or equal to') %]&lt;/option&gt;
++ &lt;option value=&quot;lt&quot;&gt;[% l('less than') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td --&gt;
+- &lt;td&gt;&lt;input name=&quot;value&quot; value=&quot;&quot; /&gt;&lt;/td&gt;
++ &lt;td&gt;&lt;input type=&quot;text&quot; name=&quot;value&quot; value=&quot;&quot; /&gt;&lt;/td&gt;
++ &lt;td&gt;&lt;button type=&quot;submit&quot; value=&quot;[% l('Search') %]&quot;&gt;[% l('Search') %]&lt;/button&gt;&lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;/table&gt;
+ &lt;/form&gt;
+@@ -28,11 +29,11 @@
+ [% IF entries %]
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Username&lt;/th&gt;
+- &lt;th&gt;Email&lt;/th&gt;
+- &lt;th&gt;First Name&lt;/th&gt;
+- &lt;th&gt;Surname&lt;/td&gt;
+- &lt;th&gt;Full Name&lt;/td&gt;
++ &lt;th&gt;[% l('Username') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Email') %]&lt;/th&gt;
++ &lt;th&gt;[% l('First Name') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Surname') %]&lt;/td&gt;
++ &lt;th&gt;[% l('Full Name') %]&lt;/td&gt;
+ &lt;/tr&gt;
+ [% FOREACH entry IN entries %]
+ &lt;tr&gt;
+
+<a id="identityCatDapbranchesliverootadminaccount_addoctt">Modified: identity/CatDap/branches/live/root/admin/account_addoc.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_addoc.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_addoc.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,4 @@
+-Adding objectclass [% oc %] to dn [% dn %]
++[% l('Adding objectclass [_1] to dn [_2]', oc, dn) %]
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type=&quot;hidden&quot; name=&quot;dn&quot; value=&quot;[% dn %]&quot; /&gt;
+@@ -6,8 +6,8 @@
+ &lt;input type=&quot;hidden&quot; name=&quot;objectclass&quot; value=&quot;[% oc %]&quot; /&gt;
+ &lt;table&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Attribute&lt;/th&gt;
+- &lt;th&gt;Value&lt;/th&gt;
++ &lt;th&gt;[% l('Attribute') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Value') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH attr IN must %]
+ [% IF attr != &quot;objectClass&quot; %]
+@@ -25,6 +25,6 @@
+ &lt;/tr&gt;
+ [% END %]
+ &lt;/table&gt;
+- &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;Add&quot; /&gt;&lt;/p&gt;
++ &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot; /&gt;&lt;/p&gt;
+
+ &lt;/form&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootadminaccount_grouptt">Modified: identity/CatDap/branches/live/root/admin/account_group.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_group.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_group.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,4 @@
+-&lt;h2&gt;Add user [% uid %] to a new group&lt;/h2&gt;
++&lt;h2&gt;[% l('Add user [_1] to a new group, uid) %]&lt;/h2&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type='hidden' name='uid' value='[% uid %]' /&gt;
+@@ -8,12 +8,12 @@
+ &lt;option value='[% group.cn %]'&gt;[% group.cn %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type='submit' value='Add' /&gt;
++ &lt;input type='submit' value='[% l('Add') %]' /&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+
+-&lt;h2&gt;Delete user [% uid %] from an existing group:&lt;/h2&gt;
++&lt;h2&gt;[% l('Delete user [_1] from an existing group:', uid) %] &lt;/h2&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type='hidden' name='uid' value='[% uid %]' /&gt;
+@@ -23,7 +23,7 @@
+ &lt;option value='[% group.cn %]'&gt;[% group.cn %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type='submit' value='Delete' /&gt;
++ &lt;input type='submit' value='[% l('Delete') %]' /&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootadminaccount_modifytt">Modified: identity/CatDap/branches/live/root/admin/account_modify.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_modify.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_modify.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,12 +1,12 @@
+-&lt;a href=&quot;[% c.uri_for('/admin/password') %]/[% uid %]&quot;&gt;Reset password&lt;/a&gt;
+-&lt;a href=&quot;[% c.uri_for('/admin/account_group') %]/[% uid %]&quot;&gt;Groups&lt;/a&gt;
++&lt;a href=&quot;[% c.uri_for('/admin/password') %]/[% uid %]&quot;&gt;[% l('Reset password') %]&lt;/a&gt;
++&lt;a href=&quot;[% c.uri_for('/admin/account_group') %]/[% uid %]&quot;&gt;[% l('Groups') %]&lt;/a&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;input type='hidden' name='operation' value='replace' /&gt;
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Attribute&lt;/th&gt;
+- &lt;th&gt;Value&lt;/th&gt;
++ &lt;th&gt;[% l('Attribute') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Value') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH attr IN values %]
+ &lt;tr&gt;
+@@ -21,10 +21,10 @@
+ &lt;br/&gt;
+ [% END %]
+ [% IF attr.addable AND attr.editable %]
+- &lt;a href=&quot;[% c.uri_for('/admin/account_edit') %]/add/[% attr.name %]&quot;&gt;Add&lt;/a&gt;
++ &lt;a href=&quot;[% c.uri_for('/admin/account_edit') %]/add/[% attr.name %]&quot;&gt;[% l('Add') %]&lt;/a&gt;
+ [% END %]
+ [% IF attr.removable AND attr.editable %]
+- &lt;a href=&quot;[% c.uri_for('/admin/account_modifydel') %]/[% uid %]/[% attr.name %]/[% val %]&quot;&gt;Delete&lt;/a&gt;
++ &lt;a href=&quot;[% c.uri_for('/admin/account_modifydel') %]/[% uid %]/[% attr.name %]/[% val %]&quot;&gt;[% l('Delete') %]&lt;/a&gt;
+ [% END %]
+ [% END %]
+ &lt;/td&gt;
+@@ -32,7 +32,7 @@
+ [% END %]
+ &lt;tr&gt;
+ &lt;td colspan=2 align=center&gt;
+- &lt;input type='Submit' value='Update'&gt;
++ &lt;input type='Submit' value='[% l('Update') %]'&gt;
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ &lt;/table&gt;
+@@ -44,13 +44,13 @@
+ &lt;input type=&quot;hidden&quot; name=&quot;operation&quot; value=&quot;add&quot; /&gt;
+
+ &lt;p&gt;
+- Add attribute
++ [% l('Add attribute') %]
+ &lt;select name='attribute'&gt;
+ [% FOREACH attr IN may %]
+ &lt;option value=&quot;[% attr %]&quot;&gt;[% attr %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- with value
++ [% l('with value') %]
+ &lt;input name=&quot;value&quot; value=&quot;&quot; /&gt;
+ &lt;input type=&quot;submit&quot; value=&quot;Add&quot; /&gt;
+ &lt;/p&gt;
+@@ -59,7 +59,7 @@
+ &lt;hr /&gt;
+
+ [% IF groups %]
+-&lt;p&gt;Promote user to posixAccount with primary group: &lt;/p&gt;
++&lt;p&gt;[% l('Promote user to posixAccount with primary group:') %] &lt;/p&gt;
+
+ &lt;form method=&quot;post&quot; action=&quot;[% c.uri_for('/admin/account_promote') %]&quot;&gt;
+ &lt;input type=&quot;hidden&quot; name=&quot;dn&quot; value=&quot;[% dn %]&quot; /&gt;
+@@ -68,7 +68,7 @@
+ &lt;option value=&quot;[% group.gidNumber %]&quot;&gt;[% group.name %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type=&quot;submit&quot; value=&quot;Promote&quot; /&gt;
++ &lt;input type=&quot;submit&quot; value=&quot;[% l('Promote') %]&quot; /&gt;
+ &lt;/form&gt;
+ [% END %]
+
+@@ -82,7 +82,7 @@
+ &lt;option value='[% oc %]'&gt;[% oc %]&lt;/option&gt;
+ [% END %]
+ &lt;/select&gt;
+- &lt;input type=&quot;submit&quot; value=&quot;Add ObjectClass&quot; /&gt;
++ &lt;input type=&quot;submit&quot; value=&quot;[% l('Add ObjectClass') %]&quot; /&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootadminaccount_promotett">Modified: identity/CatDap/branches/live/root/admin/account_promote.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/account_promote.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/account_promote.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,12 +1,12 @@
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Select&lt;/th&gt;
+- &lt;th&gt;Username&lt;/th&gt;
+- &lt;th&gt;Email&lt;/th&gt;
+- &lt;th&gt;First Name&lt;/th&gt;
+- &lt;th&gt;Surname&lt;/td&gt;
+- &lt;th&gt;Full Name&lt;/td&gt;
++ &lt;th&gt;[% l('Select') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Username') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Email') %]&lt;/th&gt;
++ &lt;th&gt;[% l('First Name') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Surname') %]&lt;/td&gt;
++ &lt;th&gt;[% l('Full Name') %]&lt;/td&gt;
+ &lt;/tr&gt;
+ [% FOREACH entry IN entries %]
+ &lt;tr&gt;
+@@ -22,7 +22,7 @@
+
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+- &lt;td&gt;Primary group&lt;/td&gt;
++ &lt;td&gt;[% l('Primary group') %]&lt;/td&gt;
+ &lt;td&gt;
+ &lt;select name=&quot;gid&quot;&gt;
+ [% FOREACH group IN groups %]
+
+<a id="identityCatDapbranchesliverootadmingrouptt">Modified: identity/CatDap/branches/live/root/admin/group.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/group.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/group.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -2,20 +2,20 @@
+ &lt;table&gt;
+ &lt;tr&gt;
+ &lt;td&gt;
+-Search by
++[% l('Search by') %]
+ &lt;/td&gt;
+ &lt;td&gt;
+ &lt;select name=&quot;attribute&quot;&gt;
+-&lt;option value=&quot;cn&quot;&gt;Group name&lt;/option&gt;
+-&lt;option value=&quot;member&quot;&gt;member&lt;/option&gt;
++&lt;option value=&quot;cn&quot;&gt;[% l('Group name') %]&lt;/option&gt;
++&lt;option value=&quot;member&quot;&gt;[% l('member') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td&gt;
+ &lt;!-- td&gt;
+ &lt;select name=&quot;matchtype&quot;&gt;
+-&lt;option value=&quot;substring&quot;&gt;contains&lt;/option&gt;
+-&lt;option value=&quot;exact&quot;&gt;is exactly&lt;/option&gt;
+-&lt;option value=&quot;gte&quot;&gt;greater than or equal to&lt;/option&gt;
+-&lt;option value=&quot;lt&quot;&gt;less than&lt;/option&gt;
++&lt;option value=&quot;substring&quot;&gt;[% l('contains') %]&lt;/option&gt;
++&lt;option value=&quot;exact&quot;&gt;[% l('is exactly') %]&lt;/option&gt;
++&lt;option value=&quot;gte&quot;&gt;[% l('greater than or equal to') %]&lt;/option&gt;
++&lt;option value=&quot;lt&quot;&gt;[% l('less than') %]&lt;/option&gt;
+ &lt;/select&gt;
+ &lt;/td --&gt;
+ &lt;td&gt;&lt;input name='value'&gt;&lt;/td&gt;
+@@ -24,7 +24,7 @@
+ [% IF entries %]
+ &lt;table border=0&gt;
+ &lt;tr&gt;
+-&lt;th&gt;Group Name&lt;/th&gt;
++&lt;th&gt;[% l('Group Name') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH entry IN entries %]
+ &lt;tr&gt;
+
+<a id="identityCatDapbranchesliverootadmingroup_modifytt">Modified: identity/CatDap/branches/live/root/admin/group_modify.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/group_modify.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/group_modify.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -2,8 +2,8 @@
+ &lt;input type='hidden' name='dn' value='[% group.dn %]'&gt;
+ &lt;table&gt;
+ &lt;tr&gt;
+- &lt;th&gt;Attribute&lt;/th&gt;
+- &lt;th&gt;Value&lt;/th&gt;
++ &lt;th&gt;[% l('Attribute') %]&lt;/th&gt;
++ &lt;th&gt;[% l('Value') %]&lt;/th&gt;
+ &lt;/tr&gt;
+ [% FOREACH attr IN group.attributes %]
+ &lt;tr&gt;
+@@ -11,11 +11,11 @@
+ &lt;td&gt;
+ [% FOREACH value IN group.get_value(attr) %]
+ [% value %]
+- &lt;a href=&quot;[% c.uri_for('/admin/group_modify') %]/delete/[% group.dn %]/[% attr %]/[% value %]&quot;&gt;delete&lt;/a&gt;
++ &lt;a href=&quot;[% c.uri_for('/admin/group_modify') %]/delete/[% group.dn %]/[% attr %]/[% value %]&quot;&gt;[% l('delete') %]&lt;/a&gt;
+ &lt;br/&gt;
+ [% END %]
+ &lt;input name=&quot;[% attr %]&quot; value=&quot;&quot; /&gt;
+- &lt;input type=&quot;submit&quot; value=&quot;Add&quot; /&gt;
++ &lt;input type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot; /&gt;
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ [% END %]
+
+<a id="identityCatDapbranchesliverootadminindextt">Modified: identity/CatDap/branches/live/root/admin/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/admin/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/admin/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1 +1 @@
+-&lt;p&gt;Please use the menus above.&lt;/p&gt;
+\ No newline at end of file
++&lt;p&gt;[% l('Please use the menus above.') %]&lt;/p&gt;
+
+<a id="identityCatDapbranchesliverootemailactivationtt">Modified: identity/CatDap/branches/live/root/email/activation.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/email/activation.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/email/activation.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -4,4 +4,4 @@
+ [% url %]
+
+ --
+-http://mageia.org/
+\ No newline at end of file
++[% c.config.project_url %]
+
+<a id="identityCatDapbranchesliverootemailadminpasswordtt">Modified: identity/CatDap/branches/live/root/email/admin/password.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/email/admin/password.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/email/admin/password.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -7,4 +7,4 @@
+ [% url %]
+
+ --
+-http://mageia.org/
+\ No newline at end of file
++[% c.config.project_url %]
+
+<a id="identityCatDapbranchesliverootindextt">Modified: identity/CatDap/branches/live/root/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,21 +1,22 @@
+ &lt;h1&gt;[% l('Login') %]&lt;/h1&gt;
+
++&lt;div id=&quot;login_form&quot;&gt;
+ &lt;form method=&quot;post&quot; action=&quot;/user&quot;&gt;
++ &lt;div id=&quot;login_form_inputs&quot;&gt;
++ &lt;label for=&quot;username_&quot;&gt;[% l('Username : ') %]&lt;/label&gt;
++ &lt;input id=&quot;username_&quot; type=&quot;text&quot; name=&quot;username&quot; value=&quot;[% c.user.username %]&quot; /&gt;
++ &lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;username_&quot;&gt;[% l('Username') %]&lt;/label&gt;
+- &lt;input id=&quot;username_&quot; type=&quot;text&quot; name=&quot;username&quot; value=&quot;[% c.user.username %]&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;
+- &lt;label for=&quot;password_&quot;&gt;[% l('Password') %]&lt;/label&gt;
+- &lt;input id=&quot;password_&quot; type=&quot;password&quot; name=&quot;password&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; /&gt;
+- [% l('or') %]
+- &lt;a href=&quot;/register&quot;&gt;[% l('Register') %]&lt;/a&gt;&lt;/p&gt;
+-
+- &lt;p&gt;@todo [% l('Forgotten password?') %]&lt;/p&gt;
+-
++ &lt;label for=&quot;password_&quot;&gt;[% l('Password : ') %]&lt;/label&gt;
++ &lt;input id=&quot;password_&quot; type=&quot;password&quot; name=&quot;password&quot; /&gt;
++ &lt;br /&gt;
++ &lt;/div&gt;
++ &lt;div id=&quot;login_form_line&quot;&gt;
++ &lt;span&gt;&lt;a href=&quot;/register&quot;&gt;[% l('Register') %]&lt;/a&gt; |
++ @todo [% l('Forgotten password?') %]
++ &lt;!--&lt;a href=&quot;/forgot_password&quot;&gt;[% l('Forgotten password?') %]&lt;/a&gt; --&gt;
++ &lt;/span&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Login') %]&quot; &gt;[% l('Login') %]&lt;/button&gt;
++ &lt;/div&gt;
+ &lt;/form&gt;
++&lt;/div&gt;
+
+<a id="identityCatDapbranchesliverootregisterchecktt">Modified: identity/CatDap/branches/live/root/register/check.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/register/check.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/register/check.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,4 @@
+-&lt;h2&gt;Success&lt;/h2&gt;
++&lt;h2&gt;[% l('Success') %]&lt;/h2&gt;
+ &lt;p&gt;
+ [% message %]
+ &lt;/p&gt;
+\ No newline at end of file
+
+<a id="identityCatDapbranchesliverootregisterindextt">Modified: identity/CatDap/branches/live/root/register/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/register/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/register/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,48 +1,37 @@
+-[% MACRO l(text, args) BLOCK;
+- c.localize(text, args);
+-END; %]
+
+
+ &lt;h2&gt;[% l('Register') %]&lt;/h2&gt;
+
+-&lt;p class=&quot;error&quot;&gt;
+- [% FOREACH error IN errors %]
+- [% error %]&lt;br/&gt;
+- [% END %]
+-&lt;/p&gt;
+-
++&lt;div id=&quot;input_form&quot;&gt;
+ &lt;form method=&quot;post&quot; action=&quot;/register/check&quot;&gt;
++ &lt;h3&gt;[% l('Username') %]&lt;/h3&gt;
++ &lt;label for=&quot;uid_&quot;&gt;[% l('Username') %]&lt;/label&gt;&lt;br /&gt;
++ &lt;input id=&quot;uid_&quot; type=&quot;text&quot; name=&quot;uid&quot; value=&quot;[% c.request.params.uid %]&quot; /&gt;&lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;uid_&quot;&gt;[% l('Username') %]&lt;/label&gt;
+- &lt;input id=&quot;uid_&quot; type=&quot;text&quot; name=&quot;uid&quot; value=&quot;[% c.request.params.uid %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;p&gt;
++ &lt;h3&gt;[% l('Personal Information') %]&lt;/h3&gt;
++ &lt;label for=&quot;gn_&quot;&gt;[% l('First name') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;gn_&quot; type=&quot;text&quot; name=&quot;gn&quot; value=&quot;[% c.request.params.gn %]&quot; /&gt;&lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;gn_&quot;&gt;[% l('First name') %]&lt;/label&gt;
+- &lt;input id=&quot;gn_&quot; type=&quot;text&quot; name=&quot;gn&quot; value=&quot;[% c.request.params.gn %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;label for=&quot;sn_&quot;&gt;[% l('Surname') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;sn_&quot; type=&quot;text&quot; name=&quot;sn&quot; value=&quot;[% c.request.params.sn %]&quot; /&gt;&lt;br /&gt;
++ &lt;/p&gt;
++ &lt;p&gt;
++ &lt;h3&gt;[% l('Email') %]&lt;/h3&gt;
++ &lt;label for=&quot;mail1_&quot;&gt;[% l('Email address') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;mail1_&quot; type=&quot;text&quot; name=&quot;mail1&quot; value=&quot;[% c.request.params.mail1 %]&quot; /&gt;&lt;br /&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;sn_&quot;&gt;[% l('Surname') %]&lt;/label&gt;
+- &lt;input id=&quot;sn_&quot; type=&quot;text&quot; name=&quot;sn&quot; value=&quot;[% c.request.params.sn %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;label for=&quot;mail2_&quot;&gt;[% l('Confirm Email address') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input id=&quot;mail2_&quot; type=&quot;text&quot; name=&quot;mail2&quot; value=&quot;[% c.request.params.mail2 %]&quot; /&gt;&lt;br /&gt;
++ &lt;/p&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;mail1_&quot;&gt;[% l('Email address') %]&lt;/label&gt;
+- &lt;input id=&quot;mail1_&quot; type=&quot;text&quot; name=&quot;mail1&quot; value=&quot;[% c.request.params.mail1 %]&quot; /&gt;
+- &lt;/p&gt;
++ &lt;p&gt;
++ &lt;h3&gt;[% l('Captcha') %]&lt;/h3&gt;
+
+- &lt;p&gt;
+- &lt;label for=&quot;mail2_&quot;&gt;[% l('Confirm Email address') %]&lt;/label&gt;
+- &lt;input id=&quot;mail2_&quot; type=&quot;text&quot; name=&quot;mail2&quot; value=&quot;[% c.request.params.mail2 %]&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;
+- &lt;img src=&quot;/register/captcha&quot; /&gt;
+- &lt;input type=&quot;text&quot; name=&quot;validate&quot; /&gt;
+- &lt;/p&gt;
+-
+- &lt;p&gt;&lt;input type=&quot;submit&quot; value=&quot;[% l('Register') %]&quot; /&gt;&lt;/p&gt;
+-
+-&lt;/form&gt;
+\ No newline at end of file
++ &lt;img src=&quot;/register/captcha&quot; /&gt;&lt;br /&gt;
++ &lt;label for=&quot;test&quot;&gt;[% l('Enter text') %]&lt;/label&gt;&lt;br/&gt;
++ &lt;input type=&quot;text&quot; name=&quot;validate&quot; /&gt;&lt;br/&gt;
++ &lt;/p&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Register') %]&quot;&gt;[% l('Register') %]&lt;/button&gt;
++&lt;/form&gt;
++&lt;/div&gt;
+
+<a id="identityCatDapbranchesliveroottemplatefooter">Modified: identity/CatDap/branches/live/root/template/footer</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/footer 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/footer 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,4 +1,5 @@
+-&lt;p&gt;2010 &lt;a href=&quot;http://mageia.org/&quot;&gt;Mageia.org&lt;/a&gt;
++&lt;div class=&quot;hnav&quot;&gt;
++&lt;div align=center&gt;&lt;p&gt;2010 &lt;a href=&quot;http://mageia.org/&quot;&gt;Mageia.org&lt;/a&gt;
+ | &lt;a href=&quot;http://mageia.org/policies/privacy/&quot;&gt;Privacy policy&lt;/a&gt;
+ | &lt;a href=&quot;http://mageia.org/faq/accounts/&quot;&gt;Mageia user accounts FAQ&lt;/a&gt;
+- &lt;/p&gt;
+\ No newline at end of file
++&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
+
+<a id="identityCatDapbranchesliveroottemplateheader">Modified: identity/CatDap/branches/live/root/template/header</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/header 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/header 2011-01-05 15:32:57 UTC (rev 212)
+@@ -8,8 +8,6 @@
+ [% IF c.user.username %]
+ &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;[% c.uri_for(&quot;/user&quot;) %]&quot;&gt;[% c.user.username %]&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
+ &lt;li&gt;&lt;a href=&quot;/user/logout&quot;&gt;[% l('Log out') %]&lt;/a&gt;&lt;/li&gt;
+- [% ELSE %]
+- &lt;li&gt;&lt;a href=&quot;/&quot;&gt;[% l('Login') %]&lt;/a&gt;&lt;/li&gt;
+ [% END %]
+ &lt;/ul&gt;
+ &lt;/div&gt;
+
+<a id="identityCatDapbranchesliveroottemplatehtml">Modified: identity/CatDap/branches/live/root/template/html</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/html 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/html 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,17 +1,17 @@
+ &lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+ &lt;!DOCTYPE html&gt;
+-&lt;html lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
++&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;
+ &lt;head&gt;
+ &lt;meta charset=&quot;utf-8&quot; /&gt;
+ &lt;title&gt;[% template.title or site.title or c.config.apptitle %]&lt;/title&gt;
+- &lt;meta content=&quot;description&quot; value=&quot;Mageia.org online user account panel&quot; /&gt;
+- &lt;meta content=&quot;keywords&quot; value=&quot;mageia, user, account, password&quot; /&gt;
+- &lt;meta content=&quot;robots&quot; value=&quot;index,nofollow&quot; /&gt;
+- &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/reset-fonts-grids.css&quot;&gt;
+- &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/base-min.css&quot;&gt;
++ &lt;meta name=&quot;description&quot; content=&quot;Mageia.org online user account panel&quot; /&gt;
++ &lt;meta name=&quot;keywords&quot; content=&quot;mageia, user, account, password&quot; /&gt;
++ &lt;meta name=&quot;robots&quot; content=&quot;index,nofollow&quot; /&gt;
++ &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/reset-fonts-grids.css&quot; /&gt;
++ &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/yui/base-min.css&quot; /&gt;
+ &lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; href=&quot;/static/style/ttsite.css&quot; /&gt;
+ &lt;/head&gt;
+ &lt;body&gt;
+ [% content %]
+ &lt;/body&gt;
+-&lt;/html&gt;
+\ No newline at end of file
++&lt;/html&gt;
+
+<a id="identityCatDapbranchesliveroottemplatepre">Modified: identity/CatDap/branches/live/root/template/pre</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/pre 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/pre 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,3 +1,3 @@
+-[% MACRO l(text, args) BLOCK;
++[%- MACRO l(text, args) BLOCK;
+ c.localize(text, args);
+-END; %]
++END; -%]
+
+<a id="identityCatDapbranchesliveroottemplatewrapper">Modified: identity/CatDap/branches/live/root/template/wrapper</a>
+===================================================================
+--- identity/CatDap/branches/live/root/template/wrapper 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/template/wrapper 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,7 +1,4 @@
+-[% MACRO l(text, args) BLOCK;
+- c.localize(text, args);
+-END; %]
+-[% IF template.name.match('\.(css|js|txt)');
++[%- IF template.name.match('\.(css|js|txt)');
+ debug(&quot;Passing page through as text: $template.name&quot;);
+ content;
+ ELSE;
+
+<a id="identityCatDapbranchesliverootuserindextt">Modified: identity/CatDap/branches/live/root/user/index.tt</a>
+===================================================================
+--- identity/CatDap/branches/live/root/user/index.tt 2011-01-05 15:09:20 UTC (rev 211)
++++ identity/CatDap/branches/live/root/user/index.tt 2011-01-05 15:32:57 UTC (rev 212)
+@@ -1,30 +1,34 @@
++&lt;div id=&quot;input_form&quot;&gt;
+ &lt;form method=&quot;post&quot; action=&quot;&quot;&gt;
+- &lt;table border=0&gt;
+- &lt;tr&gt;&lt;th&gt;Attribute&lt;/th&gt;&lt;th&gt;Value&lt;/th&gt;&lt;/tr&gt;
++ &lt;table&gt;
++ &lt;tr&gt;&lt;th&gt;[% l('Attribute') %]&lt;/th&gt;&lt;th&gt;[% l('Value') %]&lt;/th&gt;&lt;th&gt;&lt;/th&gt;&lt;/tr&gt;
+ [% FOREACH attr IN values %]
+ &lt;tr&gt;
+ &lt;td&gt;[% attr.name %]&lt;/td&gt;
+ &lt;td&gt;
+ [% FOREACH val IN attr.values %]
+- [% IF attr.editable %]&lt;input type=hidden name=&quot;[% attr.name %]_old&quot; value=&quot;[% val %]&quot;&gt;
+- &lt;input name=&quot;[% attr.name %]_new&quot; value=&quot;[% val %]&quot;&gt;
++ [% IF attr.editable %]&lt;input type=&quot;hidden&quot; name=&quot;[% attr.name %]_old&quot; value=&quot;[% val %]&quot; /&gt;
++ &lt;input name=&quot;[% attr.name %]_new&quot; value=&quot;[% val %]&quot; /&gt;
+ [% ELSE %]
+ [% val %]
+ &lt;br/&gt;
+ [% END %]
++ &lt;/td&gt;
++ &lt;td&gt;
+ [% IF attr.addable AND attr.editable %]
+- &lt;a href=&quot;/user/add/[% attr.name %]&quot;&gt;[% l('Add') %]&lt;/a&gt;
++ &lt;button type=&quot;button&quot; onclick=&quot;location='/user/add/[% attr.name %]'&quot;&gt;[% l('Add') %]&lt;/button&gt;
+ [% END %]
+ [% IF attr.removable AND attr.editable %]
+- &lt;a href=&quot;/user/delete/[% attr.name %]/[% val %]&quot;&gt;[% l('Delete') %]&lt;/a&gt;
++ &lt;button type=&quot;button&quot; onclick=&quot;location='/user/delete/[% attr.name %]/[% val %]'&quot;&gt;[% l('Delete') %]&lt;/button&gt;
+ [% END %]
+ [% END %]
+ &lt;/td&gt;
+ &lt;/tr&gt;
+ [% END %]
++ &lt;tr&gt;
++ &lt;td colspan=&quot;3&quot; style=&quot;text-align:center;&quot;&gt;&lt;button type=&quot;Submit&quot; value=&quot;[% l('Update') %]&quot;&gt;[% l('Update') %]&lt;/button&gt;&lt;/td&gt;
++ &lt;/tr&gt;
+ &lt;/table&gt;
+-
+- &lt;p&gt;&lt;input type=&quot;Submit&quot; value=&quot;[% l('Update') %]&quot; /&gt;&lt;/p&gt;
+ &lt;/form&gt;
+
+ &lt;hr /&gt;
+@@ -35,9 +39,11 @@
+ [% FOREACH attr IN may %]
+ &lt;option value=&quot;[% attr %]&quot;&gt;[% attr %]&lt;/option&gt;
+ [% END %]
++ &lt;/select&gt;
+
+ &lt;input name=&quot;value&quot; value=&quot;&quot; /&gt;
+
+- &lt;input type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot; /&gt;
++ &lt;button type=&quot;submit&quot; value=&quot;[% l('Add') %]&quot;&gt;[% l('Add') %]&lt;/button&gt;
+ &lt;/p&gt;
+ &lt;/form&gt;
++&lt;/div&gt;
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment-0001.html
new file mode 100644
index 000000000..e9ebff1b7
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment-0001.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[207] version 1.9.2</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>207</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 00:43:39 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>version 1.9.2</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#build_systemrepsystrunkCHANGES">build_system/repsys/trunk/CHANGES</a></li>
+<li><a href="#build_systemrepsystrunkrepsys">build_system/repsys/trunk/repsys</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemrepsystrunkCHANGES">Modified: build_system/repsys/trunk/CHANGES</a>
+===================================================================
+--- build_system/repsys/trunk/CHANGES 2011-01-04 23:34:58 UTC (rev 206)
++++ build_system/repsys/trunk/CHANGES 2011-01-04 23:43:39 UTC (rev 207)
+@@ -1,3 +1,6 @@
++* 1.9.2-binrepo
++- add .xz files in binrepo
++
+ * 1.9.1-binrepo
+ - fix problem with python threads on 2010.1
+
+
+<a id="build_systemrepsystrunkrepsys">Modified: build_system/repsys/trunk/repsys</a>
+===================================================================
+--- build_system/repsys/trunk/repsys 2011-01-04 23:34:58 UTC (rev 206)
++++ build_system/repsys/trunk/repsys 2011-01-04 23:43:39 UTC (rev 207)
+@@ -4,7 +4,7 @@
+ import getopt
+ import sys
+
+-VERSION=&quot;1.9.1-binrepo&quot;
++VERSION=&quot;1.9.2-binrepo&quot;
+
+ HELP = &quot;&quot;&quot;\
+ Usage: repsys COMMAND [COMMAND ARGUMENTS]
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment.html
new file mode 100644
index 000000000..e9ebff1b7
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/643d1b25/attachment.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[207] version 1.9.2</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>207</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 00:43:39 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>version 1.9.2</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#build_systemrepsystrunkCHANGES">build_system/repsys/trunk/CHANGES</a></li>
+<li><a href="#build_systemrepsystrunkrepsys">build_system/repsys/trunk/repsys</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemrepsystrunkCHANGES">Modified: build_system/repsys/trunk/CHANGES</a>
+===================================================================
+--- build_system/repsys/trunk/CHANGES 2011-01-04 23:34:58 UTC (rev 206)
++++ build_system/repsys/trunk/CHANGES 2011-01-04 23:43:39 UTC (rev 207)
+@@ -1,3 +1,6 @@
++* 1.9.2-binrepo
++- add .xz files in binrepo
++
+ * 1.9.1-binrepo
+ - fix problem with python threads on 2010.1
+
+
+<a id="build_systemrepsystrunkrepsys">Modified: build_system/repsys/trunk/repsys</a>
+===================================================================
+--- build_system/repsys/trunk/repsys 2011-01-04 23:34:58 UTC (rev 206)
++++ build_system/repsys/trunk/repsys 2011-01-04 23:43:39 UTC (rev 207)
+@@ -4,7 +4,7 @@
+ import getopt
+ import sys
+
+-VERSION=&quot;1.9.1-binrepo&quot;
++VERSION=&quot;1.9.2-binrepo&quot;
+
+ HELP = &quot;&quot;&quot;\
+ Usage: repsys COMMAND [COMMAND ARGUMENTS]
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment-0001.html
new file mode 100644
index 000000000..e2fa9ed73
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment-0001.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[206] add .xz files belonging in binrepo (patch from tmb)</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>206</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 00:34:58 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add .xz files belonging in binrepo (patch from tmb)</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#build_systemrepsystrunkRepSysbinrepopy">build_system/repsys/trunk/RepSys/binrepo.py</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemrepsystrunkRepSysbinrepopy">Modified: build_system/repsys/trunk/RepSys/binrepo.py</a>
+===================================================================
+--- build_system/repsys/trunk/RepSys/binrepo.py 2011-01-04 16:17:04 UTC (rev 205)
++++ build_system/repsys/trunk/RepSys/binrepo.py 2011-01-04 23:34:58 UTC (rev 206)
+@@ -107,7 +107,7 @@
+ raw = config.get(&quot;binrepo&quot;, &quot;upload-match&quot;,
+ &quot;\.(7z|Z|bin|bz2|cpio|db|deb|egg|gem|gz|jar|jisp|lzma|&quot;\
+ &quot;pdf|pgn\\.gz|pk3|rpm|rpm|run|sdz|smzip|tar|tbz|&quot;\
+- &quot;tbz2|tgz|ttf|uqm|wad|war|xar|xpi|zip)$&quot;)
++ &quot;tbz2|tgz|ttf|uqm|wad|war|xar|xpi|xz|zip)$&quot;)
+ maxsize = config.getint(&quot;binrepo&quot;, &quot;upload-match-size&quot;, &quot;1048576&quot;) # 1MiB
+ expr = re.compile(raw)
+ name = os.path.basename(path)
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment.html
new file mode 100644
index 000000000..e2fa9ed73
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/6a4d43b3/attachment.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[206] add .xz files belonging in binrepo (patch from tmb)</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>206</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 00:34:58 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add .xz files belonging in binrepo (patch from tmb)</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#build_systemrepsystrunkRepSysbinrepopy">build_system/repsys/trunk/RepSys/binrepo.py</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemrepsystrunkRepSysbinrepopy">Modified: build_system/repsys/trunk/RepSys/binrepo.py</a>
+===================================================================
+--- build_system/repsys/trunk/RepSys/binrepo.py 2011-01-04 16:17:04 UTC (rev 205)
++++ build_system/repsys/trunk/RepSys/binrepo.py 2011-01-04 23:34:58 UTC (rev 206)
+@@ -107,7 +107,7 @@
+ raw = config.get(&quot;binrepo&quot;, &quot;upload-match&quot;,
+ &quot;\.(7z|Z|bin|bz2|cpio|db|deb|egg|gem|gz|jar|jisp|lzma|&quot;\
+ &quot;pdf|pgn\\.gz|pk3|rpm|rpm|run|sdz|smzip|tar|tbz|&quot;\
+- &quot;tbz2|tgz|ttf|uqm|wad|war|xar|xpi|zip)$&quot;)
++ &quot;tbz2|tgz|ttf|uqm|wad|war|xar|xpi|xz|zip)$&quot;)
+ maxsize = config.getint(&quot;binrepo&quot;, &quot;upload-match-size&quot;, &quot;1048576&quot;) # 1MiB
+ expr = re.compile(raw)
+ name = os.path.basename(path)
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment-0001.html
new file mode 100644
index 000000000..0af6a0b32
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment-0001.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[655] - deploy trunk as a test instance, as asked several time on irc</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>655</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 19:12:50 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- deploy trunk as a test instance, as asked several time on irc</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulescatdapmanifestsinitpp">puppet/modules/catdap/manifests/init.pp</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulescatdapmanifestsinitpp">Modified: puppet/modules/catdap/manifests/init.pp</a>
+===================================================================
+--- puppet/modules/catdap/manifests/init.pp 2011-01-05 13:41:16 UTC (rev 654)
++++ puppet/modules/catdap/manifests/init.pp 2011-01-05 18:12:50 UTC (rev 655)
+@@ -1,7 +1,6 @@
+ class catdap {
+
+- $catdap_location = &quot;/var/www/identity&quot;
+- $catdap_vhost = &quot;identity.$domain&quot;
++ $upstream_svn = &quot;svn://svn.mageia.org/svn/soft/identity/CatDap/&quot;
+
+ # TODO switch to a proper rpm packaging
+ $rpm_requirement = ['perl-Catalyst-Runtime',&quot;perl-FCGI&quot;, 'perl-Catalyst-Plugin-Authorization-Roles',
+@@ -17,27 +16,41 @@
+ ensure =&gt; installed
+ }
+
+- subversion::snapshot { $catdap_location:
+- source =&gt; &quot;svn://svn.mageia.org/svn/soft/identity/CatDap/branches/live&quot;
+- }
+-
+ $ldap_password = extlookup('catdap_ldap','x')
+
+- file { &quot;$catdap_location/catdap_local.yml&quot;:
+- ensure =&gt; present,
+- owner =&gt; root,
+- group =&gt; apache,
+- mode =&gt; 640,
+- content =&gt; template(&quot;catdap/catdap_local.yml&quot;),
+- require =&gt; Subversion::Snapshot[$catdap_location]
++
++
++ define catdap_snapshot($location, $svn_location) {
++ file { &quot;$location/catdap_local.yml&quot;:
++ ensure =&gt; present,
++ owner =&gt; root,
++ group =&gt; apache,
++ mode =&gt; 640,
++ content =&gt; template(&quot;catdap/catdap_local.yml&quot;),
++ require =&gt; Subversion::Snapshot[$location],
++ }
++
++ subversion::snapshot { $location:
++ source =&gt; $svn_location
++ }
++
++ apache::vhost_catalyst_app { $name:
++ script =&gt; &quot;$location/script/catdap_fastcgi.pl&quot;,
++ location =&gt; $location,
++ use_ssl =&gt; true,
++ }
++
++ apache::vhost_redirect_ssl { $name: }
+ }
+
+- apache::vhost_catalyst_app { $catdap_vhost:
+- script =&gt; &quot;$catdap_location/script/catdap_fastcgi.pl&quot;,
+- location =&gt; $catdap_location,
+- use_ssl =&gt; true,
++ catdap_snapshot { &quot;identity.$domain&quot;:
++ location =&gt; &quot;/var/www/identity&quot;,
++ svn_location =&gt; &quot;$upstream_svn/branches/live&quot;
+ }
+
+- apache::vhost_redirect_ssl { $catdap_vhost: }
++ catdap_snapshot { &quot;identity-trunk.$domain&quot;:
++ location =&gt; &quot;/var/www/identity-trunk&quot;,
++ svn_location =&gt; &quot;$upstream_svn/trunk&quot;
++ }
+
+ }
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment.html
new file mode 100644
index 000000000..0af6a0b32
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/6f9d880c/attachment.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[655] - deploy trunk as a test instance, as asked several time on irc</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>655</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 19:12:50 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- deploy trunk as a test instance, as asked several time on irc</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulescatdapmanifestsinitpp">puppet/modules/catdap/manifests/init.pp</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulescatdapmanifestsinitpp">Modified: puppet/modules/catdap/manifests/init.pp</a>
+===================================================================
+--- puppet/modules/catdap/manifests/init.pp 2011-01-05 13:41:16 UTC (rev 654)
++++ puppet/modules/catdap/manifests/init.pp 2011-01-05 18:12:50 UTC (rev 655)
+@@ -1,7 +1,6 @@
+ class catdap {
+
+- $catdap_location = &quot;/var/www/identity&quot;
+- $catdap_vhost = &quot;identity.$domain&quot;
++ $upstream_svn = &quot;svn://svn.mageia.org/svn/soft/identity/CatDap/&quot;
+
+ # TODO switch to a proper rpm packaging
+ $rpm_requirement = ['perl-Catalyst-Runtime',&quot;perl-FCGI&quot;, 'perl-Catalyst-Plugin-Authorization-Roles',
+@@ -17,27 +16,41 @@
+ ensure =&gt; installed
+ }
+
+- subversion::snapshot { $catdap_location:
+- source =&gt; &quot;svn://svn.mageia.org/svn/soft/identity/CatDap/branches/live&quot;
+- }
+-
+ $ldap_password = extlookup('catdap_ldap','x')
+
+- file { &quot;$catdap_location/catdap_local.yml&quot;:
+- ensure =&gt; present,
+- owner =&gt; root,
+- group =&gt; apache,
+- mode =&gt; 640,
+- content =&gt; template(&quot;catdap/catdap_local.yml&quot;),
+- require =&gt; Subversion::Snapshot[$catdap_location]
++
++
++ define catdap_snapshot($location, $svn_location) {
++ file { &quot;$location/catdap_local.yml&quot;:
++ ensure =&gt; present,
++ owner =&gt; root,
++ group =&gt; apache,
++ mode =&gt; 640,
++ content =&gt; template(&quot;catdap/catdap_local.yml&quot;),
++ require =&gt; Subversion::Snapshot[$location],
++ }
++
++ subversion::snapshot { $location:
++ source =&gt; $svn_location
++ }
++
++ apache::vhost_catalyst_app { $name:
++ script =&gt; &quot;$location/script/catdap_fastcgi.pl&quot;,
++ location =&gt; $location,
++ use_ssl =&gt; true,
++ }
++
++ apache::vhost_redirect_ssl { $name: }
+ }
+
+- apache::vhost_catalyst_app { $catdap_vhost:
+- script =&gt; &quot;$catdap_location/script/catdap_fastcgi.pl&quot;,
+- location =&gt; $catdap_location,
+- use_ssl =&gt; true,
++ catdap_snapshot { &quot;identity.$domain&quot;:
++ location =&gt; &quot;/var/www/identity&quot;,
++ svn_location =&gt; &quot;$upstream_svn/branches/live&quot;
+ }
+
+- apache::vhost_redirect_ssl { $catdap_vhost: }
++ catdap_snapshot { &quot;identity-trunk.$domain&quot;:
++ location =&gt; &quot;/var/www/identity-trunk&quot;,
++ svn_location =&gt; &quot;$upstream_svn/trunk&quot;
++ }
+
+ }
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment-0001.html
new file mode 100644
index 000000000..0274c6c96
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment-0001.html
@@ -0,0 +1,11434 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[210] add mandriva version of youri-core, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/core/trunk/ at revision 271600</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>210</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 14:23:45 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add mandriva version of youri-core, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/core/trunk/ at revision 271600</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>build_system/mdv-youri-core/</li>
+<li>build_system/mdv-youri-core/branches/</li>
+<li>build_system/mdv-youri-core/tags/</li>
+<li>build_system/mdv-youri-core/trunk/</li>
+<li><a href="#build_systemmdvyouricoretrunkChangeLog">build_system/mdv-youri-core/trunk/ChangeLog</a></li>
+<li><a href="#build_systemmdvyouricoretrunkMANIFESTSKIP">build_system/mdv-youri-core/trunk/MANIFEST.SKIP</a></li>
+<li><a href="#build_systemmdvyouricoretrunkMakefilePL">build_system/mdv-youri-core/trunk/Makefile.PL</a></li>
+<li><a href="#build_systemmdvyouricoretrunkREADME">build_system/mdv-youri-core/trunk/README</a></li>
+<li><a href="#build_systemmdvyouricoretrunkTODO">build_system/mdv-youri-core/trunk/TODO</a></li>
+<li>build_system/mdv-youri-core/trunk/bin/</li>
+<li><a href="#build_systemmdvyouricoretrunkbinfillbugzilla">build_system/mdv-youri-core/trunk/bin/fillbugzilla</a></li>
+<li>build_system/mdv-youri-core/trunk/cgi/</li>
+<li><a href="#build_systemmdvyouricoretrunkcgimaintainerscgi">build_system/mdv-youri-core/trunk/cgi/maintainers.cgi</a></li>
+<li>build_system/mdv-youri-core/trunk/etc/</li>
+<li>build_system/mdv-youri-core/trunk/etc/bash_completion.d/</li>
+<li><a href="#build_systemmdvyouricoretrunketcbash_completiondyouri">build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri</a></li>
+<li><a href="#build_systemmdvyouricoretrunketccheckconf">build_system/mdv-youri-core/trunk/etc/check.conf</a></li>
+<li><a href="#build_systemmdvyouricoretrunketcuploadconf">build_system/mdv-youri-core/trunk/etc/upload.conf</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriBugzillapm">build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputAgepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceIurtpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceLBDpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildSourcepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputConflictspm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputDependenciespm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputMandrivaConflictspm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputMissingpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputOrphanspm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputRpmlintpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputSignaturepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceCPANpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceDebianpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFedorapm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFreshmeatpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGNOMEpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGentoopm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceNetBSDpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceRAApm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceSourceforgepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourcepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatespm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencesFilepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencespm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverBugzillapm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverCGIpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatHTMLpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatRSSpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatTextpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFilepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatHTMLpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatTextpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckResultsetDBIpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckResultsetIteratorpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckResultsetpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriConfigpm">build_system/mdv-youri-core/trunk/lib/Youri/Config.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Media/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriMediaURPMpm">build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriMediapm">build_system/mdv-youri-core/trunk/lib/Youri/Media.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Package/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageRPMpm">build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageRPM4pm">build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageTestpm">build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageURPMpm">build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackagepm">build_system/mdv-youri-core/trunk/lib/Youri/Package.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Repository/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositoryMandriva_uploadpm">build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositoryMandriva_upload_prepm">build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositoryPLFpm">build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositorypm">build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriUtilspm">build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/t/</li>
+<li><a href="#build_systemmdvyouricoretrunkt00distributiont">build_system/mdv-youri-core/trunk/t/00distribution.t</a></li>
+<li><a href="#build_systemmdvyouricoretrunktcowsay30311mdv20070noarchrpm">build_system/mdv-youri-core/trunk/t/cowsay-3.03-11mdv2007.0.noarch.rpm</a></li>
+<li>build_system/mdv-youri-core/trunk/t/gpghome/</li>
+<li><a href="#build_systemmdvyouricoretrunktgpghomepubringgpg">build_system/mdv-youri-core/trunk/t/gpghome/pubring.gpg</a></li>
+<li><a href="#build_systemmdvyouricoretrunktgpghomesecringgpg">build_system/mdv-youri-core/trunk/t/gpghome/secring.gpg</a></li>
+<li><a href="#build_systemmdvyouricoretrunktgpghometrustdbgpg">build_system/mdv-youri-core/trunk/t/gpghome/trustdb.gpg</a></li>
+<li><a href="#build_systemmdvyouricoretrunktpackaget">build_system/mdv-youri-core/trunk/t/package.t</a></li>
+<li><a href="#build_systemmdvyouricoretrunktversiont">build_system/mdv-youri-core/trunk/t/version.t</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemmdvyouricoretrunkChangeLog">Added: build_system/mdv-youri-core/trunk/ChangeLog</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/ChangeLog (rev 0)
++++ build_system/mdv-youri-core/trunk/ChangeLog 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,2 @@
++2006-04-23 Guillaume Rousse &lt;guillomovitch@zarb.org&gt; 0.9
++ * initial release
+
+<a id="build_systemmdvyouricoretrunkMANIFESTSKIP">Added: build_system/mdv-youri-core/trunk/MANIFEST.SKIP</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/MANIFEST.SKIP (rev 0)
++++ build_system/mdv-youri-core/trunk/MANIFEST.SKIP 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,14 @@
++CVS/.*
++\.svn/.*
++^cover_db/
++^blib/
++\.bak$
++\.swp$
++\.tar$
++\.tgz$
++\.tar\.gz$
++\.SKIP$
++~$
++^pm_to_blib$
++^Makefile$
++^Makefile\.old$
+
+<a id="build_systemmdvyouricoretrunkMakefilePL">Added: build_system/mdv-youri-core/trunk/Makefile.PL</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/Makefile.PL (rev 0)
++++ build_system/mdv-youri-core/trunk/Makefile.PL 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,31 @@
++# $Id: Makefile.PL 1724 2006-10-17 13:55:27Z warly $
++use ExtUtils::MakeMaker;
++
++WriteMakefile(
++ NAME =&gt; 'youri-core',
++ VERSION =&gt; 0.9,
++ AUTHOR =&gt; 'Youri project &lt;youri@zarb.org&gt;',
++ PREREQ_PM =&gt; {
++ 'AppConfig' =&gt; 0,
++ 'YAML' =&gt; 0,
++ 'Pod::Simple::HTMLBatch' =&gt; 0,
++ 'Test::Exception' =&gt; 0,
++ 'Exception' =&gt; 0,
++ 'RPM4' =&gt; 0,
++ 'URPM' =&gt; 0
++ }
++);
++
++package MY;
++
++sub top_targets {
++ my ($self) = @_;
++ my $top_targets = $self-&gt;SUPER::top_targets(@_);
++ $top_targets =~ s/all :: pure_all manifypods/all :: pure_all manifypods htmlifypods/;
++ $top_targets .= &lt;&lt;'EOF';
++htmlifypods : $(TO_INST_PM)
++ if [ ! -d blib/html ]; then mkdir blib/html; fi
++ perl -MPod::Simple::HTMLBatch -e Pod::Simple::HTMLBatch::go lib blib/html
++EOF
++ return $top_targets;
++}
+
+<a id="build_systemmdvyouricoretrunkREADME">Added: build_system/mdv-youri-core/trunk/README</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/README (rev 0)
++++ build_system/mdv-youri-core/trunk/README 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,33 @@
++youri-core
++----------
++
++Youri core libraries.
++
++Description
++-----------
++YOURI stands for &quot;Youri Offers an Upload &amp; Repository Infrastucture&quot;. It aims
++to build tools making management of a coherent set of packages easier.
++
++This package provides basic components used by other youri programs.
++
++Installation
++------------
++To install, just use:
++perl Makefile.PL
++make
++make test
++
++Copyright and License
++---------------------
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under
++the same terms as Perl itself.
++
++Authors
++-------
++Guillaume Rousse &lt;guillomovitch@zarb.org&gt;,
++Pascal Terjan &lt;pterjan@zarb.org&gt;
++Damien Krotkine &lt;dams@zarb.org&gt;
++Olivier Thauvin &lt;nanardon@zarb.org&gt;
++Ville Skytt\xE4 &lt;ville.skytta@iki.fi&gt;
+
+<a id="build_systemmdvyouricoretrunkTODO">Added: build_system/mdv-youri-core/trunk/TODO</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/TODO (rev 0)
++++ build_system/mdv-youri-core/trunk/TODO 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,7 @@
++1.0 Goals
++=========
++
++library:
++- API-based bugzilla interface, instead of SQL-based one
++- more generic check-specific options handling in medias (don't use a
++specific attribute for each of them)
+
+<a id="build_systemmdvyouricoretrunkbinfillbugzilla">Added: build_system/mdv-youri-core/trunk/bin/fillbugzilla</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/bin/fillbugzilla (rev 0)
++++ build_system/mdv-youri-core/trunk/bin/fillbugzilla 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,81 @@
++#!/usr/bin/perl
++# fillbugzilla
++# copyright (c) 2002 Guillaume Rousse &lt;guillomovitch@zarb.org&gt;
++# $Id: fillbugzilla 1179 2006-08-05 08:30:57Z warly $
++
++use strict;
++use warnings;
++use Getopt::Long;
++use Bugzilla;
++use Mail::Sendmail;
++
++# constants
++my $name = &quot;fillbugzilla&quot;;
++my $version = &quot;1.0&quot;;
++
++# command-line parameters
++my ($base, $user, $pass, $project, $mode, $help);
++GetOptions(
++ &quot;base=s&quot; =&gt; \$base,
++ &quot;user=s&quot; =&gt; \$user,
++ &quot;pass=s&quot; =&gt; \$pass,
++ &quot;mode=s&quot; =&gt; \$mode,
++ &quot;help&quot; =&gt; \$help,
++);
++
++# mandatory argument
++die usage() unless ($base &amp;&amp; $user &amp;&amp; $pass);
++die usage() unless ($mode eq 'package' || $mode eq 'packager');
++
++usage() &amp;&amp; exit 0 if $help;
++
++my $bugzilla = Bugzilla-&gt;new('localhost', $base, $user, $pass);
++
++if ($mode eq 'packager') {
++ while (my $packager = &lt;&gt;) {
++ chomp $packager;
++ my ($name, $login) = split(/\t/, $packager);
++
++ # random passwd
++ my @chars = (0..9, 'A'..'Z', 'a'..'z', '-', '_', '!', '@', '#', '$', '%', '^', '&amp;', '*');
++ my $password = join('', map { $chars[rand(scalar @chars)] } 1 .. 8);
++
++ # insert into database
++ $bugzilla-&gt;add_packager($name, $login, $password);
++
++ # mail user
++ my %mail = (
++ smtp =&gt; 'localhost',
++ To =&gt; $login,
++ From =&gt; 'bugmaster@zarb.org',
++ Subject =&gt; 'bugzilla password',
++ 'X-Mailer' =&gt; &quot;$name $version&quot;,
++ );
++ $mail{Message} .= &quot;login: $login\n&quot;;
++ $mail{Message} .= &quot;password: $password\n&quot;;
++ sendmail(%mail) or warn $Mail::Sendmail::error;
++ }
++}
++
++if ($mode eq 'package') {
++ while (my $line = &lt;&gt;) {
++ chomp $line;
++ my ($name, $summary, $version, $maintainer) = split(/\t/, $line);
++ $bugzilla-&gt;add_package($name, $summary, $version, $maintainer);
++ }
++}
++
++sub usage {
++ print &lt;&lt;EOF;
++$name $version
++
++Usage:
++$name --base &lt;base&gt; --user &lt;user&gt; --pass &lt;pass&gt; --mode &lt;mode&gt; &lt; $file
++
++Options:
++--base &lt;base&gt; bugzilla base name
++--user &lt;user&gt; bugzilla base user
++--pass &lt;pass&gt; bugzilla base password
++--mode &lt;mode&gt; package or packager
++EOF
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/bin/fillbugzilla
+___________________________________________________________________
+<a id="svnexecutable">Added: svn:executable</a>
+ + *
+
+<a id="build_systemmdvyouricoretrunkcgimaintainerscgi">Added: build_system/mdv-youri-core/trunk/cgi/maintainers.cgi</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/cgi/maintainers.cgi (rev 0)
++++ build_system/mdv-youri-core/trunk/cgi/maintainers.cgi 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,65 @@
++#!/usr/bin/perl
++# $Id: maintainers.cgi 1179 2006-08-05 08:30:57Z warly $
++
++=head1 NAME
++
++maintainers.cgi - youri CGI interface to maintainers list
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 DESCRIPTION
++
++This script allows to get package maintainers list through CGI interface.
++
++=head1 SYNOPSIS
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2004-2005, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=head1 AUTHORS
++
++Guillaume Rousse &lt;guillomovitch@zarb.org&gt;,
++
++=cut
++
++use Youri::Bugzilla;
++use CGI;
++use AppConfig qw/:argcount :expand/;
++use strict;
++use warnings;
++
++my $config = AppConfig-&gt;new(
++ {
++ GLOBAL =&gt; {
++ DEFAULT =&gt; undef,
++ EXPAND =&gt; EXPAND_ALL,
++ ARGCOUNT =&gt; ARGCOUNT_ONE,
++ }
++ },
++ host =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++ base =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++ user =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++ pass =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++);
++
++my $home = (getpwnam($ENV{PROJECT}))[7];
++foreach my $file (&quot;/etc/youri/maintainers.conf&quot;, &quot;$home/.youri/maintainers.conf&quot;) {
++ $config-&gt;file($file) if -f $file &amp;&amp; -r $file;
++}
++
++my $bugzilla = Bugzilla-&gt;new(
++ $config-&gt;host(),
++ $config-&gt;base(),
++ $config-&gt;user(),
++ $config-&gt;pass(),
++);
++
++my $cgi = CGI-&gt;new();
++print $cgi-&gt;header(-type=&gt;'text/plain');
++
++$bugzilla-&gt;browse_packages(sub { print &quot;$_[0]\t$_[2]\n&quot;; });
+
+
+Property changes on: build_system/mdv-youri-core/trunk/cgi/maintainers.cgi
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyouricoretrunketcbash_completiondyouri">Added: build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri (rev 0)
++++ build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,141 @@
++# youri tools completion
++# $Id$
++
++_youri-check()
++{
++
++ local cur prev config i mode
++
++ COMPREPLY=()
++ cur=${COMP_WORDS[COMP_CWORD]}
++ prev=${COMP_WORDS[COMP_CWORD-1]}
++
++ case &quot;$prev&quot; in
++ --config)
++ _filedir
++ return 0
++ ;;
++ --skip-plugin)
++ _find_config check.conf
++ if [ -n &quot;$config&quot; ]; then
++ # try to guess mode
++ for (( i=1; i &lt; COMP_CWORD; i++ )); do
++ if [[ &quot;${COMP_WORDS[i]}&quot; != -* ]]; then
++ mode=${COMP_WORDS[i]}
++ break
++ fi
++ done
++
++ if [ -n $mode ]; then
++ COMPREPLY=( $( awk -F= '/^'$mode's/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ fi
++ return 0
++ ;;
++ --skip-media)
++ _find_config check.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^medias/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ return 0
++ ;;
++ esac
++
++ if [[ &quot;$cur&quot; == -* ]]; then
++ COMPREPLY=( $( compgen -W '--config --skip-plugin --skip-media -h \
++ --help -t --test -v --verbose' -- $cur ) )
++ else
++ _count_args
++ case $args in
++ 1)
++ COMPREPLY=( $( compgen -W 'input output' -- $cur ) )
++ ;;
++ esac
++ fi
++
++}
++complete -F _youri-check youri-check
++
++_youri-upload()
++{
++
++ local cur prev config
++
++ COMPREPLY=()
++ cur=${COMP_WORDS[COMP_CWORD]}
++ prev=${COMP_WORDS[COMP_CWORD-1]}
++
++ case &quot;$prev&quot; in
++ --config)
++ _filedir
++ return 0
++ ;;
++ --skip-check)
++ _find_config upload.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^checks/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ return 0
++ ;;
++ --skip-action)
++ _find_config upload.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^actions/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ return 0
++ ;;
++ esac
++
++ if [[ &quot;$cur&quot; == -* ]]; then
++ COMPREPLY=( $( compgen -W '--config --skip-check --skip-action \
++ --define -h --help -t --test -v --verbose' -- $cur ) )
++ else
++ _count_args
++ case $args in
++ 1)
++ _find_config upload.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^targets/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ ;;
++ *)
++ _filedir
++ ;;
++ esac
++ fi
++
++}
++complete -F _youri-upload youri-upload
++
++_find_config()
++{
++ local name i
++
++ name=$1
++
++ for (( i=1; i &lt; COMP_CWORD; i++ )); do
++ if [[ &quot;${COMP_WORDS[i]}&quot; == --config ]]; then
++ config=${COMP_WORDS[i+1]}
++ break
++ fi
++ done
++ if [ -f &quot;$config&quot; ]; then
++ return 0
++ fi
++
++ if [ -f &quot;$HOME/.youri/$name&quot; ]; then
++ config=$HOME/.youri/$name
++ return 0
++ fi
++
++ if [ -f &quot;/etc/youri/$name&quot; ]; then
++ config=/etc/youri/$name
++ return 0
++ fi
++
++}
+
+<a id="build_systemmdvyouricoretrunketccheckconf">Added: build_system/mdv-youri-core/trunk/etc/check.conf</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/etc/check.conf (rev 0)
++++ build_system/mdv-youri-core/trunk/etc/check.conf 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,300 @@
++# youri-check sample configuration file
++# $Id: check.conf 1179 2006-08-05 08:30:57Z warly $
++
++# resolver declaration
++resolver = cgi
++
++# preferences declaration
++preferences = file_pref
++
++# resultset declaration
++resultset = dbi
++
++# input plugins declaration
++inputs = rpmlint \
++ age \
++ updates \
++ build \
++ conflicts \
++ dependencies \
++ missing \
++ orphans
++
++# output plugins declaration
++outputs = file mail
++
++# medias declaration
++medias = main.i586 \
++ main.x86_64 \
++ main.sources \
++ contrib.i586 \
++ contrib.x86_64 \
++ contrib.sources \
++ free \
++ non-free \
++ free.sources \
++ non-free.sources
++
++# helper variables
++mirror = ftp://ftp.free.fr/pub/Distributions_Linux/Mandrakelinux/devel/cooker
++mirror_i586 = $mirror/i586/media
++mirror_x86_64 = $mirror/x86_64/media
++
++# resolver definition
++[cgi]
++class = Youri::Check::Maintainer::Resolver::CGI
++url = http://plf.zarb.org/cgi-bin/maintainers.cgi
++
++# preferences definition
++[file_pref]
++class = Youri::Check::Maintainer::Preferences::File
++
++# resultset definition
++[dbi]
++class = Youri::Check::Resultset::DBI
++driver = mysql
++host = localhost
++base = plf_youri
++user = plf
++pass = s3kr3t
++
++# checks definitions
++[updates]
++class = Youri::Check::Input::Updates
++aliases = &lt;&lt;EOF
++--- #YAML:1.0
++libfame0.8: ~
++EOF
++sources = &lt;&lt;EOF
++--- #YAML:1.0
++debian:
++ class: Youri::Check::Input::Updates::Source::Debian
++ aliases:
++ fuse-emulator: ~
++cpan:
++ class: Youri::Check::Input::Updates::Source::CPAN
++fedora:
++ class: Youri::Check::Input::Updates::Source::Fedora
++gentoo:
++ class: Youri::Check::Input::Updates::Source::Gentoo
++freshmeat:
++ class: Youri::Check::Input::Updates::Source::Freshmeat
++netbsd:
++ class: Youri::Check::Input::Updates::Source::NetBSD
++raa:
++ class: Youri::Check::Input::Updates::Source::RAA
++sourceforge:
++ class: Youri::Check::Input::Updates::Source::Sourceforge
++ aliases:
++ openquicktime: ~
++ klibido: ~
++EOF
++
++[rpmlint]
++class = Youri::Check::Input::Rpmlint
++
++[age]
++class = Youri::Check::Input::Age
++max_age = 12 months
++pattern = %m months
++
++[dependencies]
++class = Youri::Check::Input::Dependencies
++
++[conflicts]
++class = Youri::Check::Input::Conflicts
++
++[build]
++class = Youri::Check::Input::Build
++sources = &lt;&lt;EOF
++--- #YAML:1.0
++stefan:
++ class: Youri::Check::Input::Build::Source::LBD
++ url: http://eijk.homelinux.org/build/
++ medias:
++ - cooker_plf-free
++ - cooker_plf-non-free
++ archs:
++ - i586
++EOF
++
++[missing]
++class = Youri::Check::Input::Missing
++
++[orphans]
++class = Youri::Check::Input::Orphans
++
++# reports definitions
++[file]
++class = Youri::Check::Output::File
++to = ${HOME}/www/qa
++global = 1
++individual = 1
++formats = &lt;&lt;EOF
++--- #YAML:1.0
++html:
++ class: Youri::Check::Output::File::Format::HTML
++text:
++ class: Youri::Check::Output::File::Format::Text
++rss:
++ class: Youri::Check::Output::File::Format::RSS
++EOF
++
++[mail]
++class = Youri::Check::Output::Mail
++mta = /usr/sbin/sendmail
++to = plf-admin@zarb.org
++from = plf@zarb.org
++reply_to = plf-admin@zarb.org
++formats = &lt;&lt;EOF
++--- #YAML:1.0
++text:
++ class: Youri::Check::Output::Mail::Format::Text
++EOF
++
++# media definitions
++[main.i586]
++class = Youri::Media::URPM
++name = main
++type = binary
++path = $mirror_i586/main
++hdlist = $mirror_i586/media_info/hdlist_main.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[main.x86_64]
++class = Youri::Media::URPM
++name = main
++type = binary
++path = $mirror_x86_64/main
++hdlist = $mirror_x86_64/media_info/hdlist_main.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[main.sources]
++class = Youri::Media::URPM
++name = main
++type = source
++path = $mirror_i586/main
++hdlist = $mirror_i586/media_info/hdlist_main.src.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[contrib.i586]
++class = Youri::Media::URPM
++name = contrib
++type = binary
++path = $mirror_i586/contrib
++hdlist = $mirror_i586/media_info/hdlist_contrib.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[contrib.x86_64]
++class = Youri::Media::URPM
++name = contrib
++type = binary
++path = $mirror_x86_64/contrib
++hdlist = $mirror_x86_64/media_info/hdlist_contrib.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[contrib.sources]
++class = Youri::Media::URPM
++name = contrib
++type = source
++path = $mirror_i586/contrib
++hdlist = $mirror_i586/media_info/hdlist_contrib.src.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[free]
++class = Youri::Media::URPM
++name = free
++type = binary
++path = ${HOME}/ftp/mandrake/free/cooker/i586
++hdlist = ${HOME}/ftp/mandrake/free/cooker/i586/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- main.x86_64
++- contrib.i586
++- contrib.x86_64
++- free
++EOF
++allow_srcs = &lt;&lt;EOF
++--- #YAML:1.0
++- free.sources
++- main.sources
++- contrib.sources
++EOF
++skip_archs = &lt;&lt;EOF
++--- #YAML:1.0
++- ppc
++EOF
++
++[free.sources]
++class = Youri::Media::URPM
++name = free
++type = source
++path = ${HOME}/ftp/mandrake/free/src
++hdlist = ${HOME}/ftp/mandrake/free/src/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- contrib.i586
++- free
++EOF
++
++[non-free]
++class = Youri::Media::URPM
++name = non-free
++type = binary
++path = ${HOME}/ftp/mandrake/non-free/cooker/i586
++hdlist = ${HOME}/ftp/mandrake/non-free/cooker/i586/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-non-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- main.x86_64
++- contrib.i586
++- contrib.x86_64
++- free
++- non-free
++EOF
++allow_srcs = &lt;&lt;EOF
++--- #YAML:1.0
++- non-free.sources
++EOF
++skip_archs = &lt;&lt;EOF
++--- #YAML:1.0
++- ppc
++EOF
++
++[non-free.sources]
++class = Youri::Media::URPM
++name = non-free
++type = source
++path = ${HOME}/ftp/mandrake/non-free/src
++hdlist = ${HOME}/ftp/mandrake/non-free/src/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-non-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- contrib.i586
++- free
++- non-free
++EOF
+
+<a id="build_systemmdvyouricoretrunketcuploadconf">Added: build_system/mdv-youri-core/trunk/etc/upload.conf</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/etc/upload.conf (rev 0)
++++ build_system/mdv-youri-core/trunk/etc/upload.conf 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,139 @@
++# youri-upload sample configuration file
++# $Id: upload.conf 1179 2006-08-05 08:30:57Z warly $
++
++# repository declaration
++repository = plf
++
++# targets declaration
++targets = cooker 2006.0
++
++# repository definition
++[plf]
++class = Youri::Repository::PLF
++install_root = ${HOME}/ftp/mandriva
++version_root = ${HOME}/cvs
++archive_root = ${HOME}/backup/mandriva
++noarch = i586
++
++# targets definition
++[cooker]
++checks = &lt;&lt;EOF
++--- #YAML:1.0
++- tag
++- recency
++- history
++EOF
++actions = &lt;&lt;EOF
++--- #YAML:1.0
++- sign
++- install
++- link
++- archive
++- clean
++- bugzilla
++- cvs
++- mail
++- rss
++EOF
++
++[2006.0]
++checks = &lt;&lt;EOF
++--- #YAML:1.0
++- type
++- tag
++- recency
++- history
++- precedence
++EOF
++actions = &lt;&lt;EOF
++--- #YAML:1.0
++- sign
++- install
++- link
++- archive
++- clean
++EOF
++
++# checks definition
++[tag]
++class = Youri::Upload::Check::Tag
++tags = &lt;&lt;EOF
++--- #YAML:1.0
++release: 'plf$'
++packager: '&lt;\w+@zarb\.org&gt;$'
++distribution: '^Mandriva Linux$'
++vendor: '^Penguin Liberation Front$'
++EOF
++
++[recency]
++class = Youri::Upload::Check::Recency
++
++[history]
++class = Youri::Upload::Check::History
++
++[precedence]
++class = Youri::Upload::Check::Precedence
++target = cooker
++
++[type]
++class = Youri::Upload::Check::Type
++type = binary
++
++# actions definitions
++[sign]
++class = Youri::Upload::Action::Sign
++name = plf@zarb.org
++path = ${HOME}/.gnupg
++passphrase = s3kr3t
++
++[install]
++class = Youri::Upload::Action::Install
++
++[link]
++class = Youri::Upload::Action::Link
++
++[archive]
++class = Youri::Upload::Action::Archive
++
++[clean]
++class = Youri::Upload::Action::Clean
++
++[mail]
++class = Youri::Upload::Action::Mail
++mta = /usr/sbin/sendmail
++to = plf-announce@zarb.org
++reply_to = plf-discuss@zarb.org
++from = plf@zarb.org
++prefix = RPM
++cc = &lt;&lt;EOF
++--- #YAML:1.0
++hot-base: david@dindinx.org bellamy@neverland.net
++dcgui: mathen@ketelhot.de
++dclib: mathen@ketelhot.de
++Video-DVDRip: dvdrip-users@exit1.org
++hackVideo-DVDRip: dvdrip-users@exit1.org
++goosnes: tak@bard.sytes.net
++avidemux: fixounet@free.fr
++vobcopy: robos@muon.de
++drip: drip-devel@lists.sourceforge.net
++libdscaler: vektor@dumbterm.net
++xawdecode: pingus77@ifrance.com
++EOF
++
++[rss]
++class = Youri::Upload::Action::RSS
++file = ${HOME}/www/changelog.rss
++title = PLF packages updates
++link = http://plf.zarb.org/
++description = ChangeLog for PLF packages
++
++[cvs]
++class = Youri::Upload::Action::CVS
++
++[bugzilla]
++class = Youri::Upload::Action::Bugzilla
++host = localhost
++base = plf_bugs
++user = plf
++pass = s3kr3t
++contact = plf@zarb.org
+
+<a id="build_systemmdvyouricoretrunklibYouriBugzillapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,482 @@
++# $Id: Bugzilla.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Bugzilla;
++
++=head1 NAME
++
++Youri::Bugzilla - Youri Bugzilla interface
++
++=head1 SYNOPSIS
++
++ use Youri::Bugzilla;
++
++ my $bugzilla = Youri::Bugzilla-&gt;new($host, $base, $user, $pass);
++
++ print $bugzilla-&gt;get_maintainer('foobar');
++
++=head1 DESCRIPTION
++
++This module implement a database-level Bugzilla interface for managing packages.
++
++The legacy Bugzilla database model is mapped this way:
++
++=over
++
++=item *
++
++a maintainer is a user
++
++=item *
++
++a package is a product
++
++=item *
++
++each package has two pseudo components &quot;program&quot; and &quot;package&quot;, owned by the package maintainer
++
++=back
++
++=cut
++
++use DBI;
++use Carp;
++use strict;
++use warnings;
++
++my %queries = (
++ get_package_id =&gt; 'SELECT id FROM products WHERE name = ?',
++ get_maintainer_id =&gt; 'SELECT userid FROM profiles WHERE login_name = ?',
++ get_versions =&gt; 'SELECT value FROM versions WHERE product_id = ?',
++ get_components =&gt; 'SELECT name FROM components WHERE product_id = ?',
++ add_package =&gt; 'INSERT INTO products (name, description) VALUES (?, ?)',
++ add_maintainer =&gt; 'INSERT INTO profiles (login_name, cryptpassword, realname, emailflags, refreshed_when) VALUES (?, ENCRYPT(?), ?, ?, SYSDATE())',
++ add_component =&gt; 'INSERT INTO components (product_id, name, description,initialowner, initialqacontact) VALUES (?, ?, ?, ?, ?)',
++ add_version =&gt; 'INSERT INTO versions (product_id, value) VALUES (?, ?)',
++ del_package =&gt; 'DELETE FROM products WHERE product = ?',
++ del_maintainer =&gt; 'DELETE FROM profiles WHERE login_name = ?',
++ del_components =&gt; 'DELETE FROM components WHERE program = ?',
++ del_versions =&gt; 'DELETE FROM versions WHERE program = ?',
++ reset_password =&gt; 'UPDATE profiles SET cryptpassword = ENCRYPT(?) WHERE login_name = ?',
++ browse_packages =&gt; &lt;&lt;EOF,
++SELECT products.name, max(versions.value), login_name
++FROM products, versions, profiles, components
++WHERE versions.product_id = products.id
++ AND components.product_id = products.id
++ AND profiles.userid = components.initialowner
++ AND components.name = 'package'
++GROUP BY name
++EOF
++ get_maintainer =&gt; &lt;&lt;EOF
++SELECT login_name
++FROM profiles, components, products
++WHERE profiles.userid = components.initialowner
++ AND components.name = 'package'
++ AND components.product_id = products.id
++ AND products.name = ?
++EOF
++);
++
++my @default_flags = qw/
++ ExcludeSelf
++ FlagRequestee
++ FlagRequester
++ emailOwnerRemoveme
++ emailOwnerComments
++ emailOwnerAttachments
++ emailOwnerStatus
++ emailOwnerResolved
++ emailOwnerKeywords
++ emailOwnerCC
++ emailOwnerOther
++ emailOwnerUnconfirmed
++ emailReporterRemoveme
++ emailReporterComments
++ emailReporterAttachments
++ emailReporterStatus
++ emailReporterResolved
++ emailReporterKeywords
++ emailReporterCC
++ emailReporterOther
++ emailReporterUnconfirmed
++ emailQAcontactRemoveme
++ emailQAcontactComments
++ emailQAcontactAttachments
++ emailQAcontactStatus
++ emailQAcontactResolved
++ emailQAcontactKeywords
++ emailQAcontactCC
++ emailQAcontactOther
++ emailQAcontactUnconfirmed
++ emailCClistRemoveme
++ emailCClistComments
++ emailCClistAttachments
++ emailCClistStatus
++ emailCClistResolved
++ emailCClistKeywords
++ emailCClistCC
++ emailCClistOther
++ emailCClistUnconfirmed
++ emailVoterRemoveme
++ emailVoterComments
++ emailVoterAttachments
++ emailVoterStatus
++ emailVoterResolved
++ emailVoterKeywords
++ emailVoterCC
++ emailVoterOther
++ emailVoterUnconfirmed
++/;
++
++my $default_flags = join('~', map { &quot;$_~on&quot; } @default_flags);
++
++=head1 CLASS METHODS
++
++Except stated otherwise, maintainers are specified by their login, and packages
++are specified by their name.
++
++=head2 new($host, $base, $user, $password)
++
++Creates a new L&lt;Youri::Bugzilla&gt; object, wrapping bugzilla database I&lt;$base&gt;
++hosted on I&lt;$host&gt;, and accessed by user I&lt;$user&gt; with password I&lt;$password&gt;.
++
++=cut
++
++sub new {
++ my ($class, $host, $base, $user, $pass) = @_;
++
++ my $dbh = DBI-&gt;connect(&quot;DBI:mysql:database=$base;host=$host&quot;, $user, $pass) or croak &quot;Unable to connect: $DBI::errstr&quot;;
++
++ my $self = bless {
++ _dbh =&gt; $dbh
++ }, $class;
++
++ return $self;
++}
++
++=head1 INSTANCE METHODS
++
++=head2 has_package($package)
++
++Return true if bugzilla contains given package.
++
++=cut
++
++sub has_package {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_package_id($package);
++}
++
++=head2 has_maintainer($maintainer)
++
++Return true if bugzilla contains given maintainer.
++
++=cut
++
++sub has_maintainer {
++ my ($self, $maintainer) = @_;
++ return $self-&gt;_get_maintainer_id($maintainer);
++}
++
++=head2 get_maintainer($package)
++
++Return maintainer of given package.
++
++=cut
++
++sub get_maintainer {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_single('get_maintainer', $package);
++}
++
++=head2 get_versions($package)
++
++Return versions from given package.
++
++=cut
++
++sub get_versions {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_multiple(
++ 'get_versions',
++ $self-&gt;_get_package_id($package)
++ );
++}
++
++=head2 get_components($package)
++
++Return components from given package.
++
++=cut
++
++sub get_components {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_multiple(
++ 'get_components',
++ $self-&gt;_get_package_id($package)
++ );
++}
++
++=head2 get_packages()
++
++Return all packages from the database.
++
++=cut
++
++sub get_packages {
++ my ($self) = @_;
++ return $self-&gt;_get_multiple('get_packages');
++}
++
++sub _get_package_id {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_single('get_package_id', $package);
++}
++
++sub _get_maintainer_id {
++ my ($self, $maintainer) = @_;
++ return $self-&gt;_get_single('get_maintainer_id', $maintainer);
++}
++
++sub _get_single {
++ my ($self, $type, $value) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{$type};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{$type});
++ $self-&gt;{_queries}-&gt;{$type} = $query;
++ }
++
++ $query-&gt;execute($value);
++
++ my @row = $query-&gt;fetchrow_array();
++ return @row ? $row[0]: undef;
++}
++
++sub _get_multiple {
++ my ($self, $type, $value) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{$type};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{$type});
++ $self-&gt;{_queries}-&gt;{$type} = $query;
++ }
++
++ $query-&gt;execute($value);
++
++ my @results;
++ while (my @row = $query-&gt;fetchrow_array()) {
++ push @results, $row[0];
++ }
++ return @results;
++}
++
++=head2 add_package($name, $summary, $version, $maintainer, $contact)
++
++Adds a new package in the database, with given name, summary, version,
++maintainer and initial QA contact.
++
++=cut
++
++sub add_package {
++ my ($self, $name, $summary, $version, $maintainer, $contact) = @_;
++ return unless ref $self;
++
++ my $maintainer_id = $self-&gt;_get_maintainer_id($maintainer);
++ unless ($maintainer_id) {
++ carp &quot;Unknown maintainer $maintainer, aborting&quot;;
++ return;
++ }
++
++ my $contact_id = $self-&gt;_get_maintainer_id($contact);
++ unless ($contact_id) {
++ carp &quot;Unknown QA contact $contact, aborting&quot;;
++ return;
++ }
++
++ my $query = $self-&gt;{_queries}-&gt;{add_package};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_package});
++ $self-&gt;{_queries}-&gt;{add_package} = $query;
++ }
++
++ $query-&gt;execute($name, $summary);
++
++ my $package_id = $self-&gt;_get_package_id($name);
++
++ $self-&gt;_add_version($package_id, $version);
++ $self-&gt;_add_component(
++ $package_id,
++ 'package',
++ 'problem related to the package',
++ $maintainer_id,
++ $contact_id
++ );
++ $self-&gt;_add_component(
++ $package_id,
++ 'program',
++ 'problem related to the program',
++ $maintainer_id,
++ $contact_id
++ );
++}
++
++=head2 add_version($package, $version)
++
++Adds a new version to given package.
++
++=cut
++
++sub add_version {
++ my ($self, $package, $version) = @_;
++ return unless ref $self;
++
++ my $package_id = $self-&gt;_get_package_id($package);
++ $self-&gt;_add_version($package_id, $version);
++}
++
++sub _add_version {
++ my ($self, $package_id, $version) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{add_version};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_version});
++ $self-&gt;{_queries}-&gt;{add_version} = $query;
++ }
++
++ $query-&gt;execute($package_id, $version);
++}
++
++
++=head2 add_maintainer($name, $login, $password)
++
++Adds a new maintainer in the database, with given name, login and password.
++
++=cut
++
++sub add_maintainer {
++ my ($self, $name, $login, $pass) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{add_maintainer};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_maintainer});
++ $self-&gt;{_queries}-&gt;{add_maintainer} = $query;
++ }
++
++ $query-&gt;execute($login, $pass, $name, $default_flags);
++}
++
++sub _add_component {
++ my ($self, $package_id, $name, $description, $maintainer_id, $contact_id) = @_;
++
++ my $query = $self-&gt;{_queries}-&gt;{add_component};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_component});
++ $self-&gt;{_queries}-&gt;{add_component} = $query;
++ }
++
++ $query-&gt;execute($package_id, $name, $description, $maintainer_id, $contact_id);
++}
++
++=head2 del_package($package)
++
++Delete given package from database.
++
++=cut
++
++sub del_package {
++ my ($self, $package) = @_;
++ $self-&gt;_delete('del_package', $package);
++ $self-&gt;_delete('del_versions', $package);
++ $self-&gt;_delete('del_components', $package);
++}
++
++=head2 del_maintainer($maintainer)
++
++Delete given maintainer from database.
++
++=cut
++
++sub del_maintainer {
++ my ($self, $maintainer) = @_;
++ $self-&gt;_delete('del_maintainer', $maintainer);
++}
++
++sub _delete {
++ my ($self, $type, $value) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{$type};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{$type});
++ $self-&gt;{_queries}-&gt;{$type} = $query;
++ }
++
++ $query-&gt;execute($value);
++}
++
++=head2 reset_password(I&lt;$maintainer&gt;, I&lt;$password&gt;)
++
++Reset password of a maintainer to given password.
++
++=cut
++
++sub reset_password {
++ my ($self, $login, $pass) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{reset_password};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{reset_password});
++ $self-&gt;{_queries}-&gt;{reset_password} = $query;
++ }
++
++ $query-&gt;execute($pass, $login);
++}
++
++=head2 browse_packages($callback)
++
++Browse all packages from bugzilla, and execute given callback with name and
++maintainer as argument for each of them.
++
++=cut
++
++sub browse_packages {
++ my ($self, $callback) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{browse_packages};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{browse_packages});
++ $self-&gt;{_queries}-&gt;{browse_packages} = $query;
++ }
++
++ $query-&gt;execute();
++
++ while (my @row = $query-&gt;fetchrow_array()) {
++ $callback-&gt;(@row);
++ }
++}
++
++# close database connection
++sub DESTROY {
++ my ($self) = @_;
++
++ foreach my $query (values %{$self-&gt;{_queries}}) {
++ $query-&gt;finish();
++ }
++
++ $self-&gt;{_dbh}-&gt;disconnect();
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputAgepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,110 @@
++# $Id: Age.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Age;
++
++=head1 NAME
++
++Youri::Check::Input::Age - Check maximum age
++
++=head1 DESCRIPTION
++
++This plugin checks packages age, and report the ones exceeding maximum limit.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use DateTime;
++use DateTime::Format::Duration;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ buildtime
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Age object.
++
++Specific parameters:
++
++=over
++
++=item max_age $age
++
++Maximum age allowed (default: 1 year)
++
++=item pattern $pattern
++
++Pattern used to describe age (default: %Y year)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ max_age =&gt; '1 year',
++ pattern =&gt; '%Y year',
++ @_
++ );
++
++ $self-&gt;{_format} = DateTime::Format::Duration-&gt;new(
++ pattern =&gt; $options{pattern}
++ );
++
++ $self-&gt;{_now} = DateTime-&gt;from_epoch(
++ epoch =&gt; time()
++ );
++
++ $self-&gt;{_max_age} = $options{max_age};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $max_age_string = $media-&gt;max_age() ?
++ $media-&gt;max_age() :
++ $self-&gt;{_max_age};
++
++ my $max_age = $self-&gt;{_format}-&gt;parse_duration($max_age_string);
++
++ my $check = sub {
++ my ($package) = @_;
++
++ my $buildtime = DateTime-&gt;from_epoch(
++ epoch =&gt; $package-&gt;get_age()
++ );
++
++ my $age = $self-&gt;{_now}-&gt;subtract_datetime($buildtime);
++
++ if (DateTime::Duration-&gt;compare($age, $max_age) &gt; 0) {
++ my $date = $buildtime-&gt;strftime(&quot;%a %d %b %G&quot;);
++
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $package-&gt;get_arch(),
++ buildtime =&gt; $date
++ });
++ }
++ };
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceIurtpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,117 @@
++# $Id: LBD.pm 574 2005-12-27 14:31:16Z guillomovitch $
++package Youri::Check::Input::Build::Source::Iurt;
++
++=head1 NAME
++
++Youri::Check::Input::Build::Source::Iurt - Iurt build log source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Build&gt; collects build logs
++available from a iurt build bot.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use base 'Youri::Check::Input::Build::Source';
++
++my %status = (
++ install_deps =&gt; 0,
++ build =&gt; 1,
++ binary_test =&gt; 2
++);
++
++my $pattern = '^('
++ . join('|', keys %status)
++ . ')_\S+-[^-]+-[^-]+\.src\.rpm\.\d+\.log$';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build::LBD object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL of logs for this iurt instance (default:
++http://qa.mandriva.com/build/iurt/cooker)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://qa.mandriva.com/build/iurt/cooker',
++ @_
++ );
++
++ $self-&gt;{_agent} = LWP::UserAgent-&gt;new();
++
++ # try to connect to base URL directly, and abort if not available
++ my $response = $self-&gt;{_agent}-&gt;head($options{url});
++ die &quot;Unavailable URL $options{url}: &quot; . $response-&gt;status_line()
++ unless $response-&gt;is_success();
++
++ $self-&gt;{_url} = $options{url};
++}
++
++sub fails {
++ my ($self, $name, $version, $release, $arch) = @_;
++
++ my $result;
++ my $url = &quot;$self-&gt;{_url}/$arch/log/$name-$version-$release.src.rpm&quot;;
++ print &quot;Fetching URL $url: &quot; if $self-&gt;{_verbose} &gt; 1;
++ my $response = $self-&gt;{_agent}-&gt;get($url);
++ print $response-&gt;status_line() . &quot;\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ if ($response-&gt;is_success()) {
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /$pattern/o;
++ my $status = $1;
++ if (
++ !$result-&gt;{status} ||
++ $status{$result-&gt;{status}} &lt; $status{$status}
++ ) {
++ $result-&gt;{status} = $status;
++ $result-&gt;{url} = $url . '/' . $href;
++ }
++ }
++ }
++
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch} = $result;
++
++ return $result-&gt;{status} &amp;&amp; $result-&gt;{status} ne 'binary_test';
++}
++
++sub status {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{status};
++}
++
++sub url {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{url};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceLBDpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,135 @@
++# $Id: LBD.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Build::Source::LBD;
++
++=head1 NAME
++
++Youri::Check::Input::Build::Source::LBD - LBD build log source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Build&gt; collects build logs
++available from a LBD build bot.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use base 'Youri::Check::Input::Build::Source';
++
++my @status = qw/
++ OK
++ arch_excl
++ broken
++ cannot_be_installed
++ debug
++ dependency
++ file_not_found
++ multiarch
++ problem
++ unpackaged_files
++/;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build::LBD object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL of logs for this LBD instance (default: http://eijk.homelinux.org/build)
++
++=item medias $medias
++
++List of medias monitored by this LBD instance
++
++=item archs $archs
++
++List of architectures monitored by this LBD instance
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://eijk.homelinux.org/build',
++ medias =&gt; undef,
++ archs =&gt; undef,
++ @_
++ );
++
++ my $agent = LWP::UserAgent-&gt;new();
++
++ # try to connect to base URL directly, and abort if not available
++ my $response = $agent-&gt;head($options{url});
++ die &quot;Unavailable URL $options{url}: &quot; . $response-&gt;status_line()
++ unless $response-&gt;is_success();
++
++ my $pattern = '^(\S+)-([^-]+)-([^-]+)(?:\.gz)?$';
++
++ foreach my $arch (@{$options{archs}}) {
++ foreach my $media (@{$options{medias}}) {
++ my $url_base = &quot;$options{url}/$arch/$media/BO&quot;;
++ foreach my $status (@status) {
++ my $url = &quot;$url_base/$status/&quot;;
++ print &quot;Fetching URL $url: &quot; if $self-&gt;{_verbose} &gt; 1;
++ my $response = $agent-&gt;get($url);
++ print $response-&gt;status_line() . &quot;\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ if ($response-&gt;is_success()) {
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /$pattern/o;
++ my $name = $1;
++ my $version = $2;
++ my $release = $3;
++ my $result;
++ $result-&gt;{status} = $status;
++ $result-&gt;{url} = $url . '/' . $href;
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch} = $result;
++ }
++ }
++ }
++ }
++ }
++}
++
++sub fails {
++ my ($self, $name, $version, $release, $arch) = @_;
++
++ my $status =
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{status};
++
++ return $status &amp;&amp; $status ne 'OK' &amp;&amp; $status ne 'arch_excl';
++}
++
++sub status {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{status};
++}
++
++sub url {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{url};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildSourcepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,109 @@
++# $Id: Source.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Build::Source;
++
++=head1 NAME
++
++Youri::Check::Input::Build::Source - Abstract build log source
++
++=head1 DESCRIPTION
++
++This abstract class defines the updates source interface for
++L&lt;Youri::Check::Input::Build&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns source identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 fails($name, $version, $release, $arch)
++
++Returns true if build fails for package with given name, version and release on
++given architecture.
++
++=head2 status($name, $version, $release, $arch)
++
++Returns exact build status for package with given name, version and release on
++given architecture. It has to be called after fails().
++
++=head2 url($name, $version, $release, $arch)
++
++Returns URL of information source for package with given name, version and
++release on given architecture. It has to be called after fails().
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item fails
++
++=item status
++
++=item url
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,128 @@
++# $Id: Build.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Build;
++
++=head1 NAME
++
++Youri::Check::Input::Build - Check build outputs
++
++=head1 DESCRIPTION
++
++This plugin checks build outputs of packages, and report failures. Additional
++source plugins handle specific sources.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ bot
++ status
++ /;
++}
++
++sub links {
++ return qw/
++ status url
++ /;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build object.
++
++Specific parameters:
++
++=over
++
++=item sources $sources
++
++Hash of source plugins definitions
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ sources =&gt; undef,
++ @_
++ );
++
++ croak &quot;No source defined&quot; unless $options{sources};
++ croak &quot;sources should be an hashref&quot; unless ref $options{sources} eq 'HASH';
++
++ foreach my $id (keys %{$options{sources}}) {
++ print &quot;Creating source $id\n&quot; if $options{verbose};
++ eval {
++ push(
++ @{$self-&gt;{_sources}},
++ create_instance(
++ 'Youri::Check::Input::Build::Source',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ %{$options{sources}-&gt;{$id}}
++ )
++ );
++ # register monitored archs
++ $self-&gt;{_archs}-&gt;{$_}-&gt;{$id} = 1
++ foreach @{$options{sources}-&gt;{$id}-&gt;{archs}};
++ };
++ print STDERR &quot;Failed to create source $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no sources created&quot; unless @{$self-&gt;{_sources}};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a source media check only
++ return unless $media-&gt;get_type() eq 'source';
++
++ my $callback = sub {
++ my ($package) = @_;
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++
++ foreach my $source (@{$self-&gt;{_sources}}) {
++ my $id = $source-&gt;get_id();
++ foreach my $arch (keys %{$self-&gt;{_archs}}) {
++ next unless $self-&gt;{_archs}-&gt;{$arch}-&gt;{$id};
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ bot =&gt; $id,
++ status =&gt; $source-&gt;status($name, $version, $release, $arch),
++ url =&gt; $source-&gt;url($name, $version, $release, $arch),
++ }) if $source-&gt;fails(
++ $name,
++ $version,
++ $release,
++ $arch,
++ );
++ }
++ }
++ };
++
++ $media-&gt;traverse_headers($callback);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputConflictspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,231 @@
++# $Id: Conflicts.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Conflicts;
++
++=head1 NAME
++
++Youri::Check::Input::Conflicts - Check file conflicts
++
++=head1 DESCRIPTION
++
++This plugin checks packages files, and report conflict and duplications.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use constant;
++use Youri::Package;
++use base 'Youri::Check::Input';
++
++use constant TYPE_MASK =&gt; 0170000;
++use constant TYPE_DIR =&gt; 0040000;
++
++use constant PACKAGE =&gt; 0;
++use constant MODE =&gt; 1;
++use constant MD5SUM =&gt; 2;
++
++my $compatibility = {
++ x86_64 =&gt; 'i586',
++ i586 =&gt; 'x86_64',
++ sparc64 =&gt; 'sparc',
++ sparc =&gt; 'sparc64',
++ ppc64 =&gt; 'ppc',
++ ppc =&gt; 'ppc64'
++};
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ level
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Conflicts object.
++
++No specific parameters.
++
++=cut
++
++sub prepare {
++ my ($self, @medias) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $index = sub {
++ my ($package) = @_;
++
++ # index files
++ foreach my $file ($package-&gt;get_files()) {
++ push(
++ @{$self-&gt;{_files}-&gt;{$file-&gt;[Youri::Package::FILE_NAME]}},
++ [ $package, $file-&gt;[Youri::Package::FILE_MODE], $file-&gt;[Youri::Package::FILE_MD5SUM] ]
++ );
++ }
++ };
++
++ foreach my $media (@medias) {
++ # don't index source media files
++ next unless $media-&gt;get_type() eq 'binary';
++
++ my $media_id = $media-&gt;get_id();
++ $self-&gt;{_medias}-&gt;{$media_id} = 1;
++ print STDERR &quot;Indexing media $media_id files\n&quot;
++ if $self-&gt;{_verbose};
++
++ $media-&gt;traverse_headers($index);
++ }
++}
++
++sub run {
++ my ($self, $media, $result) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a binary media check only
++ return unless $media-&gt;get_type() eq 'binary';
++
++ my $check = sub {
++ my ($package) = @_;
++
++ return if $package-&gt;get_arch() eq 'src';
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ foreach my $file ($package-&gt;get_files()) {
++
++ my $found =
++ $self-&gt;{_files}-&gt;{$file-&gt;[Youri::Package::FILE_NAME]};
++
++ my @found = $found ? @$found : ();
++
++ foreach my $found (@found) {
++ next if $found-&gt;[PACKAGE] == $package;
++ next unless compatible($found-&gt;[PACKAGE], $package);
++ next if conflict($found-&gt;[PACKAGE], $package);
++ next if replace($found-&gt;[PACKAGE], $package);
++ if (
++ ($file-&gt;[Youri::Package::FILE_MODE] &amp; TYPE_MASK) == TYPE_DIR &amp;&amp;
++ ($found-&gt;[MODE] &amp; TYPE_MASK) == TYPE_DIR
++ ) {
++ $result-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;directory $file-&gt;[Youri::Package::FILE_NAME] duplicated with package &quot; . $found-&gt;[PACKAGE]-&gt;get_name(),
++ level =&gt; Youri::Check::Input::WARNING
++ }) unless $self-&gt;_directory_duplicate_exception(
++ $package,
++ $found-&gt;[PACKAGE],
++ $file
++ );
++ } else {
++ if ($found-&gt;[MD5SUM] eq $file-&gt;[Youri::Package::FILE_MD5SUM]) {
++ $result-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;file $file-&gt;[Youri::Package::FILE_NAME] duplicated with package &quot; . $found-&gt;[PACKAGE]-&gt;get_name(),
++ level =&gt; Youri::Check::Input::WARNING
++ }) unless $self-&gt;_file_duplicate_exception(
++ $package,
++ $found-&gt;[PACKAGE],
++ $file
++ );
++ } else {
++ $result-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;non-explicit conflict on file $file-&gt;[Youri::Package::FILE_NAME] with package &quot; . $found-&gt;[PACKAGE]-&gt;get_name(),
++ level =&gt; Youri::Check::Input::ERROR
++ }) unless $self-&gt;_file_conflict_exception(
++ $package,
++ $found-&gt;[PACKAGE],
++ $file
++ );
++ }
++ }
++ }
++ }
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++# return true if $package1 is arch-compatible with $package2
++sub compatible {
++ my ($package1, $package2) = @_;
++
++ my $arch1 = $package1-&gt;get_arch();
++ my $arch2 = $package2-&gt;get_arch();
++
++ return 1 if $arch1 eq $arch2;
++
++ return 1 if $compatibility-&gt;{$arch1} &amp;&amp; $compatibility-&gt;{$arch1} eq $arch2;
++
++ return 0;
++}
++
++# return true if $package1 conflict with $package2
++# or the other way around
++sub conflict {
++ my ($package1, $package2) = @_;
++
++ my $name2 = $package2-&gt;get_name();
++
++ foreach my $conflict ($package1-&gt;get_conflicts()) {
++ return 1 if $conflict eq $name2;
++ }
++
++ my $name1 = $package1-&gt;get_name();
++
++ foreach my $conflict ($package2-&gt;get_conflicts()) {
++ return 1 if $conflict eq $name1;
++ }
++
++ return 0;
++}
++
++# return true if $package1 replace $package2
++sub replace {
++ my ($package1, $package2) = @_;
++
++
++ my $name1 = $package1-&gt;get_name();
++ my $name2 = $package2-&gt;get_name();
++
++ return 1 if $name1 eq $name2;
++
++ foreach my $obsolete ($package1-&gt;get_obsoletes()) {
++ return 1 if $obsolete-&gt;[Youri::Package::DEPENDENCY_NAME] eq $name2;
++ }
++
++ return 0;
++}
++
++sub _directory_duplicate_exception {
++ return 0;
++}
++
++sub _file_duplicate_exception {
++ return 0;
++}
++
++sub _file_conflict_exception {
++ return 0;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputDependenciespm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,162 @@
++# $Id: Dependencies.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Dependencies;
++
++=head1 NAME
++
++Youri::Check::Input::Dependencies - Check dependencies consistency
++
++=head1 DESCRIPTION
++
++This class checks dependencies consistency.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Package;
++use base 'Youri::Check::Input';
++
++use constant MEDIA =&gt; 0;
++use constant RANGE =&gt; 1;
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ level
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++sub prepare {
++ my ($self, @medias) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ foreach my $media (@medias) {
++ my $media_id = $media-&gt;get_id();
++ $self-&gt;{_medias}-&gt;{$media_id} = 1;
++ print STDERR &quot;Indexing media $media_id dependencies\n&quot;
++ if $self-&gt;{_verbose};
++
++ my $index = sub {
++ my ($package) = @_;
++
++ # index provides
++ foreach my $provide ($package-&gt;get_provides()) {
++ push(
++ @{$self-&gt;{_provides}-&gt;{$provide-&gt;[Youri::Package::DEPENDENCY_NAME]}},
++ [ $media_id, $provide-&gt;[Youri::Package::DEPENDENCY_RANGE] ]
++ );
++ }
++
++ # index files
++ foreach my $file ($package-&gt;get_files()) {
++ push(
++ @{$self-&gt;{_files}-&gt;{$file-&gt;[Youri::Package::FILE_NAME]}},
++ [ $media_id, undef ]
++ );
++ }
++ };
++ $media-&gt;traverse_headers($index);
++ }
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @allowed_ids = $media-&gt;allow_deps();
++
++ # abort unless all allowed medias are present
++ foreach my $id (@allowed_ids) {
++ unless ($self-&gt;{_medias}-&gt;{$id}) {
++ carp &quot;Missing media $id, aborting&quot;;
++ return;
++ }
++ }
++
++ # index allowed medias
++ my %allowed_ids = map { $_ =&gt; 1 } @allowed_ids;
++ my $allowed_ids = join(&quot;,&quot;, @allowed_ids);
++
++ my $class = $media-&gt;get_package_class();
++
++ my $check = sub {
++ my ($package) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ foreach my $require ($package-&gt;get_requires()) {
++
++ my $found =
++ substr($require-&gt;[Youri::Package::DEPENDENCY_NAME], 0, 1) eq '/' ?
++ $self-&gt;{_files}-&gt;{$require-&gt;[Youri::Package::DEPENDENCY_NAME]} :
++ $self-&gt;{_provides}-&gt;{$require-&gt;[Youri::Package::DEPENDENCY_NAME]};
++
++ my @found = $found ? @$found : ();
++
++ if (!@found) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;$require-&gt;[Youri::Package::DEPENDENCY_NAME] not found&quot;,
++ level =&gt; Youri::Check::Input::ERROR
++ });
++ next;
++ }
++
++ my @found_in_media =
++ grep { $allowed_ids{$_-&gt;[MEDIA]} }
++ @found;
++
++ if (!@found_in_media) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;$require-&gt;[Youri::Package::DEPENDENCY_NAME] found in incorrect media $_-&gt;[MEDIA] (allowed $allowed_ids)&quot;,
++ level =&gt; Youri::Check::Input::ERROR
++ }) foreach @found;
++ next;
++ }
++
++ next unless $require-&gt;[Youri::Package::DEPENDENCY_RANGE];
++
++ my @found_in_range =
++ grep {
++ !$_-&gt;[RANGE] ||
++ $class-&gt;compare_ranges(
++ $require-&gt;[Youri::Package::DEPENDENCY_RANGE],
++ $_-&gt;[RANGE]
++ )
++ } @found_in_media;
++
++ if (!@found_in_range) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;$require-&gt;[Youri::Package::DEPENDENCY_NAME] found with incorrect range $_-&gt;[RANGE] (needed $require-&gt;[Youri::Package::DEPENDENCY_RANGE])&quot;,
++ level =&gt; Youri::Check::Input::ERROR
++ }) foreach @found_in_media;
++ next;
++ }
++ }
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputMandrivaConflictspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,63 @@
++# $Id: Conflicts.pm 533 2005-10-20 07:08:03Z guillomovitch $
++package Youri::Check::Input::MandrivaConflicts;
++
++=head1 NAME
++
++Youri::Check::Input::MandrivaConflicts - Check file conflicts on Mandriva
++
++=head1 DESCRIPTION
++
++This class checks file conflicts between packages, taking care of Mandriva
++packaging policy.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Package;
++use base 'Youri::Check::Input::Conflicts';
++
++sub _directory_duplicate_exception {
++ my ($self, $package1, $package2, $file) = @_;
++
++ # allow shared directories between devel packages of different arch
++ return 1 if _multiarch_exception($package1, $package2);
++
++ # allow shared modules directories between perl packages
++ return 1 if
++ $file-&gt;[Youri::Package::FILE_NAME] =~ /^\/usr\/lib\/perl5\/vendor_perl\// &amp;&amp;
++ $file-&gt;[Youri::Package::FILE_NAME] !~ /^(auto|[^\/]+-linux)$/;
++
++ return 0;
++}
++
++sub _file_duplicate_exception {
++ my ($self, $package1, $package2, $file) = @_;
++
++ # allow shared files between devel packages of different arch
++ return 1 if _multiarch_exception($package1, $package2);
++
++ return 0;
++}
++
++sub _multiarch_exception {
++ my ($package1, $package2) = @_;
++
++ return 1 if
++ $package1-&gt;get_canonical_name() eq $package2-&gt;get_canonical_name()
++ &amp;&amp; $package1-&gt;get_name() =~ /-devel$/
++ &amp;&amp; $package2-&gt;get_name() =~ /-devel$/;
++
++ return 0;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputMissingpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,138 @@
++package Youri::Check::Input::Missing;
++
++=head1 NAME
++
++Youri::Check::Input::Missing - Check components consistency
++
++=head1 DESCRIPTION
++
++This plugin checks consistency between package components, and report outdated
++ones.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use List::MoreUtils qw/all any/;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ component
++ arch
++ revision
++ error
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Missing object.
++
++No specific parameters.
++
++=cut
++
++sub prepare {
++ my ($self, @medias) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ $self-&gt;{_srcs} = ();
++ foreach my $media (@medias) {
++ # only index source media
++ next unless $media-&gt;get_type() eq 'source';
++
++ my $media_id = $media-&gt;get_id();
++ $self-&gt;{_medias}-&gt;{$media_id} = 1;
++ print STDERR &quot;Indexing media $media_id packages\n&quot; if $self-&gt;{_verbose};
++
++ my $index = sub {
++ my ($package) = @_;
++ $self-&gt;{_srcs}-&gt;{$media_id}-&gt;{$package-&gt;get_name()} =
++ $package-&gt;get_version() . '-' . $package-&gt;get_release();
++ };
++
++ $media-&gt;traverse_headers($index);
++ }
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a binary media check only
++ return unless $media-&gt;get_type() eq 'binary';
++
++ my @allowed_ids = $media-&gt;allow_srcs();
++
++ # abort unless all allowed medias are present
++ foreach my $id (@allowed_ids) {
++ unless ($self-&gt;{_medias}-&gt;{$id}) {
++ carp &quot;Missing media $id, aborting&quot;;
++ return;
++ }
++ }
++
++ my $class = $media-&gt;get_package_class();
++
++ my $check_package = sub {
++ my ($package) = @_;
++ my $canonical_name = $package-&gt;get_canonical_name();
++
++ my $bin_revision =
++ $package-&gt;get_version() . '-' . $package-&gt;get_release();
++
++ my $src_revision;
++ foreach my $id (@allowed_ids) {
++ $src_revision = $self-&gt;{_srcs}-&gt;{$id}-&gt;{$canonical_name};
++ last if $src_revision;
++ }
++
++ if ($src_revision) {
++ # check if revision match
++ unless ($src_revision eq $bin_revision) {
++ if ($class-&gt;compare_versions($src_revision, $bin_revision) &gt; 0) {
++ # binary package is obsolete
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ component =&gt; $package-&gt;get_name(),
++ arch =&gt; $package-&gt;get_arch(),
++ revision =&gt; $bin_revision,
++ error =&gt; &quot;Obsolete binaries (source $src_revision found)&quot;,
++ });
++ } else {
++ # source package is obsolete
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ component =&gt; $package-&gt;get_canonical_name(),
++ arch =&gt; 'src',
++ revision =&gt; $src_revision,
++ error =&gt; &quot;Obsolete source (binaries $bin_revision found)&quot;,
++ });
++ }
++ }
++ } else {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ component =&gt; $package-&gt;get_name(),
++ arch =&gt; $package-&gt;get_arch(),
++ revision =&gt; $bin_revision,
++ error =&gt; &quot;Missing source package&quot;,
++ });
++ }
++ };
++
++ $media-&gt;traverse_headers($check_package);
++}
++
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputOrphanspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,74 @@
++package Youri::Check::Input::Orphans;
++
++=head1 NAME
++
++Youri::Check::Input::Orphans - Check maintainance
++
++=head1 DESCRIPTION
++
++This plugin checks maintainance status of packages, and reports unmaintained
++ones.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ error
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Orphans object.
++
++No specific parameters.
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ resolver =&gt; undef,
++ @_
++ );
++
++ croak &quot;No resolver defined&quot; unless $options{resolver};
++
++ $self-&gt;{_resolver} = $options{resolver};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a source media check only
++ return unless $media-&gt;get_type() eq 'source';
++
++ my $check = sub {
++ my ($package) = @_;
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ error =&gt; &quot;unmaintained package&quot;
++ }) unless $self-&gt;{_resolver}-&gt;get_maintainer($package);
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputRpmlintpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,113 @@
++# $Id: Rpmlint.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Rpmlint;
++
++=head1 NAME
++
++Youri::Check::Input::Rpmlint - Check packages with rpmlint
++
++=head1 DESCRIPTION
++
++This plugins checks packages with rpmlint, and reports output.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ level
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Rpmlint object.
++
++Specific parameters:
++
++=over
++
++=item path $path
++
++Path to the rpmlint executable (default: /usr/bin/rpmlint)
++
++=item config $config
++
++Specific rpmlint configuration.
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ path =&gt; '/usr/bin/rpmlint', # path to rpmlint
++ config =&gt; '', # default rpmlint configuration
++ @_
++ );
++
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_config} = $options{config};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $config = $media-&gt;rpmlint_config() ?
++ $media-&gt;rpmlint_config() :
++ $self-&gt;{_config};
++
++ my $check = sub {
++ my ($file, $package) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ my $command = &quot;$self-&gt;{_path} -f $config $file&quot;;
++ open(RPMLINT, &quot;$command |&quot;) or die &quot;Can't run $command: $!&quot;;
++ while (&lt;RPMLINT&gt;) {
++ chomp;
++ if (/^E: \Q$name\E (.+)/) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; $1,
++ level =&gt; Youri::Check::Input::ERROR
++ });
++ } elsif (/^W: \Q$name\E (.+)/) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; $1,
++ level =&gt; Youri::Check::Input::WARNING
++ });
++ }
++ }
++ close(RPMLINT);
++ };
++
++ $media-&gt;traverse_files($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputSignaturepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,96 @@
++# $Id: Rpmlint.pm 567 2005-12-12 21:24:56Z guillomovitch $
++package Youri::Check::Input::Signature;
++
++=head1 NAME
++
++Youri::Check::Input::Signature - Check signature
++
++=head1 DESCRIPTION
++
++This plugin checks packages signature, and report unsigned ones.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Signature object.
++
++Specific parameters:
++
++=over
++
++=item key $key
++
++Expected GPG key identity
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ key =&gt; '',
++ @_
++ );
++
++ $self-&gt;{_key} = $options{key};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $check = sub {
++ my ($package) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ my $key = $package-&gt;get_gpg_key();
++
++ if (!$key) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;unsigned package $name&quot;
++ });
++ } elsif ($key ne $self-&gt;{_key}) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;invalid key id $key for package $name (allowed $self-&gt;{_key})&quot;
++ });
++ }
++
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceCPANpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,75 @@
++# $Id: CPAN.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::CPAN;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::CPAN - CPAN updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from CPAN.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::CPAN object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to CPAN full modules list (default:
++http://www.cpan.org/modules/01modules.index.html)
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://www.cpan.org/modules/01modules.index.html',
++ @_
++ );
++
++ my $versions;
++ open(INPUT, &quot;GET $options{url} |&quot;) or croak &quot;Can't fetch $options{url}: $!&quot;;
++ while (&lt;INPUT&gt;) {
++ next unless $_ =~ /&gt;([\w-]+)-([\d\.]+)\.tar\.gz&lt;\/a&gt;/;
++ $versions-&gt;{$1} = $2;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://search.cpan.org/dist/$name&quot;;
++}
++
++sub _name {
++ my ($self, $name) = @_;
++ $name =~ s/^perl-//g;
++ return $name;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceDebianpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,82 @@
++# $Id: Debian.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Debian;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Debian - Debian source for updates
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++ available from Debian.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Debian object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to Debian mirror content file (default: http://ftp.debian.org/ls-lR.gz)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://ftp.debian.org/ls-lR.gz',
++ @_
++ );
++
++ my $versions;
++ open(INPUT, &quot;GET $options{url} | zcat |&quot;) or croak &quot;Can't fetch $options{url}: $!&quot;;
++ while (my $line = &lt;INPUT&gt;) {
++ next unless $line =~ /([\w\.-]+)_([\d\.]+)\.orig\.tar\.gz$/;
++ my $name = $1;
++ my $version = $2;
++ $versions-&gt;{$name} = $version;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://packages.debian.org/$name&quot;;
++}
++
++sub _name {
++ my ($self, $name) = @_;
++
++ if ($name =~ /^(perl|ruby)-([-\w]+)$/) {
++ $name = lc(&quot;lib$2-$1&quot;);
++ } elsif ($name =~ /^apache-([-\w]+)$/) {
++ $name = &quot;libapache-$1&quot;;
++ $name =~ s/_/-/g;
++ }
++
++ return $name;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFedorapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,63 @@
++# $Id: Fedora.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Fedora;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Fedora - Fedora updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Fedora.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Fedora object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to Fedora development SRPMS directory (default:
++http://fr.rpmfind.net/linux/fedora/core/development/SRPMS)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://fr.rpmfind.net/linux/fedora/core/development/SRPMS',
++ @_
++ );
++
++ my $versions;
++ open(INPUT, &quot;GET $options{url} |&quot;) or die &quot;Can't fetch $options{url}: $!\n&quot;;
++ while (&lt;INPUT&gt;) {
++ next unless $_ =~ /&gt;([\w-]+)-([\w\.]+)-[\w\.]+\.src\.rpm&lt;\/a&gt;/;
++ $versions-&gt;{$1} = $2;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFreshmeatpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,111 @@
++# $Id: Freshmeat.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Freshmeat;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Freshmeat - Freshmeat source for updates
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Freshmeat.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use XML::Twig;
++use LWP::UserAgent;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Freshmeat
++object.
++
++Specific parameters:
++
++=over
++
++=item preload true/false
++
++Allows to load full Freshmeat catalogue at once instead of checking each software independantly (default: false)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ preload =&gt; 0,
++ @_
++ );
++
++ if ($options{preload}) {
++ my $versions;
++
++ my $project = sub {
++ my ($twig, $project) = @_;
++ my $name = $project-&gt;first_child('projectname_short')-&gt;text();
++ my $version = $project-&gt;first_child('latest_release')-&gt;first_child('latest_release_version')-&gt;text();
++ $versions-&gt;{$name} = $version;
++ $twig-&gt;purge();
++ };
++
++ my $twig = XML::Twig-&gt;new(
++ TwigRoots =&gt; { project =&gt; $project }
++ );
++
++ my $url = 'http://download.freshmeat.net/backend/fm-projects.rdf.bz2';
++
++ open(INPUT, &quot;GET $url | bzcat |&quot;) or die &quot;Can't fetch $url: $!\n&quot;;
++ $twig-&gt;parse(\*INPUT);
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++ }
++}
++
++sub _version {
++ my ($self, $name) = @_;
++
++ if ($self-&gt;{_versions}) {
++ return $self-&gt;{_versions}-&gt;{$name};
++ } else {
++ my $version;
++
++ my $latest_release_version = sub {
++ $version = $_[1]-&gt;text();
++ };
++
++ my $twig = XML::Twig-&gt;new(
++ TwigRoots =&gt; { latest_release_version =&gt; $latest_release_version }
++ );
++
++ my $url = &quot;http://freshmeat.net/projects-xml/$name&quot;;
++
++ open(INPUT, &quot;GET $url |&quot;) or die &quot;Can't fetch $url: $!\n&quot;;
++ # freshmeat answer with an HTML page when project doesn't exist
++ $twig-&gt;safe_parse(\*INPUT);
++ close(INPUT);
++
++ return $version;
++ }
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://freshmeat.net/projects/$name&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGNOMEpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,104 @@
++# $Id$
++package Youri::Check::Input::Updates::Source::GNOME;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::GNOME - GNOME updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from GNOME.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use List::MoreUtils 'any';
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Gnome object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to GNOME sources directory (default:
++http://fr2.rpmfind.net/linux/gnome.org/sources)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://fr2.rpmfind.net/linux/gnome.org/sources/', # default url
++ # We use HTTP as it offers a better sorting (1.2 &lt; 1.10)
++ @_
++ );
++
++ $self-&gt;{_agent} = LWP::UserAgent-&gt;new();
++ my $response = $self-&gt;{_agent}-&gt;get($options{url});
++ if($response-&gt;is_success()) {
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /^([-\w]+)\/$/o;
++ $self-&gt;{_names}-&gt;{$1} = 1;
++ }
++ }
++
++ $self-&gt;{_url} = $options{url};
++}
++
++sub _version {
++ my ($self, $name) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $self-&gt;{_names}-&gt;{$name};
++
++ my $response = $self-&gt;{_agent}-&gt;get(&quot;$self-&gt;{_url}/$name/&quot;);
++ if($response-&gt;is_success()) {
++ my $major;
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /^([.\d]+)\/$/o;
++ $major = $1;
++ }
++ return unless $major;
++
++ $response = $self-&gt;{_agent}-&gt;get(&quot;$self-&gt;{_url}/$name/$major/&quot;);
++ if($response-&gt;is_success()) {
++ $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /^LATEST-IS-([.\d]+)$/o;
++ return $1;
++ }
++ }
++ }
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return $self-&gt;{_url}.&quot;$name/&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGentoopm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,75 @@
++# $Id: Gentoo.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Gentoo;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Gentoo - Gentoo updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Gentoo.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::Simple;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Gentoo object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to Gentoo snapshots directory (default:
++http://gentoo.mirror.sdv.fr/snapshots)
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://gentoo.mirror.sdv.fr/snapshots', # default URL
++ @_
++ );
++
++ my $versions;
++ my $content = get($options{url});
++ my $file;
++ while ($content =~ /&lt;A HREF=&quot;(portage-\d{8}.tar.bz2)&quot;&gt;/g) {
++ $file = $1;
++ }
++ open(INPUT, &quot;GET $options{url}/$file | tar tjf - |&quot;) or croak &quot;Can't fetch $options{url}/$file: $!&quot;;
++ while (my $line = &lt;INPUT&gt;) {
++ next unless $line =~ /.*\/([\w-]+)-([\d\.]+)(:?-r\d)?\.ebuild$/;
++ $versions-&gt;{$1} = $2;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://packages.gentoo.org/search/?sstring=$name&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceNetBSDpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,75 @@
++# $Id$
++package Youri::Check::Input::Updates::Source::NetBSD;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::NetBSD - NetBSD source for updates
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++ available from NetBSD.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++use IO::Ftp;
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::NetBSD object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to NetBSD mirror content file, without ftp: (default: //ftp.free.fr/mirrors/ftp.netbsd.org/NetBSD-current/pkgsrc/README-all.html)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; '//ftp.free.fr/mirrors/ftp.netbsd.org/NetBSD-current/pkgsrc/README-all.html',
++ @_
++ );
++
++ my $versions;
++ my $urls;
++
++ my $in = IO::Ftp-&gt;new('&lt;',$options{url}) or croak &quot;Can't fetch $options{url}: $!&quot;;
++ while (my $line = &lt;$in&gt;) {
++ next unless $line =~ /&lt;!-- (.+)-([^-]*?)(nb\d*)? \(for sorting\).*?href=&quot;([^&quot;]+)&quot;/;
++ my $name = $1;
++ my $version = $2;
++ $versions-&gt;{$name} = $version;
++ $urls-&gt;{$name} = $4;
++ }
++ close($in);
++
++ $self-&gt;{_versions} = $versions;
++ $self-&gt;{_urls} = $urls;
++ $self-&gt;{_url} = $options{url};
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return $self-&gt;{_urls}-&gt;{$name};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceRAApm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,121 @@
++# $Id: RAA.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::RAA;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::RAA - RAA updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from RAA.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use SOAP::Lite;
++use List::MoreUtils 'any';
++use Youri::Package;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::RAA object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to RAA SOAP interface (default:
++http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/',
++ @_
++ );
++
++ my $raa = SOAP::Lite-&gt;service($options{url})
++ or croak &quot;Can't connect to $options{url}&quot;;
++
++ $self-&gt;{_raa} = $raa;
++ $self-&gt;{_names} = $raa-&gt;names();
++}
++
++sub get_version {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name;
++ if (ref $package &amp;&amp; $package-&gt;isa('Youri::Package')) {
++ # don't bother checking for non-ruby packages
++ if (
++ any { $_-&gt;[Youri::Package::DEPENDENCY_NAME] =~ /ruby/ }
++ $package-&gt;get_requires()
++ ) {
++ $name = $package-&gt;get_canonical_name();
++ } else {
++ return;
++ }
++ } else {
++ $name = $package;
++ }
++
++ # translate in grabber namespace
++ $name = $self-&gt;get_name($name);
++
++ # return if aliased to null
++ return unless $name;
++
++ # susceptible to throw exception for timeout
++ eval {
++ my $gem = $self-&gt;{_raa}-&gt;gem($name);
++ return $gem-&gt;{project}-&gt;{version} if $gem;
++ };
++
++ return;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://raa.ruby-lang.org/project/$name/&quot;;
++}
++
++sub _name {
++ my ($self, $name) = @_;
++
++ if (ref $self) {
++ my $match = $name;
++ $match =~ s/^ruby[-_]//;
++ $match =~ s/[-_]ruby$//;
++ my @results =
++ grep { /^(ruby[-_])?\Q$match\E([-_]ruby)$/ }
++ @{$self-&gt;{_names}};
++ if (@results) {
++ return $results[0];
++ } else {
++ return $name;
++ }
++ } else {
++ return $name;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceSourceforgepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,103 @@
++# $Id: Sourceforge.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Sourceforge;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Sourceforge - Sourceforge updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Sourceforge.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use Youri::Check::Input::Updates;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Sourceforge
++object.
++
++No specific parameters.
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++
++ $self-&gt;{_agent} = LWP::UserAgent-&gt;new();
++}
++
++sub get_version {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name;
++ if (ref $package &amp;&amp; $package-&gt;isa('Youri::Package')) {
++ # don't bother checking for packages without sf.net URL
++ my $url = $package-&gt;get_url();
++ if (
++ $url =~ /http:\/\/(.*)\.sourceforge\.net/ ||
++ $url =~ /http:\/\/.*sourceforge\.net\/projects\/([^\/]+)/
++ ) {
++ $name = $package-&gt;get_canonical_name();
++ } else {
++ return;
++ }
++ } else {
++ $name = $package;
++ }
++
++ # translate in grabber namespace
++ $name = $self-&gt;get_name($name);
++
++ # return if aliased to null
++ return unless $name;
++
++ my $response = $self-&gt;{_agent}-&gt;get($self-&gt;_url($name));
++ if($response-&gt;is_success()) {
++ my $max = 0;
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $text = $parser-&gt;get_trimmed_text(&quot;/$token-&gt;[0]&quot;);
++ next unless $text;
++ next unless $text =~ /^
++ \Q$name\E
++ [._-]?($Youri::Check::Input::Updates::VERSION_REGEXP)
++ [._-]?(w(?:in)?(?:32)?|mips|sparc|bin|ppc|i\d86|src|sources?)?
++ \.(?:tar\.(?:gz|bz2)|tgz|zip)
++ $/iox;
++ my $version = $1;
++ my $arch = $2;
++ next if $arch &amp;&amp; $arch !~ /(src|sources?)/;
++ $max = $version if Youri::Check::Input::Updates::is_newer($version, $max);
++ }
++ return $max if $max;
++ }
++ return;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://prdownloads.sourceforge.net/$name/&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourcepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,240 @@
++# $Id: Source.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source - Abstract updates source
++
++=head1 DESCRIPTION
++
++This abstract class defines the updates source interface for
++L&lt;Youri::Check::Input::Updates&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates object.
++
++Generic parameters (subclasses may define additional ones):
++
++=over
++
++=item aliases $aliases
++
++Hash of package aliases.
++
++=back
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ aliases =&gt; undef, # aliases
++ resolver =&gt; undef, # maintainer resolver
++ preferences =&gt; undef, # maintainer preferences
++ check_id =&gt; '', # parent check id
++ @_
++ );
++
++ if ($options{aliases}) {
++ croak &quot;aliases should be an hashref&quot; unless ref $options{aliases} eq 'HASH';
++ }
++ if ($options{resolver}) {
++ croak &quot;resolver should be a Youri::Check::Maintainer::Resolver object&quot; unless $options{resolver}-&gt;isa(&quot;Youri::Check::Maintainer::Resolver&quot;);
++ }
++ if ($options{preferences}) {
++ croak &quot;preferences should be a Youri::Check::Maintainer::Preferences object&quot; unless $options{preferences}-&gt;isa(&quot;Youri::Check::Maintainer::Preferences&quot;);
++ }
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _aliases =&gt; $options{aliases},
++ _resolver =&gt; $options{resolver},
++ _preferences =&gt; $options{preferences},
++ _check_id =&gt; $options{check_id},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++Excepted explicit statement, package name is expressed with Mandriva naming
++conventions.
++
++=head2 get_id()
++
++Returns source identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 get_version($package)
++
++Returns available version for given package, which can be either a full
++L&lt;Youri::Package&gt; object or just a package name.
++
++=cut
++
++sub get_version {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name = ref $package &amp;&amp; $package-&gt;isa('Youri::Package') ?
++ $package-&gt;get_canonical_name() :
++ $package;
++
++ # translate in grabber namespace
++ $name = $self-&gt;get_name($name);
++
++ # return if aliased to null
++ return unless $name;
++
++ # return subclass computation
++ return $self-&gt;_version($name);
++}
++
++=head2 get_url($name)
++
++Returns the URL of information source for package with given name.
++
++=cut
++
++sub get_url {
++ my ($self, $name) = @_;
++
++ # retun subclass computation
++ return $self-&gt;_url($self-&gt;get_name($name));
++}
++
++=head2 name($name)
++
++Returns name converted to specific source naming conventions for package with given name.
++
++=cut
++
++sub get_name {
++ my ($self, $name) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # return config aliases if it exists
++ if ($self-&gt;{_aliases} ) {
++ return $self-&gt;{_aliases}-&gt;{$name} if exists $self-&gt;{_aliases}-&gt;{$name};
++ }
++
++ # return maintainer aliases if it exists
++ if ($self-&gt;{_resolver} &amp;&amp; $self-&gt;{_preferences}) {
++ my $maintainer = $self-&gt;{_resolver}-&gt;get_maintainer($name);
++ if ($maintainer) {
++ my $aliases = $self-&gt;{_preferences}-&gt;get_preference(
++ $maintainer,
++ $self-&gt;{_check_id},
++ 'aliases'
++ );
++ if ($aliases) {
++ if ($aliases-&gt;{all}) {
++ return $aliases-&gt;{all}-&gt;{$name} if exists $aliases-&gt;{all}-&gt;{$name};
++ }
++ if ($aliases-&gt;{$self-&gt;{_id}}) {
++ return $aliases-&gt;{$self-&gt;{_id}}-&gt;{$name} if exists $aliases-&gt;{$self-&gt;{_id}}-&gt;{$name};
++ }
++ }
++ }
++ }
++
++ # return return subclass computation
++ return $self-&gt;_name($name);
++}
++
++=head2 _version($name)
++
++Hook called by default B&lt;version()&gt; implementation after name translation.
++
++=cut
++
++sub _version {
++ my ($self, $name) = @_;
++ return $self-&gt;{_versions}-&gt;{$name};
++}
++
++=head2 _url($name)
++
++Hook called by default B&lt;url()&gt; implementation after name translation.
++
++=cut
++
++sub _url {
++ my ($self, $name) = @_;
++ return undef;
++}
++
++=head2 _name($name)
++
++Hook called by default B&lt;name()&gt; implementation if given name was not found in
++the aliases.
++
++=cut
++
++sub _name {
++ my ($self, $name) = @_;
++ return $name;
++}
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item version
++
++As an alternative, the B&lt;_version()&gt; hook can be implemented.
++
++=item url
++
++As an alternative, the &lt;_url()&gt; hook can be implemented.
++
++=item name
++
++As an alternative, the B&lt;_name()&gt; hook can be implemented.
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatespm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,275 @@
++# $Id: Updates.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates;
++
++=head1 NAME
++
++Youri::Check::Input::Updates - Check available updates
++
++=head1 DESCRIPTION
++
++This plugin checks available updates for packages, and report existing ones.
++Additional source plugins handle specific sources.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use Youri::Utils;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ current
++ available
++ source
++ /;
++}
++
++sub links {
++ return qw/
++ source url
++ /;
++}
++
++memoize('is_newer');
++
++our $VERSION_REGEXP = 'v?([\d._-]*\d)[._ -]*(?:(alpha|beta|pre|rc|pl|rev|cvs|svn|[a-z])[_ -.]*([\d.]*))?([_ -.]*.*)';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates object.
++
++Specific parameters:
++
++=over
++
++=item aliases $aliases
++
++Hash of global aliases definitions
++
++=item sources $sources
++
++Hash of source plugins definitions
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ aliases =&gt; undef,
++ sources =&gt; undef,
++ @_
++ );
++
++ croak &quot;No source defined&quot; unless $options{sources};
++ croak &quot;sources should be an hashref&quot; unless ref $options{sources} eq 'HASH';
++ if ($options{aliases}) {
++ croak &quot;aliases should be an hashref&quot; unless ref $options{aliases} eq 'HASH';
++ }
++
++ foreach my $id (keys %{$options{sources}}) {
++ print &quot;Creating source $id\n&quot; if $options{verbose};
++ eval {
++ # add global aliases if defined
++ if ($options{aliases}) {
++ foreach my $alias (keys %{$options{aliases}}) {
++ $options{sources}-&gt;{$id}-&gt;{aliases}-&gt;{$alias} =
++ $options{aliases}-&gt;{$alias}
++ }
++ }
++
++ push(
++ @{$self-&gt;{_sources}},
++ create_instance(
++ 'Youri::Check::Input::Updates::Source',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ check_id =&gt; $options{id},
++ resolver =&gt; $options{resolver},
++ preferences =&gt; $options{preferences},
++ %{$options{sources}-&gt;{$id}}
++ )
++ );
++ };
++ print STDERR &quot;Failed to create source $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no sources created&quot; unless @{$self-&gt;{_sources}};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a source media check only
++ return unless $media-&gt;get_type() eq 'source';
++
++ my $callback = sub {
++ my ($package) = @_;
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++
++ # compute version with rpm subtilities related to preversions
++ my $current_version = ($release =~ /^0\.(\w+)\.\w+$/) ?
++ $version . $1 :
++ $version;
++ my $current_stable = is_stable($current_version);
++
++ my ($max_version, $max_source, $max_url);
++ $max_version = $current_version;
++
++ foreach my $source (@{$self-&gt;{_sources}}) {
++ my $available_version = $source-&gt;get_version($package);
++ if (
++ $available_version &amp;&amp;
++ (! $current_stable || is_stable($available_version)) &amp;&amp;
++ is_newer($available_version, $max_version)
++ ) {
++ $max_version = $available_version;
++ $max_source = $source-&gt;get_id();
++ $max_url = $source-&gt;get_url($name);
++ }
++ }
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ current =&gt; $current_version,
++ available =&gt; $max_version,
++ source =&gt; $max_source,
++ url =&gt; $max_url
++ }) if $max_version ne $current_version;
++ };
++
++ $media-&gt;traverse_headers($callback);
++}
++
++=head2 is_stable($version)
++
++Checks if given version is stable.
++
++=cut
++
++sub is_stable {
++ my ($version) = @_;
++ return $version !~ /alpha|beta|pre|rc|cvs|svn/i;
++
++}
++
++=head2 is_newer($v1, $v2)
++
++Checks if $v1 is newer than $v2.
++
++This function will return true only if we are sure this is newer (and not equal).
++If we can't compare the versions, a warning will be displayed.
++
++=cut
++
++sub is_newer {
++ my ($v1, $v2) = @_;
++ return 0 if $v1 eq $v2;
++
++ # Reject strange cases
++ # One is a large number (like date or revision) and the other one not, or
++ # has different length
++ if (($v1 =~ /^\d{3,}$/ || $v2 =~ /^\d{3,}$/)
++ &amp;&amp; (join('0',split(/\d/, $v1.&quot;X&quot;)) ne join('0',split(/\d/, $v2.&quot;X&quot;)))) {
++ carp &quot;strange : $v1 vs $v2&quot;;
++ return 0;
++ }
++
++ my %states = (alpha=&gt;-4,beta=&gt;-3,pre=&gt;-2,rc=&gt;-1);
++ my $i; $states{$_} = ++$i foreach 'a'..'z';
++
++ if ($v1 =~ /^[\d._-]+$/ &amp;&amp; $v2 =~ /^[\d._-]+$/) {
++ my @v1 = split(/[._-]/, $v1);
++ my @v2 = split(/[._-]/, $v2);
++ if (join('',@v1) eq (join '',@v2)) {
++ # Might be something like 1.2.0 vs 1.20, usual false positive
++ carp &quot;strange : $v1 vs $v2&quot;;
++ return 0;
++ }
++ for my $i (0 .. $#v1) {
++ $v1[$i] ||= 0;
++ $v2[$i] ||= 0;
++ return 1 if $v1[$i] &gt; $v2[$i];
++ return 0 if $v1[$i] &lt; $v2[$i];
++ }
++ # When v2 is longer than v1 but start the same, v1 &lt;= v2
++ return 0;
++ } else {
++ my ($num1, $state1, $statenum1, $other1, $num2, $state2, $statenum2, $other2);
++
++ if ($v1 =~ /^$VERSION_REGEXP$/io) {
++ ($num1, $state1, $statenum1, $other1) = ($1, &quot;\L$2&quot;, $3, $4);
++ } else {
++ carp &quot;unknown version format $v1&quot;;
++ return 0;
++ }
++
++ if ($v2 =~ /^$VERSION_REGEXP$/io) {
++ ($num2, $state2, $statenum2, $other2) = ($1, &quot;\L$2&quot;, $3, $4);
++ } else {
++ carp &quot;unknown version format $v2&quot;;
++ return 0;
++ }
++
++ # If we know the format of only one, there might be an issue, do nothing
++
++ if (($other1 &amp;&amp; ! $other2 )||(!$other1 &amp;&amp; $other2 )) {
++ carp &quot;can't compare $v1 vs $v2&quot;;
++ return 0;
++ }
++
++ return 1 if is_newer($num1, $num2);
++ return 0 unless $num1 eq $num2;
++
++ # The numeric part is the same but not the end
++
++ if ($state1 eq '') {
++ return 1 if $state2 =~ /^(alpha|beta|pre|rc)/;
++ return 0 if $state2 =~ /^([a-z]|pl)$/;
++ carp &quot;unknown state format $state2&quot;;
++ return 0;
++ }
++
++ if ($state2 eq '') {
++ return 0 if $state1 =~ /^(alpha|beta|pre|rc)/;
++ return 1 if $state1 =~ /^([a-z]|pl)$/;
++ carp &quot;unknown state format $state1&quot;;
++ return 0;
++ }
++
++ if ($state1 eq $state2) {
++ return 1 if is_newer($statenum1, $statenum2);
++ return 0 unless $statenum1 eq $statenum2;
++ # If everything is the same except this, just compare it
++ # as we have no idea on the format
++ return &quot;$other1&quot; gt &quot;$other2&quot;;
++ }
++
++ my $s1 = 0;
++ my $s2 = 0;
++ $s1=$states{$state1} if exists $states{$state1};
++ $s2=$states{$state2} if exists $states{$state2};
++ return $s1&gt;$s2 if ($s1 != 0 &amp;&amp; $s2 != 0);
++ return 1 if $s1&lt;0 &amp;&amp; $state2 =~ /^([a-z]|pl)$/;
++ return 0 if $s2&lt;0 &amp;&amp; $state1 =~ /^([a-z]|pl)$/;
++ carp &quot;unknown case $v1, $v2&quot;;
++ return 0;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,120 @@
++# $Id: Input.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input;
++
++=head1 NAME
++
++Youri::Check::Input - Abstract input plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines input plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++
++use constant WARNING =&gt; 'warning';
++use constant ERROR =&gt; 'error';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ resolver =&gt; undef, # maintainer resolver
++ preferences =&gt; undef, # maintainer preferences
++ @_
++ );
++
++ if ($options{resolver}) {
++ croak &quot;resolver should be a Youri::Check::Maintainer::Resolver object&quot; unless $options{resolver}-&gt;isa(&quot;Youri::Check::Maintainer::Resolver&quot;);
++ }
++ if ($options{preferences}) {
++ croak &quot;preferences should be a Youri::Check::Maintainer::Preferences object&quot; unless $options{preferences}-&gt;isa(&quot;Youri::Check::Maintainer::Preferences&quot;);
++ }
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _resolver =&gt; $options{resolver},
++ _preferences =&gt; $options{preferences},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns plugin identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 prepare(@medias)
++
++Perform optional preliminary initialisation, using given list of
++&lt;Youri::Media&gt; objects.
++
++=cut
++
++sub prepare {
++ # do nothing
++}
++
++=head2 run($media, $resultset)
++
++Check the packages from given L&lt;Youri::Media&gt; object, and store the
++result in given L&lt;Youri::Check::Resultset&gt; object.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item run
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencesFilepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,87 @@
++# $Id: File.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Preferences::File;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Preferences::File - File-based maintainer preferences implementation
++
++=head1 DESCRIPTION
++
++This is a file-based L&lt;Youri::Check::Maintainer::Preferences&gt; implementation.
++
++It uses files in maintainer home directories.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Config;
++use base 'Youri::Check::Maintainer::Preferences';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Preferences::File object.
++
++No specific parameters.
++
++=cut
++
++sub get_preference {
++ my ($self, $maintainer, $plugin, $value) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return unless $maintainer &amp;&amp; $plugin &amp;&amp; $value;
++
++ print &quot;Retrieving maintainer $maintainer preferences\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ $self-&gt;_load_config($maintainer)
++ unless exists $self-&gt;{_config}-&gt;{$maintainer};
++
++ return $self-&gt;{_config}-&gt;{$maintainer} ?
++ $self-&gt;{_config}-&gt;{$maintainer}-&gt;get($plugin . '_' . $value) :
++ undef;
++}
++
++sub _load_config {
++ my ($self, $maintainer) = @_;
++
++ print &quot;Attempting to load maintainers preferences for $maintainer\n&quot; if $self-&gt;{_verbose} &gt; 1;
++
++
++ my ($login) = $maintainer =~ /^(\S+)\@\S+$/;
++ my $home = (getpwnam($login))[7];
++ my $file = &quot;$home/.youri/check.prefs&quot;;
++
++ if (-f $file &amp;&amp; -r $file) {
++ print &quot;Found, loading\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ my $config = Youri::Config-&gt;new(
++ {
++ CREATE =&gt; 1,
++ GLOBAL =&gt; {
++ DEFAULT =&gt; undef,
++ EXPAND =&gt; EXPAND_VAR | EXPAND_ENV,
++ ARGCOUNT =&gt; ARGCOUNT_ONE,
++ }
++ }
++ );
++ $config-&gt;file($file);
++ $self-&gt;{_config}-&gt;{$maintainer} = $config;
++ } else {
++ print &quot;Not found, aborting\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ $self-&gt;{_config}-&gt;{$maintainer} = undef;
++ }
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencespm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,80 @@
++# $Id: Preferences.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Preferences;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Preferences - Abstract maintainer preferences
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Check::Maintainer::Preferences interface.
++
++=head1 SYNOPSIS
++
++ use Youri::Check::Maintainer::Preferences::Foo;
++
++ my $preferences = Youri::Check::Maintainer::Preferences::Foo-&gt;new();
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Preferences object.
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_preference($maintainer, $plugin, $item)
++
++Returns preference of given maintainer for given plugin and configuration item.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item get
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverBugzillapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,100 @@
++# $Id: Bugzilla.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Resolver::Bugzilla;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Resolver::Bugzilla - Bugzilla-based maintainer resolver
++
++=head1 DESCRIPTION
++
++This is a Bugzilla-based L&lt;Youri::Check::Maintainer::Resolver&gt; implementation.
++
++It uses Bugzilla SQL database for resolving maintainers.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Bugzilla;
++use base 'Youri::Check::Maintainer::Resolver';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Resolver::Bugzilla object.
++
++Specific parameters:
++
++=over
++
++=item host $host
++
++Bugzilla database host.
++
++=item base $base
++
++Bugzilla database name.
++
++=item user $user
++
++Bugzilla database user.
++
++=item pass $pass
++
++Bugzilla database password.
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ host =&gt; '', # host of the bug database
++ base =&gt; '', # name of the bug database
++ user =&gt; '', # user of the bug database
++ pass =&gt; '', # pass of the bug database
++ @_
++ );
++
++ croak &quot;No host given&quot; unless $options{host};
++ croak &quot;No base given&quot; unless $options{base};
++ croak &quot;No user given&quot; unless $options{user};
++ croak &quot;No pass given&quot; unless $options{pass};
++
++ my $bugzilla = Youri::Bugzilla-&gt;new(
++ $options{host},
++ $options{base},
++ $options{user},
++ $options{pass}
++ );
++
++ $self-&gt;{_bugzilla} = $bugzilla;
++}
++
++sub get_maintainer {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name = ref $package &amp;&amp; $package-&gt;isa('Youri::Package') ?
++ $package-&gt;get_canonical_name() :
++ $package;
++
++ $self-&gt;{_maintainers}-&gt;{$name} =
++ $self-&gt;{_bugzilla}-&gt;get_maintainer($name)
++ unless exists $self-&gt;{_maintainers}-&gt;{$name};
++
++ return $self-&gt;{_maintainers}-&gt;{$name};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverCGIpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,79 @@
++# $Id: CGI.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Resolver::CGI;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Resolver::CGI - CGI-based maintainer resolver
++
++=head1 DESCRIPTION
++
++This is a CGI-based L&lt;Youri::Check::Maintainer::Resolver&gt; implementation.
++
++It uses a remote CGI to resolve maintainers.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Maintainer::Resolver';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Resolver::CGI object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++CGI's URL.
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; '', # url to fetch maintainers
++ @_
++ );
++
++ croak &quot;No URL given&quot; unless $options{url};
++
++ open (INPUT, &quot;GET $options{url} |&quot;);
++ while (&lt;INPUT&gt;) {
++ chomp;
++ my ($package, $maintainer) = split(/\t/, $_);
++ $self-&gt;{_maintainers}-&gt;{$package} = $maintainer if $maintainer;
++ }
++ close(INPUT);
++}
++
++sub get_maintainer {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ print &quot;Retrieving package $package maintainer\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my $name = ref $package &amp;&amp; $package-&gt;isa('Youri::Package') ?
++ $package-&gt;get_canonical_name() :
++ $package;
++
++ return $self-&gt;{_maintainers}-&gt;{$name};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,86 @@
++# $Id: Resolver.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Resolver;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Resolver - Abstract maintainer resolver
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Check::Maintainer::Resolver interface.
++
++=head1 SYNOPSIS
++
++ use Youri::Check::Maintainer::Resolver::Foo;
++
++ my $resolver = Youri::Check::Maintainer::Resolver::Foo-&gt;new();
++
++ print $resolver-&gt;get_maintainer('foo');
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Resolver object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose}
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_maintainer($package)
++
++Returns maintainer for given package, which can be either a full
++L&lt;Youri::Package&gt; object or just a package name.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item get_maintainer
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatHTMLpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,222 @@
++# $Id: HTML.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output::File::Format::HTML;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format::HTML - File HTML format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::File&gt; provides HTML format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use CGI;
++use base 'Youri::Check::Output::File::Format';
++
++sub extension {
++ return 'html';
++}
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ style =&gt; &lt;&lt;EOF, # css style
++h1 {
++ text-align:center;
++}
++table {
++ border-style:solid;
++ border-width:1px;
++ border-color:black;
++ width:100%;
++}
++tr.odd {
++ background-color:white;
++}
++tr.even {
++ background-color:silver;
++}
++p.footer {
++ font-size:smaller;
++ text-align:center;
++}
++EOF
++ @_
++ );
++
++ $self-&gt;{_style} = $options{style};
++ $self-&gt;{_cgi} = CGI-&gt;new();
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $content;
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my $line;
++ my @results;
++ $content .= $self-&gt;{_cgi}-&gt;start_table();
++ $content .= $self-&gt;{_cgi}-&gt;Tr([
++ $self-&gt;{_cgi}-&gt;th([
++ @$lead_columns,
++ @$columns
++ ])
++ ]);
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_table();
++
++ return $self-&gt;_get_html_page($time, $title, \$content);
++}
++
++sub get_index {
++ my ($self, $time, $title, $reports, $maintainers) = @_;
++
++ my $content;
++
++ if ($reports) {
++ $content .= $self-&gt;{_cgi}-&gt;h2(&quot;Reports&quot;);
++ my @types = keys %{$reports};
++
++ $content .= $self-&gt;{_cgi}-&gt;start_ul();
++ foreach my $type (sort @types) {
++ my $item;
++ $item = $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; &quot;$type.html&quot; },
++ $type
++ );
++ foreach my $extension (@{$reports-&gt;{$type}}) {
++ next if ($extension eq extension());
++ $item .= &quot; &quot;.$self-&gt;{_cgi}-&gt;a(
++ { href =&gt; &quot;$type.$extension&quot; },
++ &quot;[$extension]&quot;
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;li($item);
++ }
++ $content .= $self-&gt;{_cgi}-&gt;end_ul();
++ }
++
++ if ($maintainers) {
++ $content .= $self-&gt;{_cgi}-&gt;h2(&quot;Individual reports&quot;);
++
++ $content .= $self-&gt;{_cgi}-&gt;start_ul();
++ foreach my $maintainer (sort @{$maintainers}) {
++ $content .= $self-&gt;{_cgi}-&gt;li(
++ $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; &quot;$maintainer/index.html&quot; },
++ _obfuscate($maintainer)
++ )
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;end_ul();
++ }
++
++ return $self-&gt;_get_html_page($time, $title, \$content);
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $links, $class, $results) = @_;
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ for my $i (0 .. $#$results) {
++ $content .= $self-&gt;{_cgi}-&gt;start_Tr(
++ { class =&gt; $class }
++ );
++ if ($i == 0) {
++ # first line contains spanned cells
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ { rowspan =&gt; scalar @$results },
++ [
++ map { $results-&gt;[$i]-&gt;{$_} }
++ @$lead_columns
++ ]
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ [
++ map {
++ $links-&gt;{$_} &amp;&amp; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} ?
++ $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} },
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ ) :
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ } @$columns
++ ]
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ }
++
++ return $content;
++}
++
++
++sub _get_html_page {
++ my ($self, $time, $title, $body) = @_;
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;start_html(
++ -title =&gt; $title,
++ -style =&gt; { code =&gt; $self-&gt;{_style} }
++ );
++ $content .= $self-&gt;{_cgi}-&gt;h1($title);
++ $content .= $$body;
++ $content .= $self-&gt;{_cgi}-&gt;hr();
++ $content .= $self-&gt;{_cgi}-&gt;p(
++ { class =&gt; 'footer' },
++ &quot;Page generated $time&quot;
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_html();
++
++ return \$content;
++}
++
++sub _obfuscate {
++ my ($email) = @_;
++
++ return unless $email;
++
++ $email =~ s/\@/ at /;
++ $email =~ s/\./ dot /;
++
++ return $email;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatRSSpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,68 @@
++# $Id$
++package Youri::Check::Output::File::Format::RSS;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format::RSS - File RSS format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::File&gt; provides RSS format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use XML::RSS;
++use base 'Youri::Check::Output::File::Format';
++
++sub extension {
++ return 'rss';
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ return unless $maintainer;
++
++ my $rss = new XML::RSS (version =&gt; '2.0');
++ $rss-&gt;channel(
++ title =&gt; $title,
++ description =&gt; $title,
++ language =&gt; 'en',
++ ttl =&gt; 1440
++ );
++
++ while (my $result = $iterator-&gt;get_result()) {
++ if ($type eq 'updates') {
++ $rss-&gt;add_item(
++ title =&gt; &quot;$result-&gt;{package} $result-&gt;{available} is available&quot;,
++ description =&gt; &quot;Current version is $result-&gt;{current}&quot;,
++ link =&gt; $result-&gt;{url} ?
++ $result-&gt;{url} : $result-&gt;{source},
++ guid =&gt; &quot;$result-&gt;{package}-$result-&gt;{available}&quot;
++ );
++ } else {
++ $rss-&gt;add_item(
++ title =&gt; &quot;[$type] $result-&gt;{package}&quot;,
++ description =&gt; join(&quot;\n&quot;, (map { $result-&gt;{$_} || '' } @$columns)),
++ link =&gt; $result-&gt;{url},
++ guid =&gt; &quot;$type-$result-&gt;{package}&quot;
++ );
++ }
++ }
++
++ return \$rss-&gt;as_string();
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatTextpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,88 @@
++# $Id: Text.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output::File::Format::Text;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format::Text - File text format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::File&gt; provides text format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Output::File::Format';
++
++sub extension {
++ return 'txt';
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $content;
++ $content .= $title;
++ $content .= &quot;\n&quot;;
++
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my @results;
++ $content .= join(&quot;\t&quot;, @$lead_columns, @$columns) . &quot;\n&quot;;
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++
++ $content .= &quot;\n&quot;;
++ $content .= &quot;Page generated $time\n&quot;;
++
++ return \$content;
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $results) = @_;
++
++ my $content;
++ $content .= join(
++ &quot;\t&quot;,
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$lead_columns),
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ for my $i (1 .. $#$results) {
++ $content .= join(
++ &quot;\t&quot;,
++ (map { '' } @$lead_columns),
++ (map { $results-&gt;[$i]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ }
++ return $content;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,66 @@
++# $Id: Base.pm 579 2006-01-09 21:17:54Z guillomovitch $
++package Youri::Check::Output::File::Format;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format - Abstract file format support
++
++=head1 DESCRIPTION
++
++This abstract class defines the format support interface for
++L&lt;Youri::Check::Output::File&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '',
++ test =&gt; 0,
++ verbose =&gt; 0,
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_id()
++
++Returns format handler identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFilepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,203 @@
++# $Id: Text.pm 523 2005-10-11 08:36:49Z misc $
++package Youri::Check::Output::File;
++
++=head1 NAME
++
++Youri::Check::Output::File - Report results in files
++
++=head1 DESCRIPTION
++
++This plugin reports results in files. Additional subplugins handle specific
++formats.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use File::Path;
++use DateTime;
++use Youri::Utils;
++use base 'Youri::Check::Output';
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ to =&gt; '', # target directory
++ noclean =&gt; 0, # don't clean up target directory
++ noempty =&gt; 0, # don't generate empty reports
++ formats =&gt; undef,
++ @_
++ );
++
++ croak &quot;no format defined&quot; unless $options{formats};
++ croak &quot;formats should be an hashref&quot; unless ref $options{formats} eq 'HASH';
++
++ my $now = DateTime-&gt;now(time_zone =&gt; 'local');
++ my $time = &quot;the &quot; . $now-&gt;ymd() . &quot; at &quot; . $now-&gt;hms();
++
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_noclean} = $options{noclean};
++ $self-&gt;{_noempty} = $options{noempty};
++ $self-&gt;{_time} = $time;
++
++ foreach my $id (keys %{$options{formats}}) {
++ print &quot;Creating format $id\n&quot; if $options{verbose};
++ eval {
++ push(
++ @{$self-&gt;{_formats}},
++ create_instance(
++ 'Youri::Check::Output::File::Format',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ %{$options{formats}-&gt;{$id}}
++ )
++ );
++ };
++ print STDERR &quot;Failed to create format $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no formats created&quot; unless @{$self-&gt;{_formats}};
++}
++
++sub _init_report {
++ my ($self) = @_;
++
++ # clean up output directory
++ unless ($self-&gt;{_test} || $self-&gt;{_noclean} || !$self-&gt;{_to}) {
++ my @files = glob($self-&gt;{_to} . '/*');
++ rmtree(\@files) if @files;
++ }
++}
++
++sub _global_report {
++ my ($self, $resultset, $type, $columns, $links) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ]
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type global report&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ undef
++ );
++
++ # create and register file
++ my $extension = $format-&gt;extension();
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/$type.$extension&quot;,
++ $content
++ );
++ push(
++ @{$self-&gt;{_files}-&gt;{global}-&gt;{$type}},
++ $extension
++ );
++ }
++}
++
++sub _individual_report {
++ my ($self, $resultset, $type, $columns, $links, $maintainer) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ],
++ { maintainer =&gt; [ $maintainer ] }
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type individual report for $maintainer&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ $maintainer
++ );
++
++ # create and register file
++ my $extension = $format-&gt;extension();
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/$maintainer/$type.$extension&quot;,
++ $content
++ );
++ push(
++ @{$self-&gt;{_files}-&gt;{maintainers}-&gt;{$maintainer}-&gt;{$type}},
++ $extension
++ );
++ }
++}
++
++sub _finish_report {
++ my ($self, $types, $maintainers) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ next unless $format-&gt;can('get_index');
++ my $extension = $format-&gt;extension();
++ print STDERR &quot;writing global index page\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/index.$extension&quot;,
++ $format-&gt;get_index(
++ $self-&gt;{_time},
++ &quot;QA global report&quot;,
++ $self-&gt;{_files}-&gt;{global},
++ [ keys %{$self-&gt;{_files}-&gt;{maintainers}} ],
++ )
++ );
++ foreach my $maintainer (@$maintainers) {
++ print STDERR &quot;writing index page for $maintainer\n&quot; if $self-&gt;{_verbose};
++
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/$maintainer/index.$extension&quot;,
++ $format-&gt;get_index(
++ $self-&gt;{_time},
++ &quot;QA report for $maintainer&quot;,
++ $self-&gt;{_files}-&gt;{maintainers}-&gt;{$maintainer},
++ undef,
++ )
++ );
++ }
++ }
++}
++
++sub _write_file {
++ my ($self, $file, $content) = @_;
++
++ return unless $content;
++
++ my $dirname = dirname($file);
++ mkpath($dirname) unless -d $dirname;
++
++ if ($self-&gt;{_test}) {
++ *OUT = *STDOUT;
++ } else {
++ open(OUT, &quot;&gt;$file&quot;) or die &quot;Can't open file $file: $!&quot;;
++ }
++
++ print OUT $$content;
++
++ close(OUT) unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatHTMLpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,158 @@
++# $Id: Mail.pm 580 2006-01-11 22:59:36Z guillomovitch $
++package Youri::Check::Output::Mail::Format::HTML;
++
++=head1 NAME
++
++Youri::Check::Output::Mail::Format::HTML - Mail HTML format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::Mail&gt; provides HTML format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use CGI;
++use base 'Youri::Check::Output::Mail::Format';
++
++sub type {
++ return 'text/html';
++}
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ style =&gt; &lt;&lt;EOF, # css style
++h1 {
++ text-align:center;
++}
++table {
++ border-style:solid;
++ border-width:1px;
++ border-color:black;
++ width:100%;
++}
++tr.odd {
++ background-color:white;
++}
++tr.even {
++ background-color:silver;
++}
++p.footer {
++ font-size:smaller;
++ text-align:center;
++}
++EOF
++ @_
++ );
++
++ $self-&gt;{_style} = $options{style};
++ $self-&gt;{_cgi} = CGI-&gt;new();
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $body;
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my $line;
++ my @results;
++ $body .= $self-&gt;{_cgi}-&gt;start_table();
++ $body .= $self-&gt;{_cgi}-&gt;Tr([
++ $self-&gt;{_cgi}-&gt;th([
++ @$lead_columns,
++ @$columns
++ ])
++ ]);
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $body .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++ $body .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ $body .= $self-&gt;{_cgi}-&gt;end_table();
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;start_html(
++ -title =&gt; $title,
++ -style =&gt; { code =&gt; $self-&gt;{_style} }
++ );
++ $content .= $self-&gt;{_cgi}-&gt;h1($title);
++ $content .= $body;
++ $content .= $self-&gt;{_cgi}-&gt;hr();
++ $content .= $self-&gt;{_cgi}-&gt;p(
++ { class =&gt; 'footer' },
++ &quot;Page generated $time&quot;
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_html();
++
++ return \$content;
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $links, $class, $results) = @_;
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ for my $i (0 .. $#$results) {
++ $content .= $self-&gt;{_cgi}-&gt;start_Tr(
++ { class =&gt; $class }
++ );
++ if ($i == 0) {
++ # first line contains spanned cells
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ { rowspan =&gt; scalar @$results },
++ [
++ map { $results-&gt;[$i]-&gt;{$_} }
++ @$lead_columns
++ ]
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ [
++ map {
++ $links-&gt;{$_} &amp;&amp; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} ?
++ $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} },
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ ) :
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ } @$columns
++ ]
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ }
++
++ return $content;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatTextpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,83 @@
++# $Id: Mail.pm 580 2006-01-11 22:59:36Z guillomovitch $
++package Youri::Check::Output::Mail::Format::Text;
++
++=head1 NAME
++
++Youri::Check::Output::Mail::Format::Text - Mail text format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::Mail&gt; provides text format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Output::Mail::Format';
++
++sub type {
++ return 'text/plain';
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $content;
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my @results;
++ $content .= join(&quot;\t&quot;, @$lead_columns, @$columns) . &quot;\n&quot;;
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++
++ return \$content;
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $results) = @_;
++
++ my $content;
++ $content .= join(
++ &quot;\t&quot;,
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$lead_columns),
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ for my $i (1 .. $#$results) {
++ $content .= join(
++ &quot;\t&quot;,
++ (map { '' } @$lead_columns),
++ (map { $results-&gt;[$i]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ }
++ return $content;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,66 @@
++# $Id: Base.pm 579 2006-01-09 21:17:54Z guillomovitch $
++package Youri::Check::Output::Mail::Format;
++
++=head1 NAME
++
++Youri::Check::Output::Mail::Format - Abstract mail format support
++
++=head1 DESCRIPTION
++
++This abstract class defines the format support interface for
++L&lt;Youri::Check::Output::Mail&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '',
++ test =&gt; 0,
++ verbose =&gt; 0,
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_id()
++
++Returns format handler identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,156 @@
++# $Id: Mail.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output::Mail;
++
++=head1 NAME
++
++Youri::Check::Output::Mail - Report results by mail
++
++=head1 DESCRIPTION
++
++This plugin reports results by mail. Additional subplugins handle specific
++formats.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use MIME::Entity;
++use Youri::Utils;
++use base 'Youri::Check::Output';
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ from =&gt; '', # mail from header
++ to =&gt; '', # mail to header
++ reply_to =&gt; '', # mail reply-to header
++ mta =&gt; '', # mta path
++ noempty =&gt; 1, # don't generate empty reports
++ formats =&gt; {},
++ @_
++ );
++
++ croak &quot;no format defined&quot; unless $options{formats};
++ croak &quot;formats should be an hashref&quot; unless ref $options{formats} eq 'HASH';
++
++ $self-&gt;{_from} = $options{from};
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_reply_to} = $options{reply_to};
++ $self-&gt;{_mta} = $options{mta};
++ $self-&gt;{_noempty} = $options{noempty};
++
++ foreach my $id (keys %{$options{formats}}) {
++ print &quot;Creating format $id\n&quot; if $options{verbose};
++ eval {
++ push(
++ @{$self-&gt;{_formats}},
++ create_instance(
++ 'Youri::Check::Output::Mail::Format',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ %{$options{formats}-&gt;{$id}}
++ )
++ );
++ };
++ print STDERR &quot;Failed to create format $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no formats created&quot; unless @{$self-&gt;{_formats}};
++}
++
++sub _global_report {
++ my ($self, $resultset, $type, $columns, $links) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ]
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type global report&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ undef
++ );
++
++ $self-&gt;_send_mail(
++ $format-&gt;type(),
++ $self-&gt;{_to},
++ &quot;$type global report&quot;,
++ $content,
++ );
++ }
++}
++
++sub _individual_report {
++ my ($self, $resultset, $type, $columns, $links, $maintainer) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ],
++ { maintainer =&gt; [ $maintainer ] }
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type individual report for $maintainer&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ $maintainer
++ );
++
++ $self-&gt;_send_mail(
++ $format-&gt;type(),
++ $maintainer,
++ &quot;$type individual report for $maintainer&quot;,
++ $content,
++ );
++ }
++
++}
++
++sub _send_mail {
++ my ($self, $type, $to, $subject, $content) = @_;
++
++ return unless $content;
++
++ my $mail = MIME::Entity-&gt;build(
++ 'Type' =&gt; $type,
++ 'From' =&gt; $self-&gt;{_from},
++ 'Reply-To' =&gt; $self-&gt;{_reply_to},
++ 'To' =&gt; $to,
++ 'Subject' =&gt; $subject,
++ 'Data' =&gt; $$content
++ );
++
++ if ($self-&gt;{_test}) {
++ $mail-&gt;print(\*STDOUT);
++ } else {
++ open(MAIL, &quot;| $self-&gt;{_mta} -t -oi -oem&quot;) or die &quot;Can't open MTA program: $!&quot;;
++ $mail-&gt;print(\*MAIL);
++ close MAIL;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,190 @@
++# $Id: Output.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output;
++
++=head1 NAME
++
++Youri::Check::Output - Abstract output plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines output plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Output object.
++
++Generic parameters (subclasses may define additional ones):
++
++=over
++
++=item global true/false
++
++Global reports generation (default: true).
++
++=item individual true/false
++
++Individual reports generation (default: true).
++
++=back
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '',
++ test =&gt; 0,
++ verbose =&gt; 0,
++ global =&gt; 1,
++ individual =&gt; 1,
++ config =&gt; undef,
++ @_
++ );
++
++ croak &quot;Neither global nor individual reporting selected&quot; unless $options{global} || $options{individual};
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _global =&gt; $options{global},
++ _individual =&gt; $options{individual},
++ _config =&gt; $options{config}
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns plugin identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 run($resultset)
++
++Reports the result stored in given L&lt;Youri::Check::Resultset&gt; object.
++
++=cut
++
++sub run {
++ my ($self, $resultset) = @_;
++
++ $self-&gt;_init_report();
++
++ # get types and maintainers list from resultset
++ my @maintainers = $resultset-&gt;get_maintainers();
++ my @types = $resultset-&gt;get_types();
++
++ foreach my $type (@types) {
++ # get formatting instructions from class
++ my $class = $self-&gt;{_config}-&gt;get($type . '_class');
++ load($class);
++ my @columns = $class-&gt;columns();
++ my %links = $class-&gt;links();
++
++ if ($self-&gt;{_global}) {
++ print STDERR &quot;generating global report for $type\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;_global_report(
++ $resultset,
++ $type,
++ \@columns,
++ \%links
++ );
++ }
++
++ if ($self-&gt;{_individual}) {
++ foreach my $maintainer (@maintainers) {
++ print STDERR &quot;generating individual report for $type and $maintainer\n&quot; if $self-&gt;{_verbose};
++
++ $self-&gt;_individual_report(
++ $resultset,
++ $type,
++ \@columns,
++ \%links,
++ $maintainer
++ );
++ }
++ }
++ }
++
++ $self-&gt;_finish_report(\@types, \@maintainers);
++}
++
++sub _init_report {
++ # do nothing
++}
++
++sub _global_report {
++ # do nothing
++}
++
++sub _individual_report {
++ # do nothing
++}
++
++sub _finish_report {
++ # do nothing
++}
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item run
++
++As an alternative, the following hooks can be implemented:
++
++=over
++
++=item _init_report
++
++=item _global_report
++
++=item _individual_report
++
++=item _finish_report
++
++=back
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckResultsetDBIpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,372 @@
++# $Id: Result.pm 485 2005-08-01 21:48:21Z guillomovitch $
++package Youri::Check::Resultset::DBI;
++
++=head1 NAME
++
++Youri::Check::Resultset::DBI - DBI-based resultset
++
++=head1 DESCRIPTION
++
++This is a DBI-based L&lt;Youri::Check::Resultset&gt; implementation.
++
++It can be created with any DBI-supported database.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use DBI 1.38;
++use base 'Youri::Check::Resultset';
++
++my %tables = (
++ packages =&gt; {
++ id =&gt; 'SERIAL PRIMARY KEY',
++ package =&gt; 'TEXT',
++ media =&gt; 'TEXT',
++ maintainer =&gt; 'TEXT',
++ }
++);
++
++my %queries = (
++ add_package =&gt;
++ 'INSERT INTO packages (package, media, maintainer) VALUES (?, ?, ?)',
++ get_package_id =&gt;
++ 'SELECT id FROM packages WHERE package = ?',
++ get_maintainers =&gt;
++ 'SELECT DISTINCT(maintainer) FROM packages WHERE maintainer IS NOT NULL',
++);
++
++=head1 CLASS METHODS
++
++=head2 new(%hash)
++
++Creates and returns a new Youri::Check::Resultset::DBI object.
++
++Specific parameters:
++
++=over
++
++=item driver $driver
++
++Use given string as DBI driver.
++
++=item base $base
++
++Use given string as database name.
++
++=item port $port
++
++Use given string as database port.
++
++=item user $user
++
++Use given string as database user.
++
++=item pass $pass
++
++Use given string as database password.
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ driver =&gt; '', # driver
++ base =&gt; '', # base
++ port =&gt; '', # port
++ user =&gt; '', # user
++ pass =&gt; '', # pass
++ @_
++ );
++
++ croak &quot;No driver defined&quot; unless $options{driver};
++ croak &quot;No base defined&quot; unless $options{base};
++
++ my $datasource = &quot;DBI:$options{driver}:dbname=$options{base}&quot;;
++ $datasource .= &quot;;host=$options{host}&quot; if $options{host};
++ $datasource .= &quot;;port=$options{port}&quot; if $options{port};
++
++ $self-&gt;{_dbh} = DBI-&gt;connect($datasource, $options{user}, $options{pass}, {
++ RaiseError =&gt; 1,
++ PrintError =&gt; 0,
++ AutoCommit =&gt; 1
++ }) or croak &quot;Unable to connect: $DBI::errstr&quot;;
++
++ $self-&gt;{_dbh}-&gt;trace($options{verbose} - 1) if $options{verbose} &gt; 1;
++}
++
++sub clone {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $clone = bless {
++ _test =&gt; $self-&gt;{_test},
++ _verbose =&gt; $self-&gt;{_verbose},
++ _resolver =&gt; $self-&gt;{_resolver},
++ _dbh =&gt; $self-&gt;{_dbh}-&gt;clone()
++ }, ref $self;
++
++ return $clone;
++}
++
++sub reset {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ foreach my $table ($self-&gt;_get_tables()) {
++ my $query = &quot;DROP TABLE $table&quot;;
++ $self-&gt;{_dbh}-&gt;do($query);
++ }
++
++ foreach my $table (keys %tables) {
++ $self-&gt;_create_table($table, $tables{$table});
++ }
++}
++
++sub _get_tables {
++ my ($self) = @_;
++ my @tables = $self-&gt;{_dbh}-&gt;tables(undef, undef, '%', 'TABLE');
++ # unquote table name if needed
++ my $char = $self-&gt;{_dbh}-&gt;get_info(29);
++ @tables = map { substr($_, 1 , -1) } @tables if $char;
++ return @tables;
++}
++
++sub _get_columns {
++ my ($self, $table) = @_;
++ # proper way would be to use column_info(), but unfortunatly DBD::SQLite
++ # doesn't support it :(
++ return
++ keys
++ %{$self-&gt;{_dbh}-&gt;selectrow_hashref(&quot;SELECT * from $table&quot;)};
++}
++
++sub _create_table {
++ my ($self, $name, $fields) = @_;
++
++ my $query = &quot;CREATE TABLE $name (&quot; .
++ join(',',
++ map { &quot;$_ $fields-&gt;{$_}&quot; }
++ keys %$fields
++ ) .
++ &quot;)&quot;;
++ $self-&gt;{_dbh}-&gt;do($query);
++}
++
++sub add_result {
++ my ($self, $type, $media, $package, $values) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ croak &quot;No type defined&quot; unless $type;
++ croak &quot;No package defined&quot; unless $package;
++ croak &quot;No values defined&quot; unless $values;
++
++ my $key = &quot;add_$type&quot;;
++ my $sth = $self-&gt;{_sths}-&gt;{$key};
++
++ unless ($sth) {
++ my @fields = keys %$values;
++ $self-&gt;_create_table($type, {
++ 'package_id' =&gt; 'INT',
++ map { $_ =&gt; 'TEXT' } @fields
++ });
++ my $query = &quot;INSERT INTO $type (&quot; .
++ join(',', 'package_id', @fields) .
++ &quot;) VALUES (&quot; .
++ join(',', '?', map { '?' } @fields) .
++ &quot;)&quot;;
++ $sth = $self-&gt;{_dbh}-&gt;prepare($query);
++ $self-&gt;{_sths}-&gt;{$key} = $sth;
++ }
++
++ print &quot;adding result for type $type and package $package\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ $sth-&gt;execute(
++ $self-&gt;_get_package_id(
++ $package-&gt;get_canonical_name(),
++ $media-&gt;get_name(),
++ ),
++ values %$values
++ );
++}
++
++sub get_types {
++ my ($self) = @_;
++
++ return
++ grep { ! $tables{$_} }
++ $self-&gt;_get_tables();
++}
++
++sub get_maintainers {
++ my ($self) = @_;
++
++ return $self-&gt;_get_multiple_values('get_maintainers');
++}
++
++sub get_iterator {
++ my ($self, $id, $sort, $filter) = @_;
++
++ die 'No id given, aborting'
++ unless $id;
++ die 'sort should be an arrayref'
++ if $sort and ref $sort ne 'ARRAY';
++ die 'filter should be an hashref'
++ if $filter and ref $filter ne 'HASH';
++
++ my $query = $self-&gt;_get_iterator_query($id, $sort, $filter);
++
++ my $sth = $self-&gt;{_dbh}-&gt;prepare($query);
++ $sth-&gt;execute();
++
++ return Youri::Check::Resultset::DBI::Iterator-&gt;new($sth);
++}
++
++sub _get_iterator_query {
++ my ($self, $table, $sort, $filter) = @_;
++
++ my @fields =
++ grep { ! /package_id/ }
++ $self-&gt;_get_columns($table);
++
++ my $query = &quot;SELECT DISTINCT &quot; .
++ join(',', qw/package media maintainer/, @fields) .
++ &quot; FROM $table, packages&quot; .
++ &quot; WHERE packages.id = $table.package_id&quot;;
++
++ if ($filter) {
++ foreach my $column (keys %{$filter}) {
++ foreach my $value (@{$filter-&gt;{$column}}) {
++ $query .= &quot; AND $column = &quot; . $self-&gt;{_dbh}-&gt;quote($value);
++ }
++ }
++ }
++
++ if ($sort) {
++ $query .= &quot; ORDER BY &quot; . join(', ', @{$sort});
++ }
++
++ return $query;
++}
++
++sub _get_package_id {
++ my ($self, $package, $media) = @_;
++
++ my $id = $self-&gt;_get_single_value(
++ 'get_package_id',
++ $package
++ );
++ $id = $self-&gt;_add_package($package, $media) unless $id;
++
++ return $id;
++}
++
++sub _add_package {
++ my ($self, $package, $media) = @_;
++
++ my $maintainer = $self-&gt;{_resolver} ?
++ $self-&gt;{_resolver}-&gt;get_maintainer($package) :
++ undef;
++
++ my $sth =
++ $self-&gt;{_sths}-&gt;{add_package} ||=
++ $self-&gt;{_dbh}-&gt;prepare($queries{add_package});
++
++ $sth-&gt;execute(
++ $package,
++ $media,
++ $maintainer
++ );
++
++ my $id = $self-&gt;{_dbh}-&gt;last_insert_id(undef, undef, 'packages', 'id');
++
++ return $id;
++}
++
++sub _get_single_value {
++ my ($self, $query, @values) = @_;
++
++ my $sth =
++ $self-&gt;{_sths}-&gt;{$query} ||=
++ $self-&gt;{_dbh}-&gt;prepare($queries{$query});
++
++ $sth-&gt;execute(@values);
++
++ my @row = $sth-&gt;fetchrow_array();
++ return @row ? $row[0]: undef;
++}
++
++sub _get_multiple_values {
++ my ($self, $query, @values) = @_;
++
++ my $sth =
++ $self-&gt;{_sths}-&gt;{$query} ||=
++ $self-&gt;{_dbh}-&gt;prepare($queries{$query});
++
++ $sth-&gt;execute(@values);
++
++ my @results;
++ while (my @row = $sth-&gt;fetchrow_array()) {
++ push @results, $row[0];
++ }
++ return @results;
++}
++
++# close database connection
++sub DESTROY {
++ my ($self) = @_;
++
++ foreach my $sth (values %{$self-&gt;{_sths}}) {
++ $sth-&gt;finish() if $sth;
++ }
++
++ # warning, may be called before _dbh is created
++ $self-&gt;{_dbh}-&gt;disconnect() if $self-&gt;{_dbh};
++}
++
++package Youri::Check::Resultset::DBI::Iterator;
++
++sub new {
++ my ($class, $sth) = @_;
++
++ my $self = bless {
++ _sth =&gt; $sth,
++ _queue =&gt; []
++ }, $class;
++
++ return $self;
++}
++
++sub has_results {
++ my ($self) = @_;
++
++ return 1 if @{$self-&gt;{_queue}};
++
++ push(
++ @{$self-&gt;{_queue}},
++ $self-&gt;{_sth}-&gt;fetchrow_hashref()
++ );
++
++ return defined $self-&gt;{_queue}-&gt;[-1];
++}
++
++sub get_result {
++ my ($self) = @_;
++
++ return @{$self-&gt;{_queue}} ?
++ shift @{$self-&gt;{_queue}}:
++ $self-&gt;{_sth}-&gt;fetchrow_hashref();
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckResultsetIteratorpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,22 @@
++# $Id: Base.pm 483 2005-08-01 21:39:05Z guillomovitch $
++package Youri::Check::Resultset::Iterator;
++
++=head1 INSTANCE METHODS
++
++=head2 has_results()
++
++Returns true if results are available.
++
++=head2 get_result()
++
++Returns next available result, as an field =&gt; value hash reference.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckResultsetpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,116 @@
++# $Id: Base.pm 483 2005-08-01 21:39:05Z guillomovitch $
++package Youri::Check::Resultset;
++
++=head1 NAME
++
++Youri::Check::Resultset - Abstract resultset
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Check::Resultset interface
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Scalar::Util qw/blessed/;
++use Youri::Utils;
++
++=head1 CLASS METHODS
++
++=head2 new(%hash)
++
++Creates and returns a new Youri::Check::Resultset object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ my %options = (
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ resolver =&gt; undef, # maintainer resolver,
++ mode =&gt; 'output', # access mode
++ @_
++ );
++
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my $self = bless {
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _resolver =&gt; $options{resolver},
++ _mode =&gt; $options{mode}
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 set_resolver()
++
++Set L&lt;Youri::Check::Maintainer::Resolver&gt; object used to resolve package
++maintainers.
++
++=cut
++
++sub set_resolver {
++ my ($self, $resolver) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ croak &quot;resolver should be a Youri::Check::Maintainer::Resolver object&quot;
++ unless blessed $resolver &amp;&amp;
++ $resolver-&gt;isa(&quot;Youri::Check::Maintainer::Resolver&quot;);
++
++ $self-&gt;{_resolver} = $resolver;
++}
++
++=head2 clone()
++
++Clone resultset object.
++
++=head2 reset()
++
++Reset resultset object, by deleting all contained results.
++
++=head2 add_result($type, $media, $package, $values)
++
++Add given hash reference as a new result for given type and L&lt;Youri::Package&gt; object.
++
++=head2 get_maintainers()
++
++Returns the list of all maintainers with results.
++
++=head2 get_iterator($id, $sort, $filter)
++
++Returns a L&lt;Youri::Check::Resultset::Iterator&gt; object over results for given input it, with optional sort and filter directives.
++
++sort must be an arrayref of column names, such as [ 'package' ].
++
++filter must be a hashref of arrayref of acceptables values indexed by column names, such as { level =&gt; [ 'warning', 'error'] }.
++
++=head1 SUBCLASSING
++
++All instances methods have to be implemented.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriConfigpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Config.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Config.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Config.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,202 @@
++# $Id: Config.pm 1709 2006-10-16 16:33:43Z warly $
++package Youri::Config;
++
++=head1 NAME
++
++Youri::Application - Youri application handler
++
++=head1 SYNOPSIS
++
++ use Youri::Application;
++
++ my $app = Youri::Application-&gt;new(
++ options =&gt; {
++ help =&gt; '|h!'
++ },
++ directories =&gt; [ '/etc/youri', &quot;$ENV{HOME}/.youri&quot; ],
++ file =&gt; 'app.conf',
++ );
++
++ # get command line argument
++ my $foo = $app-&gt;get_arg('foo');
++
++ # get configuration file parameter
++ my $bar = $app-&gt;get_param('bar');
++
++=head1 DESCRIPTION
++
++This class handle configuration for all YOURI applications.
++
++The command line specification is used to manage arguments through
++Getopt::Long. Unless B&lt;--config&gt; argument is given, the list of directories is
++then scanned for a file with given name, and halt as soon as it find one. If no
++readable file is found, an exception is thrown. The file is then processed
++through YAML::AppConfig. If parsing fails, an exception is thrown.
++
++=head1 CONFIGURATION FILE FORMAT
++
++=head2 SHARED KEYS
++
++In addition to the application-specific optional or mandatory parameters, all
++YOURI applications support the following optional top-level parameters:
++
++=over
++
++=item B&lt;includes&gt;
++
++A list of additional configuration files.
++
++=item B&lt;foo&gt;
++
++An arbitrary variable, usable everywhere else in the file.
++
++=back
++
++=head2 PLUGIN DEFINITION
++
++All YOURI application heavily rely on plugins defined in their configuration
++files. A plugin definition is composed from the following parameters:
++
++=over
++
++=item B&lt;class&gt;
++
++The class of this plugin.
++
++=item B&lt;options&gt;
++
++The options of this plugin.
++
++=back
++
++=head1 SEE ALSO
++
++YAML::AppConfig, Getopt::Long
++
++=cut
++
++use strict;
++use warnings;
++use YAML::AppConfig;
++use Getopt::Long;
++use File::Spec;
++use Pod::Usage;
++use Carp;
++
++sub new {
++ my ($class, %options) = @_;
++
++
++ # command line arguments
++ my $args = {
++ verbose =&gt; 0
++ };
++ my @args;
++ if ($options{args}) {
++ while (my ($arg, $spec) = each %{$options{args}}) {
++ push(@args, ($arg . $spec) =&gt; \$args-&gt;{$arg});
++ }
++ }
++ push(@args,
++ 'config=s' =&gt; \$args-&gt;{config},
++ 'h|help' =&gt; \$args-&gt;{help},
++ 'v|verbose+' =&gt; \$args-&gt;{verbose}
++ );
++ GetOptions(@args);
++
++ if ($args-&gt;{help}) {
++ if (!@ARGV) {
++ # standard help, available immediatly
++ my $filename = (caller)[1];
++ pod2usage(
++ -input =&gt; $filename,
++ -verbose =&gt; 0
++ );
++ }
++ }
++
++ # config files parameters
++
++ # find configuration file to use
++ my $main_file;
++ if ($args-&gt;{config}) {
++ if (! -f $args-&gt;{config}) {
++ croak &quot;Non-existing file $args-&gt;{config}&quot;;
++ } elsif (! -r $args-&gt;{config}) {
++ croak &quot;Non-readable file $args-&gt;{config}&quot;;
++ } else {
++ $main_file = $args-&gt;{config};
++ }
++ } else {
++ foreach my $directory (@{$options{directories}}) {
++ my $file = &quot;$directory/$options{file}&quot;;
++ next unless -f $file &amp;&amp; -r $file;
++ $main_file = $file;
++ last;
++ }
++ croak 'No config file found, aborting' unless $main_file;
++ }
++
++ my $params;
++ eval {
++ $params = YAML::AppConfig-&gt;new(file =&gt; $main_file);
++ };
++ if ($@) {
++ croak &quot;Invalid configuration file $main_file, aborting&quot;;
++ }
++
++ # process inclusions
++ my $includes = $params-&gt;get('includes');
++ if ($includes) {
++ foreach my $include_file (@{$includes}) {
++ # convert relative path to absolute ones
++ $include_file = File::Spec-&gt;rel2abs(
++ $include_file, (File::Spec-&gt;splitpath($main_file))[1]
++ );
++
++ if (! -f $include_file) {
++ warn &quot;Non-existing file $include_file, skipping&quot;;
++ } elsif (! -r $include_file) {
++ warn &quot;Non-readable file $include_file, skipping&quot;;
++ } else {
++ eval {
++ $params-&gt;merge(file =&gt; $include_file);
++ };
++ if ($@) {
++ carp &quot;Invalid included configuration file $include_file, skipping&quot;;
++ }
++ }
++ }
++ }
++
++ my $self = bless {
++ _args =&gt; $args,
++ _params =&gt; $params
++ }, $class;
++
++ return $self;
++}
++
++sub get_arg {
++ my ($self, $arg) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_args}-&gt;{$arg};
++}
++
++sub get_param {
++ my ($self, $param) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_params}-&gt;get($param);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriMediaURPMpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,273 @@
++# $Id: URPM.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Media::URPM;
++
++=head1 NAME
++
++Youri::Media::URPM - URPM-based media implementation
++
++=head1 DESCRIPTION
++
++This is an URPM-based L&lt;Youri::Media&gt; implementation.
++
++It can be created either from local or remote full (hdlist) or partial
++(synthesis) compressed header files, or from a package directory. File-based
++inputs are only usable with this latest option.
++
++=cut
++
++use URPM;
++use File::Find;
++use File::Temp ();
++use Youri::Utils;
++use LWP::Simple;
++use Carp;
++use strict;
++use warnings;
++use Youri::Package::URPM;
++
++use base 'Youri::Media';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Media::URPM object.
++
++Specific parameters:
++
++=over
++
++=item synthesis $synthesis
++
++Path, URL or list of path or URL of synthesis file used for creating
++this media. If a list is given, the first successfully accessed will be used,
++so as to allow better reliability.
++
++=item hdlist $hdlist
++
++Path, URL or list of path or URL of hdlist file used for creating
++this media. If a list is given, the first successfully accessed will be used,
++so as to allow better reliability.
++
++=item path $path
++
++Path or list of pathes of package directory used for creating this
++media. If a list is given, the first successfully accessed will be used, so as
++to allow better reliability.
++
++=item max_age $age
++
++Maximum age of packages for this media.
++
++=item rpmlint_config $file
++
++rpmlint configuration file for this media.
++
++=back
++
++In case of multiple B&lt;synthesis&gt;, B&lt;hdlist&gt; and B&lt;path&gt; options given, they
++will be tried in this order, so as to minimize parsing time.
++
++=cut
++
++sub _init {
++ my $self = shift;
++
++ my %options = (
++ hdlist =&gt; '', # hdlist from which to create this media
++ synthesis =&gt; '', # synthesis from which to create this media
++ path =&gt; '', # directory from which to create this media
++ max_age =&gt; '', # maximum build age for packages
++ rpmlint_config =&gt; '', # rpmlint configuration for packages
++ @_
++ );
++
++ my $urpm = URPM-&gt;new();
++ SOURCE: {
++ if ($options{synthesis}) {
++ foreach my $file (
++ ref $options{synthesis} eq 'ARRAY' ?
++ @{$options{synthesis}} :
++ $options{synthesis}
++ ) {
++ print &quot;Attempting to retrieve synthesis $file\n&quot;
++ if $options{verbose};
++ my $synthesis = $self-&gt;_get_file($file);
++ if ($synthesis) {
++ $urpm-&gt;parse_synthesis($synthesis, keep_all_tags =&gt; 1);
++ last SOURCE;
++ }
++ }
++ }
++
++ if ($options{hdlist}) {
++ foreach my $file (
++ ref $options{hdlist} eq 'ARRAY' ?
++ @{$options{hdlist}} :
++ $options{hdlist}
++ ) {
++ print &quot;Attempting to retrieve hdlist $file\n&quot;
++ if $options{verbose};
++ my $hdlist = $self-&gt;_get_file($file);
++ if ($hdlist) {
++ $urpm-&gt;parse_hdlist($hdlist, keep_all_tags =&gt; 1);
++ last SOURCE;
++ }
++ }
++ }
++
++ if ($options{path}) {
++ foreach my $path (
++ ref $options{path} eq 'ARRAY' ?
++ @{$options{path}} :
++ $options{path}
++ ) {
++ print &quot;Attempting to scan directory $path\n&quot;
++ if $options{verbose};
++ unless (-d $path) {
++ carp &quot;non-existing directory $path&quot;;
++ next;
++ }
++ unless (-r $path) {
++ carp &quot;non-readable directory $path&quot;;
++ next;
++ }
++
++ my $parse = sub {
++ return unless -f $File::Find::name;
++ return unless -r $File::Find::name;
++ return unless /\.rpm$/;
++
++ $urpm-&gt;parse_rpm($File::Find::name, keep_all_tags =&gt; 1);
++ };
++
++ find($parse, $path);
++ last SOURCE;
++ }
++ }
++
++ croak &quot;no source specified&quot;;
++ }
++
++ $self-&gt;{_urpm} = $urpm;
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_max_age} = $options{max_age};
++ $self-&gt;{_rpmlint_config} = $options{rpmlint_config};
++
++ return $self;
++}
++
++sub _remove_all_archs {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $self-&gt;{_urpm}-&gt;{depslist} = [];
++}
++
++sub _remove_archs {
++ my ($self, $skip_archs) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $urpm = $self-&gt;{_urpm};
++ $urpm-&gt;{depslist} = [
++ grep { ! $skip_archs-&gt;{$_-&gt;arch()} } @{$urpm-&gt;{depslist}}
++ ];
++}
++
++=head1 INSTANCE METHODS
++
++=head2 max_age()
++
++Returns maximum age of packages for this media.
++
++=cut
++
++sub max_age {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_max_age};
++}
++
++=head2 rpmlint_config()
++
++Returns rpmlint configuration file for this media.
++
++=cut
++
++sub rpmlint_config {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_rpmlint_config};
++}
++
++sub get_package_class {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return &quot;Youri::Package::URPM&quot;;
++}
++
++sub traverse_files {
++ my ($self, $function) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $callback = sub {
++ return unless -f $File::Find::name;
++ return unless -r $File::Find::name;
++ return unless $_ =~ /\.rpm$/;
++
++ my $package = Youri::Package::URPM-&gt;new(file =&gt; $File::Find::name);
++ return if $self-&gt;{_skip_archs}-&gt;{$package-&gt;get_arch()};
++
++ $function-&gt;($File::Find::name, $package);
++ };
++
++ find($callback, $self-&gt;{_path});
++}
++
++sub traverse_headers {
++ my ($self, $function) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $self-&gt;{_urpm}-&gt;traverse(sub {
++ local $_; # workaround mysterious problem between URPM and AppConfig
++ $function-&gt;(Youri::Package::URPM-&gt;new(header =&gt; $_[0]));
++ });
++
++}
++
++sub _get_file {
++ my ($self, $file) = @_;
++
++ if ($file =~ /^(?:http|ftp):\/\/.*$/) {
++ my $tempfile = File::Temp-&gt;new();
++ my $status = getstore($file, $tempfile-&gt;filename());
++ unless (is_success($status)) {
++ carp &quot;invalid URL $file: $status&quot;;
++ return;
++ }
++ return $tempfile;
++ } else {
++ unless (-f $file) {
++ carp &quot;non-existing file $file&quot;;
++ return;
++ }
++ unless (-r $file) {
++ carp &quot;non-readable file $file&quot;;
++ return;
++ }
++ return $file;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriMediapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Media.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Media.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Media.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,311 @@
++# $Id: Media.pm 1710 2006-10-16 16:35:11Z warly $
++package Youri::Media;
++
++=head1 NAME
++
++Youri::Media - Abstract media class
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Media interface.
++
++=cut
++
++use Carp;
++use strict;
++use warnings;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Media object.
++
++Generic parameters:
++
++=over
++
++=item id $id
++
++Media id.
++
++=item name $name
++
++Media name.
++
++=item type $type (source/binary)
++
++Media type.
++
++=item test true/false
++
++Test mode (default: false).
++
++=item verbose true/false
++
++Verbose mode (default: false).
++
++=item allow_deps $media_ids
++
++list of ids of medias allowed to provide dependencies.
++
++=item skip_tests $test_ids
++
++list of ids of test plugins to skip.
++
++=item skip_archs $arches
++
++list of arches to skip.
++
++=back
++
++Subclass may define additional parameters.
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ name =&gt; '', # media name
++ canonical_name =&gt; '', # media canonical name
++ type =&gt; '', # media type
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ allow_deps =&gt; undef, # list of media ids from which deps are allowed
++ allow_srcs =&gt; undef, # list of media ids from which packages can be built
++ skip_tests =&gt; undef, # list of tests ids to skip
++ skip_archs =&gt; undef, # list of archs for which to skip tests
++ @_
++ );
++
++
++ croak &quot;No type given&quot; unless $options{type};
++ croak &quot;Wrong value for type: $options{type}&quot;
++ unless $options{type} =~ /^(?:binary|source)$/o;
++
++ # some options need to be arrays. Check it and convert to hashes
++ foreach my $option (qw(allow_deps allow_srcs skip_archs skip_tests)) {
++ next unless defined $options{$option};
++ croak &quot;$option should be an arrayref&quot; unless ref $options{$option} eq 'ARRAY';
++ $options{$option} = {
++ map { $_ =&gt; 1 } @{$options{$option}}
++ };
++ }
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _name =&gt; $options{name} || $options{id},
++ _type =&gt; $options{type},
++ _allow_deps =&gt; $options{allow_deps},
++ _allow_srcs =&gt; $options{allow_srcs},
++ _skip_archs =&gt; $options{skip_archs},
++ _skip_tests =&gt; $options{skip_tests},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ # remove unwanted archs
++ if ($options{skip_archs}-&gt;{all}) {
++ $self-&gt;_remove_all_archs()
++ } elsif ($options{skip_archs}) {
++ $self-&gt;_remove_archs($options{skip_archs});
++ }
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns media identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 get_name()
++
++Returns the name of this media.
++
++=cut
++
++sub get_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_name};
++}
++
++=head2 get_type()
++
++Returns the type of this media.
++
++=cut
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_type};
++}
++
++=head2 allow_deps()
++
++Returns the list of id of medias allowed to provide dependencies for this
++media.
++
++=cut
++
++sub allow_deps {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_allow_deps}};
++}
++
++=head2 allow_dep($media_id)
++
++Tells wether media with given id is allowed to provide dependencies for
++this media.
++
++=cut
++
++sub allow_dep {
++ my ($self, $dep) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_allow_deps}-&gt;{all} ||
++ $self-&gt;{_allow_deps}-&gt;{$dep};
++}
++
++=head2 allow_srcs()
++
++Returns the list medias where the source packages can be
++
++=cut
++
++sub allow_srcs {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_allow_srcs}};
++}
++
++=head2 allow_src($media_id)
++
++Tells wether media with given id is allowed to host sources dependencies for
++this media.
++
++=cut
++
++sub allow_src {
++ my ($self, $src) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_allow_srcs}-&gt;{all} || $self-&gt;{_allow_srcs}-&gt;{$src};
++}
++
++=head2 skip_archs()
++
++Returns the list of arch which are to be skipped for this media.
++
++=cut
++
++sub skip_archs {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_skip_archs}};
++}
++
++=head2 skip_arch($arch)
++
++Tells wether given arch is to be skipped for this media.
++
++=cut
++
++sub skip_arch {
++ my ($self, $arch) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_skip_archs}-&gt;{all} ||
++ $self-&gt;{_skip_archs}-&gt;{$arch};
++}
++
++=head2 skip_tests()
++
++Returns the list of id of test which are to be skipped for this media.
++
++=cut
++
++sub skip_tests {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_skip_tests}};
++}
++
++=head2 skip_test($test_id)
++
++Tells wether test with given id is to be skipped for this media.
++
++=cut
++
++sub skip_test {
++ my ($self, $test) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_skip_tests}-&gt;{all} ||
++ $self-&gt;{_skip_tests}-&gt;{$test};
++}
++
++=head2 get_package_class()
++
++Return package class for this media.
++
++=head2 traverse_files($function)
++
++Apply given function to all files of this media.
++
++=head2 traverse_headers($function)
++
++Apply given function to all headers of this media.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item traverse_headers
++
++=item traverse_files
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageRPMpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,58 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Package/URPM.pm 2257 2006-07-05T09:22:47.088572Z guillaume $
++package Youri::Package::RPM;
++
++=head1 NAME
++
++Youri::Package::RPM - Base class for all RPM-based package implementation
++
++=head1 DESCRIPTION
++
++This bases class factorize code between various RPM-based package
++implementation.
++
++=cut
++
++use strict;
++use warnings;
++use base 'Youri::Package';
++use Carp;
++
++sub get_pattern {
++ my ($class, $name, $version, $release, $arch) = @_;
++
++ return
++ ($name ? quotemeta($name) : '[\w-]+' ).
++ '-' .
++ ($version ? quotemeta($version) : '[^-]+' ).
++ '-' .
++ ($release ? quotemeta($release) : '[^-]+' ).
++ '\.' .
++ ($arch ? quotemeta($arch) : '\w+' ).
++ '\.rpm';
++}
++
++sub as_file {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_file};
++}
++
++sub is_debug {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name = $self-&gt;get_name();
++ my $group = $self-&gt;get_tag('group');
++
++ # debug packages' names must end in -debug, except kernel
++ if ($group =~ m,^Development/Debug$, &amp;&amp;
++ ($name =~ /-debug$/o || $name =~ /^kernel-.*-debug/o)) {
++ return 1;
++ }
++ else {
++ return 0;
++ }
++}
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageRPM4pm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,424 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Package/URPM.pm 2129 2006-06-23T09:41:01.599329Z guillomovitch $
++package Youri::Package::RPM4;
++
++=head1 NAME
++
++Youri::Package::RPM4 - URPM-based rpm package implementation
++
++=head1 DESCRIPTION
++
++This is an RPM4-based L&lt;Youri::Package&gt; implementation for rpm.
++
++=cut
++
++use strict;
++use warnings;
++use Carp;
++use RPM4;
++use RPM4::Header;
++use RPM4::Sign;
++use File::Spec;
++use Scalar::Util qw/refaddr/;
++use base 'Youri::Package::RPM';
++use overload
++ '&quot;&quot;' =&gt; 'as_string',
++ '0+' =&gt; '_to_number',
++ fallback =&gt; 1;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package::RPM4 object.
++
++Specific parameters:
++
++=over
++
++=item file $file
++
++Path of file to use for creating this package.
++
++=item header $header
++
++L&lt;RPM4::Header&gt; object to use for creating this package.
++
++=back
++
++=cut
++
++sub _init {
++ my ($self, %options) = @_;
++
++ my $header;
++ HEADER: {
++ if (exists $options{header}) {
++ croak &quot;undefined header&quot;
++ unless $options{header};
++ croak &quot;invalid header&quot;
++ unless $options{header}-&gt;isa('RPM4::Header');
++ $header = $options{header};
++ last HEADER;
++ }
++
++ if (exists $options{file}) {
++ croak &quot;undefined file&quot;
++ unless $options{file};
++ croak &quot;non-existing file $options{file}&quot;
++ unless -f $options{file};
++ croak &quot;non-readable file $options{file}&quot;
++ unless -r $options{file};
++ $header = RPM4::Header-&gt;new($options{file});
++ croak &quot;Can't get header from file $options{file}&quot; if (!$header);
++
++ last HEADER;
++ }
++
++ croak &quot;no way to extract header from arguments&quot;;
++ }
++
++ $self-&gt;{_header} = $header;
++ $self-&gt;{_file} = File::Spec-&gt;rel2abs($options{file});
++}
++
++sub compare_versions {
++ my ($class, $version1, $version2) = @_;
++
++ return RPM4::rpmvercmp($version1, $version2);
++}
++
++sub _depsense2flag {
++ my ($string) = @_;
++ my @flags = 0;
++ push(@flags, 'EQUAL') if ($string =~ /=/);
++ push(@flags, 'LESS') if ($string =~ /&lt;/);
++ push(@flags, 'GREATER') if ($string =~ /&gt;/);
++ return \@flags;
++}
++
++sub check_ranges_compatibility {
++ my ($class, $range1, $range2) = @_;
++ my @deps1 = split(/ /, $range1);
++ my @deps2 = split(/ /, $range2);
++ $deps1[1] = _depsense2flag($range1);
++ $deps2[1] = _depsense2flag($range2);
++ my $dep1 = RPM4::Header::Dependencies(
++ &quot;PROVIDENAME&quot;,
++ \@deps1,
++ );
++ my $dep2 = RPM4::Header::Dependencies(
++ &quot;PROVIDENAME&quot;,
++ \@deps2,
++ );
++
++ return $dep1-&gt;overlap($dep2);
++}
++
++sub get_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('name');
++}
++
++sub get_version {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('version');
++}
++
++sub get_release {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('release');
++}
++
++sub get_revision {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}');
++}
++
++sub get_file_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%{NAME}-%{VERSION}-%{RELEASE}.%|SOURCERPM?{%{ARCH}}:{src}|.rpm');
++}
++
++
++sub get_arch {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%|SOURCERPM?{%{ARCH}}:{src}|');
++}
++
++sub get_url {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('url');
++}
++
++sub get_summary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('summary');
++}
++
++sub get_description {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('description');
++}
++
++sub get_packager {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('packager');
++}
++
++sub is_source {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;issrc();
++}
++
++sub is_binary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return !$self-&gt;{_header}-&gt;issrc();
++}
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_header}-&gt;issrc() ?
++ &quot;source&quot; :
++ &quot;binary&quot;;
++}
++
++sub get_age {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('buildtime');
++}
++
++sub get_source_package {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('sourcerpm');
++}
++
++sub get_canonical_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $self-&gt;{_header}-&gt;sourcerpmname() =~ /^(\S+)-[^-]+-[^-]+\.src\.rpm$/;
++ return $1;
++}
++
++sub get_tag {
++ my ($self, $tag) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ #croak &quot;invalid tag $tag&quot; unless $self-&gt;{_header}-&gt;can($tag);
++ return $self-&gt;{_header}-&gt;tag($tag);
++}
++
++
++sub _get_dependencies {
++ my ($self, $deptype) = @_;
++ my $deps = $self-&gt;{_header}-&gt;dep($deptype);
++ my @deps_list;
++ if ($deps) {
++ $deps-&gt;init();
++ while ($deps-&gt;next() &gt;= 0) {
++ my @deps = $deps-&gt;info();
++ $deps[1] =~ m/^rpmlib\(/ and next; # skipping internal rpmlib dep
++ $deps[2] =~ s/^=$/==/; # rpm say foo = 1, not foo == 1, == come from URPM, which sucks
++ my $range = $deps[3] ? ($deps[2] . ' ' . $deps[3]) : undef;
++ push(@deps_list, [ $deps[1], $range ]);
++ }
++ }
++ @deps_list
++}
++
++sub get_requires {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('REQUIRENAME');
++}
++
++sub get_provides {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('PROVIDENAME');
++}
++
++sub get_obsoletes {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('OBSOLETENAME');
++}
++
++sub get_conflicts {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('CONFLICTNAME');
++}
++
++sub get_files {
++ my ($self) = @_;
++
++ my $files = $self-&gt;{_header}-&gt;files();
++ my @fileslist;
++ if ($files) {
++ $files-&gt;init();
++ while ($files-&gt;next() &gt;= 0) {
++ my $smode = $files-&gt;mode();
++ my $umode = 0;
++ foreach (0..15) { # converting unsigned to signed int :\
++ $umode |= $smode &amp; (1 &lt;&lt; $_);
++ }
++ push(@fileslist, [ $files-&gt;filename(), $umode, $files-&gt;md5() || '' ]);
++ }
++ }
++ @fileslist
++}
++
++sub get_gpg_key {
++ my ($self) = @_;
++
++ my $signature = $self-&gt;{_header}-&gt;queryformat('%{SIGGPG:pgpsig}');
++
++ return if $signature eq '(not a blob)';
++
++ my $key_id = (split(/\s+/, $signature))[-1];
++
++ return substr($key_id, 8);
++}
++
++sub get_information {
++ my ($self) = @_;
++
++ return $self-&gt;{_header}-&gt;queryformat(&lt;&lt;EOF);
++Name : %-27{NAME} Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|
++Version : %-27{VERSION} Vendor: %{VENDOR}
++Release : %-27{RELEASE} Build Date: %{BUILDTIME:date}
++Install Date: %|INSTALLTIME?{%-27{INSTALLTIME:date}}:{(not installed) }| Build Host: %{BUILDHOST}
++Group : %-27{GROUP} Source RPM: %{SOURCERPM}
++Size : %-27{SIZE}%|LICENSE?{ License: %{LICENSE}}|
++Signature : %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|
++%|PACKAGER?{Packager : %{PACKAGER}\n}|%|URL?{URL : %{URL}\n}|Summary : %{SUMMARY}
++Description :\n%{DESCRIPTION}
++EOF
++}
++
++sub get_changes {
++ my ($self) = @_;
++
++ my @names = $self-&gt;{_header}-&gt;tag('changelogname');
++ my @time = $self-&gt;{_header}-&gt;tag('changelogtime');
++ my @text = $self-&gt;{_header}-&gt;tag('changelogtext');
++
++ my @changes;
++ foreach my $i (0 .. $#names) {
++ $changes[$i] = [
++ $names[$i],
++ $time[$i],
++ $text[$i],
++ ];
++ }
++
++ return @changes;
++}
++
++sub get_last_change {
++ my ($self) = @_;
++
++ return [
++ ($self-&gt;{_header}-&gt;tag('changelogname'))[0],
++ ($self-&gt;{_header}-&gt;tag('changelogtime'))[0],
++ ($self-&gt;{_header}-&gt;tag('changelogtext'))[0],
++ ];
++}
++
++sub as_string {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;fullname();
++}
++
++sub as_formated_string {
++ my ($self, $format) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat($format);
++}
++
++sub _to_number {
++ return refaddr($_[0]);
++}
++
++sub compare {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;compare($package-&gt;{_header}) || 0;
++}
++
++sub satisfy_range {
++ my ($self, $range) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;check_range_compatibility($self-&gt;get_revision(), $range);
++}
++
++sub sign {
++ my ($self, $name, $path, $passphrase) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # check if parent directory is writable
++ my $parent = (File::Spec-&gt;splitpath($self-&gt;{_file}))[1];
++ croak &quot;Unsignable package, parent directory is read-only&quot;
++ unless -w $parent;
++
++ my $sign = RPM4::Sign-&gt;new(
++ name =&gt; $name,
++ path =&gt; $path,
++ );
++ $sign-&gt;{passphrase} = $passphrase;
++
++ $sign-&gt;rpmssign($self-&gt;{_file})
++}
++
++sub extract {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ system(&quot;rpm2cpio $self-&gt;{_file} | cpio -id &gt;/dev/null 2&gt;&amp;1&quot;);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageTestpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,151 @@
++# $Id: /local/youri/soft/core/trunk/lib/Youri/Package/URPM.pm 2133 2006-09-20T21:40:20.575763Z guillaume $
++package Youri::Package::Test;
++
++=head1 NAME
++
++Youri::Package::Test - Fake test package
++
++=head1 DESCRIPTION
++
++This is just a fake package object, intended for testing purposes.
++
++=cut
++
++use strict;
++use warnings;
++use Carp;
++use base 'Youri::Package::RPM';
++use overload
++ '&quot;&quot;' =&gt; 'as_string',
++ '0+' =&gt; '_to_number',
++ fallback =&gt; 1;
++
++our $AUTOLOAD;
++
++my @tags = qw/
++ name
++ version
++ release
++ filename
++ arch
++ url
++ summary
++ description
++ packager
++ buildtime
++ sourcerpm
++/;
++
++my %tags = map { $_ =&gt; 1 } @tags;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package::Test object.
++
++Specific parameters:
++
++=over
++
++=item tag $tag
++
++Use given value for given tag
++
++=back
++
++=cut
++
++sub _init {
++ my ($self, %options) = @_;
++
++ $self-&gt;{&quot;_$_&quot;} = $options{$_} foreach keys %options;
++}
++
++sub get_revision {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_epoch} ?
++ &quot;$self-&gt;{_epoch}:$self-&gt;{_version}-$self-&gt;{_release}&quot; :
++ &quot;$self-&gt;{_version}-$self-&gt;{_release}&quot;;
++}
++
++sub get_tag {
++ my ($self, $tag) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ croak &quot;invalid tag $tag&quot; unless $tags{$tag};
++ return $self-&gt;{'_' . $tag};
++}
++
++sub is_source {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_arch} eq 'src';
++}
++
++sub is_binary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_arch} ne 'src';
++}
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_arch} eq 'src' ?
++ &quot;source&quot; :
++ &quot;binary&quot;;
++}
++
++sub get_canonical_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ if ($self-&gt;{_arch} eq 'src') {
++ return $self-&gt;{_name};
++ } else {
++ if ($self-&gt;{_sourcerpm}) {
++ $self-&gt;{_sourcerpm} =~ /^(\S+)-[^-]+-[^-]+\.src\.rpm$/;
++ return $1;
++ } else {
++ return undef;
++ }
++ }
++}
++
++sub as_string {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_name} ? $self-&gt;{_name} : '' .
++ '-' .
++ $self-&gt;{_version} ? $self-&gt;{_version} : '' .
++ '-' .
++ $self-&gt;{_release} ? $self-&gt;{_release} : '';
++}
++
++sub _to_number {
++ return refaddr($_[0]);
++}
++
++sub AUTOLOAD {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $method = $AUTOLOAD;
++ $method =~ s/.*:://;
++ return if $method eq 'DESTROY';
++ croak &quot;invalid method&quot; unless $method =~ /^get_(\w+)$/;
++
++ my $tag = $1;
++ croak &quot;invalid tag $tag&quot; unless $tags{$tag};
++ return $self-&gt;{'_' . $tag};
++}
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageURPMpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,399 @@
++# $Id: URPM.pm 266577 2010-03-02 14:51:24Z bogdano $
++package Youri::Package::URPM;
++
++=head1 NAME
++
++Youri::Package::URPM - URPM-based rpm package implementation
++
++=head1 DESCRIPTION
++
++This is an URPM-based L&lt;Youri::Package&gt; implementation for rpm.
++
++It is merely a wrapper over URPM::Package class, with a more structured
++interface.
++
++=cut
++
++use strict;
++use warnings;
++use Carp;
++use URPM;
++use File::Spec;
++use Expect;
++use Scalar::Util qw/refaddr/;
++use base 'Youri::Package::RPM';
++use overload
++ '&quot;&quot;' =&gt; 'as_string',
++ '0+' =&gt; '_to_number',
++ fallback =&gt; 1;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package::URPM object.
++
++Specific parameters:
++
++=over
++
++=item file $file
++
++Path of file to use for creating this package.
++
++=item header $header
++
++L&lt;URPM::Package&gt; object to use for creating this package.
++
++=back
++
++=cut
++
++sub _init {
++ my ($self, %options) = @_;
++
++ my $header;
++ HEADER: {
++ if (exists $options{header}) {
++ croak &quot;undefined header&quot;
++ unless $options{header};
++ croak &quot;invalid header&quot;
++ unless $options{header}-&gt;isa('URPM::Package');
++ $header = $options{header};
++ last HEADER;
++ }
++
++ if (exists $options{file}) {
++ croak &quot;undefined file&quot;
++ unless $options{file};
++ croak &quot;non-existing file $options{file}&quot;
++ unless -f $options{file};
++ croak &quot;non-readable file $options{file}&quot;
++ unless -r $options{file};
++ my $urpm = URPM-&gt;new();
++ $urpm-&gt;parse_rpm($options{file}, keep_all_tags =&gt; 1);
++ $header = $urpm-&gt;{depslist}-&gt;[0];
++ croak &quot;non-rpm file $options{file}&quot; unless $header;
++ last HEADER;
++ }
++
++ croak &quot;no way to extract header from arguments&quot;;
++ }
++
++ $self-&gt;{_header} = $header;
++ $self-&gt;{_file} = File::Spec-&gt;rel2abs($options{file});
++}
++
++sub compare_versions {
++ my ($class, $version1, $version2) = @_;
++
++ return URPM::rpmvercmp($version1, $version2);
++}
++
++sub check_ranges_compatibility {
++ my ($class, $range1, $range2) = @_;
++
++ return URPM::ranges_overlap($range1, $range2);
++}
++
++sub get_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;name();
++}
++
++sub get_version {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;version();
++}
++
++sub get_release {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;release();
++}
++
++sub get_revision {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}');
++}
++
++sub get_file_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_file} || die &quot;_file is not defined in header-only objects!\n&quot;;
++}
++
++sub get_arch {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;arch();
++}
++
++sub get_url {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;url();
++}
++
++sub get_summary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;summary();
++}
++
++sub get_description {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;description();
++}
++
++sub get_packager {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;packager();
++}
++
++sub is_source {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;arch() eq 'src';
++}
++
++sub is_binary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;arch() ne 'src';
++}
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_header}-&gt;arch() eq 'src' ?
++ &quot;source&quot; :
++ &quot;binary&quot;;
++}
++
++sub get_age {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;buildtime();
++}
++
++sub get_source_package {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;sourcerpm();
++}
++
++sub get_canonical_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ if ($self-&gt;{_header}-&gt;arch() eq 'src') {
++ return $self-&gt;{_header}-&gt;name();
++ } else {
++ $self-&gt;{_header}-&gt;sourcerpm() =~ /^(\S+)-[^-]+-[^-]+\.src\.rpm$/;
++ return $1;
++ }
++}
++
++sub get_tag {
++ my ($self, $tag) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ croak &quot;invalid tag $tag&quot; unless $self-&gt;{_header}-&gt;can($tag);
++ return $self-&gt;{_header}-&gt;$tag();
++}
++
++sub get_requires {
++ my ($self) = @_;
++
++ return map {
++ $_ =~ /^([^[]+)(?:\[\*\])?(?:\[(.+)\])?$/;
++ [ $1, $2 ]
++ } $self-&gt;{_header}-&gt;requires();
++}
++
++sub get_provides {
++ my ($self) = @_;
++
++ return map {
++ $_ =~ /^([^[]+)(?:\[(.+)\])?$/;
++ [ $1, $2 &amp;&amp; $2 ne '*' ? $2 : undef ]
++ } $self-&gt;{_header}-&gt;provides();
++}
++
++sub get_obsoletes {
++ my ($self) = @_;
++
++ return map {
++ $_ =~ /^([^[]+)(?:\[(.+)\])?$/;
++ [ $1, $2 &amp;&amp; $2 ne '*' ? $2 : undef ]
++ } $self-&gt;{_header}-&gt;obsoletes();
++}
++
++sub get_conflicts {
++ my ($self) = @_;
++
++ return $self-&gt;{_header}-&gt;conflicts();
++}
++
++sub get_files {
++ my ($self) = @_;
++
++ my @modes = $self-&gt;{_header}-&gt;files_mode();
++ my @md5sums = $self-&gt;{_header}-&gt;files_md5sum();
++
++ return map {
++ [ $_, shift @modes, shift @md5sums ]
++ } $self-&gt;{_header}-&gt;files();
++}
++
++sub get_gpg_key {
++ my ($self) = @_;
++
++ my $signature = $self-&gt;{_header}-&gt;queryformat('%{SIGGPG:pgpsig}');
++
++ return if $signature eq '(not a blob)';
++
++ my $key_id = (split(/\s+/, $signature))[-1];
++
++ return substr($key_id, 8);
++}
++
++sub get_information {
++ my ($self) = @_;
++
++ return $self-&gt;{_header}-&gt;queryformat(&lt;&lt;EOF);
++Name : %-27{NAME} Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|
++Version : %-27{VERSION} Vendor: %{VENDOR}
++Release : %-27{RELEASE} Build Date: %{BUILDTIME:date}
++Install Date: %|INSTALLTIME?{%-27{INSTALLTIME:date}}:{(not installed) }| Build Host: %{BUILDHOST}
++Group : %-27{GROUP} Source RPM: %{SOURCERPM}
++Size : %-27{SIZE}%|LICENSE?{ License: %{LICENSE}}|
++Signature : %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|
++%|PACKAGER?{Packager : %{PACKAGER}\n}|%|URL?{URL : %{URL}\n}|Summary : %{SUMMARY}
++Description :\n%{DESCRIPTION}
++EOF
++}
++
++sub get_changes {
++ my ($self) = @_;
++
++ my @names = $self-&gt;{_header}-&gt;changelog_name();
++ my @time = $self-&gt;{_header}-&gt;changelog_time();
++ my @text = $self-&gt;{_header}-&gt;changelog_text();
++
++ my @changes;
++ foreach my $i (0 .. $#names) {
++ $changes[$i] = [
++ $names[$i],
++ $time[$i],
++ $text[$i],
++ ];
++ }
++
++ return @changes;
++}
++
++sub get_last_change {
++ my ($self) = @_;
++
++ return [
++ ($self-&gt;{_header}-&gt;changelog_name())[0],
++ ($self-&gt;{_header}-&gt;changelog_time())[0],
++ ($self-&gt;{_header}-&gt;changelog_text())[0],
++ ];
++}
++
++sub as_string {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;fullname();
++}
++
++sub as_formated_string {
++ my ($self, $format) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat($format);
++}
++
++sub _to_number {
++ return refaddr($_[0]);
++}
++
++sub compare {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;compare_pkg($package-&gt;{_header});
++}
++
++sub satisfy_range {
++ my ($self, $range) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;check_ranges_compatibility(&quot;== &quot; . $self-&gt;get_revision(), $range);
++}
++
++sub sign {
++ my ($self, $name, $path, $passphrase, $target) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # check if parent directory is writable
++ my $parent = (File::Spec-&gt;splitpath($self-&gt;{_file}))[1];
++ croak &quot;Unsignable package, parent directory is read-only&quot;
++ unless -w $parent;
++
++ # FIXME Will have to change that
++ # we sign with cooker key even fro 2007.0 because this is for testing section
++ return !system(&quot;sudo -H /root/bin/resign_cooker $self-&gt;{_file}&quot;);
++
++ my $command =
++ 'LC_ALL=C rpm --resign ' . $self-&gt;{_file} .
++ ' --define &quot;_gpg_name ' . $name . '&quot;' .
++ ' --define &quot;_gpg_path ' . $path . '&quot;';
++ my $expect = Expect-&gt;spawn($command) or die &quot;Couldn't spawn command $command: $!\n&quot;;
++ $expect-&gt;log_stdout(0);
++ $expect-&gt;expect(20, -re =&gt; 'Enter pass phrase:');
++ $expect-&gt;send(&quot;$passphrase\n&quot;);
++
++ $expect-&gt;soft_close();
++}
++
++sub extract {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ system(&quot;rpm2cpio $self-&gt;{_file} | cpio -id &gt;/dev/null 2&gt;&amp;1&quot;);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackagepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,336 @@
++# $Id: Package.pm 223952 2007-06-23 13:54:13Z pixel $
++package Youri::Package;
++
++=head1 NAME
++
++Youri::Package - Abstract package class
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Package interface.
++
++=cut
++
++use Carp;
++use strict;
++use warnings;
++
++use constant DEPENDENCY_NAME =&gt; 0;
++use constant DEPENDENCY_RANGE =&gt; 1;
++
++use constant FILE_NAME =&gt; 0;
++use constant FILE_MODE =&gt; 1;
++use constant FILE_MD5SUM =&gt; 2;
++
++use constant CHANGE_AUTHOR =&gt; 0;
++use constant CHANGE_TIME =&gt; 1;
++use constant CHANGE_TEXT =&gt; 2;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package object.
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ @_
++ );
++
++ my $self = bless {
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_pattern($name, $version, $release, $arch)
++
++Returns a pattern matching a file for a package, using available informations.
++
++=head2 compare_revisions($revision1, $revision2)
++
++Compares two revision tokens, and returns a numeric value:
++
++=over
++
++=item positive if first revision is higher
++
++=item null if both revisions are equal
++
++=item negative if first revision is lower
++
++=back
++
++=head2 check_ranges_compatibility($range1, $range2)
++
++Returns a true value if given revision ranges are compatible.
++
++=head1 INSTANCE METHODS
++
++=head2 as_file()
++
++Returns the file corresponding to this package.
++
++=head2 as_string()
++
++Returns a string representation of this package.
++
++=head2 as_formated_string(I&lt;format&gt;)
++
++Returns a string representation of this package, formated according to
++I&lt;format&gt;. Format is a string, where each %{foo} token will get replaced by
++equivalent tag value.
++
++=head2 get_name()
++
++Returns the name of this package.
++
++=head2 get_version()
++
++Returns the version of this package.
++
++=head2 get_release()
++
++Returns the release of this package.
++
++=head2 get_revision()
++
++Returns the revision of this package.
++
++=head2 get_arch()
++
++Returns the architecture of this package.
++
++=head2 get_file_name()
++
++Returns the file name of this package (name-version-release.arch.extension).
++
++=head2 is_source()
++
++Returns true if this package is a source package.
++
++=head2 is_binary()
++
++Returns true if this package is a binary package.
++
++=head2 is_debug()
++
++Returns true if this package is a debug package.
++
++=head2 get_type()
++
++Returns the type (binary/source) of this package.
++
++=head2 get_age()
++
++Returns the age of this package
++
++=head2 get_url()
++
++Returns the URL of this package
++
++=head2 get_summary()
++
++Returns the summary of this package
++
++=head2 get_description()
++
++Returns the description of this package
++
++=head2 get_packager()
++
++Returns the packager of this package.
++
++=head2 get_source_package()
++
++Returns the name of the source package of this package.
++
++=head2 get_tag($tag)
++
++Returns the value of tag $tag of this package.
++
++=head2 get_canonical_name()
++
++Returns the canonical name of this package, shared by its multiple components,
++usually the one from the source package.
++
++=head2 get_requires()
++
++Returns the list of dependencies required by this package, each dependency
++being represented as an array reference, with the following informations:
++
++=over
++
++=item B&lt;name&gt;
++
++Name of the dependency (index DEPENDENCY_NAME)
++
++=item B&lt;range&gt;
++
++Range of the dependency (index DEPENDENCY_RANGE)
++
++=back
++
++For more conveniency, fields index are available as constant in this package.
++
++=head2 get_provides()
++
++Returns the list of dependencies provided by this package, each dependency
++being represented as an array reference, using the same structure as previous method.
++
++=head2 get_obsoletes()
++
++Returns the list of other packages obsoleted by this one, each one
++being represented as an array reference, using the same structure as previous method.
++
++=head2 get_conflicts()
++
++Returns the list of other packages conflicting with this one.
++
++=head2 get_files()
++
++Returns the list of files contained in this package, each file being
++represented as an array reference, with the following informations:
++
++=over
++
++=item B&lt;name&gt;
++
++Name of the file (index FILE_NAME).
++
++=item B&lt;mode&gt;
++
++Mode of the file (index FILE_MODE).
++
++=item B&lt;md5sum&gt;
++
++Md5sum of the file (index FILE_MD5SUM).
++
++=back
++
++For more conveniency, fields index are available as constant in this package.
++
++=head2 get_gpg_key()
++
++Returns the gpg key id of package signature.
++
++=head2 get_information()
++
++Returns formated informations about the package.
++
++=head2 get_changes()
++
++Returns the list of changes for this package, each change being
++represented as an array reference, with the following informations:
++
++=over
++
++=item B&lt;author&gt;
++
++Author of the change (index CHANGE_AUTHOR).
++
++=item B&lt;time&gt;
++
++Time of the change (index CHANGE_TIME).
++
++=item B&lt;text&gt;
++
++Raw textual description of the change (index CHANGE_TEXT).
++
++=back
++
++For more conveniency, fields index are available as constant in this package.
++
++=head2 get_last_change()
++
++Returns the last change for this package, as as structure described before.
++
++=head2 compare($package)
++
++Compares ordering with other package, according to their corresponding revision
++tokens, and returns a numeric value:
++
++=over
++
++=item positive if this package is newer
++
++=item null if both have same revision
++
++=item negative if this package is older
++
++=back
++
++=head2 satisfy_range($range)
++
++Returns a true value if this package revision satisfies given revision range.
++
++=head2 sign($name, $path, $passphrase)
++
++Signs the package with given name, keyring path and passphrase.
++
++=head2 extract()
++
++Extract package content in local directory.
++
++=head1 SUBCLASSING
++
++All instances methods have to be implemented.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++sub get_file {
++ my ($self) = @_;
++ carp &quot;Deprecated method, use as_file now&quot;;
++
++ return $self-&gt;as_file();
++}
++
++sub get_full_name {
++ my ($self) = @_;
++ carp &quot;Deprecated method, use as_string now&quot;;
++
++ return $self-&gt;as_string();
++}
++
++sub compare_versions {
++ my ($self, $version1, $version2) = @_;
++ carp &quot;Deprecated method, use compare_revisions now&quot;;
++
++ return $self-&gt;compare_revisions($version1, $version2);
++}
++
++sub compare_ranges {
++ my ($self, $range1, $range2) = @_;
++ carp &quot;Deprecated method, use are_range_compatible now&quot;;
++
++ return $self-&gt;check_ranges_compatibility($range1, $range2);
++}
++
++sub get_revision_name {
++ my ($self) = @_;
++ carp &quot;Deprecated method, use as_formated_string('%name-%version-%release') now&quot;;
++
++ return $self-&gt;as_formated_string('%{name}-%{version}-%{release}');
++}
++
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositoryMandriva_uploadpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,546 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Upload/Action/RSS.pm 857 2006-01-29T10:15:43.298856Z guillaume $
++package Youri::Repository::Mandriva_upload;
++
++=head1 NAME
++
++Youri::Repository::PLF - PLF repository implementation
++
++=head1 DESCRIPTION
++
++This module implements PLF repository.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use File::Find 'find';
++use base qw/Youri::Repository/;
++use MDV::Distribconf::Build;
++use SVN::Client;
++
++use constant {
++ PACKAGE_CLASS =&gt; 'Youri::Package::URPM',
++ PACKAGE_CHARSET =&gt; 'utf8'
++};
++
++memoize('_get_media_config');
++
++my %translate_arch = (
++ i386 =&gt; 'i586',
++ sparc64 =&gt; 'sparcv9',
++);
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ noarch =&gt; 'i586', # noarch packages policy
++ src =&gt; 'i586',
++ install_root =&gt; '',
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ queue =&gt; '',
++ rejected =&gt; '',
++ @_
++ );
++ foreach my $var ('upload_state') {
++ $self-&gt;{&quot;_$var&quot;} = [];
++ foreach my $value (split ' ', $options{$var}) {
++ push @{$self-&gt;{&quot;_$var&quot;}}, $value
++ }
++ }
++ print &quot;Initializing repository\n&quot;;
++ foreach my $v ('rejected', 'svn', 'queue', 'noarch', 'install_root', 'upload_root', 'verbose') {
++ $self-&gt;{&quot;_$v&quot;} = $options{$v}
++ }
++ foreach my $target (@{$options{targets}}) {
++ $self-&gt;{$target} = [];
++ print &quot;Adding $target ($options{$target}{arch})\n&quot; if $self-&gt;{_verbose};
++ foreach my $value (split ' ', $options{$target}{arch}) {
++ push @{$self-&gt;{_arch}{$target}}, $value;
++ push @{$self-&gt;{_extra_arches}}, $value
++ }
++ }
++ $self
++}
++
++sub get_group_id {
++ my ($user) = @_;
++ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
++ $year+=1900;
++ $mon++;
++ my $hostname = `hostname`;
++ my ($host) = $hostname =~ /([^.]*)/;
++ sprintf &quot;$year%02d%02d%02d%02d%02d.$user.$host.${$}_&quot;, $mon, $mday, $hour, $min, $sec;
++}
++
++sub get_target_arch {
++ my ($self, $target) = $_;
++ return $self-&gt;{_arch}{$target}
++}
++
++sub set_arch_changed {
++ my ($self, $target, $arch) = @_;
++ if ($arch eq 'noarch') {
++ $self-&gt;{_arch_changed}{$_} = 1 foreach @{$self-&gt;{_arch}{$target}}
++ } elsif ($arch eq 'src') {
++ $self-&gt;{_arch_changed} = $self-&gt;{_src}
++ } else {
++ $self-&gt;{_arch_changed}{$arch} = 1
++ }
++}
++
++sub get_arch_changed {
++ my ($self, $target) = @_;
++ return [ keys %{$self-&gt;{_arch_changed}} ]
++}
++
++sub set_install_dir_changed {
++ my ($self, $install_dir) = @_;
++ $self-&gt;{_install_dir_changed}{$install_dir} = 1;
++}
++
++sub get_install_dir_changed {
++ my ($self) = @_;
++ return [ keys %{$self-&gt;{_install_dir_changed}} ];
++}
++
++sub _get_media_config {
++ my ($self, $target) = @_;
++ my %media;
++ my $real_target = $target;
++ $real_target =~ s/_force//;
++ foreach my $arch (@{$self-&gt;{_arch}{$target}}) {
++ my $root = &quot;$self-&gt;{_install_root}/$real_target/$arch&quot;;
++ my $distrib = MDV::Distribconf::Build-&gt;new($root);
++ print &quot;Getting media config from $root\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;{distrib}{$arch} = $distrib;
++ $distrib-&gt;loadtree or die &quot;$root does not seem to be a distribution tree\n&quot;;
++ $distrib-&gt;parse_mediacfg;
++ foreach my $media ($distrib-&gt;listmedia) {
++ my $rpms = $distrib-&gt;getvalue($media, 'rpms');
++ my $debug_for = $distrib-&gt;getvalue($media, 'debug_for');
++ my $srpms = $distrib-&gt;getvalue($media, 'srpms');
++ my $path = $distrib-&gt;getfullpath($media, 'path');
++ if (!$rpms) {
++ if (-d $path) {
++ print &quot;MEDIA defining $media in $path\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ $media{$arch}{$media} = $path
++ } else {
++ print &quot;ERROR $path does not exist for media $media on $arch\n&quot;
++ }
++ } else {
++ my ($media) = split ' ', $rpms;
++ if (-d $path) {
++ print &quot;MEDIA defining SOURCE media for $media in $path\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ $media{src}{$media} = $path
++ } else {
++ print &quot;ERROR $path does not exist for source media $media on $arch\n&quot;
++ }
++ }
++ }
++ }
++ \%media
++}
++
++sub get_package_class {
++ return PACKAGE_CLASS;
++}
++
++sub get_package_charset {
++ return PACKAGE_CHARSET;
++}
++
++sub get_upload_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ return
++ $self-&gt;{_upload_root} .
++ &quot;/$self-&gt;{_queue}/$target/&quot; .
++ _get_section($self, $package, $target, $user_context, $app_context) .
++ '/' .
++ ($user_context-&gt;{prefix} ? '' : get_group_id($user_context-&gt;{user}))
++}
++
++sub get_install_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ return $self-&gt;_get_path($package, $target, $user_context, $app_context);
++}
++
++
++sub get_distribution_paths {
++ my ($self, $package, $target) = @_;
++
++ return $self-&gt;_get_distribution_paths($package, $target);
++}
++
++sub get_archive_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ return $self-&gt;_get_path($package, $target, $user_context, $app_context);
++}
++
++sub get_reject_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ return $self-&gt;{_rejected};
++}
++
++
++sub _get_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++ my $arch = $app_context-&gt;{arch} || $package-&gt;get_arch();
++ $arch = $translate_arch{$arch} || $arch;
++ if ($arch eq 'noarch') {
++ $arch = $self-&gt;{_noarch}
++ } elsif ($arch eq 'src') {
++ return &quot;$target/SRPMS/$section&quot;
++ }
++ &quot;$target/$arch/media/$section&quot;
++}
++
++sub _get_distribution_paths {
++ my ($self, $package, $target) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ $arch = $translate_arch{$arch} || $arch;
++ if ($arch eq 'noarch') {
++ map { &quot;$target/$_&quot; } $self-&gt;get_extra_arches;
++ } elsif ($arch eq 'src') {
++ die &quot;no way to get distribution path using a $arch package&quot;;
++ } else {
++ &quot;$target/$arch&quot;;
++ }
++}
++
++sub get_arch {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ my $arch = $package-&gt;get_arch();
++ $arch = $translate_arch{$arch} || $arch;
++ if ($arch eq 'noarch') {
++ $arch = $self-&gt;{_noarch}
++ }
++ $arch
++}
++
++sub get_version_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++
++ return &quot;$self-&gt;{_module}/$section&quot;;
++}
++
++=head2 get_replaced_packages($package, $target, $user_context, $app_context)
++
++Overrides parent method to add libified packages.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @replaced_packages =
++ $self-&gt;SUPER::get_replaced_packages($package, $target, $user_context, $app_context);
++
++ # mandriva lib policy:
++ # library package names change with revision, making mandatory to
++ # duplicate older revisions search with a custom pattern
++ my $name = $package-&gt;get_name();
++ if ($name =~ /^(lib\w+[a-zA-Z_])[\d_\.]+([-\w]*)$/) {
++ push(@replaced_packages,
++ grep { $package-&gt;compare($_) &gt; 0 }
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $user_context, $app_context),
++ PACKAGE_CLASS-&gt;get_pattern(
++ $1 . '[\d_\.]+' . $2, # custom name pattern
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ # kernel packages have the version in the name
++ # binary dkms built for old kernels have to be removed too
++ if ($name =~ /^kernel-([^\d]*-)?([\d.]*)-(.*)$/) { # &quot;desktop&quot;, &quot;2.6.28&quot;, &quot;2mnb&quot;
++ push(@replaced_packages,
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $user_context, $app_context),
++ PACKAGE_CLASS-&gt;get_pattern(
++ '(kernel-' . $1 . '\d.*|.*-kernel-[\d.]*-' . $1 . '\d.*)',
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ return @replaced_packages;
++
++}
++
++sub _get_main_section {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++ my ($main_section) = $section =~ m,^([^/]+),;
++ $main_section
++}
++
++sub _get_section {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $name = $package-&gt;get_name();
++ my $cname = $package-&gt;get_canonical_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++ my $section = $user_context-&gt;{section};
++ my $media = $self-&gt;_get_media_config($target);
++ my $arch = $package-&gt;get_arch();
++ my $file = $package-&gt;as_file();
++ $file =~ s,/+,/,g; # unneeded?
++ # FIXME: use $self-&gt;get_arch()
++ $arch = $self-&gt;{_noarch} if $arch eq 'noarch';
++ $arch = $translate_arch{$arch} || $arch;
++
++ if (!$section) {
++ $section = $self-&gt;{packages}{$file}{section};
++ print &quot;Section undefined, repository says it is '$section' for '$file'\n&quot; if $self-&gt;{_verbose};
++ }
++ if ($section &amp;&amp; $section !~ /debug_/ &amp;&amp; $package-&gt;is_debug()) {
++ $section = &quot;debug_$section&quot;
++ }
++
++ # if have section already, check if it exists, and may return immediately
++ if ($section) {
++ print &quot;Using requested section $section\n&quot;;
++ if ($media-&gt;{$arch}{$section}) {
++ return $section
++ } else {
++ die &quot;FATAL youri: unknown section $section for target $target for arch $arch\n&quot;
++ }
++ }
++ # else, try to find section automatically
++
++ # pattern for search of src package with specific version-release,
++ # should be searched first, because we prefer to find the precise
++ # section a package is already in
++ my $specific_source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $cname,
++ $version,
++ $release,
++ 'src'
++ );
++
++ my $source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $cname,
++ undef,
++ undef,
++ 'src'
++ );
++
++ # if a media has no source media configured, or if it is a debug
++ # package, we search in binary media
++
++ # pattern for search when a binary media has no src media configured
++ my $specific_binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $name,
++ $version,
++ $release,
++ $arch
++ );
++
++ # last resort pattern: previous existing binary packages
++ my $binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $name,
++ undef,
++ undef,
++ $arch
++ );
++
++ # first try to find section for the specific version, as it is possibly already there;
++ # this is the case for when called in Youri::Submit::Action::Archive, to find the
++ # section the package got installed
++ print &quot;Looking for package $name with version $version-$release\n&quot;;
++ foreach my $m (keys %{$media-&gt;{$arch}}) {
++ print &quot; .. section '$m' path '&quot;.$media-&gt;{$arch}{$m}.&quot;'\n&quot; if $self-&gt;{_verbose};
++ # - prefer source for non-debug packages, use binary if there is no source media configured
++ # - debug packages must be searched in binary medias, due to their
++ # src section != binary section; NOTE: should/need we search in
++ # src medias and add the 'debug_' prefix?
++ if (!$package-&gt;is_debug() &amp;&amp; $media-&gt;{src}{$m}) {
++ next unless $self-&gt;get_files('', $media-&gt;{src}{$m}, $specific_source_pattern);
++ } else {
++ next unless $self-&gt;get_files('', $media-&gt;{$arch}{$m}, $specific_binary_pattern);
++ }
++ $section = $m;
++ last;
++ }
++
++ # if still not found, try finding any version of the package in a
++ # /release subsection (safe default: /release is default for cooker,
++ # should be locked for released distros, and we don't risk wrongly
++ # choosing /backports, /testing, or /updates);
++ # this is the case for when called at submit, to find the section where
++ # the package already resides
++ if (!$section) {
++ # debug packages should be found by previous specific version search
++ # NOTE: as above, should/need we search here and add the 'debug_' prefix?
++ # ... probably... as at least mdv-youri-submit-force will process debug packages
++ if ($package-&gt;is_debug() &amp;&amp; $self-&gt;{_verbose}) {
++ print &quot;Warning: debug package $name with version $version-$release not found.\n&quot;;
++ }
++
++ print &quot;Warning: Looking for any section with a package $name of any version\n&quot;;
++ foreach my $m (keys %{$media-&gt;{$arch}}) {
++ print &quot; .. section '$m' path '&quot;.$media-&gt;{$arch}{$m}.&quot;'\n&quot; if $self-&gt;{_verbose};
++ # NOTE: !$package-&gt;is_debug() test is here to prevent when above FATAL error is removed
++ next if $m !~ /release/ || ($m =~ /debug/ &amp;&amp; !$package-&gt;is_debug());
++ # - prefer source
++ if ($media-&gt;{src}{$m}) {
++ next unless $self-&gt;get_files('', $media-&gt;{src}{$m}, $source_pattern);
++ } else {
++ next unless $self-&gt;get_files('', $media-&gt;{$arch}{$m}, $binary_pattern);
++ }
++ $section = $m;
++ last;
++ }
++ }
++
++ # FIXME: doing this here is wrong; this way the caller can never know if
++ # a section was actually found or not; should return undef and let the
++ # caller set a default (Note: IIRC PLF|Zarb has this right, see there) -spuk
++ print STDERR &quot;Warning: Can't guess destination: section missing, defaulting to contrib/release\n&quot; unless $section;
++ $section ||= 'contrib/release';
++
++ # next time we don't need to search everything again
++ $self-&gt;{packages}{$file}{section} = $section;
++
++ print &quot;Section is '$section'.\n&quot;;
++
++ return $section;
++}
++
++sub get_upload_newer_revisions {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_full_name;
++ $name =~ s/^\@\d+://;
++ my $pattern = $self-&gt;get_package_class()-&gt;get_pattern($package-&gt;get_name(), undef, undef, $arch);
++ my $media = $self-&gt;_get_media_config($target);
++ my @packages;
++ foreach my $state (@{$self-&gt;{_upload_state}}) {
++ foreach my $m (keys %{$media-&gt;{$arch}}) {
++ my $path = &quot;$self-&gt;{_upload_root}/$state/$target/$m&quot;;
++ print &quot;Looking for package $package revisions for $target in $path (pattern $pattern)\n&quot; if $self-&gt;{_verbose};
++ find(
++ sub {
++ s/\d{14}\.[^.]*\.[^.]*\.\d+_//;
++ s/^\@\d+://;
++ return if ! /^$pattern/;
++ return if /\.info$/;
++ print &quot;Find $_\n&quot;;
++ push @packages, $File::Find::name if $package-&gt;check_ranges_compatibility(&quot;== $name&quot;, &quot;&lt; $_&quot;)
++ }, $path);
++ }
++ }
++ return
++ @packages;
++}
++
++sub package_in_svn {
++ my ($self, $srpm_name) = @_;
++ my $ctx = new SVN::Client(
++ auth =&gt; [SVN::Client::get_simple_provider(),
++ SVN::Client::get_simple_prompt_provider(\&amp;simple_prompt,2),
++ SVN::Client::get_username_provider()]
++ );
++
++ my $svn_entry = $ctx-&gt;ls(&quot;$self-&gt;{_svn}/$srpm_name&quot;, 'HEAD', 0);
++ if ($svn_entry) {
++ print &quot;Package $srpm_name is in the SVN\n&quot;;
++ return 1
++ }
++}
++
++sub get_svn_url {
++ my ($self) = @_;
++ $self-&gt;{_svn}
++}
++
++sub get_revisions {
++ my ($self, $package, $target, $user_context, $app_context, $filter) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package revisions for $target\n&quot; if $self-&gt;{_verbose} &gt; 0;
++
++ my $arch = $app_context-&gt;{arch} || $user_context-&gt;{arch} || $package-&gt;get_arch();
++ my $media_arch = $arch eq 'noarch' ? $self-&gt;{_noarch} : $arch;
++ my $path = $arch eq 'src' ? &quot;$target/SRPMS/&quot; : &quot;$target/$media_arch/media&quot;;
++ my $media = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++ my $name = $package-&gt;get_name();
++ my @packages = map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$path/$media&quot;,
++ $self-&gt;get_package_class()-&gt;get_pattern(
++ $name,
++ undef,
++ undef,
++ $package-&gt;get_arch(),
++ )
++ );
++
++ @packages = grep { $filter-&gt;($_) } @packages if $filter;
++
++ return
++ sort { $b-&gt;compare($a) } # sort by revision order
++ @packages;
++}
++
++sub reject {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++
++}
++
++sub get_archive_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_archive_root}
++}
++
++
++# 20060801 warly
++#
++# Upload steps
++# SRPMS are uploaded in /home/mandrake/uploads/todo/$target/$media/group_id
++#
++#
++#
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositoryMandriva_upload_prepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,274 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Upload/Action/RSS.pm 857 2006-01-29T10:15:43.298856Z guillaume $
++package Youri::Repository::Mandriva_upload_pre;
++
++=head1 NAME
++
++Youri::Repository::PLF - PLF repository implementation
++
++=head1 DESCRIPTION
++
++This module implements PLF repository.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use File::Find 'find';
++use base qw/Youri::Repository/;
++use SVN::Client;
++use constant {
++ PACKAGE_CLASS =&gt; 'Youri::Package::URPM',
++ PACKAGE_CHARSET =&gt; 'utf8'
++};
++
++memoize('_get_section');
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ module =&gt; 'SPECS', # CVS module
++ noarch =&gt; 'i586', # noarch packages policy
++ svn =&gt; '',
++ upload_root =&gt; '',
++ @_
++ );
++
++ $self-&gt;{_module} = $options{module};
++ $self-&gt;{_noarch} = $options{noarch};
++ $self-&gt;{_svn} = $options{svn};
++ $self-&gt;{_upload_root} = $options{upload_root};
++
++ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
++ $year+=1900;
++ my $hostname = `hostname`;
++ my ($host) = $hostname =~ /([^.]*)/;
++ $self-&gt;{group_dir} = sprintf &quot;$ENV{SUDO_USER}.$host.$$.$year%02d%02d%02d%02d%02d&quot;, $mon, $mday, $hour, $min, $sec;
++}
++
++sub get_package_class {
++ return PACKAGE_CLASS;
++}
++
++sub package_in_svn {
++ my ($self, $srpm_name) = @_;
++ my $ctx = new SVN::Client(
++ auth =&gt; [SVN::Client::get_simple_provider(),
++ SVN::Client::get_simple_prompt_provider(\&amp;simple_prompt,2),
++ SVN::Client::get_username_provider()]
++ );
++
++ my $svn_entry = $ctx-&gt;ls(&quot;$self-&gt;{_svn}/&quot;, 'HEAD', 0);
++ foreach (keys %{$svn_entry}) {
++ if ($srpm_name eq $_) {
++ print &quot;Package $_ is in the SVN\n&quot;;
++ return 1
++ }
++ }
++}
++
++sub get_svn_url {
++ my ($self) = @_;
++ $self-&gt;{_svn}
++}
++
++sub get_revisions {
++ my ($self, $package, $target, $define, $filter) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my $arch = $define-&gt;{arch} || $package-&gt;get_arch;
++ if ($arch eq 'src') {
++ $arch = 'SRPMS'
++ } else {
++ $arch .= '/media'
++ }
++ my @packages;
++ foreach my $dir ('main', 'contrib') {
++ print &quot;Looking into $self-&gt;{_install_root}/$target/$arch/$dir/release\n&quot;;
++ push @packages,
++ map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$target/$arch/$dir/release&quot; ,
++ $self-&gt;get_package_class()-&gt;get_pattern($package-&gt;get_name(),undef, undef, $arch)
++ );
++ }
++
++ @packages = grep { $filter-&gt;($_) } @packages if $filter;
++
++ return
++ sort { $b-&gt;compare($a) } # sort by revision order
++ @packages;
++}
++
++sub get_package_charset {
++ return PACKAGE_CHARSET;
++}
++
++sub get_upload_dir {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ my $section = $self-&gt;_get_section($package, $target, $define);
++ my $media_path = $section eq 'main' ? $target : $target =~ /^cooker/ ? &quot;contrib&quot; : &quot;$target/contrib&quot;;
++ my $arch_path = $arch eq 'src' ? 'SRPMS' : 'RPMS';
++ my $force = $target =~ /_force/ ? 'force' : '';
++ $self-&gt;{_upload_root} . &quot;/$media_path/$force/$arch_path/&quot;
++}
++
++sub get_arch {
++ my ($self, $package, $target, $define) = @_;
++ my $arch = $package-&gt;get_arch();
++ if ($arch eq 'noarch') {
++ $arch = $self-&gt;{_noarch}
++ }
++ $arch
++}
++
++sub get_install_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub get_archive_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub _get_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $arch = $package-&gt;get_arch;
++ if ($arch eq 'src') {
++ $arch = 'SRPMS'
++ } else {
++ $arch .= '/media'
++ }
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ return &quot;$target/$arch/$section/release/&quot;;
++}
++
++
++sub get_version_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ return &quot;$self-&gt;{_module}/$section/release/&quot;;
++}
++
++=head2 get_replaced_packages($package, $target, $define)
++
++Overrides parent method to add libified packages.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @replaced_packages =
++ $self-&gt;SUPER::get_replaced_packages($package, $target, $define);
++
++ # mandriva lib policy:
++ # library package names change with revision, making mandatory to
++ # duplicate older revisions search with a custom pattern
++ my $name = $package-&gt;get_name();
++ if ($name =~ /^(lib\w+[a-zA-Z_])[\d_\.]+([-\w]*)$/) {
++ push(@replaced_packages,
++ grep { $package-&gt;compare($_) &gt; 0 }
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $define),
++ PACKAGE_CLASS-&gt;get_pattern(
++ $1 . '[\d_\.]+' . $2, # custom name pattern
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ return @replaced_packages;
++
++}
++
++sub _get_section {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section;
++
++ # try to find section automatically
++ my $arch = $package-&gt;get_arch();
++ $arch = $self-&gt;{_noarch} if $arch eq 'noarch';
++
++ my $source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_canonical_name(),
++ undef,
++ undef,
++ 'src'
++ );
++
++ my $binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_name(),
++ undef,
++ undef,
++ $arch
++ );
++
++ # for each potential section, try to match
++ # a suitable source patten in source directory
++ # a suitable binary patten in binary directory
++ foreach my $dir (qw/main contrib/) {
++ next unless
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$target/SRPMS/$dir/release&quot;,
++ $source_pattern
++ ) || $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$target/$arch/media/$dir/release&quot;,
++ $binary_pattern
++ );
++ print &quot;Section is $dir\n&quot;;
++ $section = $dir;
++ last;
++ }
++
++ # use defined section if not found
++ $section = $define-&gt;{section} unless $section;
++
++ $section || 'contrib'
++}
++
++sub get_upload_newer_revisions {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ my $pattern = $self-&gt;get_package_class()-&gt;get_pattern($package-&gt;get_name(), undef, undef, $arch);
++ print &quot;Looking for package $package revisions for $target in $self-&gt;{_upload_root} (pattern $pattern)\n&quot;;
++ my @packages;
++ foreach my $dir ('cooker', 'contrib') {
++ find(sub { return if ! /^$pattern/; print &quot;Find $_\n&quot;; push @packages, $File::Find::name if $package-&gt;compare($self-&gt;get_package_class()-&gt;new(file =&gt; $File::Find::name)) &lt;= 0 }, &quot;$self-&gt;{_upload_root}/$dir&quot;);
++ }
++ return
++ @packages;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositoryPLFpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,196 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Upload/Action/RSS.pm 857 2006-01-29T10:15:43.298856Z guillaume $
++package Youri::Repository::PLF;
++
++=head1 NAME
++
++Youri::Repository::PLF - PLF repository implementation
++
++=head1 DESCRIPTION
++
++This module implements PLF repository.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use base qw/Youri::Repository/;
++use constant {
++ PACKAGE_CLASS =&gt; 'Youri::Package::URPM',
++ PACKAGE_CHARSET =&gt; 'utf8'
++};
++
++memoize('_get_section');
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ module =&gt; 'SPECS', # CVS module
++ noarch =&gt; 'noarch', # noarch packages policy
++ @_
++ );
++
++ $self-&gt;{_module} = $options{module};
++ $self-&gt;{_noarch} = $options{noarch};
++}
++
++sub get_package_class {
++ return PACKAGE_CLASS;
++}
++
++sub get_package_charset {
++ return PACKAGE_CHARSET;
++}
++
++sub get_install_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub get_archive_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub _get_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ my $subpath = $self-&gt;_get_subpath($package, $target);
++
++ return &quot;$section/$subpath&quot;;
++}
++
++
++sub get_version_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ return &quot;$self-&gt;{_module}/$section&quot;;
++}
++
++=head2 get_replaced_packages($package, $target, $define)
++
++Overrides parent method to add libified packages.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @replaced_packages =
++ $self-&gt;SUPER::get_replaced_packages($package, $target, $define);
++
++ # mandriva lib policy:
++ # library package names change with revision, making mandatory to
++ # duplicate older revisions search with a custom pattern
++ my $name = $package-&gt;get_name();
++ if ($name =~ /^(lib\w+[a-zA-Z_])[\d_\.]+([-\w]*)$/) {
++ push(@replaced_packages,
++ grep { $package-&gt;compare($_) &gt; 0 }
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $define),
++ PACKAGE_CLASS-&gt;get_pattern(
++ $1 . '[\d_\.]+' . $2, # custom name pattern
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ return @replaced_packages;
++
++}
++
++sub _get_section {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section;
++
++ # try to find section automatically
++ my $arch = $package-&gt;get_arch();
++
++ my $source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_canonical_name(),
++ undef,
++ undef,
++ 'src'
++ );
++
++ my $binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_name(),
++ undef,
++ undef,
++ $arch
++ );
++
++ my $source_subpath = $self-&gt;_get_subpath($package, $target, 'src');
++ my $binary_subpath = $self-&gt;_get_subpath($package, $target, $arch);
++
++ # for each potential section, try to match
++ # a suitable source patten in source directory
++ # a suitable binary patten in binary directory
++ foreach my $dir (qw/free non-free/) {
++ next unless
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$dir/$source_subpath&quot;,
++ $source_pattern
++ ) || $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$dir/$binary_subpath&quot;,
++ $binary_pattern
++ );
++ $section = $dir;
++ last;
++ }
++
++ # use defined section if not found
++ $section = $define-&gt;{section} unless $section;
++
++ die &quot;Can't guess destination: section missing&quot; unless $section;
++
++ return $section;
++}
++
++sub _get_subpath {
++ my ($self, $package, $target, $arch) = @_;
++
++ my $subpath;
++
++ # use package arch if not specified
++ $arch = $package-&gt;get_arch() unless $arch;
++
++ if ($arch eq 'src') {
++ $subpath = 'src';
++ } else {
++ if ($arch eq 'noarch') {
++ $subpath = &quot;$target/$self-&gt;{_noarch}&quot;;
++ } else {
++ $subpath = &quot;$target/$arch&quot;;
++ }
++ }
++
++ return $subpath;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositorypm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,492 @@
++# $Id: Base.pm 631 2006-01-26 22:22:23Z guillomovitch $
++package Youri::Repository;
++
++=head1 NAME
++
++Youri::Repository - Abstract repository
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Repository interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use Youri::Package;
++
++=head1 CLASS METHODS
++
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Repository object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ install_root =&gt; '', # path to top-level directory
++ archive_root =&gt; '', # path to top-level directory
++ version_root =&gt; '', # path to top-level directory
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++
++ croak &quot;no install root&quot; unless $options{install_root};
++ croak &quot;invalid install root&quot; unless -d $options{install_root};
++
++ my $self = bless {
++ _install_root =&gt; $options{install_root},
++ _archive_root =&gt; $options{archive_root},
++ _version_root =&gt; $options{version_root},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_package_class()
++
++Return package class for this repository.
++
++=cut
++
++sub get_package_class {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return $self-&gt;{_package_class};
++}
++
++=head2 get_package_charset()
++
++Return package charset for this repository.
++
++=cut
++
++sub get_package_charset {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return $self-&gt;{_package_charset};
++}
++
++=head2 get_extra_arches()
++
++Return the list of additional archictectures to handle when dealing with noarch
++packages.
++
++=cut
++
++sub get_extra_arches {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return @{$self-&gt;{_extra_arches}};
++}
++
++
++=head2 get_older_revisions($package, $target, $user_context, $app_context)
++
++Get all older revisions from a package found in its installation directory, as a
++list of L&lt;Youri::Package&gt; objects.
++
++=cut
++
++sub get_older_revisions {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package older revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ return $self-&gt;get_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context,
++ sub { return $package-&gt;compare($_[0]) &gt; 0 }
++ );
++}
++
++=head2 get_last_older_revision($package, $target, $user_context, $app_context)
++
++Get last older revision from a package found in its installation directory, as a
++single L&lt;Youri::Package&gt; object.
++
++=cut
++
++sub get_last_older_revision {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package last older revision for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ return (
++ $self-&gt;get_older_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ )
++ )[0];
++}
++
++=head2 get_newer_revisions($package, $target, $user_context, $app_context)
++
++Get all newer revisions from a package found in its installation directory, as
++a list of L&lt;Youri::Package&gt; objects.
++
++=cut
++
++sub get_newer_revisions {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package newer revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ return $self-&gt;get_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context,
++ sub { return $_[0]-&gt;compare($package) &gt; 0 }
++ );
++}
++
++
++=head2 get_revisions($package, $target, $user_context, $app_context, $filter)
++
++Get all revisions from a package found in its installation directory, using an
++optional filter, as a list of L&lt;Youri::Package&gt; objects.
++
++=cut
++
++sub get_revisions {
++ my ($self, $package, $target, $user_context, $app_context, $filter) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my @packages =
++ map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ ),
++ $self-&gt;get_package_class()-&gt;get_pattern(
++ $package-&gt;get_name(),
++ undef,
++ undef,
++ $package-&gt;get_arch(),
++ )
++ );
++ @packages = grep { $filter-&gt;($_) } @packages if $filter;
++
++ return
++ sort { $b-&gt;compare($a) } # sort by revision order
++ @packages;
++}
++
++=head2 get_obsoleted_packages($package, $target, $user_context, $app_context)
++
++Get all packages obsoleted by given one, as a list of L&lt;Youri::Package&gt;
++objects.
++
++=cut
++
++sub get_obsoleted_packages {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for packages obsoleted by $package for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my @packages;
++ foreach my $obsolete ($package-&gt;get_obsoletes()) {
++ my $pattern = $self-&gt;get_package_class()-&gt;get_pattern($obsolete-&gt;[Youri::Package::DEPENDENCY_NAME]);
++ my $range = $obsolete-&gt;[Youri::Package::DEPENDENCY_RANGE];
++ push(@packages,
++ grep { $range ? $_-&gt;satisfy_range($range) : 1 }
++ map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path(
++ $package, $target,
++ $user_context,
++ $app_context
++ ),
++ $pattern
++ )
++ );
++ }
++
++ return @packages;
++}
++
++=head2 get_replaced_packages($package, $target, $user_context, $app_context)
++
++Get all packages replaced by given one, as a list of L&lt;Youri::Package&gt;
++objects.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for packages replaced by $package for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my @list;
++
++ # collect all older revisions
++ push(@list, $self-&gt;get_older_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ ));
++
++ # noarch packages are potentially linked from other directories
++ if ($package-&gt;get_arch() eq 'noarch') {
++ foreach my $arch ($self-&gt;get_extra_arches()) {
++ push(@list, $self-&gt;get_older_revisions(
++ $package,
++ $target,
++ $user_context,
++ { arch =&gt; $arch }
++ ));
++ }
++ }
++
++ # collect all obsoleted packages
++ push(@list, $self-&gt;get_obsoleted_packages(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ ));
++
++ return @list;
++}
++
++=head2 get_files($path, $pattern)
++
++Get all files found in a directory, using an optional filtering pattern
++(applied to the whole file name), as a list of files.
++
++=cut
++
++sub get_files {
++ my ($self, $root, $path, $pattern) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ # debugging for bug 34999
++ print &quot;Looking for files matching $pattern in $root/$path\n&quot;;
++# if $self-&gt;{_verbose} &gt; 1;
++
++ my $grep = &quot;&quot;;
++ $grep = &quot;-regextype posix-egrep -regex '.*\/$pattern'&quot; if ($pattern);
++ # XXX: run find in a directory the user is guaranteed to have read
++ # permissions! find simply exits with error if the user doesn't have
++ # read permission on the *current* dir; as this code is run thru many
++ # sudo invocations, sometimes the user calling it has $HOME chmoded to
++ # 0700, making find fail when run as mandrake
++ # debugging for bug 34999
++ print &quot;.. running command: find -L $root/$path $grep -type f\n&quot;;
++ my @files = map { chop; $_; } `cd &amp;&amp; find -L $root/$path $grep -type f`;
++ die &quot;FATAL: get_files(): find failed!&quot; if ($?);
++
++ return @files;
++}
++
++=head2 get_install_root()
++
++Returns installation root
++
++=cut
++
++sub get_install_root {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_install_root};
++}
++
++
++=head2 get_distribution_roots()
++
++Returns distribution roots (ie install_root + target + arch)
++(it returns a list in case of noarch)
++
++=cut
++
++sub get_distribution_roots {
++ my ($self, $package, $target) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ map {
++ $self-&gt;_get_dir($self-&gt;{_install_root}, $_);
++ } $self-&gt;get_distribution_paths($package, $target);
++}
++
++=head2 get_install_dir($package, $target, $user_context, $app_context)
++
++Returns install destination directory for given L&lt;Youri::Package&gt; object
++and given target.
++
++=cut
++
++sub get_install_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;_get_dir(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $user_context, $app_context)
++ );
++}
++
++=head2 get_archive_root()
++
++Returns archiving root
++
++=cut
++
++sub get_archive_root {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_archive_root};
++}
++
++=head2 get_archive_dir($package, $target, $user_context, $app_context)
++
++Returns archiving destination directory for given L&lt;Youri::Package&gt; object
++and given target.
++
++=cut
++
++sub get_archive_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;_get_dir(
++ $self-&gt;{_archive_root},
++ $self-&gt;get_archive_path($package, $target, $user_context, $app_context)
++ );
++}
++
++
++=head2 get_version_root()
++
++Returns versionning root
++
++=cut
++
++sub get_version_root {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_version_root};
++}
++
++=head2 get_version_dir($package, $target, $user_context, $app_context)
++
++Returns versioning destination directory for given L&lt;Youri::Package&gt;
++object and given target.
++
++=cut
++
++sub get_version_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;_get_dir(
++ $self-&gt;{_version_root},
++ $self-&gt;get_version_path($package, $target, $user_context, $app_context)
++ );
++}
++
++sub _get_dir {
++ my ($self, $root, $path) = @_;
++
++ return substr($path, 0, 1) eq '/' ?
++ $path :
++ $root . '/' . $path;
++}
++
++=head2 get_install_file($package, $target, $user_context, $app_context)
++
++Returns install destination file for given L&lt;Youri::Package&gt; object and
++given target.
++
++=cut
++
++sub get_install_file {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;get_install_dir($package, $target, $user_context, $app_context) .
++ '/' .
++ $package-&gt;get_file_name();
++}
++
++=head2 get_install_path($package, $target, $user_context, $app_context)
++
++Returns installation destination path (relative to repository root) for given
++L&lt;Youri::Package&gt; object and given target.
++
++=head2 get_archive_path($package, $target, $user_context, $app_context)
++
++Returns archiving destination path (relative to repository root) for given
++L&lt;Youri::Package&gt; object and given target.
++
++=head2 get_version_path($package, $target, $user_context, $app_context)
++
++Returns versioning destination path (relative to repository root) for given
++L&lt;Youri::Package&gt; object and given target.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item get_install_path
++
++=item get_archive_path
++
++=item get_version_path
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriUtilspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,98 @@
++# $Id: Utils.pm 1713 2006-10-16 16:39:53Z warly $
++package Youri::Utils;
++
++=head1 NAME
++
++Youri::Utils - Youri shared functions
++
++=head1 DESCRIPTION
++
++This module implement some helper functions for all youri applications.
++
++=cut
++
++use base qw(Exporter);
++use Carp;
++use strict;
++use warnings;
++
++our @EXPORT = qw(
++ create_instance
++ load_class
++ add2hash
++ add2hash_
++);
++
++=head2 create_instance($class, $config, $options)
++
++Create an instance from a plugin implementing given interface, using given
++configuration and local options.
++Returns a plugin instance, or undef if something went wrong.
++
++=cut
++
++sub create_instance {
++ my ($interface, $config, $options) = @_;
++
++ croak 'No interface given' unless $interface;
++ croak 'No config given' unless $config;
++
++ my $class = $config-&gt;{class};
++ if (!$class) {
++ carp &quot;No class given, can't load plugin&quot;;
++ return;
++ }
++
++ # ensure loaded
++ load_class($class);
++
++ # check interface
++ if (!$class-&gt;isa($interface)) {
++ carp &quot;$class is not a $interface&quot;;
++ return;
++ }
++
++ # instantiate
++ no strict 'refs';
++
++ return $class-&gt;new(
++ $config-&gt;{options} ? %{$config-&gt;{options}} : (),
++ $options ? %{$options} : (),
++ );
++}
++
++sub load_class {
++ my ($class) = @_;
++
++ $class .= '.pm';
++ $class =~ s/::/\//g;
++ require $class;
++}
++
++# structure helpers
++
++sub add2hash {
++ my ($a, $b) = @_;
++ while (my ($k, $v) = each %{$b || {}}) {
++ $a-&gt;{$k} ||= $v;
++ }
++ return $a;
++}
++
++sub add2hash_ {
++ my ($a, $b) = @_;
++ while (my ($k, $v) = each %{$b || {}}) {
++ exists $a-&gt;{$k} or $a-&gt;{$k} = $v;
++ }
++ return $a;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunkt00distributiont">Added: build_system/mdv-youri-core/trunk/t/00distribution.t</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/t/00distribution.t (rev 0)
++++ build_system/mdv-youri-core/trunk/t/00distribution.t 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,15 @@
++#!/usr/bin/perl
++# $Id: 00distribution.t 1179 2006-08-05 08:30:57Z warly $
++
++use Test::More;
++
++BEGIN {
++ eval {
++ require Test::Distribution;
++ };
++ if($@) {
++ plan skip_all =&gt; 'Test::Distribution not installed';
++ } else {
++ import Test::Distribution only =&gt; [ qw/use pod description/ ];
++ }
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/00distribution.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyouricoretrunktcowsay30311mdv20070noarchrpm">Added: build_system/mdv-youri-core/trunk/t/cowsay-3.03-11mdv2007.0.noarch.rpm</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/cowsay-3.03-11mdv2007.0.noarch.rpm
+___________________________________________________________________
+<a id="svnmimetype">Added: svn:mime-type</a>
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktgpghomepubringgpg">Added: build_system/mdv-youri-core/trunk/t/gpghome/pubring.gpg</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/gpghome/pubring.gpg
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktgpghomesecringgpg">Added: build_system/mdv-youri-core/trunk/t/gpghome/secring.gpg</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/gpghome/secring.gpg
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktgpghometrustdbgpg">Added: build_system/mdv-youri-core/trunk/t/gpghome/trustdb.gpg</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/gpghome/trustdb.gpg
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktpackaget">Added: build_system/mdv-youri-core/trunk/t/package.t</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/t/package.t (rev 0)
++++ build_system/mdv-youri-core/trunk/t/package.t 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,482 @@
++#!/usr/bin/perl
++# $Id: /local/youri/soft/trunk/t/version.t 2257 2006-07-05T09:22:47.088572Z guillaume $
++
++use Test::More;
++use Test::Exception;
++use Youri::Utils;
++use File::Temp qw/tempdir/;
++use File::Basename;
++use strict;
++
++my @classes = qw/
++ Youri::Package::URPM
++ Youri::Package::RPM4
++/;
++my $dir = dirname($0);
++my $rpm = 'cowsay-3.03-11mdv2007.0.noarch.rpm';
++my $fake_rpm = 'foobar.rpm';
++plan(tests =&gt; 37 * scalar @classes);
++
++foreach my $class (@classes) {
++ load_class($class);
++
++ my $temp_dir = tempdir(CLEANUP =&gt; 1);
++ my $file = &quot;$dir/$rpm&quot;;
++ my $fake_file = &quot;$temp_dir/$fake_rpm&quot;;
++
++ # instanciation errors
++ dies_ok { $class-&gt;new(file =&gt; undef) } 'undefined file';
++ dies_ok { $class-&gt;new(file =&gt; $fake_file) } 'non-existant file';
++ system('touch', $fake_file);
++ chmod 0000, $fake_file;
++ dies_ok { $class-&gt;new(file =&gt; $fake_file) } 'non-readable file';
++ chmod 0644, $fake_file;
++ dies_ok { $class-&gt;new(file =&gt; $fake_file) } 'non-rpm file';
++
++ my $package = $class-&gt;new(file =&gt; $file);
++ isa_ok($package, $class);
++
++ # tag value access
++ is($package-&gt;get_name(), 'cowsay', 'get name directly');
++ is($package-&gt;get_tag('name'), 'cowsay', 'get name indirectly');
++ is($package-&gt;get_version(), '3.03', 'get version directly');
++ is($package-&gt;get_tag('version'), '3.03', 'get version indirectly');
++ is($package-&gt;get_release(), '11mdv2007.0', 'get release directly');
++ is($package-&gt;get_tag('release'), '11mdv2007.0', 'get release indirectly');
++ is($package-&gt;get_arch(), 'noarch', 'get arch directly');
++ is($package-&gt;get_tag('arch'), 'noarch', 'get arch indirectly');
++ is($package-&gt;get_summary(), 'Configurable talking cow', 'get summary directly');
++ is($package-&gt;get_tag('summary'), 'Configurable talking cow', 'get summary indirectly');
++ is($package-&gt;get_url(), 'http://www.nog.net/~tony/warez/cowsay.shtml', 'get url directly');
++ is($package-&gt;get_tag('url'), 'http://www.nog.net/~tony/warez/cowsay.shtml', 'get url indirectly');
++ is($package-&gt;get_packager(), 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt;', 'get packager directly');
++ is($package-&gt;get_tag('packager'), 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt;', 'get packager indirectly');
++ is($package-&gt;get_file_name(), 'cowsay-3.03-11mdv2007.0.noarch.rpm', 'file name');
++ is($package-&gt;get_revision(), '3.03-11mdv2007.0', 'revision');
++
++ # name formating
++ is($package-&gt;as_formated_string('%{name}-%{version}-%{release}'), 'cowsay-3.03-11mdv2007.0', 'formated string name');
++ is($package-&gt;as_string(), 'cowsay-3.03-11mdv2007.0.noarch', 'default string');
++ is($package, 'cowsay-3.03-11mdv2007.0.noarch', 'stringification');
++
++ # type
++ ok(!$package-&gt;is_source(), 'not a source package');
++ ok($package-&gt;is_binary(), 'a binary package');
++ is($package-&gt;get_type(), 'binary', 'a binary package');
++
++ # gpg key
++ is($package-&gt;get_gpg_key(), '26752624', 'get gpg key');
++
++ # dependencies
++ is_deeply(
++ [ $package-&gt;get_requires() ],
++ [
++ [ 'perl-base', undef ],
++ [ 'perl(Cwd)', undef ],
++ [ 'perl(File::Basename)', undef ],
++ [ 'perl(Getopt::Std)', undef ],
++ [ 'perl(Text::Tabs)', undef ],
++ [ 'perl(Text::Wrap)', undef ]
++ ],
++ 'requires'
++ );
++ is_deeply(
++ [ $package-&gt;get_provides() ],
++ [
++ [ 'cowsay', '== 3.03-11mdv2007.0']
++ ],
++ 'provides'
++ );
++ is_deeply(
++ [ $package-&gt;get_obsoletes() ],
++ [ ],
++ 'obsoletes'
++ );
++ is_deeply(
++ [ $package-&gt;get_conflicts() ],
++ [ ],
++ 'conflicts'
++ );
++
++ # files
++ is_deeply(
++ [ $package-&gt;get_files() ],
++ [
++ [
++ '/etc/bash_completion.d/cowsay',
++ 33188,
++ '6048be1dd827011c15cab0c3db1f438d'
++ ],
++ [
++ '/usr/bin/cowsay',
++ 33261,
++ 'b405026c6040eeb4781ca5c523129fe4'
++ ],
++ [
++ '/usr/bin/cowthink',
++ 41471,
++ ''
++ ],
++ [
++ '/usr/share/cows',
++ 16877,
++ ''
++ ],
++ [
++ '/usr/share/cows/beavis.zen.cow',
++ 33188,
++ '582b2ddb72122d3aa078730abd0456b3'
++ ],
++ [
++ '/usr/share/cows/bong.cow',
++ 33188,
++ '045f9bf39c027dded9a7145f619bac02'
++ ],
++ [
++ '/usr/share/cows/bud-frogs.cow',
++ 33188,
++ '5c61632eb06305d613061882e1955cd2'
++ ],
++ [
++ '/usr/share/cows/bunny.cow',
++ 33188,
++ '05eb914d3b96aea903542cb29f5c42c7'
++ ],
++ [
++ '/usr/share/cows/cheese.cow',
++ 33188,
++ 'f3618110a22d8e9ecde888c1f5e38b61'
++ ],
++ [
++ '/usr/share/cows/cower.cow',
++ 33188,
++ 'd73ea60eec692555a34a9f3eec981578'
++ ],
++ [
++ '/usr/share/cows/daemon.cow',
++ 33188,
++ 'a7dd7588ee0386a0f29e88e4881885ee'
++ ],
++ [
++ '/usr/share/cows/default.cow',
++ 33188,
++ 'f1206515a0f27e9d5cf09c188e46bc82'
++ ],
++ [
++ '/usr/share/cows/dragon-and-cow.cow',
++ 33188,
++ '0ca99b8edd1a9d14fd231a88d9746b39'
++ ],
++ [
++ '/usr/share/cows/dragon.cow',
++ 33188,
++ '448f736bf56dccafa2635e71e7485345'
++ ],
++ [
++ '/usr/share/cows/duck.cow',
++ 33188,
++ 'd8ffcd64667d2e3697a3e8b65e8bea9d'
++ ],
++ [
++ '/usr/share/cows/elephant-in-snake.cow',
++ 33188,
++ 'c5a9f406277e0e8a674bd3ffb503738f'
++ ],
++ [
++ '/usr/share/cows/elephant.cow',
++ 33188,
++ 'e355c72e893787376c047805d4a1fe9d'
++ ],
++ [
++ '/usr/share/cows/eyes.cow',
++ 33188,
++ 'b2eb5b612fae17877895aa6edafa0a5f'
++ ],
++ [
++ '/usr/share/cows/flaming-sheep.cow',
++ 33188,
++ '3213cfa04a069f42d71115ca623a2f95'
++ ],
++ [
++ '/usr/share/cows/ghostbusters.cow',
++ 33188,
++ 'df294e6278bcb275aecb0fbd6b2546ba'
++ ],
++ [
++ '/usr/share/cows/girafe.cow',
++ 33188,
++ '6d2e142313109b6a5a0a45dba0f11351'
++ ],
++ [
++ '/usr/share/cows/head-in.cow',
++ 33188,
++ '365287a5d1f34a53f8716285e79c28df'
++ ],
++ [
++ '/usr/share/cows/hellokitty.cow',
++ 33188,
++ 'e0bbea69c4cbcfb3d799740ccc8a0b0e'
++ ],
++ [
++ '/usr/share/cows/kenny.cow',
++ 33188,
++ '16ce8c334a7547197ac4c9e8a1d6ae90'
++ ],
++ [
++ '/usr/share/cows/kiss.cow',
++ 33188,
++ '2a7bdd4a20741b7769af463bf09e64e8'
++ ],
++ [
++ '/usr/share/cows/kitty.cow',
++ 33188,
++ '76d65a3ebfbacb16a654c1aa1af6ed27'
++ ],
++ [
++ '/usr/share/cows/koala.cow',
++ 33188,
++ 'cc524706707f32253dd06fc548334f11'
++ ],
++ [
++ '/usr/share/cows/kosh.cow',
++ 33188,
++ 'e4e28e0f472bd524fd1b44c67ae357c2'
++ ],
++ [
++ '/usr/share/cows/luke-koala.cow',
++ 33188,
++ '63bbc35da73cd22b8cf25f86dcf9f870'
++ ],
++ [
++ '/usr/share/cows/mech-and-cow',
++ 33188,
++ '12c0320b33704d8564dd97278d056204'
++ ],
++ [
++ '/usr/share/cows/meow.cow',
++ 33188,
++ 'a6092008647ed37cfe1663d10e388cbb'
++ ],
++ [
++ '/usr/share/cows/milk.cow',
++ 33188,
++ 'd26ac36e13e77dabb408e104fc8e0167'
++ ],
++ [
++ '/usr/share/cows/moofasa.cow',
++ 33188,
++ '5fcdd4a9f3bf521c337af0a066b14512'
++ ],
++ [
++ '/usr/share/cows/moose.cow',
++ 33188,
++ 'dcfa09df7d2b9afa112dab374bf06e99'
++ ],
++ [
++ '/usr/share/cows/mutilated.cow',
++ 33188,
++ '24cdaef0a29fb44dc673abf19a8ba631'
++ ],
++ [
++ '/usr/share/cows/phaco.cow',
++ 33188,
++ 'f277c1bf92ce2a3f6058955ba93758aa'
++ ],
++ [
++ '/usr/share/cows/pumpkin.cow',
++ 33188,
++ 'c661ea78714c1ce31559f77d73694473'
++ ],
++ [
++ '/usr/share/cows/ren.cow',
++ 33188,
++ '3d7941d454779e000adc1c91e5f0b20b'
++ ],
++ [
++ '/usr/share/cows/satanic.cow',
++ 33188,
++ 'a69ca42a31486757ddcb322a1e68f886'
++ ],
++ [
++ '/usr/share/cows/shark.cow',
++ 33188,
++ 'd8950ec63abb00bbd9d96ec63637c1ac'
++ ],
++ [
++ '/usr/share/cows/sheep.cow',
++ 33188,
++ '543b75f295cbd51326f5a40f111469f1'
++ ],
++ [
++ '/usr/share/cows/skeleton.cow',
++ 33188,
++ '64f6ec1a0c170508e72269d533492e57'
++ ],
++ [
++ '/usr/share/cows/small.cow',
++ 33188,
++ '50cb1c55628c439fc81f96db9d855252'
++ ],
++ [
++ '/usr/share/cows/sodomized.cow',
++ 33188,
++ 'b4888afcca51629cc3138b283608b837'
++ ],
++ [
++ '/usr/share/cows/stegosaurus.cow',
++ 33188,
++ 'fb0e45d101a3ecba9cf6e112facbbc7e'
++ ],
++ [
++ '/usr/share/cows/stimpy.cow',
++ 33188,
++ '9b4ec6e0750ba0eeaaa432d8d3413559'
++ ],
++ [
++ '/usr/share/cows/supermilker.cow',
++ 33188,
++ '316573fb585e4a6b375373c85be025b1'
++ ],
++ [
++ '/usr/share/cows/surgery.cow',
++ 33188,
++ '7f25005083c1fde19d4e548c005ef000'
++ ],
++ [
++ '/usr/share/cows/telebears.cow',
++ 33188,
++ '15f00abb070d9018ce6ef3441e936ef4'
++ ],
++ [
++ '/usr/share/cows/three-eyes.cow',
++ 33188,
++ 'c85faef9496f4a5b111bd92bfd7e7528'
++ ],
++ [
++ '/usr/share/cows/turkey.cow',
++ 33188,
++ '484b5bc69c09d420d7fd5586d8570f04'
++ ],
++ [
++ '/usr/share/cows/turtle.cow',
++ 33188,
++ '87eed5a00e88860b78dbec04efcdede3'
++ ],
++ [
++ '/usr/share/cows/tux.cow',
++ 33188,
++ 'dc1db4eac66c99179ef6adb15dd75bda'
++ ],
++ [
++ '/usr/share/cows/udder.cow',
++ 33188,
++ 'd97f78887c3b218a54876edc51f2963b'
++ ],
++ [
++ '/usr/share/cows/vader-koala.cow',
++ 33188,
++ '7b5dd51278f0fa217a70a9b499f97a07'
++ ],
++ [
++ '/usr/share/cows/vader.cow',
++ 33188,
++ '97b4ef9fc4c26082f253e9f0f35c4590'
++ ],
++ [
++ '/usr/share/cows/www.cow',
++ 33188,
++ 'ef4c0bc8330f329666e1705f97f283cc'
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03',
++ 16877,
++ ''
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03/INSTALL',
++ 33188,
++ '3333fd2865107626d5dffc0dbfb7e244'
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03/LICENSE',
++ 33188,
++ 'f879dda90a5a9928253a63ecd76406e6'
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03/README',
++ 33188,
++ 'a5c1c61e4920c278a735cdaaca62453e'
++ ],
++ [
++ '/usr/share/man/man1/cowsay.1.bz2',
++ 33188,
++ '01fdd49d0b477f20099aae384fe8c1b2'
++ ],
++ [
++ '/usr/share/man/man1/cowthink.1.bz2',
++ 41471,
++ ''
++ ]
++ ],
++ 'files'
++ );
++
++ # changelog
++ is_deeply(
++ [ $package-&gt;get_changes() ],
++ [
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt; 3.03-11mdv2007.0',
++ 1149847200,
++ '- %mkrel' . &quot;\n&quot; .
++ '- rpmbuildupdate aware',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt; 3.03-10mdk ',
++ 1117879200,
++ '- fix man page (fix #16291)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandrake.org&gt; 3.03-9mdk ',
++ 1090058400,
++ '- hurry businesman compliant (aka two new wonderful cows)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandrake.org&gt; 3.03-8mdk ',
++ 1089540000,
++ '- apologies to the girafes (with one only f)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandrake.org&gt; 3.03-7mdk ',
++ 1086429600,
++ '- #mandrakefr compliant (aka four new additional cows)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@linux-mandrake.com&gt; 3.03-6mdk',
++ 1061460000,
++ '- save.the.world patch',
++ ]
++ ],
++ 'changelog'
++ );
++ is_deeply(
++ $package-&gt;get_last_change(),
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt; 3.03-11mdv2007.0',
++ 1149847200,
++ '- %mkrel' . &quot;\n&quot; .
++ '- rpmbuildupdate aware',
++ ],
++ 'last change'
++ );
++ is($package-&gt;compare($package), 0, 'compare');
++
++ # signature test
++ system('cp', $file, $temp_dir);
++ $package = $class-&gt;new(file =&gt; &quot;$temp_dir/$rpm&quot;);
++
++ $package-&gt;sign('Youri', 't/gpghome', 'Youri rulez');
++
++ $package = $class-&gt;new(file =&gt; &quot;$temp_dir/$rpm&quot;);
++ is($package-&gt;get_gpg_key(), '2333e817', 'get gpg key');
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/package.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyouricoretrunktversiont">Added: build_system/mdv-youri-core/trunk/t/version.t</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/t/version.t (rev 0)
++++ build_system/mdv-youri-core/trunk/t/version.t 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,71 @@
++#!/usr/bin/perl
++# $Id: version.t 1179 2006-08-05 08:30:57Z warly $
++
++use Test::More;
++use Youri::Check::Input::Updates;
++use strict;
++
++my @differents = (
++ [ '3.0.0', '1.0.0' ],
++ [ '3.0.0', '1.99.9' ],
++ [ '3.0.1', '3.0' ],
++ [ '3.0pl1', '3.0' ],
++ [ '3.0', '3.0beta1' ],
++ [ '3.0', '3.0beta' ],
++ [ '3.0', '3.0alpha1' ],
++ [ '3.0', '3.0alpha' ],
++ [ '3.0', '3.0pre1' ],
++ [ '3.0', '3.0pre' ],
++ [ '3.0pre', '3.0beta' ],
++ [ '3.0beta', '3.0alpha' ],
++ [ '1.0.0-p1', '1.0.0RC1' ],
++ [ '0.9.7f', '0.9.7e' ],
++ [ '10', '9' ],
++);
++
++my @equals = (
++ [ '1.0.0', '1.0.0' ],
++ [ '0.9Beta1', '0.9beta1' ],
++ [ '0.9beta1', '0.9 beta 1' ],
++ [ '0.3-alpha', '0.3_alpha' ],
++ [ '0.02', '.02' ],
++ [ '2.0.11', '15aug2000' ],
++ [ '2.0.11', '20060401' ],
++ [ '20', '20060401' ],
++);
++
++plan tests =&gt; 2 * @differents + 2 * @equals;
++
++foreach my $different (@differents) {
++ ok(
++ Youri::Check::Input::Updates::is_newer(
++ $different-&gt;[0],
++ $different-&gt;[1]
++ ),
++ &quot;$different-&gt;[0] is newer as $different-&gt;[1]&quot;
++ );
++ ok(
++ !Youri::Check::Input::Updates::is_newer(
++ $different-&gt;[1],
++ $different-&gt;[0]
++ ),
++ &quot;$different-&gt;[1] is older as $different-&gt;[0]&quot;
++ );
++}
++
++foreach my $equal (@equals) {
++ ok(
++ !Youri::Check::Input::Updates::is_newer(
++ $equal-&gt;[0],
++ $equal-&gt;[1]
++ ),
++ &quot;$equal-&gt;[0] is equal as $equal-&gt;[1]&quot;
++ );
++ ok(
++ !Youri::Check::Input::Updates::is_newer(
++ $equal-&gt;[1],
++ $equal-&gt;[0]
++ ),
++ &quot;$equal-&gt;[1] is equal as $equal-&gt;[0]&quot;
++ );
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/version.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment.html
new file mode 100644
index 000000000..0274c6c96
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/797a51f6/attachment.html
@@ -0,0 +1,11434 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[210] add mandriva version of youri-core, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/core/trunk/ at revision 271600</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>210</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 14:23:45 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add mandriva version of youri-core, downloaded from http://svn.mandriva.com/svn/soft/build_system/youri/core/trunk/ at revision 271600</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>build_system/mdv-youri-core/</li>
+<li>build_system/mdv-youri-core/branches/</li>
+<li>build_system/mdv-youri-core/tags/</li>
+<li>build_system/mdv-youri-core/trunk/</li>
+<li><a href="#build_systemmdvyouricoretrunkChangeLog">build_system/mdv-youri-core/trunk/ChangeLog</a></li>
+<li><a href="#build_systemmdvyouricoretrunkMANIFESTSKIP">build_system/mdv-youri-core/trunk/MANIFEST.SKIP</a></li>
+<li><a href="#build_systemmdvyouricoretrunkMakefilePL">build_system/mdv-youri-core/trunk/Makefile.PL</a></li>
+<li><a href="#build_systemmdvyouricoretrunkREADME">build_system/mdv-youri-core/trunk/README</a></li>
+<li><a href="#build_systemmdvyouricoretrunkTODO">build_system/mdv-youri-core/trunk/TODO</a></li>
+<li>build_system/mdv-youri-core/trunk/bin/</li>
+<li><a href="#build_systemmdvyouricoretrunkbinfillbugzilla">build_system/mdv-youri-core/trunk/bin/fillbugzilla</a></li>
+<li>build_system/mdv-youri-core/trunk/cgi/</li>
+<li><a href="#build_systemmdvyouricoretrunkcgimaintainerscgi">build_system/mdv-youri-core/trunk/cgi/maintainers.cgi</a></li>
+<li>build_system/mdv-youri-core/trunk/etc/</li>
+<li>build_system/mdv-youri-core/trunk/etc/bash_completion.d/</li>
+<li><a href="#build_systemmdvyouricoretrunketcbash_completiondyouri">build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri</a></li>
+<li><a href="#build_systemmdvyouricoretrunketccheckconf">build_system/mdv-youri-core/trunk/etc/check.conf</a></li>
+<li><a href="#build_systemmdvyouricoretrunketcuploadconf">build_system/mdv-youri-core/trunk/etc/upload.conf</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriBugzillapm">build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputAgepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceIurtpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceLBDpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildSourcepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputBuildpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputConflictspm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputDependenciespm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputMandrivaConflictspm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputMissingpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputOrphanspm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputRpmlintpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputSignaturepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceCPANpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceDebianpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFedorapm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFreshmeatpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGNOMEpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGentoopm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceNetBSDpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceRAApm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceSourceforgepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourcepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputUpdatespm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckInputpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencesFilepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencespm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverBugzillapm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverCGIpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatHTMLpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatRSSpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatTextpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputFilepm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/</li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatHTMLpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatTextpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputMailpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckOutputpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckResultsetDBIpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckResultsetIteratorpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriCheckResultsetpm">build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriConfigpm">build_system/mdv-youri-core/trunk/lib/Youri/Config.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Media/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriMediaURPMpm">build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriMediapm">build_system/mdv-youri-core/trunk/lib/Youri/Media.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Package/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageRPMpm">build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageRPM4pm">build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageTestpm">build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackageURPMpm">build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriPackagepm">build_system/mdv-youri-core/trunk/lib/Youri/Package.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/lib/Youri/Repository/</li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositoryMandriva_uploadpm">build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositoryMandriva_upload_prepm">build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositoryPLFpm">build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriRepositorypm">build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm</a></li>
+<li><a href="#build_systemmdvyouricoretrunklibYouriUtilspm">build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm</a></li>
+<li>build_system/mdv-youri-core/trunk/t/</li>
+<li><a href="#build_systemmdvyouricoretrunkt00distributiont">build_system/mdv-youri-core/trunk/t/00distribution.t</a></li>
+<li><a href="#build_systemmdvyouricoretrunktcowsay30311mdv20070noarchrpm">build_system/mdv-youri-core/trunk/t/cowsay-3.03-11mdv2007.0.noarch.rpm</a></li>
+<li>build_system/mdv-youri-core/trunk/t/gpghome/</li>
+<li><a href="#build_systemmdvyouricoretrunktgpghomepubringgpg">build_system/mdv-youri-core/trunk/t/gpghome/pubring.gpg</a></li>
+<li><a href="#build_systemmdvyouricoretrunktgpghomesecringgpg">build_system/mdv-youri-core/trunk/t/gpghome/secring.gpg</a></li>
+<li><a href="#build_systemmdvyouricoretrunktgpghometrustdbgpg">build_system/mdv-youri-core/trunk/t/gpghome/trustdb.gpg</a></li>
+<li><a href="#build_systemmdvyouricoretrunktpackaget">build_system/mdv-youri-core/trunk/t/package.t</a></li>
+<li><a href="#build_systemmdvyouricoretrunktversiont">build_system/mdv-youri-core/trunk/t/version.t</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="build_systemmdvyouricoretrunkChangeLog">Added: build_system/mdv-youri-core/trunk/ChangeLog</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/ChangeLog (rev 0)
++++ build_system/mdv-youri-core/trunk/ChangeLog 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,2 @@
++2006-04-23 Guillaume Rousse &lt;guillomovitch@zarb.org&gt; 0.9
++ * initial release
+
+<a id="build_systemmdvyouricoretrunkMANIFESTSKIP">Added: build_system/mdv-youri-core/trunk/MANIFEST.SKIP</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/MANIFEST.SKIP (rev 0)
++++ build_system/mdv-youri-core/trunk/MANIFEST.SKIP 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,14 @@
++CVS/.*
++\.svn/.*
++^cover_db/
++^blib/
++\.bak$
++\.swp$
++\.tar$
++\.tgz$
++\.tar\.gz$
++\.SKIP$
++~$
++^pm_to_blib$
++^Makefile$
++^Makefile\.old$
+
+<a id="build_systemmdvyouricoretrunkMakefilePL">Added: build_system/mdv-youri-core/trunk/Makefile.PL</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/Makefile.PL (rev 0)
++++ build_system/mdv-youri-core/trunk/Makefile.PL 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,31 @@
++# $Id: Makefile.PL 1724 2006-10-17 13:55:27Z warly $
++use ExtUtils::MakeMaker;
++
++WriteMakefile(
++ NAME =&gt; 'youri-core',
++ VERSION =&gt; 0.9,
++ AUTHOR =&gt; 'Youri project &lt;youri@zarb.org&gt;',
++ PREREQ_PM =&gt; {
++ 'AppConfig' =&gt; 0,
++ 'YAML' =&gt; 0,
++ 'Pod::Simple::HTMLBatch' =&gt; 0,
++ 'Test::Exception' =&gt; 0,
++ 'Exception' =&gt; 0,
++ 'RPM4' =&gt; 0,
++ 'URPM' =&gt; 0
++ }
++);
++
++package MY;
++
++sub top_targets {
++ my ($self) = @_;
++ my $top_targets = $self-&gt;SUPER::top_targets(@_);
++ $top_targets =~ s/all :: pure_all manifypods/all :: pure_all manifypods htmlifypods/;
++ $top_targets .= &lt;&lt;'EOF';
++htmlifypods : $(TO_INST_PM)
++ if [ ! -d blib/html ]; then mkdir blib/html; fi
++ perl -MPod::Simple::HTMLBatch -e Pod::Simple::HTMLBatch::go lib blib/html
++EOF
++ return $top_targets;
++}
+
+<a id="build_systemmdvyouricoretrunkREADME">Added: build_system/mdv-youri-core/trunk/README</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/README (rev 0)
++++ build_system/mdv-youri-core/trunk/README 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,33 @@
++youri-core
++----------
++
++Youri core libraries.
++
++Description
++-----------
++YOURI stands for &quot;Youri Offers an Upload &amp; Repository Infrastucture&quot;. It aims
++to build tools making management of a coherent set of packages easier.
++
++This package provides basic components used by other youri programs.
++
++Installation
++------------
++To install, just use:
++perl Makefile.PL
++make
++make test
++
++Copyright and License
++---------------------
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under
++the same terms as Perl itself.
++
++Authors
++-------
++Guillaume Rousse &lt;guillomovitch@zarb.org&gt;,
++Pascal Terjan &lt;pterjan@zarb.org&gt;
++Damien Krotkine &lt;dams@zarb.org&gt;
++Olivier Thauvin &lt;nanardon@zarb.org&gt;
++Ville Skytt\xE4 &lt;ville.skytta@iki.fi&gt;
+
+<a id="build_systemmdvyouricoretrunkTODO">Added: build_system/mdv-youri-core/trunk/TODO</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/TODO (rev 0)
++++ build_system/mdv-youri-core/trunk/TODO 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,7 @@
++1.0 Goals
++=========
++
++library:
++- API-based bugzilla interface, instead of SQL-based one
++- more generic check-specific options handling in medias (don't use a
++specific attribute for each of them)
+
+<a id="build_systemmdvyouricoretrunkbinfillbugzilla">Added: build_system/mdv-youri-core/trunk/bin/fillbugzilla</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/bin/fillbugzilla (rev 0)
++++ build_system/mdv-youri-core/trunk/bin/fillbugzilla 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,81 @@
++#!/usr/bin/perl
++# fillbugzilla
++# copyright (c) 2002 Guillaume Rousse &lt;guillomovitch@zarb.org&gt;
++# $Id: fillbugzilla 1179 2006-08-05 08:30:57Z warly $
++
++use strict;
++use warnings;
++use Getopt::Long;
++use Bugzilla;
++use Mail::Sendmail;
++
++# constants
++my $name = &quot;fillbugzilla&quot;;
++my $version = &quot;1.0&quot;;
++
++# command-line parameters
++my ($base, $user, $pass, $project, $mode, $help);
++GetOptions(
++ &quot;base=s&quot; =&gt; \$base,
++ &quot;user=s&quot; =&gt; \$user,
++ &quot;pass=s&quot; =&gt; \$pass,
++ &quot;mode=s&quot; =&gt; \$mode,
++ &quot;help&quot; =&gt; \$help,
++);
++
++# mandatory argument
++die usage() unless ($base &amp;&amp; $user &amp;&amp; $pass);
++die usage() unless ($mode eq 'package' || $mode eq 'packager');
++
++usage() &amp;&amp; exit 0 if $help;
++
++my $bugzilla = Bugzilla-&gt;new('localhost', $base, $user, $pass);
++
++if ($mode eq 'packager') {
++ while (my $packager = &lt;&gt;) {
++ chomp $packager;
++ my ($name, $login) = split(/\t/, $packager);
++
++ # random passwd
++ my @chars = (0..9, 'A'..'Z', 'a'..'z', '-', '_', '!', '@', '#', '$', '%', '^', '&amp;', '*');
++ my $password = join('', map { $chars[rand(scalar @chars)] } 1 .. 8);
++
++ # insert into database
++ $bugzilla-&gt;add_packager($name, $login, $password);
++
++ # mail user
++ my %mail = (
++ smtp =&gt; 'localhost',
++ To =&gt; $login,
++ From =&gt; 'bugmaster@zarb.org',
++ Subject =&gt; 'bugzilla password',
++ 'X-Mailer' =&gt; &quot;$name $version&quot;,
++ );
++ $mail{Message} .= &quot;login: $login\n&quot;;
++ $mail{Message} .= &quot;password: $password\n&quot;;
++ sendmail(%mail) or warn $Mail::Sendmail::error;
++ }
++}
++
++if ($mode eq 'package') {
++ while (my $line = &lt;&gt;) {
++ chomp $line;
++ my ($name, $summary, $version, $maintainer) = split(/\t/, $line);
++ $bugzilla-&gt;add_package($name, $summary, $version, $maintainer);
++ }
++}
++
++sub usage {
++ print &lt;&lt;EOF;
++$name $version
++
++Usage:
++$name --base &lt;base&gt; --user &lt;user&gt; --pass &lt;pass&gt; --mode &lt;mode&gt; &lt; $file
++
++Options:
++--base &lt;base&gt; bugzilla base name
++--user &lt;user&gt; bugzilla base user
++--pass &lt;pass&gt; bugzilla base password
++--mode &lt;mode&gt; package or packager
++EOF
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/bin/fillbugzilla
+___________________________________________________________________
+<a id="svnexecutable">Added: svn:executable</a>
+ + *
+
+<a id="build_systemmdvyouricoretrunkcgimaintainerscgi">Added: build_system/mdv-youri-core/trunk/cgi/maintainers.cgi</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/cgi/maintainers.cgi (rev 0)
++++ build_system/mdv-youri-core/trunk/cgi/maintainers.cgi 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,65 @@
++#!/usr/bin/perl
++# $Id: maintainers.cgi 1179 2006-08-05 08:30:57Z warly $
++
++=head1 NAME
++
++maintainers.cgi - youri CGI interface to maintainers list
++
++=head1 VERSION
++
++Version 1.0
++
++=head1 DESCRIPTION
++
++This script allows to get package maintainers list through CGI interface.
++
++=head1 SYNOPSIS
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2004-2005, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=head1 AUTHORS
++
++Guillaume Rousse &lt;guillomovitch@zarb.org&gt;,
++
++=cut
++
++use Youri::Bugzilla;
++use CGI;
++use AppConfig qw/:argcount :expand/;
++use strict;
++use warnings;
++
++my $config = AppConfig-&gt;new(
++ {
++ GLOBAL =&gt; {
++ DEFAULT =&gt; undef,
++ EXPAND =&gt; EXPAND_ALL,
++ ARGCOUNT =&gt; ARGCOUNT_ONE,
++ }
++ },
++ host =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++ base =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++ user =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++ pass =&gt; { ARGCOUNT =&gt; ARGCOUNT_ONE },
++);
++
++my $home = (getpwnam($ENV{PROJECT}))[7];
++foreach my $file (&quot;/etc/youri/maintainers.conf&quot;, &quot;$home/.youri/maintainers.conf&quot;) {
++ $config-&gt;file($file) if -f $file &amp;&amp; -r $file;
++}
++
++my $bugzilla = Bugzilla-&gt;new(
++ $config-&gt;host(),
++ $config-&gt;base(),
++ $config-&gt;user(),
++ $config-&gt;pass(),
++);
++
++my $cgi = CGI-&gt;new();
++print $cgi-&gt;header(-type=&gt;'text/plain');
++
++$bugzilla-&gt;browse_packages(sub { print &quot;$_[0]\t$_[2]\n&quot;; });
+
+
+Property changes on: build_system/mdv-youri-core/trunk/cgi/maintainers.cgi
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyouricoretrunketcbash_completiondyouri">Added: build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri (rev 0)
++++ build_system/mdv-youri-core/trunk/etc/bash_completion.d/youri 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,141 @@
++# youri tools completion
++# $Id$
++
++_youri-check()
++{
++
++ local cur prev config i mode
++
++ COMPREPLY=()
++ cur=${COMP_WORDS[COMP_CWORD]}
++ prev=${COMP_WORDS[COMP_CWORD-1]}
++
++ case &quot;$prev&quot; in
++ --config)
++ _filedir
++ return 0
++ ;;
++ --skip-plugin)
++ _find_config check.conf
++ if [ -n &quot;$config&quot; ]; then
++ # try to guess mode
++ for (( i=1; i &lt; COMP_CWORD; i++ )); do
++ if [[ &quot;${COMP_WORDS[i]}&quot; != -* ]]; then
++ mode=${COMP_WORDS[i]}
++ break
++ fi
++ done
++
++ if [ -n $mode ]; then
++ COMPREPLY=( $( awk -F= '/^'$mode's/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ fi
++ return 0
++ ;;
++ --skip-media)
++ _find_config check.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^medias/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ return 0
++ ;;
++ esac
++
++ if [[ &quot;$cur&quot; == -* ]]; then
++ COMPREPLY=( $( compgen -W '--config --skip-plugin --skip-media -h \
++ --help -t --test -v --verbose' -- $cur ) )
++ else
++ _count_args
++ case $args in
++ 1)
++ COMPREPLY=( $( compgen -W 'input output' -- $cur ) )
++ ;;
++ esac
++ fi
++
++}
++complete -F _youri-check youri-check
++
++_youri-upload()
++{
++
++ local cur prev config
++
++ COMPREPLY=()
++ cur=${COMP_WORDS[COMP_CWORD]}
++ prev=${COMP_WORDS[COMP_CWORD-1]}
++
++ case &quot;$prev&quot; in
++ --config)
++ _filedir
++ return 0
++ ;;
++ --skip-check)
++ _find_config upload.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^checks/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ return 0
++ ;;
++ --skip-action)
++ _find_config upload.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^actions/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ return 0
++ ;;
++ esac
++
++ if [[ &quot;$cur&quot; == -* ]]; then
++ COMPREPLY=( $( compgen -W '--config --skip-check --skip-action \
++ --define -h --help -t --test -v --verbose' -- $cur ) )
++ else
++ _count_args
++ case $args in
++ 1)
++ _find_config upload.conf
++ if [ -n &quot;$config&quot; ]; then
++ COMPREPLY=( $( awk -F= '/^targets/ {print $2}' $config \
++ | grep &quot;^$cur&quot; ) )
++ fi
++ ;;
++ *)
++ _filedir
++ ;;
++ esac
++ fi
++
++}
++complete -F _youri-upload youri-upload
++
++_find_config()
++{
++ local name i
++
++ name=$1
++
++ for (( i=1; i &lt; COMP_CWORD; i++ )); do
++ if [[ &quot;${COMP_WORDS[i]}&quot; == --config ]]; then
++ config=${COMP_WORDS[i+1]}
++ break
++ fi
++ done
++ if [ -f &quot;$config&quot; ]; then
++ return 0
++ fi
++
++ if [ -f &quot;$HOME/.youri/$name&quot; ]; then
++ config=$HOME/.youri/$name
++ return 0
++ fi
++
++ if [ -f &quot;/etc/youri/$name&quot; ]; then
++ config=/etc/youri/$name
++ return 0
++ fi
++
++}
+
+<a id="build_systemmdvyouricoretrunketccheckconf">Added: build_system/mdv-youri-core/trunk/etc/check.conf</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/etc/check.conf (rev 0)
++++ build_system/mdv-youri-core/trunk/etc/check.conf 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,300 @@
++# youri-check sample configuration file
++# $Id: check.conf 1179 2006-08-05 08:30:57Z warly $
++
++# resolver declaration
++resolver = cgi
++
++# preferences declaration
++preferences = file_pref
++
++# resultset declaration
++resultset = dbi
++
++# input plugins declaration
++inputs = rpmlint \
++ age \
++ updates \
++ build \
++ conflicts \
++ dependencies \
++ missing \
++ orphans
++
++# output plugins declaration
++outputs = file mail
++
++# medias declaration
++medias = main.i586 \
++ main.x86_64 \
++ main.sources \
++ contrib.i586 \
++ contrib.x86_64 \
++ contrib.sources \
++ free \
++ non-free \
++ free.sources \
++ non-free.sources
++
++# helper variables
++mirror = ftp://ftp.free.fr/pub/Distributions_Linux/Mandrakelinux/devel/cooker
++mirror_i586 = $mirror/i586/media
++mirror_x86_64 = $mirror/x86_64/media
++
++# resolver definition
++[cgi]
++class = Youri::Check::Maintainer::Resolver::CGI
++url = http://plf.zarb.org/cgi-bin/maintainers.cgi
++
++# preferences definition
++[file_pref]
++class = Youri::Check::Maintainer::Preferences::File
++
++# resultset definition
++[dbi]
++class = Youri::Check::Resultset::DBI
++driver = mysql
++host = localhost
++base = plf_youri
++user = plf
++pass = s3kr3t
++
++# checks definitions
++[updates]
++class = Youri::Check::Input::Updates
++aliases = &lt;&lt;EOF
++--- #YAML:1.0
++libfame0.8: ~
++EOF
++sources = &lt;&lt;EOF
++--- #YAML:1.0
++debian:
++ class: Youri::Check::Input::Updates::Source::Debian
++ aliases:
++ fuse-emulator: ~
++cpan:
++ class: Youri::Check::Input::Updates::Source::CPAN
++fedora:
++ class: Youri::Check::Input::Updates::Source::Fedora
++gentoo:
++ class: Youri::Check::Input::Updates::Source::Gentoo
++freshmeat:
++ class: Youri::Check::Input::Updates::Source::Freshmeat
++netbsd:
++ class: Youri::Check::Input::Updates::Source::NetBSD
++raa:
++ class: Youri::Check::Input::Updates::Source::RAA
++sourceforge:
++ class: Youri::Check::Input::Updates::Source::Sourceforge
++ aliases:
++ openquicktime: ~
++ klibido: ~
++EOF
++
++[rpmlint]
++class = Youri::Check::Input::Rpmlint
++
++[age]
++class = Youri::Check::Input::Age
++max_age = 12 months
++pattern = %m months
++
++[dependencies]
++class = Youri::Check::Input::Dependencies
++
++[conflicts]
++class = Youri::Check::Input::Conflicts
++
++[build]
++class = Youri::Check::Input::Build
++sources = &lt;&lt;EOF
++--- #YAML:1.0
++stefan:
++ class: Youri::Check::Input::Build::Source::LBD
++ url: http://eijk.homelinux.org/build/
++ medias:
++ - cooker_plf-free
++ - cooker_plf-non-free
++ archs:
++ - i586
++EOF
++
++[missing]
++class = Youri::Check::Input::Missing
++
++[orphans]
++class = Youri::Check::Input::Orphans
++
++# reports definitions
++[file]
++class = Youri::Check::Output::File
++to = ${HOME}/www/qa
++global = 1
++individual = 1
++formats = &lt;&lt;EOF
++--- #YAML:1.0
++html:
++ class: Youri::Check::Output::File::Format::HTML
++text:
++ class: Youri::Check::Output::File::Format::Text
++rss:
++ class: Youri::Check::Output::File::Format::RSS
++EOF
++
++[mail]
++class = Youri::Check::Output::Mail
++mta = /usr/sbin/sendmail
++to = plf-admin@zarb.org
++from = plf@zarb.org
++reply_to = plf-admin@zarb.org
++formats = &lt;&lt;EOF
++--- #YAML:1.0
++text:
++ class: Youri::Check::Output::Mail::Format::Text
++EOF
++
++# media definitions
++[main.i586]
++class = Youri::Media::URPM
++name = main
++type = binary
++path = $mirror_i586/main
++hdlist = $mirror_i586/media_info/hdlist_main.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[main.x86_64]
++class = Youri::Media::URPM
++name = main
++type = binary
++path = $mirror_x86_64/main
++hdlist = $mirror_x86_64/media_info/hdlist_main.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[main.sources]
++class = Youri::Media::URPM
++name = main
++type = source
++path = $mirror_i586/main
++hdlist = $mirror_i586/media_info/hdlist_main.src.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[contrib.i586]
++class = Youri::Media::URPM
++name = contrib
++type = binary
++path = $mirror_i586/contrib
++hdlist = $mirror_i586/media_info/hdlist_contrib.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[contrib.x86_64]
++class = Youri::Media::URPM
++name = contrib
++type = binary
++path = $mirror_x86_64/contrib
++hdlist = $mirror_x86_64/media_info/hdlist_contrib.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[contrib.sources]
++class = Youri::Media::URPM
++name = contrib
++type = source
++path = $mirror_i586/contrib
++hdlist = $mirror_i586/media_info/hdlist_contrib.src.cz
++skip_inputs = &lt;&lt;EOF
++--- #YAML:1.0
++- all
++EOF
++
++[free]
++class = Youri::Media::URPM
++name = free
++type = binary
++path = ${HOME}/ftp/mandrake/free/cooker/i586
++hdlist = ${HOME}/ftp/mandrake/free/cooker/i586/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- main.x86_64
++- contrib.i586
++- contrib.x86_64
++- free
++EOF
++allow_srcs = &lt;&lt;EOF
++--- #YAML:1.0
++- free.sources
++- main.sources
++- contrib.sources
++EOF
++skip_archs = &lt;&lt;EOF
++--- #YAML:1.0
++- ppc
++EOF
++
++[free.sources]
++class = Youri::Media::URPM
++name = free
++type = source
++path = ${HOME}/ftp/mandrake/free/src
++hdlist = ${HOME}/ftp/mandrake/free/src/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- contrib.i586
++- free
++EOF
++
++[non-free]
++class = Youri::Media::URPM
++name = non-free
++type = binary
++path = ${HOME}/ftp/mandrake/non-free/cooker/i586
++hdlist = ${HOME}/ftp/mandrake/non-free/cooker/i586/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-non-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- main.x86_64
++- contrib.i586
++- contrib.x86_64
++- free
++- non-free
++EOF
++allow_srcs = &lt;&lt;EOF
++--- #YAML:1.0
++- non-free.sources
++EOF
++skip_archs = &lt;&lt;EOF
++--- #YAML:1.0
++- ppc
++EOF
++
++[non-free.sources]
++class = Youri::Media::URPM
++name = non-free
++type = source
++path = ${HOME}/ftp/mandrake/non-free/src
++hdlist = ${HOME}/ftp/mandrake/non-free/src/hdlist.cz
++rpmlint_config = ${HOME}/etc/rpmlint-non-free.conf
++allow_deps = &lt;&lt;EOF
++--- #YAML:1.0
++- main.i586
++- contrib.i586
++- free
++- non-free
++EOF
+
+<a id="build_systemmdvyouricoretrunketcuploadconf">Added: build_system/mdv-youri-core/trunk/etc/upload.conf</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/etc/upload.conf (rev 0)
++++ build_system/mdv-youri-core/trunk/etc/upload.conf 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,139 @@
++# youri-upload sample configuration file
++# $Id: upload.conf 1179 2006-08-05 08:30:57Z warly $
++
++# repository declaration
++repository = plf
++
++# targets declaration
++targets = cooker 2006.0
++
++# repository definition
++[plf]
++class = Youri::Repository::PLF
++install_root = ${HOME}/ftp/mandriva
++version_root = ${HOME}/cvs
++archive_root = ${HOME}/backup/mandriva
++noarch = i586
++
++# targets definition
++[cooker]
++checks = &lt;&lt;EOF
++--- #YAML:1.0
++- tag
++- recency
++- history
++EOF
++actions = &lt;&lt;EOF
++--- #YAML:1.0
++- sign
++- install
++- link
++- archive
++- clean
++- bugzilla
++- cvs
++- mail
++- rss
++EOF
++
++[2006.0]
++checks = &lt;&lt;EOF
++--- #YAML:1.0
++- type
++- tag
++- recency
++- history
++- precedence
++EOF
++actions = &lt;&lt;EOF
++--- #YAML:1.0
++- sign
++- install
++- link
++- archive
++- clean
++EOF
++
++# checks definition
++[tag]
++class = Youri::Upload::Check::Tag
++tags = &lt;&lt;EOF
++--- #YAML:1.0
++release: 'plf$'
++packager: '&lt;\w+@zarb\.org&gt;$'
++distribution: '^Mandriva Linux$'
++vendor: '^Penguin Liberation Front$'
++EOF
++
++[recency]
++class = Youri::Upload::Check::Recency
++
++[history]
++class = Youri::Upload::Check::History
++
++[precedence]
++class = Youri::Upload::Check::Precedence
++target = cooker
++
++[type]
++class = Youri::Upload::Check::Type
++type = binary
++
++# actions definitions
++[sign]
++class = Youri::Upload::Action::Sign
++name = plf@zarb.org
++path = ${HOME}/.gnupg
++passphrase = s3kr3t
++
++[install]
++class = Youri::Upload::Action::Install
++
++[link]
++class = Youri::Upload::Action::Link
++
++[archive]
++class = Youri::Upload::Action::Archive
++
++[clean]
++class = Youri::Upload::Action::Clean
++
++[mail]
++class = Youri::Upload::Action::Mail
++mta = /usr/sbin/sendmail
++to = plf-announce@zarb.org
++reply_to = plf-discuss@zarb.org
++from = plf@zarb.org
++prefix = RPM
++cc = &lt;&lt;EOF
++--- #YAML:1.0
++hot-base: david@dindinx.org bellamy@neverland.net
++dcgui: mathen@ketelhot.de
++dclib: mathen@ketelhot.de
++Video-DVDRip: dvdrip-users@exit1.org
++hackVideo-DVDRip: dvdrip-users@exit1.org
++goosnes: tak@bard.sytes.net
++avidemux: fixounet@free.fr
++vobcopy: robos@muon.de
++drip: drip-devel@lists.sourceforge.net
++libdscaler: vektor@dumbterm.net
++xawdecode: pingus77@ifrance.com
++EOF
++
++[rss]
++class = Youri::Upload::Action::RSS
++file = ${HOME}/www/changelog.rss
++title = PLF packages updates
++link = http://plf.zarb.org/
++description = ChangeLog for PLF packages
++
++[cvs]
++class = Youri::Upload::Action::CVS
++
++[bugzilla]
++class = Youri::Upload::Action::Bugzilla
++host = localhost
++base = plf_bugs
++user = plf
++pass = s3kr3t
++contact = plf@zarb.org
+
+<a id="build_systemmdvyouricoretrunklibYouriBugzillapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Bugzilla.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,482 @@
++# $Id: Bugzilla.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Bugzilla;
++
++=head1 NAME
++
++Youri::Bugzilla - Youri Bugzilla interface
++
++=head1 SYNOPSIS
++
++ use Youri::Bugzilla;
++
++ my $bugzilla = Youri::Bugzilla-&gt;new($host, $base, $user, $pass);
++
++ print $bugzilla-&gt;get_maintainer('foobar');
++
++=head1 DESCRIPTION
++
++This module implement a database-level Bugzilla interface for managing packages.
++
++The legacy Bugzilla database model is mapped this way:
++
++=over
++
++=item *
++
++a maintainer is a user
++
++=item *
++
++a package is a product
++
++=item *
++
++each package has two pseudo components &quot;program&quot; and &quot;package&quot;, owned by the package maintainer
++
++=back
++
++=cut
++
++use DBI;
++use Carp;
++use strict;
++use warnings;
++
++my %queries = (
++ get_package_id =&gt; 'SELECT id FROM products WHERE name = ?',
++ get_maintainer_id =&gt; 'SELECT userid FROM profiles WHERE login_name = ?',
++ get_versions =&gt; 'SELECT value FROM versions WHERE product_id = ?',
++ get_components =&gt; 'SELECT name FROM components WHERE product_id = ?',
++ add_package =&gt; 'INSERT INTO products (name, description) VALUES (?, ?)',
++ add_maintainer =&gt; 'INSERT INTO profiles (login_name, cryptpassword, realname, emailflags, refreshed_when) VALUES (?, ENCRYPT(?), ?, ?, SYSDATE())',
++ add_component =&gt; 'INSERT INTO components (product_id, name, description,initialowner, initialqacontact) VALUES (?, ?, ?, ?, ?)',
++ add_version =&gt; 'INSERT INTO versions (product_id, value) VALUES (?, ?)',
++ del_package =&gt; 'DELETE FROM products WHERE product = ?',
++ del_maintainer =&gt; 'DELETE FROM profiles WHERE login_name = ?',
++ del_components =&gt; 'DELETE FROM components WHERE program = ?',
++ del_versions =&gt; 'DELETE FROM versions WHERE program = ?',
++ reset_password =&gt; 'UPDATE profiles SET cryptpassword = ENCRYPT(?) WHERE login_name = ?',
++ browse_packages =&gt; &lt;&lt;EOF,
++SELECT products.name, max(versions.value), login_name
++FROM products, versions, profiles, components
++WHERE versions.product_id = products.id
++ AND components.product_id = products.id
++ AND profiles.userid = components.initialowner
++ AND components.name = 'package'
++GROUP BY name
++EOF
++ get_maintainer =&gt; &lt;&lt;EOF
++SELECT login_name
++FROM profiles, components, products
++WHERE profiles.userid = components.initialowner
++ AND components.name = 'package'
++ AND components.product_id = products.id
++ AND products.name = ?
++EOF
++);
++
++my @default_flags = qw/
++ ExcludeSelf
++ FlagRequestee
++ FlagRequester
++ emailOwnerRemoveme
++ emailOwnerComments
++ emailOwnerAttachments
++ emailOwnerStatus
++ emailOwnerResolved
++ emailOwnerKeywords
++ emailOwnerCC
++ emailOwnerOther
++ emailOwnerUnconfirmed
++ emailReporterRemoveme
++ emailReporterComments
++ emailReporterAttachments
++ emailReporterStatus
++ emailReporterResolved
++ emailReporterKeywords
++ emailReporterCC
++ emailReporterOther
++ emailReporterUnconfirmed
++ emailQAcontactRemoveme
++ emailQAcontactComments
++ emailQAcontactAttachments
++ emailQAcontactStatus
++ emailQAcontactResolved
++ emailQAcontactKeywords
++ emailQAcontactCC
++ emailQAcontactOther
++ emailQAcontactUnconfirmed
++ emailCClistRemoveme
++ emailCClistComments
++ emailCClistAttachments
++ emailCClistStatus
++ emailCClistResolved
++ emailCClistKeywords
++ emailCClistCC
++ emailCClistOther
++ emailCClistUnconfirmed
++ emailVoterRemoveme
++ emailVoterComments
++ emailVoterAttachments
++ emailVoterStatus
++ emailVoterResolved
++ emailVoterKeywords
++ emailVoterCC
++ emailVoterOther
++ emailVoterUnconfirmed
++/;
++
++my $default_flags = join('~', map { &quot;$_~on&quot; } @default_flags);
++
++=head1 CLASS METHODS
++
++Except stated otherwise, maintainers are specified by their login, and packages
++are specified by their name.
++
++=head2 new($host, $base, $user, $password)
++
++Creates a new L&lt;Youri::Bugzilla&gt; object, wrapping bugzilla database I&lt;$base&gt;
++hosted on I&lt;$host&gt;, and accessed by user I&lt;$user&gt; with password I&lt;$password&gt;.
++
++=cut
++
++sub new {
++ my ($class, $host, $base, $user, $pass) = @_;
++
++ my $dbh = DBI-&gt;connect(&quot;DBI:mysql:database=$base;host=$host&quot;, $user, $pass) or croak &quot;Unable to connect: $DBI::errstr&quot;;
++
++ my $self = bless {
++ _dbh =&gt; $dbh
++ }, $class;
++
++ return $self;
++}
++
++=head1 INSTANCE METHODS
++
++=head2 has_package($package)
++
++Return true if bugzilla contains given package.
++
++=cut
++
++sub has_package {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_package_id($package);
++}
++
++=head2 has_maintainer($maintainer)
++
++Return true if bugzilla contains given maintainer.
++
++=cut
++
++sub has_maintainer {
++ my ($self, $maintainer) = @_;
++ return $self-&gt;_get_maintainer_id($maintainer);
++}
++
++=head2 get_maintainer($package)
++
++Return maintainer of given package.
++
++=cut
++
++sub get_maintainer {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_single('get_maintainer', $package);
++}
++
++=head2 get_versions($package)
++
++Return versions from given package.
++
++=cut
++
++sub get_versions {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_multiple(
++ 'get_versions',
++ $self-&gt;_get_package_id($package)
++ );
++}
++
++=head2 get_components($package)
++
++Return components from given package.
++
++=cut
++
++sub get_components {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_multiple(
++ 'get_components',
++ $self-&gt;_get_package_id($package)
++ );
++}
++
++=head2 get_packages()
++
++Return all packages from the database.
++
++=cut
++
++sub get_packages {
++ my ($self) = @_;
++ return $self-&gt;_get_multiple('get_packages');
++}
++
++sub _get_package_id {
++ my ($self, $package) = @_;
++ return $self-&gt;_get_single('get_package_id', $package);
++}
++
++sub _get_maintainer_id {
++ my ($self, $maintainer) = @_;
++ return $self-&gt;_get_single('get_maintainer_id', $maintainer);
++}
++
++sub _get_single {
++ my ($self, $type, $value) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{$type};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{$type});
++ $self-&gt;{_queries}-&gt;{$type} = $query;
++ }
++
++ $query-&gt;execute($value);
++
++ my @row = $query-&gt;fetchrow_array();
++ return @row ? $row[0]: undef;
++}
++
++sub _get_multiple {
++ my ($self, $type, $value) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{$type};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{$type});
++ $self-&gt;{_queries}-&gt;{$type} = $query;
++ }
++
++ $query-&gt;execute($value);
++
++ my @results;
++ while (my @row = $query-&gt;fetchrow_array()) {
++ push @results, $row[0];
++ }
++ return @results;
++}
++
++=head2 add_package($name, $summary, $version, $maintainer, $contact)
++
++Adds a new package in the database, with given name, summary, version,
++maintainer and initial QA contact.
++
++=cut
++
++sub add_package {
++ my ($self, $name, $summary, $version, $maintainer, $contact) = @_;
++ return unless ref $self;
++
++ my $maintainer_id = $self-&gt;_get_maintainer_id($maintainer);
++ unless ($maintainer_id) {
++ carp &quot;Unknown maintainer $maintainer, aborting&quot;;
++ return;
++ }
++
++ my $contact_id = $self-&gt;_get_maintainer_id($contact);
++ unless ($contact_id) {
++ carp &quot;Unknown QA contact $contact, aborting&quot;;
++ return;
++ }
++
++ my $query = $self-&gt;{_queries}-&gt;{add_package};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_package});
++ $self-&gt;{_queries}-&gt;{add_package} = $query;
++ }
++
++ $query-&gt;execute($name, $summary);
++
++ my $package_id = $self-&gt;_get_package_id($name);
++
++ $self-&gt;_add_version($package_id, $version);
++ $self-&gt;_add_component(
++ $package_id,
++ 'package',
++ 'problem related to the package',
++ $maintainer_id,
++ $contact_id
++ );
++ $self-&gt;_add_component(
++ $package_id,
++ 'program',
++ 'problem related to the program',
++ $maintainer_id,
++ $contact_id
++ );
++}
++
++=head2 add_version($package, $version)
++
++Adds a new version to given package.
++
++=cut
++
++sub add_version {
++ my ($self, $package, $version) = @_;
++ return unless ref $self;
++
++ my $package_id = $self-&gt;_get_package_id($package);
++ $self-&gt;_add_version($package_id, $version);
++}
++
++sub _add_version {
++ my ($self, $package_id, $version) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{add_version};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_version});
++ $self-&gt;{_queries}-&gt;{add_version} = $query;
++ }
++
++ $query-&gt;execute($package_id, $version);
++}
++
++
++=head2 add_maintainer($name, $login, $password)
++
++Adds a new maintainer in the database, with given name, login and password.
++
++=cut
++
++sub add_maintainer {
++ my ($self, $name, $login, $pass) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{add_maintainer};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_maintainer});
++ $self-&gt;{_queries}-&gt;{add_maintainer} = $query;
++ }
++
++ $query-&gt;execute($login, $pass, $name, $default_flags);
++}
++
++sub _add_component {
++ my ($self, $package_id, $name, $description, $maintainer_id, $contact_id) = @_;
++
++ my $query = $self-&gt;{_queries}-&gt;{add_component};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{add_component});
++ $self-&gt;{_queries}-&gt;{add_component} = $query;
++ }
++
++ $query-&gt;execute($package_id, $name, $description, $maintainer_id, $contact_id);
++}
++
++=head2 del_package($package)
++
++Delete given package from database.
++
++=cut
++
++sub del_package {
++ my ($self, $package) = @_;
++ $self-&gt;_delete('del_package', $package);
++ $self-&gt;_delete('del_versions', $package);
++ $self-&gt;_delete('del_components', $package);
++}
++
++=head2 del_maintainer($maintainer)
++
++Delete given maintainer from database.
++
++=cut
++
++sub del_maintainer {
++ my ($self, $maintainer) = @_;
++ $self-&gt;_delete('del_maintainer', $maintainer);
++}
++
++sub _delete {
++ my ($self, $type, $value) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{$type};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{$type});
++ $self-&gt;{_queries}-&gt;{$type} = $query;
++ }
++
++ $query-&gt;execute($value);
++}
++
++=head2 reset_password(I&lt;$maintainer&gt;, I&lt;$password&gt;)
++
++Reset password of a maintainer to given password.
++
++=cut
++
++sub reset_password {
++ my ($self, $login, $pass) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{reset_password};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{reset_password});
++ $self-&gt;{_queries}-&gt;{reset_password} = $query;
++ }
++
++ $query-&gt;execute($pass, $login);
++}
++
++=head2 browse_packages($callback)
++
++Browse all packages from bugzilla, and execute given callback with name and
++maintainer as argument for each of them.
++
++=cut
++
++sub browse_packages {
++ my ($self, $callback) = @_;
++ return unless ref $self;
++
++ my $query = $self-&gt;{_queries}-&gt;{browse_packages};
++ unless ($query) {
++ $query = $self-&gt;{_dbh}-&gt;prepare($queries{browse_packages});
++ $self-&gt;{_queries}-&gt;{browse_packages} = $query;
++ }
++
++ $query-&gt;execute();
++
++ while (my @row = $query-&gt;fetchrow_array()) {
++ $callback-&gt;(@row);
++ }
++}
++
++# close database connection
++sub DESTROY {
++ my ($self) = @_;
++
++ foreach my $query (values %{$self-&gt;{_queries}}) {
++ $query-&gt;finish();
++ }
++
++ $self-&gt;{_dbh}-&gt;disconnect();
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputAgepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Age.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,110 @@
++# $Id: Age.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Age;
++
++=head1 NAME
++
++Youri::Check::Input::Age - Check maximum age
++
++=head1 DESCRIPTION
++
++This plugin checks packages age, and report the ones exceeding maximum limit.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use DateTime;
++use DateTime::Format::Duration;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ buildtime
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Age object.
++
++Specific parameters:
++
++=over
++
++=item max_age $age
++
++Maximum age allowed (default: 1 year)
++
++=item pattern $pattern
++
++Pattern used to describe age (default: %Y year)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ max_age =&gt; '1 year',
++ pattern =&gt; '%Y year',
++ @_
++ );
++
++ $self-&gt;{_format} = DateTime::Format::Duration-&gt;new(
++ pattern =&gt; $options{pattern}
++ );
++
++ $self-&gt;{_now} = DateTime-&gt;from_epoch(
++ epoch =&gt; time()
++ );
++
++ $self-&gt;{_max_age} = $options{max_age};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $max_age_string = $media-&gt;max_age() ?
++ $media-&gt;max_age() :
++ $self-&gt;{_max_age};
++
++ my $max_age = $self-&gt;{_format}-&gt;parse_duration($max_age_string);
++
++ my $check = sub {
++ my ($package) = @_;
++
++ my $buildtime = DateTime-&gt;from_epoch(
++ epoch =&gt; $package-&gt;get_age()
++ );
++
++ my $age = $self-&gt;{_now}-&gt;subtract_datetime($buildtime);
++
++ if (DateTime::Duration-&gt;compare($age, $max_age) &gt; 0) {
++ my $date = $buildtime-&gt;strftime(&quot;%a %d %b %G&quot;);
++
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $package-&gt;get_arch(),
++ buildtime =&gt; $date
++ });
++ }
++ };
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceIurtpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/Iurt.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,117 @@
++# $Id: LBD.pm 574 2005-12-27 14:31:16Z guillomovitch $
++package Youri::Check::Input::Build::Source::Iurt;
++
++=head1 NAME
++
++Youri::Check::Input::Build::Source::Iurt - Iurt build log source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Build&gt; collects build logs
++available from a iurt build bot.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use base 'Youri::Check::Input::Build::Source';
++
++my %status = (
++ install_deps =&gt; 0,
++ build =&gt; 1,
++ binary_test =&gt; 2
++);
++
++my $pattern = '^('
++ . join('|', keys %status)
++ . ')_\S+-[^-]+-[^-]+\.src\.rpm\.\d+\.log$';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build::LBD object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL of logs for this iurt instance (default:
++http://qa.mandriva.com/build/iurt/cooker)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://qa.mandriva.com/build/iurt/cooker',
++ @_
++ );
++
++ $self-&gt;{_agent} = LWP::UserAgent-&gt;new();
++
++ # try to connect to base URL directly, and abort if not available
++ my $response = $self-&gt;{_agent}-&gt;head($options{url});
++ die &quot;Unavailable URL $options{url}: &quot; . $response-&gt;status_line()
++ unless $response-&gt;is_success();
++
++ $self-&gt;{_url} = $options{url};
++}
++
++sub fails {
++ my ($self, $name, $version, $release, $arch) = @_;
++
++ my $result;
++ my $url = &quot;$self-&gt;{_url}/$arch/log/$name-$version-$release.src.rpm&quot;;
++ print &quot;Fetching URL $url: &quot; if $self-&gt;{_verbose} &gt; 1;
++ my $response = $self-&gt;{_agent}-&gt;get($url);
++ print $response-&gt;status_line() . &quot;\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ if ($response-&gt;is_success()) {
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /$pattern/o;
++ my $status = $1;
++ if (
++ !$result-&gt;{status} ||
++ $status{$result-&gt;{status}} &lt; $status{$status}
++ ) {
++ $result-&gt;{status} = $status;
++ $result-&gt;{url} = $url . '/' . $href;
++ }
++ }
++ }
++
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch} = $result;
++
++ return $result-&gt;{status} &amp;&amp; $result-&gt;{status} ne 'binary_test';
++}
++
++sub status {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{status};
++}
++
++sub url {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{url};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildSourceLBDpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source/LBD.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,135 @@
++# $Id: LBD.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Build::Source::LBD;
++
++=head1 NAME
++
++Youri::Check::Input::Build::Source::LBD - LBD build log source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Build&gt; collects build logs
++available from a LBD build bot.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use base 'Youri::Check::Input::Build::Source';
++
++my @status = qw/
++ OK
++ arch_excl
++ broken
++ cannot_be_installed
++ debug
++ dependency
++ file_not_found
++ multiarch
++ problem
++ unpackaged_files
++/;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build::LBD object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL of logs for this LBD instance (default: http://eijk.homelinux.org/build)
++
++=item medias $medias
++
++List of medias monitored by this LBD instance
++
++=item archs $archs
++
++List of architectures monitored by this LBD instance
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://eijk.homelinux.org/build',
++ medias =&gt; undef,
++ archs =&gt; undef,
++ @_
++ );
++
++ my $agent = LWP::UserAgent-&gt;new();
++
++ # try to connect to base URL directly, and abort if not available
++ my $response = $agent-&gt;head($options{url});
++ die &quot;Unavailable URL $options{url}: &quot; . $response-&gt;status_line()
++ unless $response-&gt;is_success();
++
++ my $pattern = '^(\S+)-([^-]+)-([^-]+)(?:\.gz)?$';
++
++ foreach my $arch (@{$options{archs}}) {
++ foreach my $media (@{$options{medias}}) {
++ my $url_base = &quot;$options{url}/$arch/$media/BO&quot;;
++ foreach my $status (@status) {
++ my $url = &quot;$url_base/$status/&quot;;
++ print &quot;Fetching URL $url: &quot; if $self-&gt;{_verbose} &gt; 1;
++ my $response = $agent-&gt;get($url);
++ print $response-&gt;status_line() . &quot;\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ if ($response-&gt;is_success()) {
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /$pattern/o;
++ my $name = $1;
++ my $version = $2;
++ my $release = $3;
++ my $result;
++ $result-&gt;{status} = $status;
++ $result-&gt;{url} = $url . '/' . $href;
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch} = $result;
++ }
++ }
++ }
++ }
++ }
++}
++
++sub fails {
++ my ($self, $name, $version, $release, $arch) = @_;
++
++ my $status =
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{status};
++
++ return $status &amp;&amp; $status ne 'OK' &amp;&amp; $status ne 'arch_excl';
++}
++
++sub status {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{status};
++}
++
++sub url {
++ my ($self, $name, $version, $release, $arch) = @_;
++ return
++ $self-&gt;{_results}-&gt;{$name}-&gt;{$version}-&gt;{$release}-&gt;{$arch}-&gt;{url};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildSourcepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build/Source.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,109 @@
++# $Id: Source.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Build::Source;
++
++=head1 NAME
++
++Youri::Check::Input::Build::Source - Abstract build log source
++
++=head1 DESCRIPTION
++
++This abstract class defines the updates source interface for
++L&lt;Youri::Check::Input::Build&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns source identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 fails($name, $version, $release, $arch)
++
++Returns true if build fails for package with given name, version and release on
++given architecture.
++
++=head2 status($name, $version, $release, $arch)
++
++Returns exact build status for package with given name, version and release on
++given architecture. It has to be called after fails().
++
++=head2 url($name, $version, $release, $arch)
++
++Returns URL of information source for package with given name, version and
++release on given architecture. It has to be called after fails().
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item fails
++
++=item status
++
++=item url
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputBuildpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Build.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,128 @@
++# $Id: Build.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Build;
++
++=head1 NAME
++
++Youri::Check::Input::Build - Check build outputs
++
++=head1 DESCRIPTION
++
++This plugin checks build outputs of packages, and report failures. Additional
++source plugins handle specific sources.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ bot
++ status
++ /;
++}
++
++sub links {
++ return qw/
++ status url
++ /;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Build object.
++
++Specific parameters:
++
++=over
++
++=item sources $sources
++
++Hash of source plugins definitions
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ sources =&gt; undef,
++ @_
++ );
++
++ croak &quot;No source defined&quot; unless $options{sources};
++ croak &quot;sources should be an hashref&quot; unless ref $options{sources} eq 'HASH';
++
++ foreach my $id (keys %{$options{sources}}) {
++ print &quot;Creating source $id\n&quot; if $options{verbose};
++ eval {
++ push(
++ @{$self-&gt;{_sources}},
++ create_instance(
++ 'Youri::Check::Input::Build::Source',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ %{$options{sources}-&gt;{$id}}
++ )
++ );
++ # register monitored archs
++ $self-&gt;{_archs}-&gt;{$_}-&gt;{$id} = 1
++ foreach @{$options{sources}-&gt;{$id}-&gt;{archs}};
++ };
++ print STDERR &quot;Failed to create source $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no sources created&quot; unless @{$self-&gt;{_sources}};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a source media check only
++ return unless $media-&gt;get_type() eq 'source';
++
++ my $callback = sub {
++ my ($package) = @_;
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++
++ foreach my $source (@{$self-&gt;{_sources}}) {
++ my $id = $source-&gt;get_id();
++ foreach my $arch (keys %{$self-&gt;{_archs}}) {
++ next unless $self-&gt;{_archs}-&gt;{$arch}-&gt;{$id};
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ bot =&gt; $id,
++ status =&gt; $source-&gt;status($name, $version, $release, $arch),
++ url =&gt; $source-&gt;url($name, $version, $release, $arch),
++ }) if $source-&gt;fails(
++ $name,
++ $version,
++ $release,
++ $arch,
++ );
++ }
++ }
++ };
++
++ $media-&gt;traverse_headers($callback);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputConflictspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Conflicts.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,231 @@
++# $Id: Conflicts.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Conflicts;
++
++=head1 NAME
++
++Youri::Check::Input::Conflicts - Check file conflicts
++
++=head1 DESCRIPTION
++
++This plugin checks packages files, and report conflict and duplications.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use constant;
++use Youri::Package;
++use base 'Youri::Check::Input';
++
++use constant TYPE_MASK =&gt; 0170000;
++use constant TYPE_DIR =&gt; 0040000;
++
++use constant PACKAGE =&gt; 0;
++use constant MODE =&gt; 1;
++use constant MD5SUM =&gt; 2;
++
++my $compatibility = {
++ x86_64 =&gt; 'i586',
++ i586 =&gt; 'x86_64',
++ sparc64 =&gt; 'sparc',
++ sparc =&gt; 'sparc64',
++ ppc64 =&gt; 'ppc',
++ ppc =&gt; 'ppc64'
++};
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ level
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Conflicts object.
++
++No specific parameters.
++
++=cut
++
++sub prepare {
++ my ($self, @medias) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $index = sub {
++ my ($package) = @_;
++
++ # index files
++ foreach my $file ($package-&gt;get_files()) {
++ push(
++ @{$self-&gt;{_files}-&gt;{$file-&gt;[Youri::Package::FILE_NAME]}},
++ [ $package, $file-&gt;[Youri::Package::FILE_MODE], $file-&gt;[Youri::Package::FILE_MD5SUM] ]
++ );
++ }
++ };
++
++ foreach my $media (@medias) {
++ # don't index source media files
++ next unless $media-&gt;get_type() eq 'binary';
++
++ my $media_id = $media-&gt;get_id();
++ $self-&gt;{_medias}-&gt;{$media_id} = 1;
++ print STDERR &quot;Indexing media $media_id files\n&quot;
++ if $self-&gt;{_verbose};
++
++ $media-&gt;traverse_headers($index);
++ }
++}
++
++sub run {
++ my ($self, $media, $result) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a binary media check only
++ return unless $media-&gt;get_type() eq 'binary';
++
++ my $check = sub {
++ my ($package) = @_;
++
++ return if $package-&gt;get_arch() eq 'src';
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ foreach my $file ($package-&gt;get_files()) {
++
++ my $found =
++ $self-&gt;{_files}-&gt;{$file-&gt;[Youri::Package::FILE_NAME]};
++
++ my @found = $found ? @$found : ();
++
++ foreach my $found (@found) {
++ next if $found-&gt;[PACKAGE] == $package;
++ next unless compatible($found-&gt;[PACKAGE], $package);
++ next if conflict($found-&gt;[PACKAGE], $package);
++ next if replace($found-&gt;[PACKAGE], $package);
++ if (
++ ($file-&gt;[Youri::Package::FILE_MODE] &amp; TYPE_MASK) == TYPE_DIR &amp;&amp;
++ ($found-&gt;[MODE] &amp; TYPE_MASK) == TYPE_DIR
++ ) {
++ $result-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;directory $file-&gt;[Youri::Package::FILE_NAME] duplicated with package &quot; . $found-&gt;[PACKAGE]-&gt;get_name(),
++ level =&gt; Youri::Check::Input::WARNING
++ }) unless $self-&gt;_directory_duplicate_exception(
++ $package,
++ $found-&gt;[PACKAGE],
++ $file
++ );
++ } else {
++ if ($found-&gt;[MD5SUM] eq $file-&gt;[Youri::Package::FILE_MD5SUM]) {
++ $result-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;file $file-&gt;[Youri::Package::FILE_NAME] duplicated with package &quot; . $found-&gt;[PACKAGE]-&gt;get_name(),
++ level =&gt; Youri::Check::Input::WARNING
++ }) unless $self-&gt;_file_duplicate_exception(
++ $package,
++ $found-&gt;[PACKAGE],
++ $file
++ );
++ } else {
++ $result-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;non-explicit conflict on file $file-&gt;[Youri::Package::FILE_NAME] with package &quot; . $found-&gt;[PACKAGE]-&gt;get_name(),
++ level =&gt; Youri::Check::Input::ERROR
++ }) unless $self-&gt;_file_conflict_exception(
++ $package,
++ $found-&gt;[PACKAGE],
++ $file
++ );
++ }
++ }
++ }
++ }
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++# return true if $package1 is arch-compatible with $package2
++sub compatible {
++ my ($package1, $package2) = @_;
++
++ my $arch1 = $package1-&gt;get_arch();
++ my $arch2 = $package2-&gt;get_arch();
++
++ return 1 if $arch1 eq $arch2;
++
++ return 1 if $compatibility-&gt;{$arch1} &amp;&amp; $compatibility-&gt;{$arch1} eq $arch2;
++
++ return 0;
++}
++
++# return true if $package1 conflict with $package2
++# or the other way around
++sub conflict {
++ my ($package1, $package2) = @_;
++
++ my $name2 = $package2-&gt;get_name();
++
++ foreach my $conflict ($package1-&gt;get_conflicts()) {
++ return 1 if $conflict eq $name2;
++ }
++
++ my $name1 = $package1-&gt;get_name();
++
++ foreach my $conflict ($package2-&gt;get_conflicts()) {
++ return 1 if $conflict eq $name1;
++ }
++
++ return 0;
++}
++
++# return true if $package1 replace $package2
++sub replace {
++ my ($package1, $package2) = @_;
++
++
++ my $name1 = $package1-&gt;get_name();
++ my $name2 = $package2-&gt;get_name();
++
++ return 1 if $name1 eq $name2;
++
++ foreach my $obsolete ($package1-&gt;get_obsoletes()) {
++ return 1 if $obsolete-&gt;[Youri::Package::DEPENDENCY_NAME] eq $name2;
++ }
++
++ return 0;
++}
++
++sub _directory_duplicate_exception {
++ return 0;
++}
++
++sub _file_duplicate_exception {
++ return 0;
++}
++
++sub _file_conflict_exception {
++ return 0;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputDependenciespm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Dependencies.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,162 @@
++# $Id: Dependencies.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Dependencies;
++
++=head1 NAME
++
++Youri::Check::Input::Dependencies - Check dependencies consistency
++
++=head1 DESCRIPTION
++
++This class checks dependencies consistency.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Package;
++use base 'Youri::Check::Input';
++
++use constant MEDIA =&gt; 0;
++use constant RANGE =&gt; 1;
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ level
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++sub prepare {
++ my ($self, @medias) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ foreach my $media (@medias) {
++ my $media_id = $media-&gt;get_id();
++ $self-&gt;{_medias}-&gt;{$media_id} = 1;
++ print STDERR &quot;Indexing media $media_id dependencies\n&quot;
++ if $self-&gt;{_verbose};
++
++ my $index = sub {
++ my ($package) = @_;
++
++ # index provides
++ foreach my $provide ($package-&gt;get_provides()) {
++ push(
++ @{$self-&gt;{_provides}-&gt;{$provide-&gt;[Youri::Package::DEPENDENCY_NAME]}},
++ [ $media_id, $provide-&gt;[Youri::Package::DEPENDENCY_RANGE] ]
++ );
++ }
++
++ # index files
++ foreach my $file ($package-&gt;get_files()) {
++ push(
++ @{$self-&gt;{_files}-&gt;{$file-&gt;[Youri::Package::FILE_NAME]}},
++ [ $media_id, undef ]
++ );
++ }
++ };
++ $media-&gt;traverse_headers($index);
++ }
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @allowed_ids = $media-&gt;allow_deps();
++
++ # abort unless all allowed medias are present
++ foreach my $id (@allowed_ids) {
++ unless ($self-&gt;{_medias}-&gt;{$id}) {
++ carp &quot;Missing media $id, aborting&quot;;
++ return;
++ }
++ }
++
++ # index allowed medias
++ my %allowed_ids = map { $_ =&gt; 1 } @allowed_ids;
++ my $allowed_ids = join(&quot;,&quot;, @allowed_ids);
++
++ my $class = $media-&gt;get_package_class();
++
++ my $check = sub {
++ my ($package) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ foreach my $require ($package-&gt;get_requires()) {
++
++ my $found =
++ substr($require-&gt;[Youri::Package::DEPENDENCY_NAME], 0, 1) eq '/' ?
++ $self-&gt;{_files}-&gt;{$require-&gt;[Youri::Package::DEPENDENCY_NAME]} :
++ $self-&gt;{_provides}-&gt;{$require-&gt;[Youri::Package::DEPENDENCY_NAME]};
++
++ my @found = $found ? @$found : ();
++
++ if (!@found) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;$require-&gt;[Youri::Package::DEPENDENCY_NAME] not found&quot;,
++ level =&gt; Youri::Check::Input::ERROR
++ });
++ next;
++ }
++
++ my @found_in_media =
++ grep { $allowed_ids{$_-&gt;[MEDIA]} }
++ @found;
++
++ if (!@found_in_media) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;$require-&gt;[Youri::Package::DEPENDENCY_NAME] found in incorrect media $_-&gt;[MEDIA] (allowed $allowed_ids)&quot;,
++ level =&gt; Youri::Check::Input::ERROR
++ }) foreach @found;
++ next;
++ }
++
++ next unless $require-&gt;[Youri::Package::DEPENDENCY_RANGE];
++
++ my @found_in_range =
++ grep {
++ !$_-&gt;[RANGE] ||
++ $class-&gt;compare_ranges(
++ $require-&gt;[Youri::Package::DEPENDENCY_RANGE],
++ $_-&gt;[RANGE]
++ )
++ } @found_in_media;
++
++ if (!@found_in_range) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;$require-&gt;[Youri::Package::DEPENDENCY_NAME] found with incorrect range $_-&gt;[RANGE] (needed $require-&gt;[Youri::Package::DEPENDENCY_RANGE])&quot;,
++ level =&gt; Youri::Check::Input::ERROR
++ }) foreach @found_in_media;
++ next;
++ }
++ }
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputMandrivaConflictspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/MandrivaConflicts.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,63 @@
++# $Id: Conflicts.pm 533 2005-10-20 07:08:03Z guillomovitch $
++package Youri::Check::Input::MandrivaConflicts;
++
++=head1 NAME
++
++Youri::Check::Input::MandrivaConflicts - Check file conflicts on Mandriva
++
++=head1 DESCRIPTION
++
++This class checks file conflicts between packages, taking care of Mandriva
++packaging policy.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Package;
++use base 'Youri::Check::Input::Conflicts';
++
++sub _directory_duplicate_exception {
++ my ($self, $package1, $package2, $file) = @_;
++
++ # allow shared directories between devel packages of different arch
++ return 1 if _multiarch_exception($package1, $package2);
++
++ # allow shared modules directories between perl packages
++ return 1 if
++ $file-&gt;[Youri::Package::FILE_NAME] =~ /^\/usr\/lib\/perl5\/vendor_perl\// &amp;&amp;
++ $file-&gt;[Youri::Package::FILE_NAME] !~ /^(auto|[^\/]+-linux)$/;
++
++ return 0;
++}
++
++sub _file_duplicate_exception {
++ my ($self, $package1, $package2, $file) = @_;
++
++ # allow shared files between devel packages of different arch
++ return 1 if _multiarch_exception($package1, $package2);
++
++ return 0;
++}
++
++sub _multiarch_exception {
++ my ($package1, $package2) = @_;
++
++ return 1 if
++ $package1-&gt;get_canonical_name() eq $package2-&gt;get_canonical_name()
++ &amp;&amp; $package1-&gt;get_name() =~ /-devel$/
++ &amp;&amp; $package2-&gt;get_name() =~ /-devel$/;
++
++ return 0;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputMissingpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Missing.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,138 @@
++package Youri::Check::Input::Missing;
++
++=head1 NAME
++
++Youri::Check::Input::Missing - Check components consistency
++
++=head1 DESCRIPTION
++
++This plugin checks consistency between package components, and report outdated
++ones.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use List::MoreUtils qw/all any/;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ component
++ arch
++ revision
++ error
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Missing object.
++
++No specific parameters.
++
++=cut
++
++sub prepare {
++ my ($self, @medias) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ $self-&gt;{_srcs} = ();
++ foreach my $media (@medias) {
++ # only index source media
++ next unless $media-&gt;get_type() eq 'source';
++
++ my $media_id = $media-&gt;get_id();
++ $self-&gt;{_medias}-&gt;{$media_id} = 1;
++ print STDERR &quot;Indexing media $media_id packages\n&quot; if $self-&gt;{_verbose};
++
++ my $index = sub {
++ my ($package) = @_;
++ $self-&gt;{_srcs}-&gt;{$media_id}-&gt;{$package-&gt;get_name()} =
++ $package-&gt;get_version() . '-' . $package-&gt;get_release();
++ };
++
++ $media-&gt;traverse_headers($index);
++ }
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a binary media check only
++ return unless $media-&gt;get_type() eq 'binary';
++
++ my @allowed_ids = $media-&gt;allow_srcs();
++
++ # abort unless all allowed medias are present
++ foreach my $id (@allowed_ids) {
++ unless ($self-&gt;{_medias}-&gt;{$id}) {
++ carp &quot;Missing media $id, aborting&quot;;
++ return;
++ }
++ }
++
++ my $class = $media-&gt;get_package_class();
++
++ my $check_package = sub {
++ my ($package) = @_;
++ my $canonical_name = $package-&gt;get_canonical_name();
++
++ my $bin_revision =
++ $package-&gt;get_version() . '-' . $package-&gt;get_release();
++
++ my $src_revision;
++ foreach my $id (@allowed_ids) {
++ $src_revision = $self-&gt;{_srcs}-&gt;{$id}-&gt;{$canonical_name};
++ last if $src_revision;
++ }
++
++ if ($src_revision) {
++ # check if revision match
++ unless ($src_revision eq $bin_revision) {
++ if ($class-&gt;compare_versions($src_revision, $bin_revision) &gt; 0) {
++ # binary package is obsolete
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ component =&gt; $package-&gt;get_name(),
++ arch =&gt; $package-&gt;get_arch(),
++ revision =&gt; $bin_revision,
++ error =&gt; &quot;Obsolete binaries (source $src_revision found)&quot;,
++ });
++ } else {
++ # source package is obsolete
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ component =&gt; $package-&gt;get_canonical_name(),
++ arch =&gt; 'src',
++ revision =&gt; $src_revision,
++ error =&gt; &quot;Obsolete source (binaries $bin_revision found)&quot;,
++ });
++ }
++ }
++ } else {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ component =&gt; $package-&gt;get_name(),
++ arch =&gt; $package-&gt;get_arch(),
++ revision =&gt; $bin_revision,
++ error =&gt; &quot;Missing source package&quot;,
++ });
++ }
++ };
++
++ $media-&gt;traverse_headers($check_package);
++}
++
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputOrphanspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Orphans.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,74 @@
++package Youri::Check::Input::Orphans;
++
++=head1 NAME
++
++Youri::Check::Input::Orphans - Check maintainance
++
++=head1 DESCRIPTION
++
++This plugin checks maintainance status of packages, and reports unmaintained
++ones.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ error
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Orphans object.
++
++No specific parameters.
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ resolver =&gt; undef,
++ @_
++ );
++
++ croak &quot;No resolver defined&quot; unless $options{resolver};
++
++ $self-&gt;{_resolver} = $options{resolver};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a source media check only
++ return unless $media-&gt;get_type() eq 'source';
++
++ my $check = sub {
++ my ($package) = @_;
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ error =&gt; &quot;unmaintained package&quot;
++ }) unless $self-&gt;{_resolver}-&gt;get_maintainer($package);
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputRpmlintpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Rpmlint.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,113 @@
++# $Id: Rpmlint.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Rpmlint;
++
++=head1 NAME
++
++Youri::Check::Input::Rpmlint - Check packages with rpmlint
++
++=head1 DESCRIPTION
++
++This plugins checks packages with rpmlint, and reports output.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ level
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Rpmlint object.
++
++Specific parameters:
++
++=over
++
++=item path $path
++
++Path to the rpmlint executable (default: /usr/bin/rpmlint)
++
++=item config $config
++
++Specific rpmlint configuration.
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ path =&gt; '/usr/bin/rpmlint', # path to rpmlint
++ config =&gt; '', # default rpmlint configuration
++ @_
++ );
++
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_config} = $options{config};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $config = $media-&gt;rpmlint_config() ?
++ $media-&gt;rpmlint_config() :
++ $self-&gt;{_config};
++
++ my $check = sub {
++ my ($file, $package) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ my $command = &quot;$self-&gt;{_path} -f $config $file&quot;;
++ open(RPMLINT, &quot;$command |&quot;) or die &quot;Can't run $command: $!&quot;;
++ while (&lt;RPMLINT&gt;) {
++ chomp;
++ if (/^E: \Q$name\E (.+)/) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; $1,
++ level =&gt; Youri::Check::Input::ERROR
++ });
++ } elsif (/^W: \Q$name\E (.+)/) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; $1,
++ level =&gt; Youri::Check::Input::WARNING
++ });
++ }
++ }
++ close(RPMLINT);
++ };
++
++ $media-&gt;traverse_files($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputSignaturepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Signature.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,96 @@
++# $Id: Rpmlint.pm 567 2005-12-12 21:24:56Z guillomovitch $
++package Youri::Check::Input::Signature;
++
++=head1 NAME
++
++Youri::Check::Input::Signature - Check signature
++
++=head1 DESCRIPTION
++
++This plugin checks packages signature, and report unsigned ones.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ arch
++ file
++ error
++ /;
++}
++
++sub links {
++ return qw//;
++}
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Signature object.
++
++Specific parameters:
++
++=over
++
++=item key $key
++
++Expected GPG key identity
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ key =&gt; '',
++ @_
++ );
++
++ $self-&gt;{_key} = $options{key};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $check = sub {
++ my ($package) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_name();
++
++ my $key = $package-&gt;get_gpg_key();
++
++ if (!$key) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;unsigned package $name&quot;
++ });
++ } elsif ($key ne $self-&gt;{_key}) {
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ arch =&gt; $arch,
++ file =&gt; $name,
++ error =&gt; &quot;invalid key id $key for package $name (allowed $self-&gt;{_key})&quot;
++ });
++ }
++
++ };
++
++ $media-&gt;traverse_headers($check);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceCPANpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/CPAN.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,75 @@
++# $Id: CPAN.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::CPAN;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::CPAN - CPAN updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from CPAN.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::CPAN object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to CPAN full modules list (default:
++http://www.cpan.org/modules/01modules.index.html)
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://www.cpan.org/modules/01modules.index.html',
++ @_
++ );
++
++ my $versions;
++ open(INPUT, &quot;GET $options{url} |&quot;) or croak &quot;Can't fetch $options{url}: $!&quot;;
++ while (&lt;INPUT&gt;) {
++ next unless $_ =~ /&gt;([\w-]+)-([\d\.]+)\.tar\.gz&lt;\/a&gt;/;
++ $versions-&gt;{$1} = $2;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://search.cpan.org/dist/$name&quot;;
++}
++
++sub _name {
++ my ($self, $name) = @_;
++ $name =~ s/^perl-//g;
++ return $name;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceDebianpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Debian.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,82 @@
++# $Id: Debian.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Debian;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Debian - Debian source for updates
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++ available from Debian.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Debian object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to Debian mirror content file (default: http://ftp.debian.org/ls-lR.gz)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://ftp.debian.org/ls-lR.gz',
++ @_
++ );
++
++ my $versions;
++ open(INPUT, &quot;GET $options{url} | zcat |&quot;) or croak &quot;Can't fetch $options{url}: $!&quot;;
++ while (my $line = &lt;INPUT&gt;) {
++ next unless $line =~ /([\w\.-]+)_([\d\.]+)\.orig\.tar\.gz$/;
++ my $name = $1;
++ my $version = $2;
++ $versions-&gt;{$name} = $version;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://packages.debian.org/$name&quot;;
++}
++
++sub _name {
++ my ($self, $name) = @_;
++
++ if ($name =~ /^(perl|ruby)-([-\w]+)$/) {
++ $name = lc(&quot;lib$2-$1&quot;);
++ } elsif ($name =~ /^apache-([-\w]+)$/) {
++ $name = &quot;libapache-$1&quot;;
++ $name =~ s/_/-/g;
++ }
++
++ return $name;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFedorapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Fedora.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,63 @@
++# $Id: Fedora.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Fedora;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Fedora - Fedora updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Fedora.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Fedora object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to Fedora development SRPMS directory (default:
++http://fr.rpmfind.net/linux/fedora/core/development/SRPMS)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://fr.rpmfind.net/linux/fedora/core/development/SRPMS',
++ @_
++ );
++
++ my $versions;
++ open(INPUT, &quot;GET $options{url} |&quot;) or die &quot;Can't fetch $options{url}: $!\n&quot;;
++ while (&lt;INPUT&gt;) {
++ next unless $_ =~ /&gt;([\w-]+)-([\w\.]+)-[\w\.]+\.src\.rpm&lt;\/a&gt;/;
++ $versions-&gt;{$1} = $2;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceFreshmeatpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Freshmeat.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,111 @@
++# $Id: Freshmeat.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Freshmeat;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Freshmeat - Freshmeat source for updates
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Freshmeat.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use XML::Twig;
++use LWP::UserAgent;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Freshmeat
++object.
++
++Specific parameters:
++
++=over
++
++=item preload true/false
++
++Allows to load full Freshmeat catalogue at once instead of checking each software independantly (default: false)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ preload =&gt; 0,
++ @_
++ );
++
++ if ($options{preload}) {
++ my $versions;
++
++ my $project = sub {
++ my ($twig, $project) = @_;
++ my $name = $project-&gt;first_child('projectname_short')-&gt;text();
++ my $version = $project-&gt;first_child('latest_release')-&gt;first_child('latest_release_version')-&gt;text();
++ $versions-&gt;{$name} = $version;
++ $twig-&gt;purge();
++ };
++
++ my $twig = XML::Twig-&gt;new(
++ TwigRoots =&gt; { project =&gt; $project }
++ );
++
++ my $url = 'http://download.freshmeat.net/backend/fm-projects.rdf.bz2';
++
++ open(INPUT, &quot;GET $url | bzcat |&quot;) or die &quot;Can't fetch $url: $!\n&quot;;
++ $twig-&gt;parse(\*INPUT);
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++ }
++}
++
++sub _version {
++ my ($self, $name) = @_;
++
++ if ($self-&gt;{_versions}) {
++ return $self-&gt;{_versions}-&gt;{$name};
++ } else {
++ my $version;
++
++ my $latest_release_version = sub {
++ $version = $_[1]-&gt;text();
++ };
++
++ my $twig = XML::Twig-&gt;new(
++ TwigRoots =&gt; { latest_release_version =&gt; $latest_release_version }
++ );
++
++ my $url = &quot;http://freshmeat.net/projects-xml/$name&quot;;
++
++ open(INPUT, &quot;GET $url |&quot;) or die &quot;Can't fetch $url: $!\n&quot;;
++ # freshmeat answer with an HTML page when project doesn't exist
++ $twig-&gt;safe_parse(\*INPUT);
++ close(INPUT);
++
++ return $version;
++ }
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://freshmeat.net/projects/$name&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGNOMEpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/GNOME.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,104 @@
++# $Id$
++package Youri::Check::Input::Updates::Source::GNOME;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::GNOME - GNOME updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from GNOME.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use List::MoreUtils 'any';
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Gnome object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to GNOME sources directory (default:
++http://fr2.rpmfind.net/linux/gnome.org/sources)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://fr2.rpmfind.net/linux/gnome.org/sources/', # default url
++ # We use HTTP as it offers a better sorting (1.2 &lt; 1.10)
++ @_
++ );
++
++ $self-&gt;{_agent} = LWP::UserAgent-&gt;new();
++ my $response = $self-&gt;{_agent}-&gt;get($options{url});
++ if($response-&gt;is_success()) {
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /^([-\w]+)\/$/o;
++ $self-&gt;{_names}-&gt;{$1} = 1;
++ }
++ }
++
++ $self-&gt;{_url} = $options{url};
++}
++
++sub _version {
++ my ($self, $name) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return unless $self-&gt;{_names}-&gt;{$name};
++
++ my $response = $self-&gt;{_agent}-&gt;get(&quot;$self-&gt;{_url}/$name/&quot;);
++ if($response-&gt;is_success()) {
++ my $major;
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /^([.\d]+)\/$/o;
++ $major = $1;
++ }
++ return unless $major;
++
++ $response = $self-&gt;{_agent}-&gt;get(&quot;$self-&gt;{_url}/$name/$major/&quot;);
++ if($response-&gt;is_success()) {
++ $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $href = $token-&gt;[1]-&gt;{href};
++ next unless $href =~ /^LATEST-IS-([.\d]+)$/o;
++ return $1;
++ }
++ }
++ }
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return $self-&gt;{_url}.&quot;$name/&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceGentoopm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Gentoo.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,75 @@
++# $Id: Gentoo.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Gentoo;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Gentoo - Gentoo updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Gentoo.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::Simple;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Gentoo object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to Gentoo snapshots directory (default:
++http://gentoo.mirror.sdv.fr/snapshots)
++
++=back
++
++=cut
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://gentoo.mirror.sdv.fr/snapshots', # default URL
++ @_
++ );
++
++ my $versions;
++ my $content = get($options{url});
++ my $file;
++ while ($content =~ /&lt;A HREF=&quot;(portage-\d{8}.tar.bz2)&quot;&gt;/g) {
++ $file = $1;
++ }
++ open(INPUT, &quot;GET $options{url}/$file | tar tjf - |&quot;) or croak &quot;Can't fetch $options{url}/$file: $!&quot;;
++ while (my $line = &lt;INPUT&gt;) {
++ next unless $line =~ /.*\/([\w-]+)-([\d\.]+)(:?-r\d)?\.ebuild$/;
++ $versions-&gt;{$1} = $2;
++ }
++ close(INPUT);
++
++ $self-&gt;{_versions} = $versions;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://packages.gentoo.org/search/?sstring=$name&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceNetBSDpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/NetBSD.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,75 @@
++# $Id$
++package Youri::Check::Input::Updates::Source::NetBSD;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::NetBSD - NetBSD source for updates
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++ available from NetBSD.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Input::Updates::Source';
++use IO::Ftp;
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::NetBSD object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to NetBSD mirror content file, without ftp: (default: //ftp.free.fr/mirrors/ftp.netbsd.org/NetBSD-current/pkgsrc/README-all.html)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; '//ftp.free.fr/mirrors/ftp.netbsd.org/NetBSD-current/pkgsrc/README-all.html',
++ @_
++ );
++
++ my $versions;
++ my $urls;
++
++ my $in = IO::Ftp-&gt;new('&lt;',$options{url}) or croak &quot;Can't fetch $options{url}: $!&quot;;
++ while (my $line = &lt;$in&gt;) {
++ next unless $line =~ /&lt;!-- (.+)-([^-]*?)(nb\d*)? \(for sorting\).*?href=&quot;([^&quot;]+)&quot;/;
++ my $name = $1;
++ my $version = $2;
++ $versions-&gt;{$name} = $version;
++ $urls-&gt;{$name} = $4;
++ }
++ close($in);
++
++ $self-&gt;{_versions} = $versions;
++ $self-&gt;{_urls} = $urls;
++ $self-&gt;{_url} = $options{url};
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return $self-&gt;{_urls}-&gt;{$name};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceRAApm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/RAA.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,121 @@
++# $Id: RAA.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::RAA;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::RAA - RAA updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from RAA.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use SOAP::Lite;
++use List::MoreUtils 'any';
++use Youri::Package;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::RAA object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++URL to RAA SOAP interface (default:
++http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4)
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; 'http://www.ruby-lang.org/xmlns/soap/interface/RAA/0.0.4/',
++ @_
++ );
++
++ my $raa = SOAP::Lite-&gt;service($options{url})
++ or croak &quot;Can't connect to $options{url}&quot;;
++
++ $self-&gt;{_raa} = $raa;
++ $self-&gt;{_names} = $raa-&gt;names();
++}
++
++sub get_version {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name;
++ if (ref $package &amp;&amp; $package-&gt;isa('Youri::Package')) {
++ # don't bother checking for non-ruby packages
++ if (
++ any { $_-&gt;[Youri::Package::DEPENDENCY_NAME] =~ /ruby/ }
++ $package-&gt;get_requires()
++ ) {
++ $name = $package-&gt;get_canonical_name();
++ } else {
++ return;
++ }
++ } else {
++ $name = $package;
++ }
++
++ # translate in grabber namespace
++ $name = $self-&gt;get_name($name);
++
++ # return if aliased to null
++ return unless $name;
++
++ # susceptible to throw exception for timeout
++ eval {
++ my $gem = $self-&gt;{_raa}-&gt;gem($name);
++ return $gem-&gt;{project}-&gt;{version} if $gem;
++ };
++
++ return;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://raa.ruby-lang.org/project/$name/&quot;;
++}
++
++sub _name {
++ my ($self, $name) = @_;
++
++ if (ref $self) {
++ my $match = $name;
++ $match =~ s/^ruby[-_]//;
++ $match =~ s/[-_]ruby$//;
++ my @results =
++ grep { /^(ruby[-_])?\Q$match\E([-_]ruby)$/ }
++ @{$self-&gt;{_names}};
++ if (@results) {
++ return $results[0];
++ } else {
++ return $name;
++ }
++ } else {
++ return $name;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourceSourceforgepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source/Sourceforge.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,103 @@
++# $Id: Sourceforge.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source::Sourceforge;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source::Sourceforge - Sourceforge updates source
++
++=head1 DESCRIPTION
++
++This source plugin for L&lt;Youri::Check::Input::Updates&gt; collects updates
++available from Sourceforge.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use LWP::UserAgent;
++use HTML::TokeParser;
++use Youri::Check::Input::Updates;
++use base 'Youri::Check::Input::Updates::Source';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates::Source::Sourceforge
++object.
++
++No specific parameters.
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ @_
++ );
++
++ $self-&gt;{_agent} = LWP::UserAgent-&gt;new();
++}
++
++sub get_version {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name;
++ if (ref $package &amp;&amp; $package-&gt;isa('Youri::Package')) {
++ # don't bother checking for packages without sf.net URL
++ my $url = $package-&gt;get_url();
++ if (
++ $url =~ /http:\/\/(.*)\.sourceforge\.net/ ||
++ $url =~ /http:\/\/.*sourceforge\.net\/projects\/([^\/]+)/
++ ) {
++ $name = $package-&gt;get_canonical_name();
++ } else {
++ return;
++ }
++ } else {
++ $name = $package;
++ }
++
++ # translate in grabber namespace
++ $name = $self-&gt;get_name($name);
++
++ # return if aliased to null
++ return unless $name;
++
++ my $response = $self-&gt;{_agent}-&gt;get($self-&gt;_url($name));
++ if($response-&gt;is_success()) {
++ my $max = 0;
++ my $parser = HTML::TokeParser-&gt;new(\$response-&gt;content());
++ while (my $token = $parser-&gt;get_tag('a')) {
++ my $text = $parser-&gt;get_trimmed_text(&quot;/$token-&gt;[0]&quot;);
++ next unless $text;
++ next unless $text =~ /^
++ \Q$name\E
++ [._-]?($Youri::Check::Input::Updates::VERSION_REGEXP)
++ [._-]?(w(?:in)?(?:32)?|mips|sparc|bin|ppc|i\d86|src|sources?)?
++ \.(?:tar\.(?:gz|bz2)|tgz|zip)
++ $/iox;
++ my $version = $1;
++ my $arch = $2;
++ next if $arch &amp;&amp; $arch !~ /(src|sources?)/;
++ $max = $version if Youri::Check::Input::Updates::is_newer($version, $max);
++ }
++ return $max if $max;
++ }
++ return;
++}
++
++sub _url {
++ my ($self, $name) = @_;
++ return &quot;http://prdownloads.sourceforge.net/$name/&quot;;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatesSourcepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates/Source.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,240 @@
++# $Id: Source.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates::Source;
++
++=head1 NAME
++
++Youri::Check::Input::Updates::Source - Abstract updates source
++
++=head1 DESCRIPTION
++
++This abstract class defines the updates source interface for
++L&lt;Youri::Check::Input::Updates&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates object.
++
++Generic parameters (subclasses may define additional ones):
++
++=over
++
++=item aliases $aliases
++
++Hash of package aliases.
++
++=back
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ aliases =&gt; undef, # aliases
++ resolver =&gt; undef, # maintainer resolver
++ preferences =&gt; undef, # maintainer preferences
++ check_id =&gt; '', # parent check id
++ @_
++ );
++
++ if ($options{aliases}) {
++ croak &quot;aliases should be an hashref&quot; unless ref $options{aliases} eq 'HASH';
++ }
++ if ($options{resolver}) {
++ croak &quot;resolver should be a Youri::Check::Maintainer::Resolver object&quot; unless $options{resolver}-&gt;isa(&quot;Youri::Check::Maintainer::Resolver&quot;);
++ }
++ if ($options{preferences}) {
++ croak &quot;preferences should be a Youri::Check::Maintainer::Preferences object&quot; unless $options{preferences}-&gt;isa(&quot;Youri::Check::Maintainer::Preferences&quot;);
++ }
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _aliases =&gt; $options{aliases},
++ _resolver =&gt; $options{resolver},
++ _preferences =&gt; $options{preferences},
++ _check_id =&gt; $options{check_id},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++Excepted explicit statement, package name is expressed with Mandriva naming
++conventions.
++
++=head2 get_id()
++
++Returns source identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 get_version($package)
++
++Returns available version for given package, which can be either a full
++L&lt;Youri::Package&gt; object or just a package name.
++
++=cut
++
++sub get_version {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name = ref $package &amp;&amp; $package-&gt;isa('Youri::Package') ?
++ $package-&gt;get_canonical_name() :
++ $package;
++
++ # translate in grabber namespace
++ $name = $self-&gt;get_name($name);
++
++ # return if aliased to null
++ return unless $name;
++
++ # return subclass computation
++ return $self-&gt;_version($name);
++}
++
++=head2 get_url($name)
++
++Returns the URL of information source for package with given name.
++
++=cut
++
++sub get_url {
++ my ($self, $name) = @_;
++
++ # retun subclass computation
++ return $self-&gt;_url($self-&gt;get_name($name));
++}
++
++=head2 name($name)
++
++Returns name converted to specific source naming conventions for package with given name.
++
++=cut
++
++sub get_name {
++ my ($self, $name) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # return config aliases if it exists
++ if ($self-&gt;{_aliases} ) {
++ return $self-&gt;{_aliases}-&gt;{$name} if exists $self-&gt;{_aliases}-&gt;{$name};
++ }
++
++ # return maintainer aliases if it exists
++ if ($self-&gt;{_resolver} &amp;&amp; $self-&gt;{_preferences}) {
++ my $maintainer = $self-&gt;{_resolver}-&gt;get_maintainer($name);
++ if ($maintainer) {
++ my $aliases = $self-&gt;{_preferences}-&gt;get_preference(
++ $maintainer,
++ $self-&gt;{_check_id},
++ 'aliases'
++ );
++ if ($aliases) {
++ if ($aliases-&gt;{all}) {
++ return $aliases-&gt;{all}-&gt;{$name} if exists $aliases-&gt;{all}-&gt;{$name};
++ }
++ if ($aliases-&gt;{$self-&gt;{_id}}) {
++ return $aliases-&gt;{$self-&gt;{_id}}-&gt;{$name} if exists $aliases-&gt;{$self-&gt;{_id}}-&gt;{$name};
++ }
++ }
++ }
++ }
++
++ # return return subclass computation
++ return $self-&gt;_name($name);
++}
++
++=head2 _version($name)
++
++Hook called by default B&lt;version()&gt; implementation after name translation.
++
++=cut
++
++sub _version {
++ my ($self, $name) = @_;
++ return $self-&gt;{_versions}-&gt;{$name};
++}
++
++=head2 _url($name)
++
++Hook called by default B&lt;url()&gt; implementation after name translation.
++
++=cut
++
++sub _url {
++ my ($self, $name) = @_;
++ return undef;
++}
++
++=head2 _name($name)
++
++Hook called by default B&lt;name()&gt; implementation if given name was not found in
++the aliases.
++
++=cut
++
++sub _name {
++ my ($self, $name) = @_;
++ return $name;
++}
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item version
++
++As an alternative, the B&lt;_version()&gt; hook can be implemented.
++
++=item url
++
++As an alternative, the &lt;_url()&gt; hook can be implemented.
++
++=item name
++
++As an alternative, the B&lt;_name()&gt; hook can be implemented.
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputUpdatespm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input/Updates.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,275 @@
++# $Id: Updates.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input::Updates;
++
++=head1 NAME
++
++Youri::Check::Input::Updates - Check available updates
++
++=head1 DESCRIPTION
++
++This plugin checks available updates for packages, and report existing ones.
++Additional source plugins handle specific sources.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use Youri::Utils;
++use base 'Youri::Check::Input';
++
++sub columns {
++ return qw/
++ current
++ available
++ source
++ /;
++}
++
++sub links {
++ return qw/
++ source url
++ /;
++}
++
++memoize('is_newer');
++
++our $VERSION_REGEXP = 'v?([\d._-]*\d)[._ -]*(?:(alpha|beta|pre|rc|pl|rev|cvs|svn|[a-z])[_ -.]*([\d.]*))?([_ -.]*.*)';
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input::Updates object.
++
++Specific parameters:
++
++=over
++
++=item aliases $aliases
++
++Hash of global aliases definitions
++
++=item sources $sources
++
++Hash of source plugins definitions
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ aliases =&gt; undef,
++ sources =&gt; undef,
++ @_
++ );
++
++ croak &quot;No source defined&quot; unless $options{sources};
++ croak &quot;sources should be an hashref&quot; unless ref $options{sources} eq 'HASH';
++ if ($options{aliases}) {
++ croak &quot;aliases should be an hashref&quot; unless ref $options{aliases} eq 'HASH';
++ }
++
++ foreach my $id (keys %{$options{sources}}) {
++ print &quot;Creating source $id\n&quot; if $options{verbose};
++ eval {
++ # add global aliases if defined
++ if ($options{aliases}) {
++ foreach my $alias (keys %{$options{aliases}}) {
++ $options{sources}-&gt;{$id}-&gt;{aliases}-&gt;{$alias} =
++ $options{aliases}-&gt;{$alias}
++ }
++ }
++
++ push(
++ @{$self-&gt;{_sources}},
++ create_instance(
++ 'Youri::Check::Input::Updates::Source',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ check_id =&gt; $options{id},
++ resolver =&gt; $options{resolver},
++ preferences =&gt; $options{preferences},
++ %{$options{sources}-&gt;{$id}}
++ )
++ );
++ };
++ print STDERR &quot;Failed to create source $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no sources created&quot; unless @{$self-&gt;{_sources}};
++}
++
++sub run {
++ my ($self, $media, $resultset) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # this is a source media check only
++ return unless $media-&gt;get_type() eq 'source';
++
++ my $callback = sub {
++ my ($package) = @_;
++
++ my $name = $package-&gt;get_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++
++ # compute version with rpm subtilities related to preversions
++ my $current_version = ($release =~ /^0\.(\w+)\.\w+$/) ?
++ $version . $1 :
++ $version;
++ my $current_stable = is_stable($current_version);
++
++ my ($max_version, $max_source, $max_url);
++ $max_version = $current_version;
++
++ foreach my $source (@{$self-&gt;{_sources}}) {
++ my $available_version = $source-&gt;get_version($package);
++ if (
++ $available_version &amp;&amp;
++ (! $current_stable || is_stable($available_version)) &amp;&amp;
++ is_newer($available_version, $max_version)
++ ) {
++ $max_version = $available_version;
++ $max_source = $source-&gt;get_id();
++ $max_url = $source-&gt;get_url($name);
++ }
++ }
++ $resultset-&gt;add_result($self-&gt;{_id}, $media, $package, {
++ current =&gt; $current_version,
++ available =&gt; $max_version,
++ source =&gt; $max_source,
++ url =&gt; $max_url
++ }) if $max_version ne $current_version;
++ };
++
++ $media-&gt;traverse_headers($callback);
++}
++
++=head2 is_stable($version)
++
++Checks if given version is stable.
++
++=cut
++
++sub is_stable {
++ my ($version) = @_;
++ return $version !~ /alpha|beta|pre|rc|cvs|svn/i;
++
++}
++
++=head2 is_newer($v1, $v2)
++
++Checks if $v1 is newer than $v2.
++
++This function will return true only if we are sure this is newer (and not equal).
++If we can't compare the versions, a warning will be displayed.
++
++=cut
++
++sub is_newer {
++ my ($v1, $v2) = @_;
++ return 0 if $v1 eq $v2;
++
++ # Reject strange cases
++ # One is a large number (like date or revision) and the other one not, or
++ # has different length
++ if (($v1 =~ /^\d{3,}$/ || $v2 =~ /^\d{3,}$/)
++ &amp;&amp; (join('0',split(/\d/, $v1.&quot;X&quot;)) ne join('0',split(/\d/, $v2.&quot;X&quot;)))) {
++ carp &quot;strange : $v1 vs $v2&quot;;
++ return 0;
++ }
++
++ my %states = (alpha=&gt;-4,beta=&gt;-3,pre=&gt;-2,rc=&gt;-1);
++ my $i; $states{$_} = ++$i foreach 'a'..'z';
++
++ if ($v1 =~ /^[\d._-]+$/ &amp;&amp; $v2 =~ /^[\d._-]+$/) {
++ my @v1 = split(/[._-]/, $v1);
++ my @v2 = split(/[._-]/, $v2);
++ if (join('',@v1) eq (join '',@v2)) {
++ # Might be something like 1.2.0 vs 1.20, usual false positive
++ carp &quot;strange : $v1 vs $v2&quot;;
++ return 0;
++ }
++ for my $i (0 .. $#v1) {
++ $v1[$i] ||= 0;
++ $v2[$i] ||= 0;
++ return 1 if $v1[$i] &gt; $v2[$i];
++ return 0 if $v1[$i] &lt; $v2[$i];
++ }
++ # When v2 is longer than v1 but start the same, v1 &lt;= v2
++ return 0;
++ } else {
++ my ($num1, $state1, $statenum1, $other1, $num2, $state2, $statenum2, $other2);
++
++ if ($v1 =~ /^$VERSION_REGEXP$/io) {
++ ($num1, $state1, $statenum1, $other1) = ($1, &quot;\L$2&quot;, $3, $4);
++ } else {
++ carp &quot;unknown version format $v1&quot;;
++ return 0;
++ }
++
++ if ($v2 =~ /^$VERSION_REGEXP$/io) {
++ ($num2, $state2, $statenum2, $other2) = ($1, &quot;\L$2&quot;, $3, $4);
++ } else {
++ carp &quot;unknown version format $v2&quot;;
++ return 0;
++ }
++
++ # If we know the format of only one, there might be an issue, do nothing
++
++ if (($other1 &amp;&amp; ! $other2 )||(!$other1 &amp;&amp; $other2 )) {
++ carp &quot;can't compare $v1 vs $v2&quot;;
++ return 0;
++ }
++
++ return 1 if is_newer($num1, $num2);
++ return 0 unless $num1 eq $num2;
++
++ # The numeric part is the same but not the end
++
++ if ($state1 eq '') {
++ return 1 if $state2 =~ /^(alpha|beta|pre|rc)/;
++ return 0 if $state2 =~ /^([a-z]|pl)$/;
++ carp &quot;unknown state format $state2&quot;;
++ return 0;
++ }
++
++ if ($state2 eq '') {
++ return 0 if $state1 =~ /^(alpha|beta|pre|rc)/;
++ return 1 if $state1 =~ /^([a-z]|pl)$/;
++ carp &quot;unknown state format $state1&quot;;
++ return 0;
++ }
++
++ if ($state1 eq $state2) {
++ return 1 if is_newer($statenum1, $statenum2);
++ return 0 unless $statenum1 eq $statenum2;
++ # If everything is the same except this, just compare it
++ # as we have no idea on the format
++ return &quot;$other1&quot; gt &quot;$other2&quot;;
++ }
++
++ my $s1 = 0;
++ my $s2 = 0;
++ $s1=$states{$state1} if exists $states{$state1};
++ $s2=$states{$state2} if exists $states{$state2};
++ return $s1&gt;$s2 if ($s1 != 0 &amp;&amp; $s2 != 0);
++ return 1 if $s1&lt;0 &amp;&amp; $state2 =~ /^([a-z]|pl)$/;
++ return 0 if $s2&lt;0 &amp;&amp; $state1 =~ /^([a-z]|pl)$/;
++ carp &quot;unknown case $v1, $v2&quot;;
++ return 0;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckInputpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Input.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,120 @@
++# $Id: Input.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Input;
++
++=head1 NAME
++
++Youri::Check::Input - Abstract input plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines input plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++
++use constant WARNING =&gt; 'warning';
++use constant ERROR =&gt; 'error';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Input object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '', # object id
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ resolver =&gt; undef, # maintainer resolver
++ preferences =&gt; undef, # maintainer preferences
++ @_
++ );
++
++ if ($options{resolver}) {
++ croak &quot;resolver should be a Youri::Check::Maintainer::Resolver object&quot; unless $options{resolver}-&gt;isa(&quot;Youri::Check::Maintainer::Resolver&quot;);
++ }
++ if ($options{preferences}) {
++ croak &quot;preferences should be a Youri::Check::Maintainer::Preferences object&quot; unless $options{preferences}-&gt;isa(&quot;Youri::Check::Maintainer::Preferences&quot;);
++ }
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _resolver =&gt; $options{resolver},
++ _preferences =&gt; $options{preferences},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns plugin identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 prepare(@medias)
++
++Perform optional preliminary initialisation, using given list of
++&lt;Youri::Media&gt; objects.
++
++=cut
++
++sub prepare {
++ # do nothing
++}
++
++=head2 run($media, $resultset)
++
++Check the packages from given L&lt;Youri::Media&gt; object, and store the
++result in given L&lt;Youri::Check::Resultset&gt; object.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item run
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencesFilepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences/File.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,87 @@
++# $Id: File.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Preferences::File;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Preferences::File - File-based maintainer preferences implementation
++
++=head1 DESCRIPTION
++
++This is a file-based L&lt;Youri::Check::Maintainer::Preferences&gt; implementation.
++
++It uses files in maintainer home directories.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Config;
++use base 'Youri::Check::Maintainer::Preferences';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Preferences::File object.
++
++No specific parameters.
++
++=cut
++
++sub get_preference {
++ my ($self, $maintainer, $plugin, $value) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return unless $maintainer &amp;&amp; $plugin &amp;&amp; $value;
++
++ print &quot;Retrieving maintainer $maintainer preferences\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ $self-&gt;_load_config($maintainer)
++ unless exists $self-&gt;{_config}-&gt;{$maintainer};
++
++ return $self-&gt;{_config}-&gt;{$maintainer} ?
++ $self-&gt;{_config}-&gt;{$maintainer}-&gt;get($plugin . '_' . $value) :
++ undef;
++}
++
++sub _load_config {
++ my ($self, $maintainer) = @_;
++
++ print &quot;Attempting to load maintainers preferences for $maintainer\n&quot; if $self-&gt;{_verbose} &gt; 1;
++
++
++ my ($login) = $maintainer =~ /^(\S+)\@\S+$/;
++ my $home = (getpwnam($login))[7];
++ my $file = &quot;$home/.youri/check.prefs&quot;;
++
++ if (-f $file &amp;&amp; -r $file) {
++ print &quot;Found, loading\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ my $config = Youri::Config-&gt;new(
++ {
++ CREATE =&gt; 1,
++ GLOBAL =&gt; {
++ DEFAULT =&gt; undef,
++ EXPAND =&gt; EXPAND_VAR | EXPAND_ENV,
++ ARGCOUNT =&gt; ARGCOUNT_ONE,
++ }
++ }
++ );
++ $config-&gt;file($file);
++ $self-&gt;{_config}-&gt;{$maintainer} = $config;
++ } else {
++ print &quot;Not found, aborting\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ $self-&gt;{_config}-&gt;{$maintainer} = undef;
++ }
++
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerPreferencespm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Preferences.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,80 @@
++# $Id: Preferences.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Preferences;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Preferences - Abstract maintainer preferences
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Check::Maintainer::Preferences interface.
++
++=head1 SYNOPSIS
++
++ use Youri::Check::Maintainer::Preferences::Foo;
++
++ my $preferences = Youri::Check::Maintainer::Preferences::Foo-&gt;new();
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Preferences object.
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_preference($maintainer, $plugin, $item)
++
++Returns preference of given maintainer for given plugin and configuration item.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item get
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverBugzillapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/Bugzilla.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,100 @@
++# $Id: Bugzilla.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Resolver::Bugzilla;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Resolver::Bugzilla - Bugzilla-based maintainer resolver
++
++=head1 DESCRIPTION
++
++This is a Bugzilla-based L&lt;Youri::Check::Maintainer::Resolver&gt; implementation.
++
++It uses Bugzilla SQL database for resolving maintainers.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Bugzilla;
++use base 'Youri::Check::Maintainer::Resolver';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Resolver::Bugzilla object.
++
++Specific parameters:
++
++=over
++
++=item host $host
++
++Bugzilla database host.
++
++=item base $base
++
++Bugzilla database name.
++
++=item user $user
++
++Bugzilla database user.
++
++=item pass $pass
++
++Bugzilla database password.
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ host =&gt; '', # host of the bug database
++ base =&gt; '', # name of the bug database
++ user =&gt; '', # user of the bug database
++ pass =&gt; '', # pass of the bug database
++ @_
++ );
++
++ croak &quot;No host given&quot; unless $options{host};
++ croak &quot;No base given&quot; unless $options{base};
++ croak &quot;No user given&quot; unless $options{user};
++ croak &quot;No pass given&quot; unless $options{pass};
++
++ my $bugzilla = Youri::Bugzilla-&gt;new(
++ $options{host},
++ $options{base},
++ $options{user},
++ $options{pass}
++ );
++
++ $self-&gt;{_bugzilla} = $bugzilla;
++}
++
++sub get_maintainer {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name = ref $package &amp;&amp; $package-&gt;isa('Youri::Package') ?
++ $package-&gt;get_canonical_name() :
++ $package;
++
++ $self-&gt;{_maintainers}-&gt;{$name} =
++ $self-&gt;{_bugzilla}-&gt;get_maintainer($name)
++ unless exists $self-&gt;{_maintainers}-&gt;{$name};
++
++ return $self-&gt;{_maintainers}-&gt;{$name};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverCGIpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver/CGI.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,79 @@
++# $Id: CGI.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Resolver::CGI;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Resolver::CGI - CGI-based maintainer resolver
++
++=head1 DESCRIPTION
++
++This is a CGI-based L&lt;Youri::Check::Maintainer::Resolver&gt; implementation.
++
++It uses a remote CGI to resolve maintainers.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Maintainer::Resolver';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Resolver::CGI object.
++
++Specific parameters:
++
++=over
++
++=item url $url
++
++CGI's URL.
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ url =&gt; '', # url to fetch maintainers
++ @_
++ );
++
++ croak &quot;No URL given&quot; unless $options{url};
++
++ open (INPUT, &quot;GET $options{url} |&quot;);
++ while (&lt;INPUT&gt;) {
++ chomp;
++ my ($package, $maintainer) = split(/\t/, $_);
++ $self-&gt;{_maintainers}-&gt;{$package} = $maintainer if $maintainer;
++ }
++ close(INPUT);
++}
++
++sub get_maintainer {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ print &quot;Retrieving package $package maintainer\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my $name = ref $package &amp;&amp; $package-&gt;isa('Youri::Package') ?
++ $package-&gt;get_canonical_name() :
++ $package;
++
++ return $self-&gt;{_maintainers}-&gt;{$name};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckMaintainerResolverpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Maintainer/Resolver.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,86 @@
++# $Id: Resolver.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Maintainer::Resolver;
++
++=head1 NAME
++
++Youri::Check::Maintainer::Resolver - Abstract maintainer resolver
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Check::Maintainer::Resolver interface.
++
++=head1 SYNOPSIS
++
++ use Youri::Check::Maintainer::Resolver::Foo;
++
++ my $resolver = Youri::Check::Maintainer::Resolver::Foo-&gt;new();
++
++ print $resolver-&gt;get_maintainer('foo');
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Maintainer::Resolver object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++ my $self = bless {
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose}
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_maintainer($package)
++
++Returns maintainer for given package, which can be either a full
++L&lt;Youri::Package&gt; object or just a package name.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item get_maintainer
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatHTMLpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/HTML.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,222 @@
++# $Id: HTML.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output::File::Format::HTML;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format::HTML - File HTML format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::File&gt; provides HTML format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use CGI;
++use base 'Youri::Check::Output::File::Format';
++
++sub extension {
++ return 'html';
++}
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ style =&gt; &lt;&lt;EOF, # css style
++h1 {
++ text-align:center;
++}
++table {
++ border-style:solid;
++ border-width:1px;
++ border-color:black;
++ width:100%;
++}
++tr.odd {
++ background-color:white;
++}
++tr.even {
++ background-color:silver;
++}
++p.footer {
++ font-size:smaller;
++ text-align:center;
++}
++EOF
++ @_
++ );
++
++ $self-&gt;{_style} = $options{style};
++ $self-&gt;{_cgi} = CGI-&gt;new();
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $content;
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my $line;
++ my @results;
++ $content .= $self-&gt;{_cgi}-&gt;start_table();
++ $content .= $self-&gt;{_cgi}-&gt;Tr([
++ $self-&gt;{_cgi}-&gt;th([
++ @$lead_columns,
++ @$columns
++ ])
++ ]);
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_table();
++
++ return $self-&gt;_get_html_page($time, $title, \$content);
++}
++
++sub get_index {
++ my ($self, $time, $title, $reports, $maintainers) = @_;
++
++ my $content;
++
++ if ($reports) {
++ $content .= $self-&gt;{_cgi}-&gt;h2(&quot;Reports&quot;);
++ my @types = keys %{$reports};
++
++ $content .= $self-&gt;{_cgi}-&gt;start_ul();
++ foreach my $type (sort @types) {
++ my $item;
++ $item = $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; &quot;$type.html&quot; },
++ $type
++ );
++ foreach my $extension (@{$reports-&gt;{$type}}) {
++ next if ($extension eq extension());
++ $item .= &quot; &quot;.$self-&gt;{_cgi}-&gt;a(
++ { href =&gt; &quot;$type.$extension&quot; },
++ &quot;[$extension]&quot;
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;li($item);
++ }
++ $content .= $self-&gt;{_cgi}-&gt;end_ul();
++ }
++
++ if ($maintainers) {
++ $content .= $self-&gt;{_cgi}-&gt;h2(&quot;Individual reports&quot;);
++
++ $content .= $self-&gt;{_cgi}-&gt;start_ul();
++ foreach my $maintainer (sort @{$maintainers}) {
++ $content .= $self-&gt;{_cgi}-&gt;li(
++ $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; &quot;$maintainer/index.html&quot; },
++ _obfuscate($maintainer)
++ )
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;end_ul();
++ }
++
++ return $self-&gt;_get_html_page($time, $title, \$content);
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $links, $class, $results) = @_;
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ for my $i (0 .. $#$results) {
++ $content .= $self-&gt;{_cgi}-&gt;start_Tr(
++ { class =&gt; $class }
++ );
++ if ($i == 0) {
++ # first line contains spanned cells
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ { rowspan =&gt; scalar @$results },
++ [
++ map { $results-&gt;[$i]-&gt;{$_} }
++ @$lead_columns
++ ]
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ [
++ map {
++ $links-&gt;{$_} &amp;&amp; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} ?
++ $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} },
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ ) :
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ } @$columns
++ ]
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ }
++
++ return $content;
++}
++
++
++sub _get_html_page {
++ my ($self, $time, $title, $body) = @_;
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;start_html(
++ -title =&gt; $title,
++ -style =&gt; { code =&gt; $self-&gt;{_style} }
++ );
++ $content .= $self-&gt;{_cgi}-&gt;h1($title);
++ $content .= $$body;
++ $content .= $self-&gt;{_cgi}-&gt;hr();
++ $content .= $self-&gt;{_cgi}-&gt;p(
++ { class =&gt; 'footer' },
++ &quot;Page generated $time&quot;
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_html();
++
++ return \$content;
++}
++
++sub _obfuscate {
++ my ($email) = @_;
++
++ return unless $email;
++
++ $email =~ s/\@/ at /;
++ $email =~ s/\./ dot /;
++
++ return $email;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatRSSpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/RSS.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,68 @@
++# $Id$
++package Youri::Check::Output::File::Format::RSS;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format::RSS - File RSS format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::File&gt; provides RSS format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use XML::RSS;
++use base 'Youri::Check::Output::File::Format';
++
++sub extension {
++ return 'rss';
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ return unless $maintainer;
++
++ my $rss = new XML::RSS (version =&gt; '2.0');
++ $rss-&gt;channel(
++ title =&gt; $title,
++ description =&gt; $title,
++ language =&gt; 'en',
++ ttl =&gt; 1440
++ );
++
++ while (my $result = $iterator-&gt;get_result()) {
++ if ($type eq 'updates') {
++ $rss-&gt;add_item(
++ title =&gt; &quot;$result-&gt;{package} $result-&gt;{available} is available&quot;,
++ description =&gt; &quot;Current version is $result-&gt;{current}&quot;,
++ link =&gt; $result-&gt;{url} ?
++ $result-&gt;{url} : $result-&gt;{source},
++ guid =&gt; &quot;$result-&gt;{package}-$result-&gt;{available}&quot;
++ );
++ } else {
++ $rss-&gt;add_item(
++ title =&gt; &quot;[$type] $result-&gt;{package}&quot;,
++ description =&gt; join(&quot;\n&quot;, (map { $result-&gt;{$_} || '' } @$columns)),
++ link =&gt; $result-&gt;{url},
++ guid =&gt; &quot;$type-$result-&gt;{package}&quot;
++ );
++ }
++ }
++
++ return \$rss-&gt;as_string();
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatTextpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format/Text.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,88 @@
++# $Id: Text.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output::File::Format::Text;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format::Text - File text format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::File&gt; provides text format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Output::File::Format';
++
++sub extension {
++ return 'txt';
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $content;
++ $content .= $title;
++ $content .= &quot;\n&quot;;
++
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my @results;
++ $content .= join(&quot;\t&quot;, @$lead_columns, @$columns) . &quot;\n&quot;;
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++
++ $content .= &quot;\n&quot;;
++ $content .= &quot;Page generated $time\n&quot;;
++
++ return \$content;
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $results) = @_;
++
++ my $content;
++ $content .= join(
++ &quot;\t&quot;,
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$lead_columns),
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ for my $i (1 .. $#$results) {
++ $content .= join(
++ &quot;\t&quot;,
++ (map { '' } @$lead_columns),
++ (map { $results-&gt;[$i]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ }
++ return $content;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFileFormatpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File/Format.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,66 @@
++# $Id: Base.pm 579 2006-01-09 21:17:54Z guillomovitch $
++package Youri::Check::Output::File::Format;
++
++=head1 NAME
++
++Youri::Check::Output::File::Format - Abstract file format support
++
++=head1 DESCRIPTION
++
++This abstract class defines the format support interface for
++L&lt;Youri::Check::Output::File&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '',
++ test =&gt; 0,
++ verbose =&gt; 0,
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_id()
++
++Returns format handler identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputFilepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/File.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,203 @@
++# $Id: Text.pm 523 2005-10-11 08:36:49Z misc $
++package Youri::Check::Output::File;
++
++=head1 NAME
++
++Youri::Check::Output::File - Report results in files
++
++=head1 DESCRIPTION
++
++This plugin reports results in files. Additional subplugins handle specific
++formats.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use File::Path;
++use DateTime;
++use Youri::Utils;
++use base 'Youri::Check::Output';
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ to =&gt; '', # target directory
++ noclean =&gt; 0, # don't clean up target directory
++ noempty =&gt; 0, # don't generate empty reports
++ formats =&gt; undef,
++ @_
++ );
++
++ croak &quot;no format defined&quot; unless $options{formats};
++ croak &quot;formats should be an hashref&quot; unless ref $options{formats} eq 'HASH';
++
++ my $now = DateTime-&gt;now(time_zone =&gt; 'local');
++ my $time = &quot;the &quot; . $now-&gt;ymd() . &quot; at &quot; . $now-&gt;hms();
++
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_noclean} = $options{noclean};
++ $self-&gt;{_noempty} = $options{noempty};
++ $self-&gt;{_time} = $time;
++
++ foreach my $id (keys %{$options{formats}}) {
++ print &quot;Creating format $id\n&quot; if $options{verbose};
++ eval {
++ push(
++ @{$self-&gt;{_formats}},
++ create_instance(
++ 'Youri::Check::Output::File::Format',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ %{$options{formats}-&gt;{$id}}
++ )
++ );
++ };
++ print STDERR &quot;Failed to create format $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no formats created&quot; unless @{$self-&gt;{_formats}};
++}
++
++sub _init_report {
++ my ($self) = @_;
++
++ # clean up output directory
++ unless ($self-&gt;{_test} || $self-&gt;{_noclean} || !$self-&gt;{_to}) {
++ my @files = glob($self-&gt;{_to} . '/*');
++ rmtree(\@files) if @files;
++ }
++}
++
++sub _global_report {
++ my ($self, $resultset, $type, $columns, $links) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ]
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type global report&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ undef
++ );
++
++ # create and register file
++ my $extension = $format-&gt;extension();
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/$type.$extension&quot;,
++ $content
++ );
++ push(
++ @{$self-&gt;{_files}-&gt;{global}-&gt;{$type}},
++ $extension
++ );
++ }
++}
++
++sub _individual_report {
++ my ($self, $resultset, $type, $columns, $links, $maintainer) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ],
++ { maintainer =&gt; [ $maintainer ] }
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type individual report for $maintainer&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ $maintainer
++ );
++
++ # create and register file
++ my $extension = $format-&gt;extension();
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/$maintainer/$type.$extension&quot;,
++ $content
++ );
++ push(
++ @{$self-&gt;{_files}-&gt;{maintainers}-&gt;{$maintainer}-&gt;{$type}},
++ $extension
++ );
++ }
++}
++
++sub _finish_report {
++ my ($self, $types, $maintainers) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ next unless $format-&gt;can('get_index');
++ my $extension = $format-&gt;extension();
++ print STDERR &quot;writing global index page\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/index.$extension&quot;,
++ $format-&gt;get_index(
++ $self-&gt;{_time},
++ &quot;QA global report&quot;,
++ $self-&gt;{_files}-&gt;{global},
++ [ keys %{$self-&gt;{_files}-&gt;{maintainers}} ],
++ )
++ );
++ foreach my $maintainer (@$maintainers) {
++ print STDERR &quot;writing index page for $maintainer\n&quot; if $self-&gt;{_verbose};
++
++ $self-&gt;_write_file(
++ &quot;$self-&gt;{_to}/$maintainer/index.$extension&quot;,
++ $format-&gt;get_index(
++ $self-&gt;{_time},
++ &quot;QA report for $maintainer&quot;,
++ $self-&gt;{_files}-&gt;{maintainers}-&gt;{$maintainer},
++ undef,
++ )
++ );
++ }
++ }
++}
++
++sub _write_file {
++ my ($self, $file, $content) = @_;
++
++ return unless $content;
++
++ my $dirname = dirname($file);
++ mkpath($dirname) unless -d $dirname;
++
++ if ($self-&gt;{_test}) {
++ *OUT = *STDOUT;
++ } else {
++ open(OUT, &quot;&gt;$file&quot;) or die &quot;Can't open file $file: $!&quot;;
++ }
++
++ print OUT $$content;
++
++ close(OUT) unless $self-&gt;{_test};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatHTMLpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/HTML.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,158 @@
++# $Id: Mail.pm 580 2006-01-11 22:59:36Z guillomovitch $
++package Youri::Check::Output::Mail::Format::HTML;
++
++=head1 NAME
++
++Youri::Check::Output::Mail::Format::HTML - Mail HTML format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::Mail&gt; provides HTML format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use CGI;
++use base 'Youri::Check::Output::Mail::Format';
++
++sub type {
++ return 'text/html';
++}
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ style =&gt; &lt;&lt;EOF, # css style
++h1 {
++ text-align:center;
++}
++table {
++ border-style:solid;
++ border-width:1px;
++ border-color:black;
++ width:100%;
++}
++tr.odd {
++ background-color:white;
++}
++tr.even {
++ background-color:silver;
++}
++p.footer {
++ font-size:smaller;
++ text-align:center;
++}
++EOF
++ @_
++ );
++
++ $self-&gt;{_style} = $options{style};
++ $self-&gt;{_cgi} = CGI-&gt;new();
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $body;
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my $line;
++ my @results;
++ $body .= $self-&gt;{_cgi}-&gt;start_table();
++ $body .= $self-&gt;{_cgi}-&gt;Tr([
++ $self-&gt;{_cgi}-&gt;th([
++ @$lead_columns,
++ @$columns
++ ])
++ ]);
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $body .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++ $body .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ $links,
++ $line++ % 2 ? 'odd' : 'even',
++ \@results
++ );
++ $body .= $self-&gt;{_cgi}-&gt;end_table();
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;start_html(
++ -title =&gt; $title,
++ -style =&gt; { code =&gt; $self-&gt;{_style} }
++ );
++ $content .= $self-&gt;{_cgi}-&gt;h1($title);
++ $content .= $body;
++ $content .= $self-&gt;{_cgi}-&gt;hr();
++ $content .= $self-&gt;{_cgi}-&gt;p(
++ { class =&gt; 'footer' },
++ &quot;Page generated $time&quot;
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_html();
++
++ return \$content;
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $links, $class, $results) = @_;
++
++ my $content;
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ for my $i (0 .. $#$results) {
++ $content .= $self-&gt;{_cgi}-&gt;start_Tr(
++ { class =&gt; $class }
++ );
++ if ($i == 0) {
++ # first line contains spanned cells
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ { rowspan =&gt; scalar @$results },
++ [
++ map { $results-&gt;[$i]-&gt;{$_} }
++ @$lead_columns
++ ]
++ );
++ }
++ $content .= $self-&gt;{_cgi}-&gt;td(
++ [
++ map {
++ $links-&gt;{$_} &amp;&amp; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} ?
++ $self-&gt;{_cgi}-&gt;a(
++ { href =&gt; $results-&gt;[$i]-&gt;{$links-&gt;{$_}} },
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ ) :
++ $self-&gt;{_cgi}-&gt;escapeHTML($results-&gt;[$i]-&gt;{$_})
++ } @$columns
++ ]
++ );
++ $content .= $self-&gt;{_cgi}-&gt;end_Tr();
++ }
++
++ return $content;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatTextpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format/Text.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,83 @@
++# $Id: Mail.pm 580 2006-01-11 22:59:36Z guillomovitch $
++package Youri::Check::Output::Mail::Format::Text;
++
++=head1 NAME
++
++Youri::Check::Output::Mail::Format::Text - Mail text format support
++
++=head1 DESCRIPTION
++
++This format plugin for L&lt;Youri::Check::Output::Mail&gt; provides text format
++support.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use base 'Youri::Check::Output::Mail::Format';
++
++sub type {
++ return 'text/plain';
++}
++
++sub get_report {
++ my ($self, $time, $title, $iterator, $type, $columns, $links, $maintainer) = @_;
++
++ my $content;
++ my $lead_columns = [
++ $maintainer ?
++ qw/package media/ :
++ qw/package media maintainer/
++ ];
++ my @results;
++ $content .= join(&quot;\t&quot;, @$lead_columns, @$columns) . &quot;\n&quot;;
++ while (my $result = $iterator-&gt;get_result()) {
++ if (@results &amp;&amp; $result-&gt;{package} ne $results[0]-&gt;{package}) {
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++ @results = ();
++ }
++ push(@results, $result);
++ }
++
++ $content .= $self-&gt;_get_formated_results(
++ $lead_columns,
++ $columns,
++ \@results
++ );
++
++ return \$content;
++}
++
++sub _get_formated_results {
++ my ($self, $lead_columns, $columns, $results) = @_;
++
++ my $content;
++ $content .= join(
++ &quot;\t&quot;,
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$lead_columns),
++ (map { $results-&gt;[0]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ for my $i (1 .. $#$results) {
++ $content .= join(
++ &quot;\t&quot;,
++ (map { '' } @$lead_columns),
++ (map { $results-&gt;[$i]-&gt;{$_} || '' } @$columns)
++ ) . &quot;\n&quot;;
++ }
++ return $content;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailFormatpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail/Format.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,66 @@
++# $Id: Base.pm 579 2006-01-09 21:17:54Z guillomovitch $
++package Youri::Check::Output::Mail::Format;
++
++=head1 NAME
++
++Youri::Check::Output::Mail::Format - Abstract mail format support
++
++=head1 DESCRIPTION
++
++This abstract class defines the format support interface for
++L&lt;Youri::Check::Output::Mail&gt;.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '',
++ test =&gt; 0,
++ verbose =&gt; 0,
++ @_
++ );
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_id()
++
++Returns format handler identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputMailpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output/Mail.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,156 @@
++# $Id: Mail.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output::Mail;
++
++=head1 NAME
++
++Youri::Check::Output::Mail - Report results by mail
++
++=head1 DESCRIPTION
++
++This plugin reports results by mail. Additional subplugins handle specific
++formats.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use MIME::Entity;
++use Youri::Utils;
++use base 'Youri::Check::Output';
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ from =&gt; '', # mail from header
++ to =&gt; '', # mail to header
++ reply_to =&gt; '', # mail reply-to header
++ mta =&gt; '', # mta path
++ noempty =&gt; 1, # don't generate empty reports
++ formats =&gt; {},
++ @_
++ );
++
++ croak &quot;no format defined&quot; unless $options{formats};
++ croak &quot;formats should be an hashref&quot; unless ref $options{formats} eq 'HASH';
++
++ $self-&gt;{_from} = $options{from};
++ $self-&gt;{_to} = $options{to};
++ $self-&gt;{_reply_to} = $options{reply_to};
++ $self-&gt;{_mta} = $options{mta};
++ $self-&gt;{_noempty} = $options{noempty};
++
++ foreach my $id (keys %{$options{formats}}) {
++ print &quot;Creating format $id\n&quot; if $options{verbose};
++ eval {
++ push(
++ @{$self-&gt;{_formats}},
++ create_instance(
++ 'Youri::Check::Output::Mail::Format',
++ id =&gt; $id,
++ test =&gt; $options{test},
++ verbose =&gt; $options{verbose},
++ %{$options{formats}-&gt;{$id}}
++ )
++ );
++ };
++ print STDERR &quot;Failed to create format $id: $@\n&quot; if $@;
++ }
++
++ croak &quot;no formats created&quot; unless @{$self-&gt;{_formats}};
++}
++
++sub _global_report {
++ my ($self, $resultset, $type, $columns, $links) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ]
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type global report&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ undef
++ );
++
++ $self-&gt;_send_mail(
++ $format-&gt;type(),
++ $self-&gt;{_to},
++ &quot;$type global report&quot;,
++ $content,
++ );
++ }
++}
++
++sub _individual_report {
++ my ($self, $resultset, $type, $columns, $links, $maintainer) = @_;
++
++ foreach my $format (@{$self-&gt;{_formats}}) {
++ my $iterator = $resultset-&gt;get_iterator(
++ $type,
++ [ 'package' ],
++ { maintainer =&gt; [ $maintainer ] }
++ );
++
++ return if $self-&gt;{_noempty} &amp;&amp; ! $iterator-&gt;has_results();
++
++ my $content = $format-&gt;get_report(
++ $self-&gt;{_time},
++ &quot;$type individual report for $maintainer&quot;,
++ $iterator,
++ $type,
++ $columns,
++ $links,
++ $maintainer
++ );
++
++ $self-&gt;_send_mail(
++ $format-&gt;type(),
++ $maintainer,
++ &quot;$type individual report for $maintainer&quot;,
++ $content,
++ );
++ }
++
++}
++
++sub _send_mail {
++ my ($self, $type, $to, $subject, $content) = @_;
++
++ return unless $content;
++
++ my $mail = MIME::Entity-&gt;build(
++ 'Type' =&gt; $type,
++ 'From' =&gt; $self-&gt;{_from},
++ 'Reply-To' =&gt; $self-&gt;{_reply_to},
++ 'To' =&gt; $to,
++ 'Subject' =&gt; $subject,
++ 'Data' =&gt; $$content
++ );
++
++ if ($self-&gt;{_test}) {
++ $mail-&gt;print(\*STDOUT);
++ } else {
++ open(MAIL, &quot;| $self-&gt;{_mta} -t -oi -oem&quot;) or die &quot;Can't open MTA program: $!&quot;;
++ $mail-&gt;print(\*MAIL);
++ close MAIL;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckOutputpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Output.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,190 @@
++# $Id: Output.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Check::Output;
++
++=head1 NAME
++
++Youri::Check::Output - Abstract output plugin
++
++=head1 DESCRIPTION
++
++This abstract class defines output plugin interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Youri::Utils;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Check::Output object.
++
++Generic parameters (subclasses may define additional ones):
++
++=over
++
++=item global true/false
++
++Global reports generation (default: true).
++
++=item individual true/false
++
++Individual reports generation (default: true).
++
++=back
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ id =&gt; '',
++ test =&gt; 0,
++ verbose =&gt; 0,
++ global =&gt; 1,
++ individual =&gt; 1,
++ config =&gt; undef,
++ @_
++ );
++
++ croak &quot;Neither global nor individual reporting selected&quot; unless $options{global} || $options{individual};
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _global =&gt; $options{global},
++ _individual =&gt; $options{individual},
++ _config =&gt; $options{config}
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns plugin identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 run($resultset)
++
++Reports the result stored in given L&lt;Youri::Check::Resultset&gt; object.
++
++=cut
++
++sub run {
++ my ($self, $resultset) = @_;
++
++ $self-&gt;_init_report();
++
++ # get types and maintainers list from resultset
++ my @maintainers = $resultset-&gt;get_maintainers();
++ my @types = $resultset-&gt;get_types();
++
++ foreach my $type (@types) {
++ # get formatting instructions from class
++ my $class = $self-&gt;{_config}-&gt;get($type . '_class');
++ load($class);
++ my @columns = $class-&gt;columns();
++ my %links = $class-&gt;links();
++
++ if ($self-&gt;{_global}) {
++ print STDERR &quot;generating global report for $type\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;_global_report(
++ $resultset,
++ $type,
++ \@columns,
++ \%links
++ );
++ }
++
++ if ($self-&gt;{_individual}) {
++ foreach my $maintainer (@maintainers) {
++ print STDERR &quot;generating individual report for $type and $maintainer\n&quot; if $self-&gt;{_verbose};
++
++ $self-&gt;_individual_report(
++ $resultset,
++ $type,
++ \@columns,
++ \%links,
++ $maintainer
++ );
++ }
++ }
++ }
++
++ $self-&gt;_finish_report(\@types, \@maintainers);
++}
++
++sub _init_report {
++ # do nothing
++}
++
++sub _global_report {
++ # do nothing
++}
++
++sub _individual_report {
++ # do nothing
++}
++
++sub _finish_report {
++ # do nothing
++}
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item run
++
++As an alternative, the following hooks can be implemented:
++
++=over
++
++=item _init_report
++
++=item _global_report
++
++=item _individual_report
++
++=item _finish_report
++
++=back
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckResultsetDBIpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/DBI.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,372 @@
++# $Id: Result.pm 485 2005-08-01 21:48:21Z guillomovitch $
++package Youri::Check::Resultset::DBI;
++
++=head1 NAME
++
++Youri::Check::Resultset::DBI - DBI-based resultset
++
++=head1 DESCRIPTION
++
++This is a DBI-based L&lt;Youri::Check::Resultset&gt; implementation.
++
++It can be created with any DBI-supported database.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use DBI 1.38;
++use base 'Youri::Check::Resultset';
++
++my %tables = (
++ packages =&gt; {
++ id =&gt; 'SERIAL PRIMARY KEY',
++ package =&gt; 'TEXT',
++ media =&gt; 'TEXT',
++ maintainer =&gt; 'TEXT',
++ }
++);
++
++my %queries = (
++ add_package =&gt;
++ 'INSERT INTO packages (package, media, maintainer) VALUES (?, ?, ?)',
++ get_package_id =&gt;
++ 'SELECT id FROM packages WHERE package = ?',
++ get_maintainers =&gt;
++ 'SELECT DISTINCT(maintainer) FROM packages WHERE maintainer IS NOT NULL',
++);
++
++=head1 CLASS METHODS
++
++=head2 new(%hash)
++
++Creates and returns a new Youri::Check::Resultset::DBI object.
++
++Specific parameters:
++
++=over
++
++=item driver $driver
++
++Use given string as DBI driver.
++
++=item base $base
++
++Use given string as database name.
++
++=item port $port
++
++Use given string as database port.
++
++=item user $user
++
++Use given string as database user.
++
++=item pass $pass
++
++Use given string as database password.
++
++=back
++
++=cut
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ driver =&gt; '', # driver
++ base =&gt; '', # base
++ port =&gt; '', # port
++ user =&gt; '', # user
++ pass =&gt; '', # pass
++ @_
++ );
++
++ croak &quot;No driver defined&quot; unless $options{driver};
++ croak &quot;No base defined&quot; unless $options{base};
++
++ my $datasource = &quot;DBI:$options{driver}:dbname=$options{base}&quot;;
++ $datasource .= &quot;;host=$options{host}&quot; if $options{host};
++ $datasource .= &quot;;port=$options{port}&quot; if $options{port};
++
++ $self-&gt;{_dbh} = DBI-&gt;connect($datasource, $options{user}, $options{pass}, {
++ RaiseError =&gt; 1,
++ PrintError =&gt; 0,
++ AutoCommit =&gt; 1
++ }) or croak &quot;Unable to connect: $DBI::errstr&quot;;
++
++ $self-&gt;{_dbh}-&gt;trace($options{verbose} - 1) if $options{verbose} &gt; 1;
++}
++
++sub clone {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $clone = bless {
++ _test =&gt; $self-&gt;{_test},
++ _verbose =&gt; $self-&gt;{_verbose},
++ _resolver =&gt; $self-&gt;{_resolver},
++ _dbh =&gt; $self-&gt;{_dbh}-&gt;clone()
++ }, ref $self;
++
++ return $clone;
++}
++
++sub reset {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ foreach my $table ($self-&gt;_get_tables()) {
++ my $query = &quot;DROP TABLE $table&quot;;
++ $self-&gt;{_dbh}-&gt;do($query);
++ }
++
++ foreach my $table (keys %tables) {
++ $self-&gt;_create_table($table, $tables{$table});
++ }
++}
++
++sub _get_tables {
++ my ($self) = @_;
++ my @tables = $self-&gt;{_dbh}-&gt;tables(undef, undef, '%', 'TABLE');
++ # unquote table name if needed
++ my $char = $self-&gt;{_dbh}-&gt;get_info(29);
++ @tables = map { substr($_, 1 , -1) } @tables if $char;
++ return @tables;
++}
++
++sub _get_columns {
++ my ($self, $table) = @_;
++ # proper way would be to use column_info(), but unfortunatly DBD::SQLite
++ # doesn't support it :(
++ return
++ keys
++ %{$self-&gt;{_dbh}-&gt;selectrow_hashref(&quot;SELECT * from $table&quot;)};
++}
++
++sub _create_table {
++ my ($self, $name, $fields) = @_;
++
++ my $query = &quot;CREATE TABLE $name (&quot; .
++ join(',',
++ map { &quot;$_ $fields-&gt;{$_}&quot; }
++ keys %$fields
++ ) .
++ &quot;)&quot;;
++ $self-&gt;{_dbh}-&gt;do($query);
++}
++
++sub add_result {
++ my ($self, $type, $media, $package, $values) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ croak &quot;No type defined&quot; unless $type;
++ croak &quot;No package defined&quot; unless $package;
++ croak &quot;No values defined&quot; unless $values;
++
++ my $key = &quot;add_$type&quot;;
++ my $sth = $self-&gt;{_sths}-&gt;{$key};
++
++ unless ($sth) {
++ my @fields = keys %$values;
++ $self-&gt;_create_table($type, {
++ 'package_id' =&gt; 'INT',
++ map { $_ =&gt; 'TEXT' } @fields
++ });
++ my $query = &quot;INSERT INTO $type (&quot; .
++ join(',', 'package_id', @fields) .
++ &quot;) VALUES (&quot; .
++ join(',', '?', map { '?' } @fields) .
++ &quot;)&quot;;
++ $sth = $self-&gt;{_dbh}-&gt;prepare($query);
++ $self-&gt;{_sths}-&gt;{$key} = $sth;
++ }
++
++ print &quot;adding result for type $type and package $package\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ $sth-&gt;execute(
++ $self-&gt;_get_package_id(
++ $package-&gt;get_canonical_name(),
++ $media-&gt;get_name(),
++ ),
++ values %$values
++ );
++}
++
++sub get_types {
++ my ($self) = @_;
++
++ return
++ grep { ! $tables{$_} }
++ $self-&gt;_get_tables();
++}
++
++sub get_maintainers {
++ my ($self) = @_;
++
++ return $self-&gt;_get_multiple_values('get_maintainers');
++}
++
++sub get_iterator {
++ my ($self, $id, $sort, $filter) = @_;
++
++ die 'No id given, aborting'
++ unless $id;
++ die 'sort should be an arrayref'
++ if $sort and ref $sort ne 'ARRAY';
++ die 'filter should be an hashref'
++ if $filter and ref $filter ne 'HASH';
++
++ my $query = $self-&gt;_get_iterator_query($id, $sort, $filter);
++
++ my $sth = $self-&gt;{_dbh}-&gt;prepare($query);
++ $sth-&gt;execute();
++
++ return Youri::Check::Resultset::DBI::Iterator-&gt;new($sth);
++}
++
++sub _get_iterator_query {
++ my ($self, $table, $sort, $filter) = @_;
++
++ my @fields =
++ grep { ! /package_id/ }
++ $self-&gt;_get_columns($table);
++
++ my $query = &quot;SELECT DISTINCT &quot; .
++ join(',', qw/package media maintainer/, @fields) .
++ &quot; FROM $table, packages&quot; .
++ &quot; WHERE packages.id = $table.package_id&quot;;
++
++ if ($filter) {
++ foreach my $column (keys %{$filter}) {
++ foreach my $value (@{$filter-&gt;{$column}}) {
++ $query .= &quot; AND $column = &quot; . $self-&gt;{_dbh}-&gt;quote($value);
++ }
++ }
++ }
++
++ if ($sort) {
++ $query .= &quot; ORDER BY &quot; . join(', ', @{$sort});
++ }
++
++ return $query;
++}
++
++sub _get_package_id {
++ my ($self, $package, $media) = @_;
++
++ my $id = $self-&gt;_get_single_value(
++ 'get_package_id',
++ $package
++ );
++ $id = $self-&gt;_add_package($package, $media) unless $id;
++
++ return $id;
++}
++
++sub _add_package {
++ my ($self, $package, $media) = @_;
++
++ my $maintainer = $self-&gt;{_resolver} ?
++ $self-&gt;{_resolver}-&gt;get_maintainer($package) :
++ undef;
++
++ my $sth =
++ $self-&gt;{_sths}-&gt;{add_package} ||=
++ $self-&gt;{_dbh}-&gt;prepare($queries{add_package});
++
++ $sth-&gt;execute(
++ $package,
++ $media,
++ $maintainer
++ );
++
++ my $id = $self-&gt;{_dbh}-&gt;last_insert_id(undef, undef, 'packages', 'id');
++
++ return $id;
++}
++
++sub _get_single_value {
++ my ($self, $query, @values) = @_;
++
++ my $sth =
++ $self-&gt;{_sths}-&gt;{$query} ||=
++ $self-&gt;{_dbh}-&gt;prepare($queries{$query});
++
++ $sth-&gt;execute(@values);
++
++ my @row = $sth-&gt;fetchrow_array();
++ return @row ? $row[0]: undef;
++}
++
++sub _get_multiple_values {
++ my ($self, $query, @values) = @_;
++
++ my $sth =
++ $self-&gt;{_sths}-&gt;{$query} ||=
++ $self-&gt;{_dbh}-&gt;prepare($queries{$query});
++
++ $sth-&gt;execute(@values);
++
++ my @results;
++ while (my @row = $sth-&gt;fetchrow_array()) {
++ push @results, $row[0];
++ }
++ return @results;
++}
++
++# close database connection
++sub DESTROY {
++ my ($self) = @_;
++
++ foreach my $sth (values %{$self-&gt;{_sths}}) {
++ $sth-&gt;finish() if $sth;
++ }
++
++ # warning, may be called before _dbh is created
++ $self-&gt;{_dbh}-&gt;disconnect() if $self-&gt;{_dbh};
++}
++
++package Youri::Check::Resultset::DBI::Iterator;
++
++sub new {
++ my ($class, $sth) = @_;
++
++ my $self = bless {
++ _sth =&gt; $sth,
++ _queue =&gt; []
++ }, $class;
++
++ return $self;
++}
++
++sub has_results {
++ my ($self) = @_;
++
++ return 1 if @{$self-&gt;{_queue}};
++
++ push(
++ @{$self-&gt;{_queue}},
++ $self-&gt;{_sth}-&gt;fetchrow_hashref()
++ );
++
++ return defined $self-&gt;{_queue}-&gt;[-1];
++}
++
++sub get_result {
++ my ($self) = @_;
++
++ return @{$self-&gt;{_queue}} ?
++ shift @{$self-&gt;{_queue}}:
++ $self-&gt;{_sth}-&gt;fetchrow_hashref();
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckResultsetIteratorpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset/Iterator.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,22 @@
++# $Id: Base.pm 483 2005-08-01 21:39:05Z guillomovitch $
++package Youri::Check::Resultset::Iterator;
++
++=head1 INSTANCE METHODS
++
++=head2 has_results()
++
++Returns true if results are available.
++
++=head2 get_result()
++
++Returns next available result, as an field =&gt; value hash reference.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriCheckResultsetpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Check/Resultset.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,116 @@
++# $Id: Base.pm 483 2005-08-01 21:39:05Z guillomovitch $
++package Youri::Check::Resultset;
++
++=head1 NAME
++
++Youri::Check::Resultset - Abstract resultset
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Check::Resultset interface
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Scalar::Util qw/blessed/;
++use Youri::Utils;
++
++=head1 CLASS METHODS
++
++=head2 new(%hash)
++
++Creates and returns a new Youri::Check::Resultset object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ my %options = (
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ resolver =&gt; undef, # maintainer resolver,
++ mode =&gt; 'output', # access mode
++ @_
++ );
++
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my $self = bless {
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ _resolver =&gt; $options{resolver},
++ _mode =&gt; $options{mode}
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 set_resolver()
++
++Set L&lt;Youri::Check::Maintainer::Resolver&gt; object used to resolve package
++maintainers.
++
++=cut
++
++sub set_resolver {
++ my ($self, $resolver) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ croak &quot;resolver should be a Youri::Check::Maintainer::Resolver object&quot;
++ unless blessed $resolver &amp;&amp;
++ $resolver-&gt;isa(&quot;Youri::Check::Maintainer::Resolver&quot;);
++
++ $self-&gt;{_resolver} = $resolver;
++}
++
++=head2 clone()
++
++Clone resultset object.
++
++=head2 reset()
++
++Reset resultset object, by deleting all contained results.
++
++=head2 add_result($type, $media, $package, $values)
++
++Add given hash reference as a new result for given type and L&lt;Youri::Package&gt; object.
++
++=head2 get_maintainers()
++
++Returns the list of all maintainers with results.
++
++=head2 get_iterator($id, $sort, $filter)
++
++Returns a L&lt;Youri::Check::Resultset::Iterator&gt; object over results for given input it, with optional sort and filter directives.
++
++sort must be an arrayref of column names, such as [ 'package' ].
++
++filter must be a hashref of arrayref of acceptables values indexed by column names, such as { level =&gt; [ 'warning', 'error'] }.
++
++=head1 SUBCLASSING
++
++All instances methods have to be implemented.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriConfigpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Config.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Config.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Config.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,202 @@
++# $Id: Config.pm 1709 2006-10-16 16:33:43Z warly $
++package Youri::Config;
++
++=head1 NAME
++
++Youri::Application - Youri application handler
++
++=head1 SYNOPSIS
++
++ use Youri::Application;
++
++ my $app = Youri::Application-&gt;new(
++ options =&gt; {
++ help =&gt; '|h!'
++ },
++ directories =&gt; [ '/etc/youri', &quot;$ENV{HOME}/.youri&quot; ],
++ file =&gt; 'app.conf',
++ );
++
++ # get command line argument
++ my $foo = $app-&gt;get_arg('foo');
++
++ # get configuration file parameter
++ my $bar = $app-&gt;get_param('bar');
++
++=head1 DESCRIPTION
++
++This class handle configuration for all YOURI applications.
++
++The command line specification is used to manage arguments through
++Getopt::Long. Unless B&lt;--config&gt; argument is given, the list of directories is
++then scanned for a file with given name, and halt as soon as it find one. If no
++readable file is found, an exception is thrown. The file is then processed
++through YAML::AppConfig. If parsing fails, an exception is thrown.
++
++=head1 CONFIGURATION FILE FORMAT
++
++=head2 SHARED KEYS
++
++In addition to the application-specific optional or mandatory parameters, all
++YOURI applications support the following optional top-level parameters:
++
++=over
++
++=item B&lt;includes&gt;
++
++A list of additional configuration files.
++
++=item B&lt;foo&gt;
++
++An arbitrary variable, usable everywhere else in the file.
++
++=back
++
++=head2 PLUGIN DEFINITION
++
++All YOURI application heavily rely on plugins defined in their configuration
++files. A plugin definition is composed from the following parameters:
++
++=over
++
++=item B&lt;class&gt;
++
++The class of this plugin.
++
++=item B&lt;options&gt;
++
++The options of this plugin.
++
++=back
++
++=head1 SEE ALSO
++
++YAML::AppConfig, Getopt::Long
++
++=cut
++
++use strict;
++use warnings;
++use YAML::AppConfig;
++use Getopt::Long;
++use File::Spec;
++use Pod::Usage;
++use Carp;
++
++sub new {
++ my ($class, %options) = @_;
++
++
++ # command line arguments
++ my $args = {
++ verbose =&gt; 0
++ };
++ my @args;
++ if ($options{args}) {
++ while (my ($arg, $spec) = each %{$options{args}}) {
++ push(@args, ($arg . $spec) =&gt; \$args-&gt;{$arg});
++ }
++ }
++ push(@args,
++ 'config=s' =&gt; \$args-&gt;{config},
++ 'h|help' =&gt; \$args-&gt;{help},
++ 'v|verbose+' =&gt; \$args-&gt;{verbose}
++ );
++ GetOptions(@args);
++
++ if ($args-&gt;{help}) {
++ if (!@ARGV) {
++ # standard help, available immediatly
++ my $filename = (caller)[1];
++ pod2usage(
++ -input =&gt; $filename,
++ -verbose =&gt; 0
++ );
++ }
++ }
++
++ # config files parameters
++
++ # find configuration file to use
++ my $main_file;
++ if ($args-&gt;{config}) {
++ if (! -f $args-&gt;{config}) {
++ croak &quot;Non-existing file $args-&gt;{config}&quot;;
++ } elsif (! -r $args-&gt;{config}) {
++ croak &quot;Non-readable file $args-&gt;{config}&quot;;
++ } else {
++ $main_file = $args-&gt;{config};
++ }
++ } else {
++ foreach my $directory (@{$options{directories}}) {
++ my $file = &quot;$directory/$options{file}&quot;;
++ next unless -f $file &amp;&amp; -r $file;
++ $main_file = $file;
++ last;
++ }
++ croak 'No config file found, aborting' unless $main_file;
++ }
++
++ my $params;
++ eval {
++ $params = YAML::AppConfig-&gt;new(file =&gt; $main_file);
++ };
++ if ($@) {
++ croak &quot;Invalid configuration file $main_file, aborting&quot;;
++ }
++
++ # process inclusions
++ my $includes = $params-&gt;get('includes');
++ if ($includes) {
++ foreach my $include_file (@{$includes}) {
++ # convert relative path to absolute ones
++ $include_file = File::Spec-&gt;rel2abs(
++ $include_file, (File::Spec-&gt;splitpath($main_file))[1]
++ );
++
++ if (! -f $include_file) {
++ warn &quot;Non-existing file $include_file, skipping&quot;;
++ } elsif (! -r $include_file) {
++ warn &quot;Non-readable file $include_file, skipping&quot;;
++ } else {
++ eval {
++ $params-&gt;merge(file =&gt; $include_file);
++ };
++ if ($@) {
++ carp &quot;Invalid included configuration file $include_file, skipping&quot;;
++ }
++ }
++ }
++ }
++
++ my $self = bless {
++ _args =&gt; $args,
++ _params =&gt; $params
++ }, $class;
++
++ return $self;
++}
++
++sub get_arg {
++ my ($self, $arg) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_args}-&gt;{$arg};
++}
++
++sub get_param {
++ my ($self, $param) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_params}-&gt;get($param);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriMediaURPMpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Media/URPM.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,273 @@
++# $Id: URPM.pm 1179 2006-08-05 08:30:57Z warly $
++package Youri::Media::URPM;
++
++=head1 NAME
++
++Youri::Media::URPM - URPM-based media implementation
++
++=head1 DESCRIPTION
++
++This is an URPM-based L&lt;Youri::Media&gt; implementation.
++
++It can be created either from local or remote full (hdlist) or partial
++(synthesis) compressed header files, or from a package directory. File-based
++inputs are only usable with this latest option.
++
++=cut
++
++use URPM;
++use File::Find;
++use File::Temp ();
++use Youri::Utils;
++use LWP::Simple;
++use Carp;
++use strict;
++use warnings;
++use Youri::Package::URPM;
++
++use base 'Youri::Media';
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Media::URPM object.
++
++Specific parameters:
++
++=over
++
++=item synthesis $synthesis
++
++Path, URL or list of path or URL of synthesis file used for creating
++this media. If a list is given, the first successfully accessed will be used,
++so as to allow better reliability.
++
++=item hdlist $hdlist
++
++Path, URL or list of path or URL of hdlist file used for creating
++this media. If a list is given, the first successfully accessed will be used,
++so as to allow better reliability.
++
++=item path $path
++
++Path or list of pathes of package directory used for creating this
++media. If a list is given, the first successfully accessed will be used, so as
++to allow better reliability.
++
++=item max_age $age
++
++Maximum age of packages for this media.
++
++=item rpmlint_config $file
++
++rpmlint configuration file for this media.
++
++=back
++
++In case of multiple B&lt;synthesis&gt;, B&lt;hdlist&gt; and B&lt;path&gt; options given, they
++will be tried in this order, so as to minimize parsing time.
++
++=cut
++
++sub _init {
++ my $self = shift;
++
++ my %options = (
++ hdlist =&gt; '', # hdlist from which to create this media
++ synthesis =&gt; '', # synthesis from which to create this media
++ path =&gt; '', # directory from which to create this media
++ max_age =&gt; '', # maximum build age for packages
++ rpmlint_config =&gt; '', # rpmlint configuration for packages
++ @_
++ );
++
++ my $urpm = URPM-&gt;new();
++ SOURCE: {
++ if ($options{synthesis}) {
++ foreach my $file (
++ ref $options{synthesis} eq 'ARRAY' ?
++ @{$options{synthesis}} :
++ $options{synthesis}
++ ) {
++ print &quot;Attempting to retrieve synthesis $file\n&quot;
++ if $options{verbose};
++ my $synthesis = $self-&gt;_get_file($file);
++ if ($synthesis) {
++ $urpm-&gt;parse_synthesis($synthesis, keep_all_tags =&gt; 1);
++ last SOURCE;
++ }
++ }
++ }
++
++ if ($options{hdlist}) {
++ foreach my $file (
++ ref $options{hdlist} eq 'ARRAY' ?
++ @{$options{hdlist}} :
++ $options{hdlist}
++ ) {
++ print &quot;Attempting to retrieve hdlist $file\n&quot;
++ if $options{verbose};
++ my $hdlist = $self-&gt;_get_file($file);
++ if ($hdlist) {
++ $urpm-&gt;parse_hdlist($hdlist, keep_all_tags =&gt; 1);
++ last SOURCE;
++ }
++ }
++ }
++
++ if ($options{path}) {
++ foreach my $path (
++ ref $options{path} eq 'ARRAY' ?
++ @{$options{path}} :
++ $options{path}
++ ) {
++ print &quot;Attempting to scan directory $path\n&quot;
++ if $options{verbose};
++ unless (-d $path) {
++ carp &quot;non-existing directory $path&quot;;
++ next;
++ }
++ unless (-r $path) {
++ carp &quot;non-readable directory $path&quot;;
++ next;
++ }
++
++ my $parse = sub {
++ return unless -f $File::Find::name;
++ return unless -r $File::Find::name;
++ return unless /\.rpm$/;
++
++ $urpm-&gt;parse_rpm($File::Find::name, keep_all_tags =&gt; 1);
++ };
++
++ find($parse, $path);
++ last SOURCE;
++ }
++ }
++
++ croak &quot;no source specified&quot;;
++ }
++
++ $self-&gt;{_urpm} = $urpm;
++ $self-&gt;{_path} = $options{path};
++ $self-&gt;{_max_age} = $options{max_age};
++ $self-&gt;{_rpmlint_config} = $options{rpmlint_config};
++
++ return $self;
++}
++
++sub _remove_all_archs {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $self-&gt;{_urpm}-&gt;{depslist} = [];
++}
++
++sub _remove_archs {
++ my ($self, $skip_archs) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $urpm = $self-&gt;{_urpm};
++ $urpm-&gt;{depslist} = [
++ grep { ! $skip_archs-&gt;{$_-&gt;arch()} } @{$urpm-&gt;{depslist}}
++ ];
++}
++
++=head1 INSTANCE METHODS
++
++=head2 max_age()
++
++Returns maximum age of packages for this media.
++
++=cut
++
++sub max_age {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_max_age};
++}
++
++=head2 rpmlint_config()
++
++Returns rpmlint configuration file for this media.
++
++=cut
++
++sub rpmlint_config {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_rpmlint_config};
++}
++
++sub get_package_class {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return &quot;Youri::Package::URPM&quot;;
++}
++
++sub traverse_files {
++ my ($self, $function) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $callback = sub {
++ return unless -f $File::Find::name;
++ return unless -r $File::Find::name;
++ return unless $_ =~ /\.rpm$/;
++
++ my $package = Youri::Package::URPM-&gt;new(file =&gt; $File::Find::name);
++ return if $self-&gt;{_skip_archs}-&gt;{$package-&gt;get_arch()};
++
++ $function-&gt;($File::Find::name, $package);
++ };
++
++ find($callback, $self-&gt;{_path});
++}
++
++sub traverse_headers {
++ my ($self, $function) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $self-&gt;{_urpm}-&gt;traverse(sub {
++ local $_; # workaround mysterious problem between URPM and AppConfig
++ $function-&gt;(Youri::Package::URPM-&gt;new(header =&gt; $_[0]));
++ });
++
++}
++
++sub _get_file {
++ my ($self, $file) = @_;
++
++ if ($file =~ /^(?:http|ftp):\/\/.*$/) {
++ my $tempfile = File::Temp-&gt;new();
++ my $status = getstore($file, $tempfile-&gt;filename());
++ unless (is_success($status)) {
++ carp &quot;invalid URL $file: $status&quot;;
++ return;
++ }
++ return $tempfile;
++ } else {
++ unless (-f $file) {
++ carp &quot;non-existing file $file&quot;;
++ return;
++ }
++ unless (-r $file) {
++ carp &quot;non-readable file $file&quot;;
++ return;
++ }
++ return $file;
++ }
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriMediapm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Media.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Media.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Media.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,311 @@
++# $Id: Media.pm 1710 2006-10-16 16:35:11Z warly $
++package Youri::Media;
++
++=head1 NAME
++
++Youri::Media - Abstract media class
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Media interface.
++
++=cut
++
++use Carp;
++use strict;
++use warnings;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Media object.
++
++Generic parameters:
++
++=over
++
++=item id $id
++
++Media id.
++
++=item name $name
++
++Media name.
++
++=item type $type (source/binary)
++
++Media type.
++
++=item test true/false
++
++Test mode (default: false).
++
++=item verbose true/false
++
++Verbose mode (default: false).
++
++=item allow_deps $media_ids
++
++list of ids of medias allowed to provide dependencies.
++
++=item skip_tests $test_ids
++
++list of ids of test plugins to skip.
++
++=item skip_archs $arches
++
++list of arches to skip.
++
++=back
++
++Subclass may define additional parameters.
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ name =&gt; '', # media name
++ canonical_name =&gt; '', # media canonical name
++ type =&gt; '', # media type
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ allow_deps =&gt; undef, # list of media ids from which deps are allowed
++ allow_srcs =&gt; undef, # list of media ids from which packages can be built
++ skip_tests =&gt; undef, # list of tests ids to skip
++ skip_archs =&gt; undef, # list of archs for which to skip tests
++ @_
++ );
++
++
++ croak &quot;No type given&quot; unless $options{type};
++ croak &quot;Wrong value for type: $options{type}&quot;
++ unless $options{type} =~ /^(?:binary|source)$/o;
++
++ # some options need to be arrays. Check it and convert to hashes
++ foreach my $option (qw(allow_deps allow_srcs skip_archs skip_tests)) {
++ next unless defined $options{$option};
++ croak &quot;$option should be an arrayref&quot; unless ref $options{$option} eq 'ARRAY';
++ $options{$option} = {
++ map { $_ =&gt; 1 } @{$options{$option}}
++ };
++ }
++
++ my $self = bless {
++ _id =&gt; $options{id},
++ _name =&gt; $options{name} || $options{id},
++ _type =&gt; $options{type},
++ _allow_deps =&gt; $options{allow_deps},
++ _allow_srcs =&gt; $options{allow_srcs},
++ _skip_archs =&gt; $options{skip_archs},
++ _skip_tests =&gt; $options{skip_tests},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ # remove unwanted archs
++ if ($options{skip_archs}-&gt;{all}) {
++ $self-&gt;_remove_all_archs()
++ } elsif ($options{skip_archs}) {
++ $self-&gt;_remove_archs($options{skip_archs});
++ }
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_id()
++
++Returns media identity.
++
++=cut
++
++sub get_id {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_id};
++}
++
++=head2 get_name()
++
++Returns the name of this media.
++
++=cut
++
++sub get_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_name};
++}
++
++=head2 get_type()
++
++Returns the type of this media.
++
++=cut
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_type};
++}
++
++=head2 allow_deps()
++
++Returns the list of id of medias allowed to provide dependencies for this
++media.
++
++=cut
++
++sub allow_deps {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_allow_deps}};
++}
++
++=head2 allow_dep($media_id)
++
++Tells wether media with given id is allowed to provide dependencies for
++this media.
++
++=cut
++
++sub allow_dep {
++ my ($self, $dep) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_allow_deps}-&gt;{all} ||
++ $self-&gt;{_allow_deps}-&gt;{$dep};
++}
++
++=head2 allow_srcs()
++
++Returns the list medias where the source packages can be
++
++=cut
++
++sub allow_srcs {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_allow_srcs}};
++}
++
++=head2 allow_src($media_id)
++
++Tells wether media with given id is allowed to host sources dependencies for
++this media.
++
++=cut
++
++sub allow_src {
++ my ($self, $src) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_allow_srcs}-&gt;{all} || $self-&gt;{_allow_srcs}-&gt;{$src};
++}
++
++=head2 skip_archs()
++
++Returns the list of arch which are to be skipped for this media.
++
++=cut
++
++sub skip_archs {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_skip_archs}};
++}
++
++=head2 skip_arch($arch)
++
++Tells wether given arch is to be skipped for this media.
++
++=cut
++
++sub skip_arch {
++ my ($self, $arch) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_skip_archs}-&gt;{all} ||
++ $self-&gt;{_skip_archs}-&gt;{$arch};
++}
++
++=head2 skip_tests()
++
++Returns the list of id of test which are to be skipped for this media.
++
++=cut
++
++sub skip_tests {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return keys %{$self-&gt;{_skip_tests}};
++}
++
++=head2 skip_test($test_id)
++
++Tells wether test with given id is to be skipped for this media.
++
++=cut
++
++sub skip_test {
++ my ($self, $test) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_skip_tests}-&gt;{all} ||
++ $self-&gt;{_skip_tests}-&gt;{$test};
++}
++
++=head2 get_package_class()
++
++Return package class for this media.
++
++=head2 traverse_files($function)
++
++Apply given function to all files of this media.
++
++=head2 traverse_headers($function)
++
++Apply given function to all headers of this media.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item traverse_headers
++
++=item traverse_files
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageRPMpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,58 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Package/URPM.pm 2257 2006-07-05T09:22:47.088572Z guillaume $
++package Youri::Package::RPM;
++
++=head1 NAME
++
++Youri::Package::RPM - Base class for all RPM-based package implementation
++
++=head1 DESCRIPTION
++
++This bases class factorize code between various RPM-based package
++implementation.
++
++=cut
++
++use strict;
++use warnings;
++use base 'Youri::Package';
++use Carp;
++
++sub get_pattern {
++ my ($class, $name, $version, $release, $arch) = @_;
++
++ return
++ ($name ? quotemeta($name) : '[\w-]+' ).
++ '-' .
++ ($version ? quotemeta($version) : '[^-]+' ).
++ '-' .
++ ($release ? quotemeta($release) : '[^-]+' ).
++ '\.' .
++ ($arch ? quotemeta($arch) : '\w+' ).
++ '\.rpm';
++}
++
++sub as_file {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_file};
++}
++
++sub is_debug {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $name = $self-&gt;get_name();
++ my $group = $self-&gt;get_tag('group');
++
++ # debug packages' names must end in -debug, except kernel
++ if ($group =~ m,^Development/Debug$, &amp;&amp;
++ ($name =~ /-debug$/o || $name =~ /^kernel-.*-debug/o)) {
++ return 1;
++ }
++ else {
++ return 0;
++ }
++}
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageRPM4pm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/RPM4.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,424 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Package/URPM.pm 2129 2006-06-23T09:41:01.599329Z guillomovitch $
++package Youri::Package::RPM4;
++
++=head1 NAME
++
++Youri::Package::RPM4 - URPM-based rpm package implementation
++
++=head1 DESCRIPTION
++
++This is an RPM4-based L&lt;Youri::Package&gt; implementation for rpm.
++
++=cut
++
++use strict;
++use warnings;
++use Carp;
++use RPM4;
++use RPM4::Header;
++use RPM4::Sign;
++use File::Spec;
++use Scalar::Util qw/refaddr/;
++use base 'Youri::Package::RPM';
++use overload
++ '&quot;&quot;' =&gt; 'as_string',
++ '0+' =&gt; '_to_number',
++ fallback =&gt; 1;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package::RPM4 object.
++
++Specific parameters:
++
++=over
++
++=item file $file
++
++Path of file to use for creating this package.
++
++=item header $header
++
++L&lt;RPM4::Header&gt; object to use for creating this package.
++
++=back
++
++=cut
++
++sub _init {
++ my ($self, %options) = @_;
++
++ my $header;
++ HEADER: {
++ if (exists $options{header}) {
++ croak &quot;undefined header&quot;
++ unless $options{header};
++ croak &quot;invalid header&quot;
++ unless $options{header}-&gt;isa('RPM4::Header');
++ $header = $options{header};
++ last HEADER;
++ }
++
++ if (exists $options{file}) {
++ croak &quot;undefined file&quot;
++ unless $options{file};
++ croak &quot;non-existing file $options{file}&quot;
++ unless -f $options{file};
++ croak &quot;non-readable file $options{file}&quot;
++ unless -r $options{file};
++ $header = RPM4::Header-&gt;new($options{file});
++ croak &quot;Can't get header from file $options{file}&quot; if (!$header);
++
++ last HEADER;
++ }
++
++ croak &quot;no way to extract header from arguments&quot;;
++ }
++
++ $self-&gt;{_header} = $header;
++ $self-&gt;{_file} = File::Spec-&gt;rel2abs($options{file});
++}
++
++sub compare_versions {
++ my ($class, $version1, $version2) = @_;
++
++ return RPM4::rpmvercmp($version1, $version2);
++}
++
++sub _depsense2flag {
++ my ($string) = @_;
++ my @flags = 0;
++ push(@flags, 'EQUAL') if ($string =~ /=/);
++ push(@flags, 'LESS') if ($string =~ /&lt;/);
++ push(@flags, 'GREATER') if ($string =~ /&gt;/);
++ return \@flags;
++}
++
++sub check_ranges_compatibility {
++ my ($class, $range1, $range2) = @_;
++ my @deps1 = split(/ /, $range1);
++ my @deps2 = split(/ /, $range2);
++ $deps1[1] = _depsense2flag($range1);
++ $deps2[1] = _depsense2flag($range2);
++ my $dep1 = RPM4::Header::Dependencies(
++ &quot;PROVIDENAME&quot;,
++ \@deps1,
++ );
++ my $dep2 = RPM4::Header::Dependencies(
++ &quot;PROVIDENAME&quot;,
++ \@deps2,
++ );
++
++ return $dep1-&gt;overlap($dep2);
++}
++
++sub get_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('name');
++}
++
++sub get_version {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('version');
++}
++
++sub get_release {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('release');
++}
++
++sub get_revision {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}');
++}
++
++sub get_file_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%{NAME}-%{VERSION}-%{RELEASE}.%|SOURCERPM?{%{ARCH}}:{src}|.rpm');
++}
++
++
++sub get_arch {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%|SOURCERPM?{%{ARCH}}:{src}|');
++}
++
++sub get_url {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('url');
++}
++
++sub get_summary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('summary');
++}
++
++sub get_description {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('description');
++}
++
++sub get_packager {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('packager');
++}
++
++sub is_source {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;issrc();
++}
++
++sub is_binary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return !$self-&gt;{_header}-&gt;issrc();
++}
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_header}-&gt;issrc() ?
++ &quot;source&quot; :
++ &quot;binary&quot;;
++}
++
++sub get_age {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('buildtime');
++}
++
++sub get_source_package {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;tag('sourcerpm');
++}
++
++sub get_canonical_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ $self-&gt;{_header}-&gt;sourcerpmname() =~ /^(\S+)-[^-]+-[^-]+\.src\.rpm$/;
++ return $1;
++}
++
++sub get_tag {
++ my ($self, $tag) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ #croak &quot;invalid tag $tag&quot; unless $self-&gt;{_header}-&gt;can($tag);
++ return $self-&gt;{_header}-&gt;tag($tag);
++}
++
++
++sub _get_dependencies {
++ my ($self, $deptype) = @_;
++ my $deps = $self-&gt;{_header}-&gt;dep($deptype);
++ my @deps_list;
++ if ($deps) {
++ $deps-&gt;init();
++ while ($deps-&gt;next() &gt;= 0) {
++ my @deps = $deps-&gt;info();
++ $deps[1] =~ m/^rpmlib\(/ and next; # skipping internal rpmlib dep
++ $deps[2] =~ s/^=$/==/; # rpm say foo = 1, not foo == 1, == come from URPM, which sucks
++ my $range = $deps[3] ? ($deps[2] . ' ' . $deps[3]) : undef;
++ push(@deps_list, [ $deps[1], $range ]);
++ }
++ }
++ @deps_list
++}
++
++sub get_requires {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('REQUIRENAME');
++}
++
++sub get_provides {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('PROVIDENAME');
++}
++
++sub get_obsoletes {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('OBSOLETENAME');
++}
++
++sub get_conflicts {
++ my ($self) = @_;
++
++ return $self-&gt;_get_dependencies('CONFLICTNAME');
++}
++
++sub get_files {
++ my ($self) = @_;
++
++ my $files = $self-&gt;{_header}-&gt;files();
++ my @fileslist;
++ if ($files) {
++ $files-&gt;init();
++ while ($files-&gt;next() &gt;= 0) {
++ my $smode = $files-&gt;mode();
++ my $umode = 0;
++ foreach (0..15) { # converting unsigned to signed int :\
++ $umode |= $smode &amp; (1 &lt;&lt; $_);
++ }
++ push(@fileslist, [ $files-&gt;filename(), $umode, $files-&gt;md5() || '' ]);
++ }
++ }
++ @fileslist
++}
++
++sub get_gpg_key {
++ my ($self) = @_;
++
++ my $signature = $self-&gt;{_header}-&gt;queryformat('%{SIGGPG:pgpsig}');
++
++ return if $signature eq '(not a blob)';
++
++ my $key_id = (split(/\s+/, $signature))[-1];
++
++ return substr($key_id, 8);
++}
++
++sub get_information {
++ my ($self) = @_;
++
++ return $self-&gt;{_header}-&gt;queryformat(&lt;&lt;EOF);
++Name : %-27{NAME} Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|
++Version : %-27{VERSION} Vendor: %{VENDOR}
++Release : %-27{RELEASE} Build Date: %{BUILDTIME:date}
++Install Date: %|INSTALLTIME?{%-27{INSTALLTIME:date}}:{(not installed) }| Build Host: %{BUILDHOST}
++Group : %-27{GROUP} Source RPM: %{SOURCERPM}
++Size : %-27{SIZE}%|LICENSE?{ License: %{LICENSE}}|
++Signature : %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|
++%|PACKAGER?{Packager : %{PACKAGER}\n}|%|URL?{URL : %{URL}\n}|Summary : %{SUMMARY}
++Description :\n%{DESCRIPTION}
++EOF
++}
++
++sub get_changes {
++ my ($self) = @_;
++
++ my @names = $self-&gt;{_header}-&gt;tag('changelogname');
++ my @time = $self-&gt;{_header}-&gt;tag('changelogtime');
++ my @text = $self-&gt;{_header}-&gt;tag('changelogtext');
++
++ my @changes;
++ foreach my $i (0 .. $#names) {
++ $changes[$i] = [
++ $names[$i],
++ $time[$i],
++ $text[$i],
++ ];
++ }
++
++ return @changes;
++}
++
++sub get_last_change {
++ my ($self) = @_;
++
++ return [
++ ($self-&gt;{_header}-&gt;tag('changelogname'))[0],
++ ($self-&gt;{_header}-&gt;tag('changelogtime'))[0],
++ ($self-&gt;{_header}-&gt;tag('changelogtext'))[0],
++ ];
++}
++
++sub as_string {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;fullname();
++}
++
++sub as_formated_string {
++ my ($self, $format) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat($format);
++}
++
++sub _to_number {
++ return refaddr($_[0]);
++}
++
++sub compare {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;compare($package-&gt;{_header}) || 0;
++}
++
++sub satisfy_range {
++ my ($self, $range) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;check_range_compatibility($self-&gt;get_revision(), $range);
++}
++
++sub sign {
++ my ($self, $name, $path, $passphrase) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # check if parent directory is writable
++ my $parent = (File::Spec-&gt;splitpath($self-&gt;{_file}))[1];
++ croak &quot;Unsignable package, parent directory is read-only&quot;
++ unless -w $parent;
++
++ my $sign = RPM4::Sign-&gt;new(
++ name =&gt; $name,
++ path =&gt; $path,
++ );
++ $sign-&gt;{passphrase} = $passphrase;
++
++ $sign-&gt;rpmssign($self-&gt;{_file})
++}
++
++sub extract {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ system(&quot;rpm2cpio $self-&gt;{_file} | cpio -id &gt;/dev/null 2&gt;&amp;1&quot;);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageTestpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/Test.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,151 @@
++# $Id: /local/youri/soft/core/trunk/lib/Youri/Package/URPM.pm 2133 2006-09-20T21:40:20.575763Z guillaume $
++package Youri::Package::Test;
++
++=head1 NAME
++
++Youri::Package::Test - Fake test package
++
++=head1 DESCRIPTION
++
++This is just a fake package object, intended for testing purposes.
++
++=cut
++
++use strict;
++use warnings;
++use Carp;
++use base 'Youri::Package::RPM';
++use overload
++ '&quot;&quot;' =&gt; 'as_string',
++ '0+' =&gt; '_to_number',
++ fallback =&gt; 1;
++
++our $AUTOLOAD;
++
++my @tags = qw/
++ name
++ version
++ release
++ filename
++ arch
++ url
++ summary
++ description
++ packager
++ buildtime
++ sourcerpm
++/;
++
++my %tags = map { $_ =&gt; 1 } @tags;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package::Test object.
++
++Specific parameters:
++
++=over
++
++=item tag $tag
++
++Use given value for given tag
++
++=back
++
++=cut
++
++sub _init {
++ my ($self, %options) = @_;
++
++ $self-&gt;{&quot;_$_&quot;} = $options{$_} foreach keys %options;
++}
++
++sub get_revision {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_epoch} ?
++ &quot;$self-&gt;{_epoch}:$self-&gt;{_version}-$self-&gt;{_release}&quot; :
++ &quot;$self-&gt;{_version}-$self-&gt;{_release}&quot;;
++}
++
++sub get_tag {
++ my ($self, $tag) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ croak &quot;invalid tag $tag&quot; unless $tags{$tag};
++ return $self-&gt;{'_' . $tag};
++}
++
++sub is_source {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_arch} eq 'src';
++}
++
++sub is_binary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_arch} ne 'src';
++}
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_arch} eq 'src' ?
++ &quot;source&quot; :
++ &quot;binary&quot;;
++}
++
++sub get_canonical_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ if ($self-&gt;{_arch} eq 'src') {
++ return $self-&gt;{_name};
++ } else {
++ if ($self-&gt;{_sourcerpm}) {
++ $self-&gt;{_sourcerpm} =~ /^(\S+)-[^-]+-[^-]+\.src\.rpm$/;
++ return $1;
++ } else {
++ return undef;
++ }
++ }
++}
++
++sub as_string {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_name} ? $self-&gt;{_name} : '' .
++ '-' .
++ $self-&gt;{_version} ? $self-&gt;{_version} : '' .
++ '-' .
++ $self-&gt;{_release} ? $self-&gt;{_release} : '';
++}
++
++sub _to_number {
++ return refaddr($_[0]);
++}
++
++sub AUTOLOAD {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my $method = $AUTOLOAD;
++ $method =~ s/.*:://;
++ return if $method eq 'DESTROY';
++ croak &quot;invalid method&quot; unless $method =~ /^get_(\w+)$/;
++
++ my $tag = $1;
++ croak &quot;invalid tag $tag&quot; unless $tags{$tag};
++ return $self-&gt;{'_' . $tag};
++}
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackageURPMpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package/URPM.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,399 @@
++# $Id: URPM.pm 266577 2010-03-02 14:51:24Z bogdano $
++package Youri::Package::URPM;
++
++=head1 NAME
++
++Youri::Package::URPM - URPM-based rpm package implementation
++
++=head1 DESCRIPTION
++
++This is an URPM-based L&lt;Youri::Package&gt; implementation for rpm.
++
++It is merely a wrapper over URPM::Package class, with a more structured
++interface.
++
++=cut
++
++use strict;
++use warnings;
++use Carp;
++use URPM;
++use File::Spec;
++use Expect;
++use Scalar::Util qw/refaddr/;
++use base 'Youri::Package::RPM';
++use overload
++ '&quot;&quot;' =&gt; 'as_string',
++ '0+' =&gt; '_to_number',
++ fallback =&gt; 1;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package::URPM object.
++
++Specific parameters:
++
++=over
++
++=item file $file
++
++Path of file to use for creating this package.
++
++=item header $header
++
++L&lt;URPM::Package&gt; object to use for creating this package.
++
++=back
++
++=cut
++
++sub _init {
++ my ($self, %options) = @_;
++
++ my $header;
++ HEADER: {
++ if (exists $options{header}) {
++ croak &quot;undefined header&quot;
++ unless $options{header};
++ croak &quot;invalid header&quot;
++ unless $options{header}-&gt;isa('URPM::Package');
++ $header = $options{header};
++ last HEADER;
++ }
++
++ if (exists $options{file}) {
++ croak &quot;undefined file&quot;
++ unless $options{file};
++ croak &quot;non-existing file $options{file}&quot;
++ unless -f $options{file};
++ croak &quot;non-readable file $options{file}&quot;
++ unless -r $options{file};
++ my $urpm = URPM-&gt;new();
++ $urpm-&gt;parse_rpm($options{file}, keep_all_tags =&gt; 1);
++ $header = $urpm-&gt;{depslist}-&gt;[0];
++ croak &quot;non-rpm file $options{file}&quot; unless $header;
++ last HEADER;
++ }
++
++ croak &quot;no way to extract header from arguments&quot;;
++ }
++
++ $self-&gt;{_header} = $header;
++ $self-&gt;{_file} = File::Spec-&gt;rel2abs($options{file});
++}
++
++sub compare_versions {
++ my ($class, $version1, $version2) = @_;
++
++ return URPM::rpmvercmp($version1, $version2);
++}
++
++sub check_ranges_compatibility {
++ my ($class, $range1, $range2) = @_;
++
++ return URPM::ranges_overlap($range1, $range2);
++}
++
++sub get_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;name();
++}
++
++sub get_version {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;version();
++}
++
++sub get_release {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;release();
++}
++
++sub get_revision {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat('%|EPOCH?{%{EPOCH}:}:{}|%{VERSION}-%{RELEASE}');
++}
++
++sub get_file_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_file} || die &quot;_file is not defined in header-only objects!\n&quot;;
++}
++
++sub get_arch {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;arch();
++}
++
++sub get_url {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;url();
++}
++
++sub get_summary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;summary();
++}
++
++sub get_description {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;description();
++}
++
++sub get_packager {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;packager();
++}
++
++sub is_source {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;arch() eq 'src';
++}
++
++sub is_binary {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;arch() ne 'src';
++}
++
++sub get_type {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_header}-&gt;arch() eq 'src' ?
++ &quot;source&quot; :
++ &quot;binary&quot;;
++}
++
++sub get_age {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;buildtime();
++}
++
++sub get_source_package {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;sourcerpm();
++}
++
++sub get_canonical_name {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ if ($self-&gt;{_header}-&gt;arch() eq 'src') {
++ return $self-&gt;{_header}-&gt;name();
++ } else {
++ $self-&gt;{_header}-&gt;sourcerpm() =~ /^(\S+)-[^-]+-[^-]+\.src\.rpm$/;
++ return $1;
++ }
++}
++
++sub get_tag {
++ my ($self, $tag) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ croak &quot;invalid tag $tag&quot; unless $self-&gt;{_header}-&gt;can($tag);
++ return $self-&gt;{_header}-&gt;$tag();
++}
++
++sub get_requires {
++ my ($self) = @_;
++
++ return map {
++ $_ =~ /^([^[]+)(?:\[\*\])?(?:\[(.+)\])?$/;
++ [ $1, $2 ]
++ } $self-&gt;{_header}-&gt;requires();
++}
++
++sub get_provides {
++ my ($self) = @_;
++
++ return map {
++ $_ =~ /^([^[]+)(?:\[(.+)\])?$/;
++ [ $1, $2 &amp;&amp; $2 ne '*' ? $2 : undef ]
++ } $self-&gt;{_header}-&gt;provides();
++}
++
++sub get_obsoletes {
++ my ($self) = @_;
++
++ return map {
++ $_ =~ /^([^[]+)(?:\[(.+)\])?$/;
++ [ $1, $2 &amp;&amp; $2 ne '*' ? $2 : undef ]
++ } $self-&gt;{_header}-&gt;obsoletes();
++}
++
++sub get_conflicts {
++ my ($self) = @_;
++
++ return $self-&gt;{_header}-&gt;conflicts();
++}
++
++sub get_files {
++ my ($self) = @_;
++
++ my @modes = $self-&gt;{_header}-&gt;files_mode();
++ my @md5sums = $self-&gt;{_header}-&gt;files_md5sum();
++
++ return map {
++ [ $_, shift @modes, shift @md5sums ]
++ } $self-&gt;{_header}-&gt;files();
++}
++
++sub get_gpg_key {
++ my ($self) = @_;
++
++ my $signature = $self-&gt;{_header}-&gt;queryformat('%{SIGGPG:pgpsig}');
++
++ return if $signature eq '(not a blob)';
++
++ my $key_id = (split(/\s+/, $signature))[-1];
++
++ return substr($key_id, 8);
++}
++
++sub get_information {
++ my ($self) = @_;
++
++ return $self-&gt;{_header}-&gt;queryformat(&lt;&lt;EOF);
++Name : %-27{NAME} Relocations: %|PREFIXES?{[%{PREFIXES} ]}:{(not relocatable)}|
++Version : %-27{VERSION} Vendor: %{VENDOR}
++Release : %-27{RELEASE} Build Date: %{BUILDTIME:date}
++Install Date: %|INSTALLTIME?{%-27{INSTALLTIME:date}}:{(not installed) }| Build Host: %{BUILDHOST}
++Group : %-27{GROUP} Source RPM: %{SOURCERPM}
++Size : %-27{SIZE}%|LICENSE?{ License: %{LICENSE}}|
++Signature : %|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|
++%|PACKAGER?{Packager : %{PACKAGER}\n}|%|URL?{URL : %{URL}\n}|Summary : %{SUMMARY}
++Description :\n%{DESCRIPTION}
++EOF
++}
++
++sub get_changes {
++ my ($self) = @_;
++
++ my @names = $self-&gt;{_header}-&gt;changelog_name();
++ my @time = $self-&gt;{_header}-&gt;changelog_time();
++ my @text = $self-&gt;{_header}-&gt;changelog_text();
++
++ my @changes;
++ foreach my $i (0 .. $#names) {
++ $changes[$i] = [
++ $names[$i],
++ $time[$i],
++ $text[$i],
++ ];
++ }
++
++ return @changes;
++}
++
++sub get_last_change {
++ my ($self) = @_;
++
++ return [
++ ($self-&gt;{_header}-&gt;changelog_name())[0],
++ ($self-&gt;{_header}-&gt;changelog_time())[0],
++ ($self-&gt;{_header}-&gt;changelog_text())[0],
++ ];
++}
++
++sub as_string {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;fullname();
++}
++
++sub as_formated_string {
++ my ($self, $format) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;queryformat($format);
++}
++
++sub _to_number {
++ return refaddr($_[0]);
++}
++
++sub compare {
++ my ($self, $package) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_header}-&gt;compare_pkg($package-&gt;{_header});
++}
++
++sub satisfy_range {
++ my ($self, $range) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;check_ranges_compatibility(&quot;== &quot; . $self-&gt;get_revision(), $range);
++}
++
++sub sign {
++ my ($self, $name, $path, $passphrase, $target) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ # check if parent directory is writable
++ my $parent = (File::Spec-&gt;splitpath($self-&gt;{_file}))[1];
++ croak &quot;Unsignable package, parent directory is read-only&quot;
++ unless -w $parent;
++
++ # FIXME Will have to change that
++ # we sign with cooker key even fro 2007.0 because this is for testing section
++ return !system(&quot;sudo -H /root/bin/resign_cooker $self-&gt;{_file}&quot;);
++
++ my $command =
++ 'LC_ALL=C rpm --resign ' . $self-&gt;{_file} .
++ ' --define &quot;_gpg_name ' . $name . '&quot;' .
++ ' --define &quot;_gpg_path ' . $path . '&quot;';
++ my $expect = Expect-&gt;spawn($command) or die &quot;Couldn't spawn command $command: $!\n&quot;;
++ $expect-&gt;log_stdout(0);
++ $expect-&gt;expect(20, -re =&gt; 'Enter pass phrase:');
++ $expect-&gt;send(&quot;$passphrase\n&quot;);
++
++ $expect-&gt;soft_close();
++}
++
++sub extract {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ system(&quot;rpm2cpio $self-&gt;{_file} | cpio -id &gt;/dev/null 2&gt;&amp;1&quot;);
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriPackagepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Package.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Package.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Package.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,336 @@
++# $Id: Package.pm 223952 2007-06-23 13:54:13Z pixel $
++package Youri::Package;
++
++=head1 NAME
++
++Youri::Package - Abstract package class
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Package interface.
++
++=cut
++
++use Carp;
++use strict;
++use warnings;
++
++use constant DEPENDENCY_NAME =&gt; 0;
++use constant DEPENDENCY_RANGE =&gt; 1;
++
++use constant FILE_NAME =&gt; 0;
++use constant FILE_MODE =&gt; 1;
++use constant FILE_MD5SUM =&gt; 2;
++
++use constant CHANGE_AUTHOR =&gt; 0;
++use constant CHANGE_TIME =&gt; 1;
++use constant CHANGE_TEXT =&gt; 2;
++
++=head1 CLASS METHODS
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Package object.
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ @_
++ );
++
++ my $self = bless {
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head2 get_pattern($name, $version, $release, $arch)
++
++Returns a pattern matching a file for a package, using available informations.
++
++=head2 compare_revisions($revision1, $revision2)
++
++Compares two revision tokens, and returns a numeric value:
++
++=over
++
++=item positive if first revision is higher
++
++=item null if both revisions are equal
++
++=item negative if first revision is lower
++
++=back
++
++=head2 check_ranges_compatibility($range1, $range2)
++
++Returns a true value if given revision ranges are compatible.
++
++=head1 INSTANCE METHODS
++
++=head2 as_file()
++
++Returns the file corresponding to this package.
++
++=head2 as_string()
++
++Returns a string representation of this package.
++
++=head2 as_formated_string(I&lt;format&gt;)
++
++Returns a string representation of this package, formated according to
++I&lt;format&gt;. Format is a string, where each %{foo} token will get replaced by
++equivalent tag value.
++
++=head2 get_name()
++
++Returns the name of this package.
++
++=head2 get_version()
++
++Returns the version of this package.
++
++=head2 get_release()
++
++Returns the release of this package.
++
++=head2 get_revision()
++
++Returns the revision of this package.
++
++=head2 get_arch()
++
++Returns the architecture of this package.
++
++=head2 get_file_name()
++
++Returns the file name of this package (name-version-release.arch.extension).
++
++=head2 is_source()
++
++Returns true if this package is a source package.
++
++=head2 is_binary()
++
++Returns true if this package is a binary package.
++
++=head2 is_debug()
++
++Returns true if this package is a debug package.
++
++=head2 get_type()
++
++Returns the type (binary/source) of this package.
++
++=head2 get_age()
++
++Returns the age of this package
++
++=head2 get_url()
++
++Returns the URL of this package
++
++=head2 get_summary()
++
++Returns the summary of this package
++
++=head2 get_description()
++
++Returns the description of this package
++
++=head2 get_packager()
++
++Returns the packager of this package.
++
++=head2 get_source_package()
++
++Returns the name of the source package of this package.
++
++=head2 get_tag($tag)
++
++Returns the value of tag $tag of this package.
++
++=head2 get_canonical_name()
++
++Returns the canonical name of this package, shared by its multiple components,
++usually the one from the source package.
++
++=head2 get_requires()
++
++Returns the list of dependencies required by this package, each dependency
++being represented as an array reference, with the following informations:
++
++=over
++
++=item B&lt;name&gt;
++
++Name of the dependency (index DEPENDENCY_NAME)
++
++=item B&lt;range&gt;
++
++Range of the dependency (index DEPENDENCY_RANGE)
++
++=back
++
++For more conveniency, fields index are available as constant in this package.
++
++=head2 get_provides()
++
++Returns the list of dependencies provided by this package, each dependency
++being represented as an array reference, using the same structure as previous method.
++
++=head2 get_obsoletes()
++
++Returns the list of other packages obsoleted by this one, each one
++being represented as an array reference, using the same structure as previous method.
++
++=head2 get_conflicts()
++
++Returns the list of other packages conflicting with this one.
++
++=head2 get_files()
++
++Returns the list of files contained in this package, each file being
++represented as an array reference, with the following informations:
++
++=over
++
++=item B&lt;name&gt;
++
++Name of the file (index FILE_NAME).
++
++=item B&lt;mode&gt;
++
++Mode of the file (index FILE_MODE).
++
++=item B&lt;md5sum&gt;
++
++Md5sum of the file (index FILE_MD5SUM).
++
++=back
++
++For more conveniency, fields index are available as constant in this package.
++
++=head2 get_gpg_key()
++
++Returns the gpg key id of package signature.
++
++=head2 get_information()
++
++Returns formated informations about the package.
++
++=head2 get_changes()
++
++Returns the list of changes for this package, each change being
++represented as an array reference, with the following informations:
++
++=over
++
++=item B&lt;author&gt;
++
++Author of the change (index CHANGE_AUTHOR).
++
++=item B&lt;time&gt;
++
++Time of the change (index CHANGE_TIME).
++
++=item B&lt;text&gt;
++
++Raw textual description of the change (index CHANGE_TEXT).
++
++=back
++
++For more conveniency, fields index are available as constant in this package.
++
++=head2 get_last_change()
++
++Returns the last change for this package, as as structure described before.
++
++=head2 compare($package)
++
++Compares ordering with other package, according to their corresponding revision
++tokens, and returns a numeric value:
++
++=over
++
++=item positive if this package is newer
++
++=item null if both have same revision
++
++=item negative if this package is older
++
++=back
++
++=head2 satisfy_range($range)
++
++Returns a true value if this package revision satisfies given revision range.
++
++=head2 sign($name, $path, $passphrase)
++
++Signs the package with given name, keyring path and passphrase.
++
++=head2 extract()
++
++Extract package content in local directory.
++
++=head1 SUBCLASSING
++
++All instances methods have to be implemented.
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++sub get_file {
++ my ($self) = @_;
++ carp &quot;Deprecated method, use as_file now&quot;;
++
++ return $self-&gt;as_file();
++}
++
++sub get_full_name {
++ my ($self) = @_;
++ carp &quot;Deprecated method, use as_string now&quot;;
++
++ return $self-&gt;as_string();
++}
++
++sub compare_versions {
++ my ($self, $version1, $version2) = @_;
++ carp &quot;Deprecated method, use compare_revisions now&quot;;
++
++ return $self-&gt;compare_revisions($version1, $version2);
++}
++
++sub compare_ranges {
++ my ($self, $range1, $range2) = @_;
++ carp &quot;Deprecated method, use are_range_compatible now&quot;;
++
++ return $self-&gt;check_ranges_compatibility($range1, $range2);
++}
++
++sub get_revision_name {
++ my ($self) = @_;
++ carp &quot;Deprecated method, use as_formated_string('%name-%version-%release') now&quot;;
++
++ return $self-&gt;as_formated_string('%{name}-%{version}-%{release}');
++}
++
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositoryMandriva_uploadpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,546 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Upload/Action/RSS.pm 857 2006-01-29T10:15:43.298856Z guillaume $
++package Youri::Repository::Mandriva_upload;
++
++=head1 NAME
++
++Youri::Repository::PLF - PLF repository implementation
++
++=head1 DESCRIPTION
++
++This module implements PLF repository.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use File::Find 'find';
++use base qw/Youri::Repository/;
++use MDV::Distribconf::Build;
++use SVN::Client;
++
++use constant {
++ PACKAGE_CLASS =&gt; 'Youri::Package::URPM',
++ PACKAGE_CHARSET =&gt; 'utf8'
++};
++
++memoize('_get_media_config');
++
++my %translate_arch = (
++ i386 =&gt; 'i586',
++ sparc64 =&gt; 'sparcv9',
++);
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ noarch =&gt; 'i586', # noarch packages policy
++ src =&gt; 'i586',
++ install_root =&gt; '',
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ queue =&gt; '',
++ rejected =&gt; '',
++ @_
++ );
++ foreach my $var ('upload_state') {
++ $self-&gt;{&quot;_$var&quot;} = [];
++ foreach my $value (split ' ', $options{$var}) {
++ push @{$self-&gt;{&quot;_$var&quot;}}, $value
++ }
++ }
++ print &quot;Initializing repository\n&quot;;
++ foreach my $v ('rejected', 'svn', 'queue', 'noarch', 'install_root', 'upload_root', 'verbose') {
++ $self-&gt;{&quot;_$v&quot;} = $options{$v}
++ }
++ foreach my $target (@{$options{targets}}) {
++ $self-&gt;{$target} = [];
++ print &quot;Adding $target ($options{$target}{arch})\n&quot; if $self-&gt;{_verbose};
++ foreach my $value (split ' ', $options{$target}{arch}) {
++ push @{$self-&gt;{_arch}{$target}}, $value;
++ push @{$self-&gt;{_extra_arches}}, $value
++ }
++ }
++ $self
++}
++
++sub get_group_id {
++ my ($user) = @_;
++ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
++ $year+=1900;
++ $mon++;
++ my $hostname = `hostname`;
++ my ($host) = $hostname =~ /([^.]*)/;
++ sprintf &quot;$year%02d%02d%02d%02d%02d.$user.$host.${$}_&quot;, $mon, $mday, $hour, $min, $sec;
++}
++
++sub get_target_arch {
++ my ($self, $target) = $_;
++ return $self-&gt;{_arch}{$target}
++}
++
++sub set_arch_changed {
++ my ($self, $target, $arch) = @_;
++ if ($arch eq 'noarch') {
++ $self-&gt;{_arch_changed}{$_} = 1 foreach @{$self-&gt;{_arch}{$target}}
++ } elsif ($arch eq 'src') {
++ $self-&gt;{_arch_changed} = $self-&gt;{_src}
++ } else {
++ $self-&gt;{_arch_changed}{$arch} = 1
++ }
++}
++
++sub get_arch_changed {
++ my ($self, $target) = @_;
++ return [ keys %{$self-&gt;{_arch_changed}} ]
++}
++
++sub set_install_dir_changed {
++ my ($self, $install_dir) = @_;
++ $self-&gt;{_install_dir_changed}{$install_dir} = 1;
++}
++
++sub get_install_dir_changed {
++ my ($self) = @_;
++ return [ keys %{$self-&gt;{_install_dir_changed}} ];
++}
++
++sub _get_media_config {
++ my ($self, $target) = @_;
++ my %media;
++ my $real_target = $target;
++ $real_target =~ s/_force//;
++ foreach my $arch (@{$self-&gt;{_arch}{$target}}) {
++ my $root = &quot;$self-&gt;{_install_root}/$real_target/$arch&quot;;
++ my $distrib = MDV::Distribconf::Build-&gt;new($root);
++ print &quot;Getting media config from $root\n&quot; if $self-&gt;{_verbose};
++ $self-&gt;{distrib}{$arch} = $distrib;
++ $distrib-&gt;loadtree or die &quot;$root does not seem to be a distribution tree\n&quot;;
++ $distrib-&gt;parse_mediacfg;
++ foreach my $media ($distrib-&gt;listmedia) {
++ my $rpms = $distrib-&gt;getvalue($media, 'rpms');
++ my $debug_for = $distrib-&gt;getvalue($media, 'debug_for');
++ my $srpms = $distrib-&gt;getvalue($media, 'srpms');
++ my $path = $distrib-&gt;getfullpath($media, 'path');
++ if (!$rpms) {
++ if (-d $path) {
++ print &quot;MEDIA defining $media in $path\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ $media{$arch}{$media} = $path
++ } else {
++ print &quot;ERROR $path does not exist for media $media on $arch\n&quot;
++ }
++ } else {
++ my ($media) = split ' ', $rpms;
++ if (-d $path) {
++ print &quot;MEDIA defining SOURCE media for $media in $path\n&quot; if $self-&gt;{_verbose} &gt; 1;
++ $media{src}{$media} = $path
++ } else {
++ print &quot;ERROR $path does not exist for source media $media on $arch\n&quot;
++ }
++ }
++ }
++ }
++ \%media
++}
++
++sub get_package_class {
++ return PACKAGE_CLASS;
++}
++
++sub get_package_charset {
++ return PACKAGE_CHARSET;
++}
++
++sub get_upload_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ return
++ $self-&gt;{_upload_root} .
++ &quot;/$self-&gt;{_queue}/$target/&quot; .
++ _get_section($self, $package, $target, $user_context, $app_context) .
++ '/' .
++ ($user_context-&gt;{prefix} ? '' : get_group_id($user_context-&gt;{user}))
++}
++
++sub get_install_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ return $self-&gt;_get_path($package, $target, $user_context, $app_context);
++}
++
++
++sub get_distribution_paths {
++ my ($self, $package, $target) = @_;
++
++ return $self-&gt;_get_distribution_paths($package, $target);
++}
++
++sub get_archive_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ return $self-&gt;_get_path($package, $target, $user_context, $app_context);
++}
++
++sub get_reject_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ return $self-&gt;{_rejected};
++}
++
++
++sub _get_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++ my $arch = $app_context-&gt;{arch} || $package-&gt;get_arch();
++ $arch = $translate_arch{$arch} || $arch;
++ if ($arch eq 'noarch') {
++ $arch = $self-&gt;{_noarch}
++ } elsif ($arch eq 'src') {
++ return &quot;$target/SRPMS/$section&quot;
++ }
++ &quot;$target/$arch/media/$section&quot;
++}
++
++sub _get_distribution_paths {
++ my ($self, $package, $target) = @_;
++
++ my $arch = $package-&gt;get_arch();
++ $arch = $translate_arch{$arch} || $arch;
++ if ($arch eq 'noarch') {
++ map { &quot;$target/$_&quot; } $self-&gt;get_extra_arches;
++ } elsif ($arch eq 'src') {
++ die &quot;no way to get distribution path using a $arch package&quot;;
++ } else {
++ &quot;$target/$arch&quot;;
++ }
++}
++
++sub get_arch {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ my $arch = $package-&gt;get_arch();
++ $arch = $translate_arch{$arch} || $arch;
++ if ($arch eq 'noarch') {
++ $arch = $self-&gt;{_noarch}
++ }
++ $arch
++}
++
++sub get_version_path {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++
++ return &quot;$self-&gt;{_module}/$section&quot;;
++}
++
++=head2 get_replaced_packages($package, $target, $user_context, $app_context)
++
++Overrides parent method to add libified packages.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @replaced_packages =
++ $self-&gt;SUPER::get_replaced_packages($package, $target, $user_context, $app_context);
++
++ # mandriva lib policy:
++ # library package names change with revision, making mandatory to
++ # duplicate older revisions search with a custom pattern
++ my $name = $package-&gt;get_name();
++ if ($name =~ /^(lib\w+[a-zA-Z_])[\d_\.]+([-\w]*)$/) {
++ push(@replaced_packages,
++ grep { $package-&gt;compare($_) &gt; 0 }
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $user_context, $app_context),
++ PACKAGE_CLASS-&gt;get_pattern(
++ $1 . '[\d_\.]+' . $2, # custom name pattern
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ # kernel packages have the version in the name
++ # binary dkms built for old kernels have to be removed too
++ if ($name =~ /^kernel-([^\d]*-)?([\d.]*)-(.*)$/) { # &quot;desktop&quot;, &quot;2.6.28&quot;, &quot;2mnb&quot;
++ push(@replaced_packages,
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $user_context, $app_context),
++ PACKAGE_CLASS-&gt;get_pattern(
++ '(kernel-' . $1 . '\d.*|.*-kernel-[\d.]*-' . $1 . '\d.*)',
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ return @replaced_packages;
++
++}
++
++sub _get_main_section {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++ my ($main_section) = $section =~ m,^([^/]+),;
++ $main_section
++}
++
++sub _get_section {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++
++ my $name = $package-&gt;get_name();
++ my $cname = $package-&gt;get_canonical_name();
++ my $version = $package-&gt;get_version();
++ my $release = $package-&gt;get_release();
++ my $section = $user_context-&gt;{section};
++ my $media = $self-&gt;_get_media_config($target);
++ my $arch = $package-&gt;get_arch();
++ my $file = $package-&gt;as_file();
++ $file =~ s,/+,/,g; # unneeded?
++ # FIXME: use $self-&gt;get_arch()
++ $arch = $self-&gt;{_noarch} if $arch eq 'noarch';
++ $arch = $translate_arch{$arch} || $arch;
++
++ if (!$section) {
++ $section = $self-&gt;{packages}{$file}{section};
++ print &quot;Section undefined, repository says it is '$section' for '$file'\n&quot; if $self-&gt;{_verbose};
++ }
++ if ($section &amp;&amp; $section !~ /debug_/ &amp;&amp; $package-&gt;is_debug()) {
++ $section = &quot;debug_$section&quot;
++ }
++
++ # if have section already, check if it exists, and may return immediately
++ if ($section) {
++ print &quot;Using requested section $section\n&quot;;
++ if ($media-&gt;{$arch}{$section}) {
++ return $section
++ } else {
++ die &quot;FATAL youri: unknown section $section for target $target for arch $arch\n&quot;
++ }
++ }
++ # else, try to find section automatically
++
++ # pattern for search of src package with specific version-release,
++ # should be searched first, because we prefer to find the precise
++ # section a package is already in
++ my $specific_source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $cname,
++ $version,
++ $release,
++ 'src'
++ );
++
++ my $source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $cname,
++ undef,
++ undef,
++ 'src'
++ );
++
++ # if a media has no source media configured, or if it is a debug
++ # package, we search in binary media
++
++ # pattern for search when a binary media has no src media configured
++ my $specific_binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $name,
++ $version,
++ $release,
++ $arch
++ );
++
++ # last resort pattern: previous existing binary packages
++ my $binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $name,
++ undef,
++ undef,
++ $arch
++ );
++
++ # first try to find section for the specific version, as it is possibly already there;
++ # this is the case for when called in Youri::Submit::Action::Archive, to find the
++ # section the package got installed
++ print &quot;Looking for package $name with version $version-$release\n&quot;;
++ foreach my $m (keys %{$media-&gt;{$arch}}) {
++ print &quot; .. section '$m' path '&quot;.$media-&gt;{$arch}{$m}.&quot;'\n&quot; if $self-&gt;{_verbose};
++ # - prefer source for non-debug packages, use binary if there is no source media configured
++ # - debug packages must be searched in binary medias, due to their
++ # src section != binary section; NOTE: should/need we search in
++ # src medias and add the 'debug_' prefix?
++ if (!$package-&gt;is_debug() &amp;&amp; $media-&gt;{src}{$m}) {
++ next unless $self-&gt;get_files('', $media-&gt;{src}{$m}, $specific_source_pattern);
++ } else {
++ next unless $self-&gt;get_files('', $media-&gt;{$arch}{$m}, $specific_binary_pattern);
++ }
++ $section = $m;
++ last;
++ }
++
++ # if still not found, try finding any version of the package in a
++ # /release subsection (safe default: /release is default for cooker,
++ # should be locked for released distros, and we don't risk wrongly
++ # choosing /backports, /testing, or /updates);
++ # this is the case for when called at submit, to find the section where
++ # the package already resides
++ if (!$section) {
++ # debug packages should be found by previous specific version search
++ # NOTE: as above, should/need we search here and add the 'debug_' prefix?
++ # ... probably... as at least mdv-youri-submit-force will process debug packages
++ if ($package-&gt;is_debug() &amp;&amp; $self-&gt;{_verbose}) {
++ print &quot;Warning: debug package $name with version $version-$release not found.\n&quot;;
++ }
++
++ print &quot;Warning: Looking for any section with a package $name of any version\n&quot;;
++ foreach my $m (keys %{$media-&gt;{$arch}}) {
++ print &quot; .. section '$m' path '&quot;.$media-&gt;{$arch}{$m}.&quot;'\n&quot; if $self-&gt;{_verbose};
++ # NOTE: !$package-&gt;is_debug() test is here to prevent when above FATAL error is removed
++ next if $m !~ /release/ || ($m =~ /debug/ &amp;&amp; !$package-&gt;is_debug());
++ # - prefer source
++ if ($media-&gt;{src}{$m}) {
++ next unless $self-&gt;get_files('', $media-&gt;{src}{$m}, $source_pattern);
++ } else {
++ next unless $self-&gt;get_files('', $media-&gt;{$arch}{$m}, $binary_pattern);
++ }
++ $section = $m;
++ last;
++ }
++ }
++
++ # FIXME: doing this here is wrong; this way the caller can never know if
++ # a section was actually found or not; should return undef and let the
++ # caller set a default (Note: IIRC PLF|Zarb has this right, see there) -spuk
++ print STDERR &quot;Warning: Can't guess destination: section missing, defaulting to contrib/release\n&quot; unless $section;
++ $section ||= 'contrib/release';
++
++ # next time we don't need to search everything again
++ $self-&gt;{packages}{$file}{section} = $section;
++
++ print &quot;Section is '$section'.\n&quot;;
++
++ return $section;
++}
++
++sub get_upload_newer_revisions {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ my $name = $package-&gt;get_full_name;
++ $name =~ s/^\@\d+://;
++ my $pattern = $self-&gt;get_package_class()-&gt;get_pattern($package-&gt;get_name(), undef, undef, $arch);
++ my $media = $self-&gt;_get_media_config($target);
++ my @packages;
++ foreach my $state (@{$self-&gt;{_upload_state}}) {
++ foreach my $m (keys %{$media-&gt;{$arch}}) {
++ my $path = &quot;$self-&gt;{_upload_root}/$state/$target/$m&quot;;
++ print &quot;Looking for package $package revisions for $target in $path (pattern $pattern)\n&quot; if $self-&gt;{_verbose};
++ find(
++ sub {
++ s/\d{14}\.[^.]*\.[^.]*\.\d+_//;
++ s/^\@\d+://;
++ return if ! /^$pattern/;
++ return if /\.info$/;
++ print &quot;Find $_\n&quot;;
++ push @packages, $File::Find::name if $package-&gt;check_ranges_compatibility(&quot;== $name&quot;, &quot;&lt; $_&quot;)
++ }, $path);
++ }
++ }
++ return
++ @packages;
++}
++
++sub package_in_svn {
++ my ($self, $srpm_name) = @_;
++ my $ctx = new SVN::Client(
++ auth =&gt; [SVN::Client::get_simple_provider(),
++ SVN::Client::get_simple_prompt_provider(\&amp;simple_prompt,2),
++ SVN::Client::get_username_provider()]
++ );
++
++ my $svn_entry = $ctx-&gt;ls(&quot;$self-&gt;{_svn}/$srpm_name&quot;, 'HEAD', 0);
++ if ($svn_entry) {
++ print &quot;Package $srpm_name is in the SVN\n&quot;;
++ return 1
++ }
++}
++
++sub get_svn_url {
++ my ($self) = @_;
++ $self-&gt;{_svn}
++}
++
++sub get_revisions {
++ my ($self, $package, $target, $user_context, $app_context, $filter) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package revisions for $target\n&quot; if $self-&gt;{_verbose} &gt; 0;
++
++ my $arch = $app_context-&gt;{arch} || $user_context-&gt;{arch} || $package-&gt;get_arch();
++ my $media_arch = $arch eq 'noarch' ? $self-&gt;{_noarch} : $arch;
++ my $path = $arch eq 'src' ? &quot;$target/SRPMS/&quot; : &quot;$target/$media_arch/media&quot;;
++ my $media = $self-&gt;_get_section($package, $target, $user_context, $app_context);
++ my $name = $package-&gt;get_name();
++ my @packages = map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$path/$media&quot;,
++ $self-&gt;get_package_class()-&gt;get_pattern(
++ $name,
++ undef,
++ undef,
++ $package-&gt;get_arch(),
++ )
++ );
++
++ @packages = grep { $filter-&gt;($_) } @packages if $filter;
++
++ return
++ sort { $b-&gt;compare($a) } # sort by revision order
++ @packages;
++}
++
++sub reject {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++
++}
++
++sub get_archive_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;{_archive_root}
++}
++
++
++# 20060801 warly
++#
++# Upload steps
++# SRPMS are uploaded in /home/mandrake/uploads/todo/$target/$media/group_id
++#
++#
++#
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositoryMandriva_upload_prepm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository/Mandriva_upload_pre.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,274 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Upload/Action/RSS.pm 857 2006-01-29T10:15:43.298856Z guillaume $
++package Youri::Repository::Mandriva_upload_pre;
++
++=head1 NAME
++
++Youri::Repository::PLF - PLF repository implementation
++
++=head1 DESCRIPTION
++
++This module implements PLF repository.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use File::Find 'find';
++use base qw/Youri::Repository/;
++use SVN::Client;
++use constant {
++ PACKAGE_CLASS =&gt; 'Youri::Package::URPM',
++ PACKAGE_CHARSET =&gt; 'utf8'
++};
++
++memoize('_get_section');
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ module =&gt; 'SPECS', # CVS module
++ noarch =&gt; 'i586', # noarch packages policy
++ svn =&gt; '',
++ upload_root =&gt; '',
++ @_
++ );
++
++ $self-&gt;{_module} = $options{module};
++ $self-&gt;{_noarch} = $options{noarch};
++ $self-&gt;{_svn} = $options{svn};
++ $self-&gt;{_upload_root} = $options{upload_root};
++
++ my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
++ $year+=1900;
++ my $hostname = `hostname`;
++ my ($host) = $hostname =~ /([^.]*)/;
++ $self-&gt;{group_dir} = sprintf &quot;$ENV{SUDO_USER}.$host.$$.$year%02d%02d%02d%02d%02d&quot;, $mon, $mday, $hour, $min, $sec;
++}
++
++sub get_package_class {
++ return PACKAGE_CLASS;
++}
++
++sub package_in_svn {
++ my ($self, $srpm_name) = @_;
++ my $ctx = new SVN::Client(
++ auth =&gt; [SVN::Client::get_simple_provider(),
++ SVN::Client::get_simple_prompt_provider(\&amp;simple_prompt,2),
++ SVN::Client::get_username_provider()]
++ );
++
++ my $svn_entry = $ctx-&gt;ls(&quot;$self-&gt;{_svn}/&quot;, 'HEAD', 0);
++ foreach (keys %{$svn_entry}) {
++ if ($srpm_name eq $_) {
++ print &quot;Package $_ is in the SVN\n&quot;;
++ return 1
++ }
++ }
++}
++
++sub get_svn_url {
++ my ($self) = @_;
++ $self-&gt;{_svn}
++}
++
++sub get_revisions {
++ my ($self, $package, $target, $define, $filter) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my $arch = $define-&gt;{arch} || $package-&gt;get_arch;
++ if ($arch eq 'src') {
++ $arch = 'SRPMS'
++ } else {
++ $arch .= '/media'
++ }
++ my @packages;
++ foreach my $dir ('main', 'contrib') {
++ print &quot;Looking into $self-&gt;{_install_root}/$target/$arch/$dir/release\n&quot;;
++ push @packages,
++ map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$target/$arch/$dir/release&quot; ,
++ $self-&gt;get_package_class()-&gt;get_pattern($package-&gt;get_name(),undef, undef, $arch)
++ );
++ }
++
++ @packages = grep { $filter-&gt;($_) } @packages if $filter;
++
++ return
++ sort { $b-&gt;compare($a) } # sort by revision order
++ @packages;
++}
++
++sub get_package_charset {
++ return PACKAGE_CHARSET;
++}
++
++sub get_upload_dir {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ my $section = $self-&gt;_get_section($package, $target, $define);
++ my $media_path = $section eq 'main' ? $target : $target =~ /^cooker/ ? &quot;contrib&quot; : &quot;$target/contrib&quot;;
++ my $arch_path = $arch eq 'src' ? 'SRPMS' : 'RPMS';
++ my $force = $target =~ /_force/ ? 'force' : '';
++ $self-&gt;{_upload_root} . &quot;/$media_path/$force/$arch_path/&quot;
++}
++
++sub get_arch {
++ my ($self, $package, $target, $define) = @_;
++ my $arch = $package-&gt;get_arch();
++ if ($arch eq 'noarch') {
++ $arch = $self-&gt;{_noarch}
++ }
++ $arch
++}
++
++sub get_install_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub get_archive_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub _get_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $arch = $package-&gt;get_arch;
++ if ($arch eq 'src') {
++ $arch = 'SRPMS'
++ } else {
++ $arch .= '/media'
++ }
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ return &quot;$target/$arch/$section/release/&quot;;
++}
++
++
++sub get_version_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ return &quot;$self-&gt;{_module}/$section/release/&quot;;
++}
++
++=head2 get_replaced_packages($package, $target, $define)
++
++Overrides parent method to add libified packages.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @replaced_packages =
++ $self-&gt;SUPER::get_replaced_packages($package, $target, $define);
++
++ # mandriva lib policy:
++ # library package names change with revision, making mandatory to
++ # duplicate older revisions search with a custom pattern
++ my $name = $package-&gt;get_name();
++ if ($name =~ /^(lib\w+[a-zA-Z_])[\d_\.]+([-\w]*)$/) {
++ push(@replaced_packages,
++ grep { $package-&gt;compare($_) &gt; 0 }
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $define),
++ PACKAGE_CLASS-&gt;get_pattern(
++ $1 . '[\d_\.]+' . $2, # custom name pattern
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ return @replaced_packages;
++
++}
++
++sub _get_section {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section;
++
++ # try to find section automatically
++ my $arch = $package-&gt;get_arch();
++ $arch = $self-&gt;{_noarch} if $arch eq 'noarch';
++
++ my $source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_canonical_name(),
++ undef,
++ undef,
++ 'src'
++ );
++
++ my $binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_name(),
++ undef,
++ undef,
++ $arch
++ );
++
++ # for each potential section, try to match
++ # a suitable source patten in source directory
++ # a suitable binary patten in binary directory
++ foreach my $dir (qw/main contrib/) {
++ next unless
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$target/SRPMS/$dir/release&quot;,
++ $source_pattern
++ ) || $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$target/$arch/media/$dir/release&quot;,
++ $binary_pattern
++ );
++ print &quot;Section is $dir\n&quot;;
++ $section = $dir;
++ last;
++ }
++
++ # use defined section if not found
++ $section = $define-&gt;{section} unless $section;
++
++ $section || 'contrib'
++}
++
++sub get_upload_newer_revisions {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ my $arch = $package-&gt;get_arch();
++ my $pattern = $self-&gt;get_package_class()-&gt;get_pattern($package-&gt;get_name(), undef, undef, $arch);
++ print &quot;Looking for package $package revisions for $target in $self-&gt;{_upload_root} (pattern $pattern)\n&quot;;
++ my @packages;
++ foreach my $dir ('cooker', 'contrib') {
++ find(sub { return if ! /^$pattern/; print &quot;Find $_\n&quot;; push @packages, $File::Find::name if $package-&gt;compare($self-&gt;get_package_class()-&gt;new(file =&gt; $File::Find::name)) &lt;= 0 }, &quot;$self-&gt;{_upload_root}/$dir&quot;);
++ }
++ return
++ @packages;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositoryPLFpm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository/PLF.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,196 @@
++# $Id: /local/youri/soft/trunk/lib/Youri/Upload/Action/RSS.pm 857 2006-01-29T10:15:43.298856Z guillaume $
++package Youri::Repository::PLF;
++
++=head1 NAME
++
++Youri::Repository::PLF - PLF repository implementation
++
++=head1 DESCRIPTION
++
++This module implements PLF repository.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use Memoize;
++use base qw/Youri::Repository/;
++use constant {
++ PACKAGE_CLASS =&gt; 'Youri::Package::URPM',
++ PACKAGE_CHARSET =&gt; 'utf8'
++};
++
++memoize('_get_section');
++
++
++sub _init {
++ my $self = shift;
++ my %options = (
++ module =&gt; 'SPECS', # CVS module
++ noarch =&gt; 'noarch', # noarch packages policy
++ @_
++ );
++
++ $self-&gt;{_module} = $options{module};
++ $self-&gt;{_noarch} = $options{noarch};
++}
++
++sub get_package_class {
++ return PACKAGE_CLASS;
++}
++
++sub get_package_charset {
++ return PACKAGE_CHARSET;
++}
++
++sub get_install_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub get_archive_path {
++ my ($self, $package, $target, $define) = @_;
++
++ return $self-&gt;_get_path($package, $target, $define);
++}
++
++sub _get_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ my $subpath = $self-&gt;_get_subpath($package, $target);
++
++ return &quot;$section/$subpath&quot;;
++}
++
++
++sub get_version_path {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section = $self-&gt;_get_section($package, $target, $define);
++
++ return &quot;$self-&gt;{_module}/$section&quot;;
++}
++
++=head2 get_replaced_packages($package, $target, $define)
++
++Overrides parent method to add libified packages.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $define) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ my @replaced_packages =
++ $self-&gt;SUPER::get_replaced_packages($package, $target, $define);
++
++ # mandriva lib policy:
++ # library package names change with revision, making mandatory to
++ # duplicate older revisions search with a custom pattern
++ my $name = $package-&gt;get_name();
++ if ($name =~ /^(lib\w+[a-zA-Z_])[\d_\.]+([-\w]*)$/) {
++ push(@replaced_packages,
++ grep { $package-&gt;compare($_) &gt; 0 }
++ map { PACKAGE_CLASS-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $define),
++ PACKAGE_CLASS-&gt;get_pattern(
++ $1 . '[\d_\.]+' . $2, # custom name pattern
++ undef,
++ undef,
++ $package-&gt;get_arch()
++ ),
++ )
++ );
++ }
++
++ return @replaced_packages;
++
++}
++
++sub _get_section {
++ my ($self, $package, $target, $define) = @_;
++
++ my $section;
++
++ # try to find section automatically
++ my $arch = $package-&gt;get_arch();
++
++ my $source_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_canonical_name(),
++ undef,
++ undef,
++ 'src'
++ );
++
++ my $binary_pattern = PACKAGE_CLASS-&gt;get_pattern(
++ $package-&gt;get_name(),
++ undef,
++ undef,
++ $arch
++ );
++
++ my $source_subpath = $self-&gt;_get_subpath($package, $target, 'src');
++ my $binary_subpath = $self-&gt;_get_subpath($package, $target, $arch);
++
++ # for each potential section, try to match
++ # a suitable source patten in source directory
++ # a suitable binary patten in binary directory
++ foreach my $dir (qw/free non-free/) {
++ next unless
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$dir/$source_subpath&quot;,
++ $source_pattern
++ ) || $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ &quot;$dir/$binary_subpath&quot;,
++ $binary_pattern
++ );
++ $section = $dir;
++ last;
++ }
++
++ # use defined section if not found
++ $section = $define-&gt;{section} unless $section;
++
++ die &quot;Can't guess destination: section missing&quot; unless $section;
++
++ return $section;
++}
++
++sub _get_subpath {
++ my ($self, $package, $target, $arch) = @_;
++
++ my $subpath;
++
++ # use package arch if not specified
++ $arch = $package-&gt;get_arch() unless $arch;
++
++ if ($arch eq 'src') {
++ $subpath = 'src';
++ } else {
++ if ($arch eq 'noarch') {
++ $subpath = &quot;$target/$self-&gt;{_noarch}&quot;;
++ } else {
++ $subpath = &quot;$target/$arch&quot;;
++ }
++ }
++
++ return $subpath;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriRepositorypm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Repository.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,492 @@
++# $Id: Base.pm 631 2006-01-26 22:22:23Z guillomovitch $
++package Youri::Repository;
++
++=head1 NAME
++
++Youri::Repository - Abstract repository
++
++=head1 DESCRIPTION
++
++This abstract class defines Youri::Repository interface.
++
++=cut
++
++use warnings;
++use strict;
++use Carp;
++use File::Basename;
++use Youri::Package;
++
++=head1 CLASS METHODS
++
++
++=head2 new(%args)
++
++Creates and returns a new Youri::Repository object.
++
++No generic parameters (subclasses may define additional ones).
++
++Warning: do not call directly, call subclass constructor instead.
++
++=cut
++
++sub new {
++ my $class = shift;
++ croak &quot;Abstract class&quot; if $class eq __PACKAGE__;
++
++ my %options = (
++ install_root =&gt; '', # path to top-level directory
++ archive_root =&gt; '', # path to top-level directory
++ version_root =&gt; '', # path to top-level directory
++ test =&gt; 0, # test mode
++ verbose =&gt; 0, # verbose mode
++ @_
++ );
++
++
++ croak &quot;no install root&quot; unless $options{install_root};
++ croak &quot;invalid install root&quot; unless -d $options{install_root};
++
++ my $self = bless {
++ _install_root =&gt; $options{install_root},
++ _archive_root =&gt; $options{archive_root},
++ _version_root =&gt; $options{version_root},
++ _test =&gt; $options{test},
++ _verbose =&gt; $options{verbose},
++ }, $class;
++
++ $self-&gt;_init(%options);
++
++ return $self;
++}
++
++sub _init {
++ # do nothing
++}
++
++=head1 INSTANCE METHODS
++
++=head2 get_package_class()
++
++Return package class for this repository.
++
++=cut
++
++sub get_package_class {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return $self-&gt;{_package_class};
++}
++
++=head2 get_package_charset()
++
++Return package charset for this repository.
++
++=cut
++
++sub get_package_charset {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return $self-&gt;{_package_charset};
++}
++
++=head2 get_extra_arches()
++
++Return the list of additional archictectures to handle when dealing with noarch
++packages.
++
++=cut
++
++sub get_extra_arches {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ return @{$self-&gt;{_extra_arches}};
++}
++
++
++=head2 get_older_revisions($package, $target, $user_context, $app_context)
++
++Get all older revisions from a package found in its installation directory, as a
++list of L&lt;Youri::Package&gt; objects.
++
++=cut
++
++sub get_older_revisions {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package older revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ return $self-&gt;get_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context,
++ sub { return $package-&gt;compare($_[0]) &gt; 0 }
++ );
++}
++
++=head2 get_last_older_revision($package, $target, $user_context, $app_context)
++
++Get last older revision from a package found in its installation directory, as a
++single L&lt;Youri::Package&gt; object.
++
++=cut
++
++sub get_last_older_revision {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package last older revision for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ return (
++ $self-&gt;get_older_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ )
++ )[0];
++}
++
++=head2 get_newer_revisions($package, $target, $user_context, $app_context)
++
++Get all newer revisions from a package found in its installation directory, as
++a list of L&lt;Youri::Package&gt; objects.
++
++=cut
++
++sub get_newer_revisions {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package newer revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ return $self-&gt;get_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context,
++ sub { return $_[0]-&gt;compare($package) &gt; 0 }
++ );
++}
++
++
++=head2 get_revisions($package, $target, $user_context, $app_context, $filter)
++
++Get all revisions from a package found in its installation directory, using an
++optional filter, as a list of L&lt;Youri::Package&gt; objects.
++
++=cut
++
++sub get_revisions {
++ my ($self, $package, $target, $user_context, $app_context, $filter) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for package $package revisions for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my @packages =
++ map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ ),
++ $self-&gt;get_package_class()-&gt;get_pattern(
++ $package-&gt;get_name(),
++ undef,
++ undef,
++ $package-&gt;get_arch(),
++ )
++ );
++ @packages = grep { $filter-&gt;($_) } @packages if $filter;
++
++ return
++ sort { $b-&gt;compare($a) } # sort by revision order
++ @packages;
++}
++
++=head2 get_obsoleted_packages($package, $target, $user_context, $app_context)
++
++Get all packages obsoleted by given one, as a list of L&lt;Youri::Package&gt;
++objects.
++
++=cut
++
++sub get_obsoleted_packages {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for packages obsoleted by $package for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my @packages;
++ foreach my $obsolete ($package-&gt;get_obsoletes()) {
++ my $pattern = $self-&gt;get_package_class()-&gt;get_pattern($obsolete-&gt;[Youri::Package::DEPENDENCY_NAME]);
++ my $range = $obsolete-&gt;[Youri::Package::DEPENDENCY_RANGE];
++ push(@packages,
++ grep { $range ? $_-&gt;satisfy_range($range) : 1 }
++ map { $self-&gt;get_package_class()-&gt;new(file =&gt; $_) }
++ $self-&gt;get_files(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path(
++ $package, $target,
++ $user_context,
++ $app_context
++ ),
++ $pattern
++ )
++ );
++ }
++
++ return @packages;
++}
++
++=head2 get_replaced_packages($package, $target, $user_context, $app_context)
++
++Get all packages replaced by given one, as a list of L&lt;Youri::Package&gt;
++objects.
++
++=cut
++
++sub get_replaced_packages {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ print &quot;Looking for packages replaced by $package for $target\n&quot;
++ if $self-&gt;{_verbose} &gt; 0;
++
++ my @list;
++
++ # collect all older revisions
++ push(@list, $self-&gt;get_older_revisions(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ ));
++
++ # noarch packages are potentially linked from other directories
++ if ($package-&gt;get_arch() eq 'noarch') {
++ foreach my $arch ($self-&gt;get_extra_arches()) {
++ push(@list, $self-&gt;get_older_revisions(
++ $package,
++ $target,
++ $user_context,
++ { arch =&gt; $arch }
++ ));
++ }
++ }
++
++ # collect all obsoleted packages
++ push(@list, $self-&gt;get_obsoleted_packages(
++ $package,
++ $target,
++ $user_context,
++ $app_context
++ ));
++
++ return @list;
++}
++
++=head2 get_files($path, $pattern)
++
++Get all files found in a directory, using an optional filtering pattern
++(applied to the whole file name), as a list of files.
++
++=cut
++
++sub get_files {
++ my ($self, $root, $path, $pattern) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++ # debugging for bug 34999
++ print &quot;Looking for files matching $pattern in $root/$path\n&quot;;
++# if $self-&gt;{_verbose} &gt; 1;
++
++ my $grep = &quot;&quot;;
++ $grep = &quot;-regextype posix-egrep -regex '.*\/$pattern'&quot; if ($pattern);
++ # XXX: run find in a directory the user is guaranteed to have read
++ # permissions! find simply exits with error if the user doesn't have
++ # read permission on the *current* dir; as this code is run thru many
++ # sudo invocations, sometimes the user calling it has $HOME chmoded to
++ # 0700, making find fail when run as mandrake
++ # debugging for bug 34999
++ print &quot;.. running command: find -L $root/$path $grep -type f\n&quot;;
++ my @files = map { chop; $_; } `cd &amp;&amp; find -L $root/$path $grep -type f`;
++ die &quot;FATAL: get_files(): find failed!&quot; if ($?);
++
++ return @files;
++}
++
++=head2 get_install_root()
++
++Returns installation root
++
++=cut
++
++sub get_install_root {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_install_root};
++}
++
++
++=head2 get_distribution_roots()
++
++Returns distribution roots (ie install_root + target + arch)
++(it returns a list in case of noarch)
++
++=cut
++
++sub get_distribution_roots {
++ my ($self, $package, $target) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ map {
++ $self-&gt;_get_dir($self-&gt;{_install_root}, $_);
++ } $self-&gt;get_distribution_paths($package, $target);
++}
++
++=head2 get_install_dir($package, $target, $user_context, $app_context)
++
++Returns install destination directory for given L&lt;Youri::Package&gt; object
++and given target.
++
++=cut
++
++sub get_install_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;_get_dir(
++ $self-&gt;{_install_root},
++ $self-&gt;get_install_path($package, $target, $user_context, $app_context)
++ );
++}
++
++=head2 get_archive_root()
++
++Returns archiving root
++
++=cut
++
++sub get_archive_root {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_archive_root};
++}
++
++=head2 get_archive_dir($package, $target, $user_context, $app_context)
++
++Returns archiving destination directory for given L&lt;Youri::Package&gt; object
++and given target.
++
++=cut
++
++sub get_archive_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;_get_dir(
++ $self-&gt;{_archive_root},
++ $self-&gt;get_archive_path($package, $target, $user_context, $app_context)
++ );
++}
++
++
++=head2 get_version_root()
++
++Returns versionning root
++
++=cut
++
++sub get_version_root {
++ my ($self) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;{_version_root};
++}
++
++=head2 get_version_dir($package, $target, $user_context, $app_context)
++
++Returns versioning destination directory for given L&lt;Youri::Package&gt;
++object and given target.
++
++=cut
++
++sub get_version_dir {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return $self-&gt;_get_dir(
++ $self-&gt;{_version_root},
++ $self-&gt;get_version_path($package, $target, $user_context, $app_context)
++ );
++}
++
++sub _get_dir {
++ my ($self, $root, $path) = @_;
++
++ return substr($path, 0, 1) eq '/' ?
++ $path :
++ $root . '/' . $path;
++}
++
++=head2 get_install_file($package, $target, $user_context, $app_context)
++
++Returns install destination file for given L&lt;Youri::Package&gt; object and
++given target.
++
++=cut
++
++sub get_install_file {
++ my ($self, $package, $target, $user_context, $app_context) = @_;
++ croak &quot;Not a class method&quot; unless ref $self;
++
++ return
++ $self-&gt;get_install_dir($package, $target, $user_context, $app_context) .
++ '/' .
++ $package-&gt;get_file_name();
++}
++
++=head2 get_install_path($package, $target, $user_context, $app_context)
++
++Returns installation destination path (relative to repository root) for given
++L&lt;Youri::Package&gt; object and given target.
++
++=head2 get_archive_path($package, $target, $user_context, $app_context)
++
++Returns archiving destination path (relative to repository root) for given
++L&lt;Youri::Package&gt; object and given target.
++
++=head2 get_version_path($package, $target, $user_context, $app_context)
++
++Returns versioning destination path (relative to repository root) for given
++L&lt;Youri::Package&gt; object and given target.
++
++=head1 SUBCLASSING
++
++The following methods have to be implemented:
++
++=over
++
++=item get_install_path
++
++=item get_archive_path
++
++=item get_version_path
++
++=back
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunklibYouriUtilspm">Added: build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm (rev 0)
++++ build_system/mdv-youri-core/trunk/lib/Youri/Utils.pm 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,98 @@
++# $Id: Utils.pm 1713 2006-10-16 16:39:53Z warly $
++package Youri::Utils;
++
++=head1 NAME
++
++Youri::Utils - Youri shared functions
++
++=head1 DESCRIPTION
++
++This module implement some helper functions for all youri applications.
++
++=cut
++
++use base qw(Exporter);
++use Carp;
++use strict;
++use warnings;
++
++our @EXPORT = qw(
++ create_instance
++ load_class
++ add2hash
++ add2hash_
++);
++
++=head2 create_instance($class, $config, $options)
++
++Create an instance from a plugin implementing given interface, using given
++configuration and local options.
++Returns a plugin instance, or undef if something went wrong.
++
++=cut
++
++sub create_instance {
++ my ($interface, $config, $options) = @_;
++
++ croak 'No interface given' unless $interface;
++ croak 'No config given' unless $config;
++
++ my $class = $config-&gt;{class};
++ if (!$class) {
++ carp &quot;No class given, can't load plugin&quot;;
++ return;
++ }
++
++ # ensure loaded
++ load_class($class);
++
++ # check interface
++ if (!$class-&gt;isa($interface)) {
++ carp &quot;$class is not a $interface&quot;;
++ return;
++ }
++
++ # instantiate
++ no strict 'refs';
++
++ return $class-&gt;new(
++ $config-&gt;{options} ? %{$config-&gt;{options}} : (),
++ $options ? %{$options} : (),
++ );
++}
++
++sub load_class {
++ my ($class) = @_;
++
++ $class .= '.pm';
++ $class =~ s/::/\//g;
++ require $class;
++}
++
++# structure helpers
++
++sub add2hash {
++ my ($a, $b) = @_;
++ while (my ($k, $v) = each %{$b || {}}) {
++ $a-&gt;{$k} ||= $v;
++ }
++ return $a;
++}
++
++sub add2hash_ {
++ my ($a, $b) = @_;
++ while (my ($k, $v) = each %{$b || {}}) {
++ exists $a-&gt;{$k} or $a-&gt;{$k} = $v;
++ }
++ return $a;
++}
++
++=head1 COPYRIGHT AND LICENSE
++
++Copyright (C) 2002-2006, YOURI project
++
++This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
++
++=cut
++
++1;
+
+<a id="build_systemmdvyouricoretrunkt00distributiont">Added: build_system/mdv-youri-core/trunk/t/00distribution.t</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/t/00distribution.t (rev 0)
++++ build_system/mdv-youri-core/trunk/t/00distribution.t 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,15 @@
++#!/usr/bin/perl
++# $Id: 00distribution.t 1179 2006-08-05 08:30:57Z warly $
++
++use Test::More;
++
++BEGIN {
++ eval {
++ require Test::Distribution;
++ };
++ if($@) {
++ plan skip_all =&gt; 'Test::Distribution not installed';
++ } else {
++ import Test::Distribution only =&gt; [ qw/use pod description/ ];
++ }
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/00distribution.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyouricoretrunktcowsay30311mdv20070noarchrpm">Added: build_system/mdv-youri-core/trunk/t/cowsay-3.03-11mdv2007.0.noarch.rpm</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/cowsay-3.03-11mdv2007.0.noarch.rpm
+___________________________________________________________________
+<a id="svnmimetype">Added: svn:mime-type</a>
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktgpghomepubringgpg">Added: build_system/mdv-youri-core/trunk/t/gpghome/pubring.gpg</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/gpghome/pubring.gpg
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktgpghomesecringgpg">Added: build_system/mdv-youri-core/trunk/t/gpghome/secring.gpg</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/gpghome/secring.gpg
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktgpghometrustdbgpg">Added: build_system/mdv-youri-core/trunk/t/gpghome/trustdb.gpg</a>
+===================================================================
+(Binary files differ)
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/gpghome/trustdb.gpg
+___________________________________________________________________
+Added: svn:mime-type
+ + application/octet-stream
+
+<a id="build_systemmdvyouricoretrunktpackaget">Added: build_system/mdv-youri-core/trunk/t/package.t</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/t/package.t (rev 0)
++++ build_system/mdv-youri-core/trunk/t/package.t 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,482 @@
++#!/usr/bin/perl
++# $Id: /local/youri/soft/trunk/t/version.t 2257 2006-07-05T09:22:47.088572Z guillaume $
++
++use Test::More;
++use Test::Exception;
++use Youri::Utils;
++use File::Temp qw/tempdir/;
++use File::Basename;
++use strict;
++
++my @classes = qw/
++ Youri::Package::URPM
++ Youri::Package::RPM4
++/;
++my $dir = dirname($0);
++my $rpm = 'cowsay-3.03-11mdv2007.0.noarch.rpm';
++my $fake_rpm = 'foobar.rpm';
++plan(tests =&gt; 37 * scalar @classes);
++
++foreach my $class (@classes) {
++ load_class($class);
++
++ my $temp_dir = tempdir(CLEANUP =&gt; 1);
++ my $file = &quot;$dir/$rpm&quot;;
++ my $fake_file = &quot;$temp_dir/$fake_rpm&quot;;
++
++ # instanciation errors
++ dies_ok { $class-&gt;new(file =&gt; undef) } 'undefined file';
++ dies_ok { $class-&gt;new(file =&gt; $fake_file) } 'non-existant file';
++ system('touch', $fake_file);
++ chmod 0000, $fake_file;
++ dies_ok { $class-&gt;new(file =&gt; $fake_file) } 'non-readable file';
++ chmod 0644, $fake_file;
++ dies_ok { $class-&gt;new(file =&gt; $fake_file) } 'non-rpm file';
++
++ my $package = $class-&gt;new(file =&gt; $file);
++ isa_ok($package, $class);
++
++ # tag value access
++ is($package-&gt;get_name(), 'cowsay', 'get name directly');
++ is($package-&gt;get_tag('name'), 'cowsay', 'get name indirectly');
++ is($package-&gt;get_version(), '3.03', 'get version directly');
++ is($package-&gt;get_tag('version'), '3.03', 'get version indirectly');
++ is($package-&gt;get_release(), '11mdv2007.0', 'get release directly');
++ is($package-&gt;get_tag('release'), '11mdv2007.0', 'get release indirectly');
++ is($package-&gt;get_arch(), 'noarch', 'get arch directly');
++ is($package-&gt;get_tag('arch'), 'noarch', 'get arch indirectly');
++ is($package-&gt;get_summary(), 'Configurable talking cow', 'get summary directly');
++ is($package-&gt;get_tag('summary'), 'Configurable talking cow', 'get summary indirectly');
++ is($package-&gt;get_url(), 'http://www.nog.net/~tony/warez/cowsay.shtml', 'get url directly');
++ is($package-&gt;get_tag('url'), 'http://www.nog.net/~tony/warez/cowsay.shtml', 'get url indirectly');
++ is($package-&gt;get_packager(), 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt;', 'get packager directly');
++ is($package-&gt;get_tag('packager'), 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt;', 'get packager indirectly');
++ is($package-&gt;get_file_name(), 'cowsay-3.03-11mdv2007.0.noarch.rpm', 'file name');
++ is($package-&gt;get_revision(), '3.03-11mdv2007.0', 'revision');
++
++ # name formating
++ is($package-&gt;as_formated_string('%{name}-%{version}-%{release}'), 'cowsay-3.03-11mdv2007.0', 'formated string name');
++ is($package-&gt;as_string(), 'cowsay-3.03-11mdv2007.0.noarch', 'default string');
++ is($package, 'cowsay-3.03-11mdv2007.0.noarch', 'stringification');
++
++ # type
++ ok(!$package-&gt;is_source(), 'not a source package');
++ ok($package-&gt;is_binary(), 'a binary package');
++ is($package-&gt;get_type(), 'binary', 'a binary package');
++
++ # gpg key
++ is($package-&gt;get_gpg_key(), '26752624', 'get gpg key');
++
++ # dependencies
++ is_deeply(
++ [ $package-&gt;get_requires() ],
++ [
++ [ 'perl-base', undef ],
++ [ 'perl(Cwd)', undef ],
++ [ 'perl(File::Basename)', undef ],
++ [ 'perl(Getopt::Std)', undef ],
++ [ 'perl(Text::Tabs)', undef ],
++ [ 'perl(Text::Wrap)', undef ]
++ ],
++ 'requires'
++ );
++ is_deeply(
++ [ $package-&gt;get_provides() ],
++ [
++ [ 'cowsay', '== 3.03-11mdv2007.0']
++ ],
++ 'provides'
++ );
++ is_deeply(
++ [ $package-&gt;get_obsoletes() ],
++ [ ],
++ 'obsoletes'
++ );
++ is_deeply(
++ [ $package-&gt;get_conflicts() ],
++ [ ],
++ 'conflicts'
++ );
++
++ # files
++ is_deeply(
++ [ $package-&gt;get_files() ],
++ [
++ [
++ '/etc/bash_completion.d/cowsay',
++ 33188,
++ '6048be1dd827011c15cab0c3db1f438d'
++ ],
++ [
++ '/usr/bin/cowsay',
++ 33261,
++ 'b405026c6040eeb4781ca5c523129fe4'
++ ],
++ [
++ '/usr/bin/cowthink',
++ 41471,
++ ''
++ ],
++ [
++ '/usr/share/cows',
++ 16877,
++ ''
++ ],
++ [
++ '/usr/share/cows/beavis.zen.cow',
++ 33188,
++ '582b2ddb72122d3aa078730abd0456b3'
++ ],
++ [
++ '/usr/share/cows/bong.cow',
++ 33188,
++ '045f9bf39c027dded9a7145f619bac02'
++ ],
++ [
++ '/usr/share/cows/bud-frogs.cow',
++ 33188,
++ '5c61632eb06305d613061882e1955cd2'
++ ],
++ [
++ '/usr/share/cows/bunny.cow',
++ 33188,
++ '05eb914d3b96aea903542cb29f5c42c7'
++ ],
++ [
++ '/usr/share/cows/cheese.cow',
++ 33188,
++ 'f3618110a22d8e9ecde888c1f5e38b61'
++ ],
++ [
++ '/usr/share/cows/cower.cow',
++ 33188,
++ 'd73ea60eec692555a34a9f3eec981578'
++ ],
++ [
++ '/usr/share/cows/daemon.cow',
++ 33188,
++ 'a7dd7588ee0386a0f29e88e4881885ee'
++ ],
++ [
++ '/usr/share/cows/default.cow',
++ 33188,
++ 'f1206515a0f27e9d5cf09c188e46bc82'
++ ],
++ [
++ '/usr/share/cows/dragon-and-cow.cow',
++ 33188,
++ '0ca99b8edd1a9d14fd231a88d9746b39'
++ ],
++ [
++ '/usr/share/cows/dragon.cow',
++ 33188,
++ '448f736bf56dccafa2635e71e7485345'
++ ],
++ [
++ '/usr/share/cows/duck.cow',
++ 33188,
++ 'd8ffcd64667d2e3697a3e8b65e8bea9d'
++ ],
++ [
++ '/usr/share/cows/elephant-in-snake.cow',
++ 33188,
++ 'c5a9f406277e0e8a674bd3ffb503738f'
++ ],
++ [
++ '/usr/share/cows/elephant.cow',
++ 33188,
++ 'e355c72e893787376c047805d4a1fe9d'
++ ],
++ [
++ '/usr/share/cows/eyes.cow',
++ 33188,
++ 'b2eb5b612fae17877895aa6edafa0a5f'
++ ],
++ [
++ '/usr/share/cows/flaming-sheep.cow',
++ 33188,
++ '3213cfa04a069f42d71115ca623a2f95'
++ ],
++ [
++ '/usr/share/cows/ghostbusters.cow',
++ 33188,
++ 'df294e6278bcb275aecb0fbd6b2546ba'
++ ],
++ [
++ '/usr/share/cows/girafe.cow',
++ 33188,
++ '6d2e142313109b6a5a0a45dba0f11351'
++ ],
++ [
++ '/usr/share/cows/head-in.cow',
++ 33188,
++ '365287a5d1f34a53f8716285e79c28df'
++ ],
++ [
++ '/usr/share/cows/hellokitty.cow',
++ 33188,
++ 'e0bbea69c4cbcfb3d799740ccc8a0b0e'
++ ],
++ [
++ '/usr/share/cows/kenny.cow',
++ 33188,
++ '16ce8c334a7547197ac4c9e8a1d6ae90'
++ ],
++ [
++ '/usr/share/cows/kiss.cow',
++ 33188,
++ '2a7bdd4a20741b7769af463bf09e64e8'
++ ],
++ [
++ '/usr/share/cows/kitty.cow',
++ 33188,
++ '76d65a3ebfbacb16a654c1aa1af6ed27'
++ ],
++ [
++ '/usr/share/cows/koala.cow',
++ 33188,
++ 'cc524706707f32253dd06fc548334f11'
++ ],
++ [
++ '/usr/share/cows/kosh.cow',
++ 33188,
++ 'e4e28e0f472bd524fd1b44c67ae357c2'
++ ],
++ [
++ '/usr/share/cows/luke-koala.cow',
++ 33188,
++ '63bbc35da73cd22b8cf25f86dcf9f870'
++ ],
++ [
++ '/usr/share/cows/mech-and-cow',
++ 33188,
++ '12c0320b33704d8564dd97278d056204'
++ ],
++ [
++ '/usr/share/cows/meow.cow',
++ 33188,
++ 'a6092008647ed37cfe1663d10e388cbb'
++ ],
++ [
++ '/usr/share/cows/milk.cow',
++ 33188,
++ 'd26ac36e13e77dabb408e104fc8e0167'
++ ],
++ [
++ '/usr/share/cows/moofasa.cow',
++ 33188,
++ '5fcdd4a9f3bf521c337af0a066b14512'
++ ],
++ [
++ '/usr/share/cows/moose.cow',
++ 33188,
++ 'dcfa09df7d2b9afa112dab374bf06e99'
++ ],
++ [
++ '/usr/share/cows/mutilated.cow',
++ 33188,
++ '24cdaef0a29fb44dc673abf19a8ba631'
++ ],
++ [
++ '/usr/share/cows/phaco.cow',
++ 33188,
++ 'f277c1bf92ce2a3f6058955ba93758aa'
++ ],
++ [
++ '/usr/share/cows/pumpkin.cow',
++ 33188,
++ 'c661ea78714c1ce31559f77d73694473'
++ ],
++ [
++ '/usr/share/cows/ren.cow',
++ 33188,
++ '3d7941d454779e000adc1c91e5f0b20b'
++ ],
++ [
++ '/usr/share/cows/satanic.cow',
++ 33188,
++ 'a69ca42a31486757ddcb322a1e68f886'
++ ],
++ [
++ '/usr/share/cows/shark.cow',
++ 33188,
++ 'd8950ec63abb00bbd9d96ec63637c1ac'
++ ],
++ [
++ '/usr/share/cows/sheep.cow',
++ 33188,
++ '543b75f295cbd51326f5a40f111469f1'
++ ],
++ [
++ '/usr/share/cows/skeleton.cow',
++ 33188,
++ '64f6ec1a0c170508e72269d533492e57'
++ ],
++ [
++ '/usr/share/cows/small.cow',
++ 33188,
++ '50cb1c55628c439fc81f96db9d855252'
++ ],
++ [
++ '/usr/share/cows/sodomized.cow',
++ 33188,
++ 'b4888afcca51629cc3138b283608b837'
++ ],
++ [
++ '/usr/share/cows/stegosaurus.cow',
++ 33188,
++ 'fb0e45d101a3ecba9cf6e112facbbc7e'
++ ],
++ [
++ '/usr/share/cows/stimpy.cow',
++ 33188,
++ '9b4ec6e0750ba0eeaaa432d8d3413559'
++ ],
++ [
++ '/usr/share/cows/supermilker.cow',
++ 33188,
++ '316573fb585e4a6b375373c85be025b1'
++ ],
++ [
++ '/usr/share/cows/surgery.cow',
++ 33188,
++ '7f25005083c1fde19d4e548c005ef000'
++ ],
++ [
++ '/usr/share/cows/telebears.cow',
++ 33188,
++ '15f00abb070d9018ce6ef3441e936ef4'
++ ],
++ [
++ '/usr/share/cows/three-eyes.cow',
++ 33188,
++ 'c85faef9496f4a5b111bd92bfd7e7528'
++ ],
++ [
++ '/usr/share/cows/turkey.cow',
++ 33188,
++ '484b5bc69c09d420d7fd5586d8570f04'
++ ],
++ [
++ '/usr/share/cows/turtle.cow',
++ 33188,
++ '87eed5a00e88860b78dbec04efcdede3'
++ ],
++ [
++ '/usr/share/cows/tux.cow',
++ 33188,
++ 'dc1db4eac66c99179ef6adb15dd75bda'
++ ],
++ [
++ '/usr/share/cows/udder.cow',
++ 33188,
++ 'd97f78887c3b218a54876edc51f2963b'
++ ],
++ [
++ '/usr/share/cows/vader-koala.cow',
++ 33188,
++ '7b5dd51278f0fa217a70a9b499f97a07'
++ ],
++ [
++ '/usr/share/cows/vader.cow',
++ 33188,
++ '97b4ef9fc4c26082f253e9f0f35c4590'
++ ],
++ [
++ '/usr/share/cows/www.cow',
++ 33188,
++ 'ef4c0bc8330f329666e1705f97f283cc'
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03',
++ 16877,
++ ''
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03/INSTALL',
++ 33188,
++ '3333fd2865107626d5dffc0dbfb7e244'
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03/LICENSE',
++ 33188,
++ 'f879dda90a5a9928253a63ecd76406e6'
++ ],
++ [
++ '/usr/share/doc/cowsay-3.03/README',
++ 33188,
++ 'a5c1c61e4920c278a735cdaaca62453e'
++ ],
++ [
++ '/usr/share/man/man1/cowsay.1.bz2',
++ 33188,
++ '01fdd49d0b477f20099aae384fe8c1b2'
++ ],
++ [
++ '/usr/share/man/man1/cowthink.1.bz2',
++ 41471,
++ ''
++ ]
++ ],
++ 'files'
++ );
++
++ # changelog
++ is_deeply(
++ [ $package-&gt;get_changes() ],
++ [
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt; 3.03-11mdv2007.0',
++ 1149847200,
++ '- %mkrel' . &quot;\n&quot; .
++ '- rpmbuildupdate aware',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt; 3.03-10mdk ',
++ 1117879200,
++ '- fix man page (fix #16291)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandrake.org&gt; 3.03-9mdk ',
++ 1090058400,
++ '- hurry businesman compliant (aka two new wonderful cows)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandrake.org&gt; 3.03-8mdk ',
++ 1089540000,
++ '- apologies to the girafes (with one only f)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandrake.org&gt; 3.03-7mdk ',
++ 1086429600,
++ '- #mandrakefr compliant (aka four new additional cows)',
++ ],
++ [
++ 'Guillaume Rousse &lt;guillomovitch@linux-mandrake.com&gt; 3.03-6mdk',
++ 1061460000,
++ '- save.the.world patch',
++ ]
++ ],
++ 'changelog'
++ );
++ is_deeply(
++ $package-&gt;get_last_change(),
++ [
++ 'Guillaume Rousse &lt;guillomovitch@mandriva.org&gt; 3.03-11mdv2007.0',
++ 1149847200,
++ '- %mkrel' . &quot;\n&quot; .
++ '- rpmbuildupdate aware',
++ ],
++ 'last change'
++ );
++ is($package-&gt;compare($package), 0, 'compare');
++
++ # signature test
++ system('cp', $file, $temp_dir);
++ $package = $class-&gt;new(file =&gt; &quot;$temp_dir/$rpm&quot;);
++
++ $package-&gt;sign('Youri', 't/gpghome', 'Youri rulez');
++
++ $package = $class-&gt;new(file =&gt; &quot;$temp_dir/$rpm&quot;);
++ is($package-&gt;get_gpg_key(), '2333e817', 'get gpg key');
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/package.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+<a id="build_systemmdvyouricoretrunktversiont">Added: build_system/mdv-youri-core/trunk/t/version.t</a>
+===================================================================
+--- build_system/mdv-youri-core/trunk/t/version.t (rev 0)
++++ build_system/mdv-youri-core/trunk/t/version.t 2011-01-05 13:23:45 UTC (rev 210)
+@@ -0,0 +1,71 @@
++#!/usr/bin/perl
++# $Id: version.t 1179 2006-08-05 08:30:57Z warly $
++
++use Test::More;
++use Youri::Check::Input::Updates;
++use strict;
++
++my @differents = (
++ [ '3.0.0', '1.0.0' ],
++ [ '3.0.0', '1.99.9' ],
++ [ '3.0.1', '3.0' ],
++ [ '3.0pl1', '3.0' ],
++ [ '3.0', '3.0beta1' ],
++ [ '3.0', '3.0beta' ],
++ [ '3.0', '3.0alpha1' ],
++ [ '3.0', '3.0alpha' ],
++ [ '3.0', '3.0pre1' ],
++ [ '3.0', '3.0pre' ],
++ [ '3.0pre', '3.0beta' ],
++ [ '3.0beta', '3.0alpha' ],
++ [ '1.0.0-p1', '1.0.0RC1' ],
++ [ '0.9.7f', '0.9.7e' ],
++ [ '10', '9' ],
++);
++
++my @equals = (
++ [ '1.0.0', '1.0.0' ],
++ [ '0.9Beta1', '0.9beta1' ],
++ [ '0.9beta1', '0.9 beta 1' ],
++ [ '0.3-alpha', '0.3_alpha' ],
++ [ '0.02', '.02' ],
++ [ '2.0.11', '15aug2000' ],
++ [ '2.0.11', '20060401' ],
++ [ '20', '20060401' ],
++);
++
++plan tests =&gt; 2 * @differents + 2 * @equals;
++
++foreach my $different (@differents) {
++ ok(
++ Youri::Check::Input::Updates::is_newer(
++ $different-&gt;[0],
++ $different-&gt;[1]
++ ),
++ &quot;$different-&gt;[0] is newer as $different-&gt;[1]&quot;
++ );
++ ok(
++ !Youri::Check::Input::Updates::is_newer(
++ $different-&gt;[1],
++ $different-&gt;[0]
++ ),
++ &quot;$different-&gt;[1] is older as $different-&gt;[0]&quot;
++ );
++}
++
++foreach my $equal (@equals) {
++ ok(
++ !Youri::Check::Input::Updates::is_newer(
++ $equal-&gt;[0],
++ $equal-&gt;[1]
++ ),
++ &quot;$equal-&gt;[0] is equal as $equal-&gt;[1]&quot;
++ );
++ ok(
++ !Youri::Check::Input::Updates::is_newer(
++ $equal-&gt;[1],
++ $equal-&gt;[0]
++ ),
++ &quot;$equal-&gt;[1] is equal as $equal-&gt;[0]&quot;
++ );
++}
+
+
+Property changes on: build_system/mdv-youri-core/trunk/t/version.t
+___________________________________________________________________
+Added: svn:executable
+ + *
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment-0001.html
new file mode 100644
index 000000000..c23d34397
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment-0001.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[656] - add a module to handle various websites, mainly for storing</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>656</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:09:50 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- add a module to handle various websites, mainly for storing
+them.
+- add the redirection of donate, asked by rda on sysadm ml</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>puppet/modules/websites/</li>
+<li>puppet/modules/websites/manifests/</li>
+<li><a href="#puppetmoduleswebsitesmanifestsinitpp">puppet/modules/websites/manifests/init.pp</a></li>
+<li>puppet/modules/websites/templates/</li>
+<li><a href="#puppetmoduleswebsitestemplatesvhost_donateconf">puppet/modules/websites/templates/vhost_donate.conf</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmoduleswebsitesmanifestsinitpp">Added: puppet/modules/websites/manifests/init.pp</a>
+===================================================================
+--- puppet/modules/websites/manifests/init.pp (rev 0)
++++ puppet/modules/websites/manifests/init.pp 2011-01-05 19:09:50 UTC (rev 656)
+@@ -0,0 +1,8 @@
++class websites {
++ # should expire on June 2011
++ class donate {
++ apache::vhost_other_app { &quot;donate.$domain&quot;:
++ vhost_file =&gt; &quot;websites/vhost_donate.conf&quot;,
++ }
++ }
++}
+
+<a id="puppetmoduleswebsitestemplatesvhost_donateconf">Added: puppet/modules/websites/templates/vhost_donate.conf</a>
+===================================================================
+--- puppet/modules/websites/templates/vhost_donate.conf (rev 0)
++++ puppet/modules/websites/templates/vhost_donate.conf 2011-01-05 19:09:50 UTC (rev 656)
+@@ -0,0 +1,14 @@
++&lt;VirtualHost *:80&gt;
++ ServerName donate.&lt;%= domain %&gt;
++
++ RewriteEngine on
++ RewriteRule ^/(.*)$ http://www.&lt;%= domain %&gt;/$1/donate/ [R=permanent,L]
++ #DocumentRoot /dev/null
++ CustomLog /var/log/httpd/donate_log combined
++ ErrorLog /var/log/httpd/error_donate_log
++
++ &lt;Location /&gt;
++ Allow from all
++ &lt;/Location&gt;
++
++&lt;/VirtualHost&gt;
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment.html
new file mode 100644
index 000000000..c23d34397
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/80473389/attachment.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[656] - add a module to handle various websites, mainly for storing</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>656</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:09:50 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- add a module to handle various websites, mainly for storing
+them.
+- add the redirection of donate, asked by rda on sysadm ml</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>puppet/modules/websites/</li>
+<li>puppet/modules/websites/manifests/</li>
+<li><a href="#puppetmoduleswebsitesmanifestsinitpp">puppet/modules/websites/manifests/init.pp</a></li>
+<li>puppet/modules/websites/templates/</li>
+<li><a href="#puppetmoduleswebsitestemplatesvhost_donateconf">puppet/modules/websites/templates/vhost_donate.conf</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmoduleswebsitesmanifestsinitpp">Added: puppet/modules/websites/manifests/init.pp</a>
+===================================================================
+--- puppet/modules/websites/manifests/init.pp (rev 0)
++++ puppet/modules/websites/manifests/init.pp 2011-01-05 19:09:50 UTC (rev 656)
+@@ -0,0 +1,8 @@
++class websites {
++ # should expire on June 2011
++ class donate {
++ apache::vhost_other_app { &quot;donate.$domain&quot;:
++ vhost_file =&gt; &quot;websites/vhost_donate.conf&quot;,
++ }
++ }
++}
+
+<a id="puppetmoduleswebsitestemplatesvhost_donateconf">Added: puppet/modules/websites/templates/vhost_donate.conf</a>
+===================================================================
+--- puppet/modules/websites/templates/vhost_donate.conf (rev 0)
++++ puppet/modules/websites/templates/vhost_donate.conf 2011-01-05 19:09:50 UTC (rev 656)
+@@ -0,0 +1,14 @@
++&lt;VirtualHost *:80&gt;
++ ServerName donate.&lt;%= domain %&gt;
++
++ RewriteEngine on
++ RewriteRule ^/(.*)$ http://www.&lt;%= domain %&gt;/$1/donate/ [R=permanent,L]
++ #DocumentRoot /dev/null
++ CustomLog /var/log/httpd/donate_log combined
++ ErrorLog /var/log/httpd/error_donate_log
++
++ &lt;Location /&gt;
++ Allow from all
++ &lt;/Location&gt;
++
++&lt;/VirtualHost&gt;
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment-0001.html
new file mode 100644
index 000000000..c81799314
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment-0001.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[657] - update dns to give the new address for donation</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>657</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:09:52 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- update dns to give the new address for donation</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulesbindtemplateszonesmageiaorgzone">puppet/modules/bind/templates/zones/mageia.org.zone</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulesbindtemplateszonesmageiaorgzone">Modified: puppet/modules/bind/templates/zones/mageia.org.zone</a>
+===================================================================
+--- puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:50 UTC (rev 656)
++++ puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:52 UTC (rev 657)
+@@ -3,7 +3,7 @@
+ ; $Id$
+ $TTL 3D
+ @ IN SOA ns0.mageia.org. root.mageia.org. (
+- 2010121501 ; Serial
++ 2010121502 ; Serial
+ 21600 ; Refresh
+ 3600 ; Retry
+ 2419200 ; Expire
+@@ -68,8 +68,8 @@
+ svn IN CNAME valstar
+ meetbot IN CNAME krampouezh
+
+-donate IN CNAME www-aufml
+-donation IN CNAME www-aufml
++donate IN CNAME alamut
++donation IN CNAME alamut
+
+ puppetmaster IN CNAME valstar
+ pkgsubmit IN CNAME valstar
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment.html
new file mode 100644
index 000000000..c81799314
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/a25cf069/attachment.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[657] - update dns to give the new address for donation</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>657</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:09:52 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- update dns to give the new address for donation</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulesbindtemplateszonesmageiaorgzone">puppet/modules/bind/templates/zones/mageia.org.zone</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulesbindtemplateszonesmageiaorgzone">Modified: puppet/modules/bind/templates/zones/mageia.org.zone</a>
+===================================================================
+--- puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:50 UTC (rev 656)
++++ puppet/modules/bind/templates/zones/mageia.org.zone 2011-01-05 19:09:52 UTC (rev 657)
+@@ -3,7 +3,7 @@
+ ; $Id$
+ $TTL 3D
+ @ IN SOA ns0.mageia.org. root.mageia.org. (
+- 2010121501 ; Serial
++ 2010121502 ; Serial
+ 21600 ; Refresh
+ 3600 ; Retry
+ 2419200 ; Expire
+@@ -68,8 +68,8 @@
+ svn IN CNAME valstar
+ meetbot IN CNAME krampouezh
+
+-donate IN CNAME www-aufml
+-donation IN CNAME www-aufml
++donate IN CNAME alamut
++donation IN CNAME alamut
+
+ puppetmaster IN CNAME valstar
+ pkgsubmit IN CNAME valstar
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment-0001.html
new file mode 100644
index 000000000..a94bd5211
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment-0001.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[211] - merge trunk@210</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>211</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 16:09:20 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- merge trunk@210</pre>
+
+<h3>Property Changed</h3>
+<ul>
+<li><a href="#identityCatDapbrancheslive">identity/CatDap/branches/live/</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+
+<a id="identityCatDapbrancheslive">Property changes on: identity/CatDap/branches/live</a>
+___________________________________________________________________
+<a id="svnmergeinfo">Modified: svn:mergeinfo</a>
+ - /identity/CatDap/trunk:64,66-68
+ + /identity/CatDap/trunk:64,66-68,210
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment.html
new file mode 100644
index 000000000..a94bd5211
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/b4bcb9b0/attachment.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[211] - merge trunk@210</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>211</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 16:09:20 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- merge trunk@210</pre>
+
+<h3>Property Changed</h3>
+<ul>
+<li><a href="#identityCatDapbrancheslive">identity/CatDap/branches/live/</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+
+<a id="identityCatDapbrancheslive">Property changes on: identity/CatDap/branches/live</a>
+___________________________________________________________________
+<a id="svnmergeinfo">Modified: svn:mergeinfo</a>
+ - /identity/CatDap/trunk:64,66-68
+ + /identity/CatDap/trunk:64,66-68,210
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment-0001.html
new file mode 100644
index 000000000..fd49a6933
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment-0001.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[659] add missing rpm</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>659</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:40:18 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add missing rpm</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulescatdapmanifestsinitpp">puppet/modules/catdap/manifests/init.pp</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulescatdapmanifestsinitpp">Modified: puppet/modules/catdap/manifests/init.pp</a>
+===================================================================
+--- puppet/modules/catdap/manifests/init.pp 2011-01-05 19:09:53 UTC (rev 658)
++++ puppet/modules/catdap/manifests/init.pp 2011-01-05 19:40:18 UTC (rev 659)
+@@ -9,7 +9,7 @@
+ &quot;perl-Catalyst-P-S-State-Cookie&quot;, &quot;perl-Catalyst-P-S-Store-File&quot;, &quot;perl-Catalyst-View-Email&quot;,
+ &quot;perl-Catalyst-View-TT&quot;, &quot;perl-Config-General&quot;, &quot;perl-Crypt-CBC&quot;, &quot;perl-Data-UUID&quot;,
+ &quot;perl-Email-Valid&quot;, &quot;perl-Moose&quot;, &quot;perl-namespace-autoclean&quot;, &quot;perl-Test-Simple&quot;,
+-&quot;perl-Crypt-Blowfish&quot;, &quot;perl-Email-Date-Format&quot;, &quot;perl-YAML-LibYAML&quot;,
++&quot;perl-Crypt-Blowfish&quot;, &quot;perl-Email-Date-Format&quot;, &quot;perl-YAML-LibYAML&quot;,&quot;perl-Catalyst-Plugin-Unicode-Encoding&quot;,
+ ]
+
+ package { $rpm_requirement:
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment.html
new file mode 100644
index 000000000..fd49a6933
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/c743e0e4/attachment.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[659] add missing rpm</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>659</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 20:40:18 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>add missing rpm</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulescatdapmanifestsinitpp">puppet/modules/catdap/manifests/init.pp</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulescatdapmanifestsinitpp">Modified: puppet/modules/catdap/manifests/init.pp</a>
+===================================================================
+--- puppet/modules/catdap/manifests/init.pp 2011-01-05 19:09:53 UTC (rev 658)
++++ puppet/modules/catdap/manifests/init.pp 2011-01-05 19:40:18 UTC (rev 659)
+@@ -9,7 +9,7 @@
+ &quot;perl-Catalyst-P-S-State-Cookie&quot;, &quot;perl-Catalyst-P-S-Store-File&quot;, &quot;perl-Catalyst-View-Email&quot;,
+ &quot;perl-Catalyst-View-TT&quot;, &quot;perl-Config-General&quot;, &quot;perl-Crypt-CBC&quot;, &quot;perl-Data-UUID&quot;,
+ &quot;perl-Email-Valid&quot;, &quot;perl-Moose&quot;, &quot;perl-namespace-autoclean&quot;, &quot;perl-Test-Simple&quot;,
+-&quot;perl-Crypt-Blowfish&quot;, &quot;perl-Email-Date-Format&quot;, &quot;perl-YAML-LibYAML&quot;,
++&quot;perl-Crypt-Blowfish&quot;, &quot;perl-Email-Date-Format&quot;, &quot;perl-YAML-LibYAML&quot;,&quot;perl-Catalyst-Plugin-Unicode-Encoding&quot;,
+ ]
+
+ package { $rpm_requirement:
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment-0001.html
new file mode 100644
index 000000000..6152ede1c
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment-0001.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[208] version 1.9.2</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>208</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 00:44:41 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>version 1.9.2</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>build_system/repsys/tags/1.9.2/</li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment.html
new file mode 100644
index 000000000..6152ede1c
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/effa0b80/attachment.html
@@ -0,0 +1,63 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[208] version 1.9.2</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>208</dd>
+<dt>Author</dt> <dd>boklm</dd>
+<dt>Date</dt> <dd>2011-01-05 00:44:41 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>version 1.9.2</pre>
+
+<h3>Added Paths</h3>
+<ul>
+<li>build_system/repsys/tags/1.9.2/</li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment-0001.html b/zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment-0001.html
new file mode 100644
index 000000000..432eefa6e
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment-0001.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[653] - do not try to do ssl when we cannot, this confuse epoll</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>653</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 01:59:39 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- do not try to do ssl when we cannot, this confuse epoll</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulespostfixtemplatesmaincf">puppet/modules/postfix/templates/main.cf</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulespostfixtemplatesmaincf">Modified: puppet/modules/postfix/templates/main.cf</a>
+===================================================================
+--- puppet/modules/postfix/templates/main.cf 2011-01-03 18:00:40 UTC (rev 652)
++++ puppet/modules/postfix/templates/main.cf 2011-01-05 00:59:39 UTC (rev 653)
+@@ -62,10 +62,12 @@
+ unknown_local_recipient_reject_code = 450
+ smtp-filter_destination_concurrency_limit = 2
+ lmtp-filter_destination_concurrency_limit = 2
+-smtpd_use_tls = yes
+-smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
+-smtpd_tls_key_file = /etc/pki/tls/private/postfix.pem
+-smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
++# disabled for the time being, as the certificate do not exist
++# FIXME create the cert in puppet
++smtpd_use_tls = no
++#smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
++#smtpd_tls_key_file = /etc/pki/tls/private/postfix.pem
++#smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
+
+ &lt;%- if all_tags.include?('postfix::smtp_server') -%&gt;
+ smtpd_etrn_restrictions = reject
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment.html b/zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment.html
new file mode 100644
index 000000000..432eefa6e
--- /dev/null
+++ b/zarb-ml/mageia-sysadm/attachments/20110105/feb9fe4b/attachment.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
+"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
+<title>[653] - do not try to do ssl when we cannot, this confuse epoll</title>
+</head>
+<body>
+
+<style type="text/css"><!--
+#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
+#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
+#msg dt:after { content:':';}
+#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
+#msg dl a { font-weight: bold}
+#msg dl a:link { color:#fc3; }
+#msg dl a:active { color:#ff0; }
+#msg dl a:visited { color:#cc6; }
+h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
+#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
+#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
+#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
+#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
+#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
+#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
+#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
+#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
+#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
+#logmsg pre { background: #eee; padding: 1em; }
+#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
+#logmsg dl { margin: 0; }
+#logmsg dt { font-weight: bold; }
+#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
+#logmsg dd:before { content:'\00bb';}
+#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
+#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
+#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
+#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
+#logmsg table th.Corner { text-align: left; }
+#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
+#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
+#patch { width: 100%; }
+--></style>
+<div id="msg">
+<dl class="meta">
+<dt>Revision</dt> <dd>653</dd>
+<dt>Author</dt> <dd>misc</dd>
+<dt>Date</dt> <dd>2011-01-05 01:59:39 +0100 (Wed, 05 Jan 2011)</dd>
+</dl>
+
+<h3>Log Message</h3>
+<pre>- do not try to do ssl when we cannot, this confuse epoll</pre>
+
+<h3>Modified Paths</h3>
+<ul>
+<li><a href="#puppetmodulespostfixtemplatesmaincf">puppet/modules/postfix/templates/main.cf</a></li>
+</ul>
+
+</div>
+<div id="patch"><pre>
+<a id="puppetmodulespostfixtemplatesmaincf">Modified: puppet/modules/postfix/templates/main.cf</a>
+===================================================================
+--- puppet/modules/postfix/templates/main.cf 2011-01-03 18:00:40 UTC (rev 652)
++++ puppet/modules/postfix/templates/main.cf 2011-01-05 00:59:39 UTC (rev 653)
+@@ -62,10 +62,12 @@
+ unknown_local_recipient_reject_code = 450
+ smtp-filter_destination_concurrency_limit = 2
+ lmtp-filter_destination_concurrency_limit = 2
+-smtpd_use_tls = yes
+-smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
+-smtpd_tls_key_file = /etc/pki/tls/private/postfix.pem
+-smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
++# disabled for the time being, as the certificate do not exist
++# FIXME create the cert in puppet
++smtpd_use_tls = no
++#smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
++#smtpd_tls_key_file = /etc/pki/tls/private/postfix.pem
++#smtpd_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
+
+ &lt;%- if all_tags.include?('postfix::smtp_server') -%&gt;
+ smtpd_etrn_restrictions = reject
+
+</pre></div>
+
+</body>
+</html> \ No newline at end of file