--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+import getopt
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+import getpass
+from common import checkdir
+import ftpio
+from config import sign_key
+from sign import is_signed, signpkgs
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], '')
+except getopt.GetoptError:
+ print >>sys.stderr, "ERR: options error"
+ print >>sys.stderr, "checksign.py tree package1 [package2...]"
+ sys.exit(1)
+
+if len(args) < 1:
+ print >>sys.stderr, "ERR: missing tree name"
+ print >>sys.stderr, "checksign.py tree package1 [package2...]"
+ sys.exit(1)
+
+if sign_key == None:
+ print >>sys.stderr, "ERR: sign_key not defined in config"
+ sys.exit(1)
+
+treename = args[0]
+packages = args[1:]
+
+checkdir(treename)
+
+ftpio.connect('sign')
+
+if not ftpio.lock(treename, True):
+ print >>sys.stderr, "ERR: %s tree already locked" % treename
+ sys.exit(1)
+
+files = []
+try:
+ if len(packages) < 1:
+ loadall = True
+ else:
+ loadall = False
+
+ # if no files specified, grab whole tree contents
+ tree = ftptree.FtpTree(treename, loadall = loadall)
+ if loadall:
+ # this is hack, should be a param, not access private .loadedpkgs element
+ tree.mark4moving(tree.loadedpkgs)
+ else:
+ tree.mark4moving(packages)
+
+except ftptree.SomeError:
+ # In case of problems we need to unlock the tree before exiting
+ ftpio.unlock(treename)
+ sys.exit(1)
+
+ftpio.unlock(treename)
+
+print "Checking signatures of %d packages" % len(tree.loadedpkgs)
+sign = []
+for pkg in tree.marked4moving:
+ unsigned = 0
+ for file in pkg.rpmfiles():
+ if not is_signed(file):
+ unsigned += 1
+
+ if unsigned != 0:
+ print '%s: %d files NOT signed' % (pkg.nvr, unsigned)
+ else:
+ print '%s signed' % pkg.nvr
+
+sys.exit(0)
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+ftptree.quietmode=True
+from common import checkdir
+import ftpio
+import config
+cval=config.value
+
+import curses
+
+if len(sys.argv) != 3:
+ print "ERR: wrong number of arguments"
+ print "check-tree.py srctree dsttree"
+ sys.exit(1)
+
+checkdir(sys.argv[1])
+
+ftpio.connect('check-tree')
+
+if not ftpio.lock(sys.argv[1], True):
+ print "ERR: %s tree already locked" % sys.argv[1]
+ sys.exit(1)
+
+if not ftpio.lock(sys.argv[2], True):
+ ftpio.unlock(sys.argv[1])
+ print "ERR: %s tree already locked" % sys.argv[2]
+ sys.exit(1)
+
+srctree=ftptree.FtpTree(sys.argv[1], loadall=True)
+dsttree=ftptree.FtpTree(sys.argv[2])
+
+srctree.checktree(dsttree)
+
+# We've loaded all interesting info, so we can continue without locks
+ftpio.unlock(sys.argv[1])
+ftpio.unlock(sys.argv[2])
+
+# The list(set(list)) cast is a fancy way to remove dups from a list
+names=sorted(list(set([pkg.name for pkg in srctree.values()])))
+
+pkgtree={}
+
+for n in names:
+ pkgtree[n]=[]
+
+for pkg in srctree.values():
+ pkgtree[pkg.name].append(pkg)
+
+for key in pkgtree.keys():
+ pkgtree[key]=sorted(pkgtree[key], reverse=True)
+
+for pkg in srctree.values():
+ pkg.marked4movingpool=pkgtree[pkg.name]
+
+pkglist=[]
+
+for key in sorted(pkgtree.keys()):
+ pkglist=pkglist+pkgtree[key]
+
+DoQuit="OMG!"
+
+class Screen:
+ def __init__(self, srctreename, dsttreename, elements):
+ self.srctree=srctreename
+ self.dsttree=dsttreename
+ self.elements=elements
+ self.pkglistselected=0
+ self.pkgliststartpad=0
+ self.win2startpad=0
+ self.window=1
+ try:
+ # initial
+ self.screen=curses.initscr()
+ self.screen.keypad(1)
+ curses.start_color()
+ curses.noecho()
+ curses.cbreak()
+ curses.meta(1)
+ curses.curs_set(0)
+
+ # Without this refresh(), nothing will show up before first getch()
+ self.screen.refresh()
+
+ self.__init_colors()
+ self.__init_windows()
+ self.__bind_keys()
+
+ try:
+ # Main loop
+ while True:
+ if self.window==1: #pkglist
+ self.__redraw_pkglist()
+ self.__redraw_statusbox()
+ elif self.window==2:
+ pass
+ curses.doupdate()
+ self.__handle_input()
+ except DoQuit:
+ pass
+ finally:
+ curses.echo()
+ curses.nocbreak()
+ curses.curs_set(1)
+ curses.endwin()
+
+ def __bind_keys(self):
+ self.globalkeys=(('qQ', 'quit'), ('KEY_RESIZE', 'resize'),
+ ('KEY_CLOSE', 'quit'))
+ self.perwindowkeys=[(), ()]
+ self.perwindowkeys[0]=(('k', 'move_up'), ('J', 'move_pgdown'),
+ ('K', 'move_pgup'), (' ', 'mark'), ('j', 'move_down'),
+ ('KEY_DOWN', 'move_down'), ('KEY_UP', 'move_up'),
+ ('KEY_HOME', 'move_home'), ('KEY_END', 'move_end'),
+ ('KEY_NPAGE', 'move_pgdown'), ('KEY_PPAGE', 'move_pgup'))
+
+
+ def __init_colors(self):
+ curses.init_pair(1, curses.COLOR_BLACK, curses.COLOR_CYAN)
+ self.COLOR_TITLEBAR=curses.color_pair(1)
+ curses.init_pair(2, curses.COLOR_WHITE, curses.COLOR_BLUE)
+ self.COLOR_STANDARD=curses.color_pair(2)
+ curses.init_pair(3, curses.COLOR_RED, curses.COLOR_BLUE)
+ self.COLOR_ERROR=curses.color_pair(3)
+ curses.init_pair(4, curses.COLOR_YELLOW, curses.COLOR_BLUE)
+ self.COLOR_WARNING=curses.color_pair(4)
+ curses.init_pair(5, curses.COLOR_WHITE, curses.COLOR_RED)
+ self.COLOR_ERRORMSG=curses.color_pair(5)
+ curses.init_pair(6, curses.COLOR_WHITE, curses.COLOR_YELLOW)
+ self.COLOR_WARNINGMSG=curses.color_pair(6)
+ curses.init_pair(7, curses.COLOR_BLACK, curses.COLOR_WHITE)
+ self.COLOR_WHITEBG=curses.color_pair(7)
+
+ def __init_windows(self):
+ self.__set_screen_coordinates()
+
+ # Titlebar
+ self.titlebar = curses.newpad(1, 200)
+ self.titlebar.bkgdset(ord(' '), self.COLOR_TITLEBAR)
+ self.__redraw_titlebar()
+
+ # Pkg list pad
+ self.pkglist = curses.newpad(len(self.elements), 200)
+ self.pkglist.bkgdset(ord(' '), self.COLOR_STANDARD)
+ self.pkglist.clrtobot()
+
+ # Status bar
+ self.statusbar = curses.newpad(1, 200)
+
+ # Pkg status box
+ self.statusbox = curses.newpad(5, 200)
+ self.statusbox.bkgdset(ord(' '), self.COLOR_STANDARD)
+ self.statusbox.clrtobot()
+ self.__redraw_statusbox()
+
+ def __set_screen_coordinates(self):
+ self.scr_h, self.scr_w = self.screen.getmaxyx()
+ self.pad_h = self.scr_h-5
+ self.sbar_y = self.scr_h-4
+ self.sbox_y = self.scr_h-3
+
+ def __redraw_titlebar(self):
+ self.titlebar.clrtobot()
+# self.titlebar.addstr(0, self.scr_w-14, "pld-ftp-admin")
+ self.titlebar.addstr(0, 1, 'Window #%s' % self.window)
+ tmp="%s => %s" % (self.srctree, self.dsttree)
+ self.titlebar.addstr(0, int(self.scr_w/2-len(tmp)/2)-1, tmp)
+ self.titlebar.addstr(0, self.scr_w-20, "Press 'h' for help.")
+ self.titlebar.noutrefresh(0, 0, 0, 0, 1, self.scr_w-1)
+
+ def __redraw_statusbox(self):
+ self.statusbox.erase()
+ pkg=self.elements[self.pkglistselected]
+ i=0
+ for error in pkg.errors:
+ self.statusbox.bkgdset(ord(' '), self.COLOR_ERRORMSG)
+ self.statusbox.addstr(i, 0, 'ERR: '+error, curses.A_BOLD)
+ self.statusbox.bkgdset(ord(' '), self.COLOR_STANDARD)
+ i+=1
+ for warning in pkg.warnings:
+ self.statusbox.bkgdset(ord(' '), self.COLOR_WARNINGMSG)
+ self.statusbox.addstr(i, 0, 'WARN: '+warning, curses.A_BOLD)
+ self.statusbox.bkgdset(ord(' '), self.COLOR_STANDARD)
+ i+=1
+ self.statusbox.noutrefresh(0,0,self.sbox_y,0,self.scr_h-1,self.scr_w-1)
+
+ def __redraw_pkglist(self):
+ # Safety in case there's a bug somewhere
+ if self.pkgliststartpad>len(self.elements)-self.pad_h:
+ self.pkgliststartpad=len(self.elements)-self.pad_h
+ if self.pkgliststartpad<0:
+ self.pkgliststartpad=0
+
+ self.pkglist.erase()
+ for i in range(len(self.elements)):
+ if self.elements[i].marked4moving:
+ if self.elements[i].warnings:
+ self.pkglist.bkgdset(ord(' '), self.COLOR_WARNINGMSG)
+ self.pkglist.addstr(i, 0, '+', curses.A_BOLD)
+ else:
+ self.pkglist.bkgdset(ord(' '), self.COLOR_WHITEBG)
+ self.pkglist.addstr(i, 0, '+')
+
+ if self.elements[i].errors:
+ self.pkglist.bkgdset(ord(' '), self.COLOR_ERROR)
+ elif self.elements[i].warnings:
+ self.pkglist.bkgdset(ord(' '), self.COLOR_WARNING)
+ else:
+ self.pkglist.bkgdset(ord(' '), self.COLOR_STANDARD)
+ if i == self.pkglistselected:
+ self.pkglist.addstr(i, 2, `self.elements[i]`, curses.A_REVERSE)
+ else:
+ self.pkglist.addstr(i, 2, `self.elements[i]`, curses.A_BOLD)
+ self.pkglist.bkgdset(ord(' '), self.COLOR_STANDARD)
+ self.pkglist.noutrefresh(self.pkgliststartpad,0,1,0,self.pad_h,self.scr_w-1)
+
+ def __do_resize(self):
+ self.__set_screen_coordinates()
+ self.__redraw_titlebar()
+ self.__redraw_statusbox()
+
+ def __do_move_down(self):
+ if 0 <= self.pkglistselected < len(self.elements)-1:
+ self.pkglistselected+=1
+ if (self.pkgliststartpad!=len(self.elements)-self.pad_h and
+ self.pad_h-(self.pkglistselected-self.pkgliststartpad)<5):
+ self.pkgliststartpad+=1
+
+ def __do_move_up(self):
+ if 0 < self.pkglistselected <= len(self.elements)-1:
+ self.pkglistselected-=1
+ if self.pkgliststartpad!=0 and self.pkglistselected-self.pkgliststartpad<4:
+ self.pkgliststartpad-=1
+
+ def __do_move_home(self):
+ self.pkglistselected=0
+ self.pkgliststartpad=0
+
+ def __do_move_end(self):
+ self.pkglistselected=len(self.elements)-1
+ self.pkgliststartpad=len(self.elements)-self.pad_h
+
+ def __do_move_pgdown(self):
+ self.pkglistselected+=self.pad_h
+ if self.pkglistselected >= len(self.elements):
+ self.pkglistselected = len(self.elements)-1
+ self.pkgliststartpad+=self.pad_h
+ if self.pkgliststartpad > len(self.elements)-self.pad_h:
+ self.pkgliststartpad=len(self.elements)-self.pad_h
+
+ def __do_move_pgup(self):
+ self.pkglistselected-=self.pad_h
+ if self.pkglistselected < 0:
+ self.pkglistselected = 0
+ self.pkgliststartpad-=self.pad_h
+ if self.pkgliststartpad < 0:
+ self.pkgliststartpad = 0
+
+ def __do_quit(self):
+ raise DoQuit
+
+ def __do_mark(self):
+ pkg=self.elements[self.pkglistselected]
+ if pkg.errors:
+ return
+ elif pkg.marked4moving:
+ pkg.unmark4moving()
+ else:
+ pkg.mark4moving()
+
+ def __handle_input(self):
+ key=self.screen.getch()
+ if key==27:
+ # Switch window
+ metakey=self.screen.getch()
+ if 0<metakey<256:
+ c=chr(metakey)
+ if c=='1':
+ self.window=1
+ elif c=='2':
+ self.window=2
+ elif 0<key<256:
+ c=chr(key)
+ for bind in self.globalkeys+self.perwindowkeys[self.window-1]:
+ if not bind[0].startswith('KEY_') and c in bind[0]:
+ exec 'self._Screen__do_%s()' % bind[1]
+
+ else:
+# self.elements[0]=`key`
+ for bind in self.globalkeys+self.perwindowkeys[self.window-1]:
+ if bind[0].startswith('KEY_'):
+ if key == getattr(curses, bind[0]):
+ exec 'self._Screen__do_%s()' % bind[1]
+
+s = Screen(sys.argv[1], sys.argv[2], pkglist)
+
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+import ftpio
+import config
+
+ftpio.connect()
+print ftpio.locks_dump()
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os, stat, time, re
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+from config import incoming_dir, default_to, ftp_archs
+from config import value as cval
+import config
+from common import noarchcachedir, tmpdir, fileexists
+from baseftptree import BaseFtpTree, BasePkg
+from ftptree import FtpTree, Pkg
+import ftpio
+
+os.umask(022)
+
+def rm(file):
+ os.remove(file)
+
+def mv(src, dst):
+ os.rename(src, dst + '/' + src.split('/')[-1])
+
+# duplicate code in ftptree.py
+def is_debuginfo(nvr):
+ """
+ returns true if NVR is debuginfo package and separate debuginfo is enabled
+ """
+ if not config.separate_debuginfo:
+ return False
+ pkg = nvr.split('-')[:-2]
+ return pkg[-1] == 'debuginfo'
+
+def findfiles(dir):
+ def filterinfos(x):
+ if x[-11:] == '.uploadinfo':
+ return True
+ else:
+ return False
+ return filter(filterinfos, os.listdir(dir))
+
+def getcontent(file):
+ f = open(file, 'r')
+ content = f.read()
+ f.close()
+ if not content[-5:] == '\nEND\n':
+ return None
+ else:
+ return content[:-4]
+
+def send_noarch_msg(files_differ, reqs_differ, pkg, rpmfile, arch):
+ req_email=pkg.build[pkg.lastbid].requester_email
+ req_bid=pkg.lastbid
+ cc_list=[]
+ if 'logs_list' in cval:
+ cc_list.append(cval['logs_list'])
+ m_subject="Noarch error: %s files differ among builders" % rpmfile
+ bids=pkg.build.keys()
+ if len(bids)>1:
+ for bid in bids:
+ newcc=pkg.build[bid].requester_email
+ if req_email!=newcc and newcc not in cc_list:
+ cc_list.append(newcc)
+
+ msg="From: %s\nTo: %s\n" % (cval['from_field'], req_email)
+ if cc_list:
+ msg=msg+"Cc: %s\n" % ", ".join(cc_list)
+ msg=msg+"""X-PLD-Builder: %s
+References: <%s@pld.src.builder>
+In-Reply-To: <%s@pld.src.builder>
+Subject: %s
+
+""" % (cval['xpldbuilder'], req_bid, req_bid, m_subject)
+
+ sm = os.popen("/usr/sbin/sendmail -t", "w")
+
+ sm.write(msg)
+
+ if files_differ:
+ f=open("%s/files.diff" % tmpdir, 'r')
+ sm.write("Difference between %s (currently in %s) and %s FILES\n" %
+ (pkg.noarch_arch[rpmfile], `ftptree`, arch)),
+ for line in f.readlines(True)[2:]:
+ sm.write(line)
+ f.close()
+
+ sm.write('\n')
+
+ if reqs_differ:
+ f=open("%s/reqs.diff" % tmpdir, 'r')
+ sm.write("Difference between %s (currently in %s) and %s REQS\n" %
+ (pkg.noarch_arch[rpmfile], `ftptree`, arch)),
+ for line in f.readlines(True)[2:]:
+ sm.write(line)
+ f.close()
+
+ sm.close()
+
+def move_noarch(f, arch, rpmfile, dstpkg):
+ if dstpkg.noarch_arch.has_key(rpmfile):
+ os.system("LC_ALL=C rpm -qlp %s | LC_ALL=C sort > %s/files.new" %
+ (incoming_dir + arch + '/' + rpmfile, tmpdir))
+ os.system("rpm -qRp %s | LC_ALL=C sort | LC_ALL=C uniq > %s/reqs.new" %
+ (incoming_dir + arch + '/' + rpmfile, tmpdir))
+
+ files_differ = False
+ reqs_differ = False
+
+ if os.system("diff -u %s/%s.filelist %s/files.new > %s/files.diff" %
+ (noarchcachedir, rpmfile, tmpdir, tmpdir)):
+ files_differ = True
+ if os.system("diff -u %s/%s.reqlist %s/reqs.new > %s/reqs.diff" %
+ (noarchcachedir, rpmfile, tmpdir, tmpdir)):
+ reqs_differ = True
+
+ if files_differ or reqs_differ:
+ send_noarch_msg(files_differ, reqs_differ, dstpkg, rpmfile, arch)
+
+ rm(incoming_dir + arch + '/' + rpmfile)
+ else:
+ os.system("LC_ALL=C rpm -qlp %s | LC_ALL=C sort > %s/%s.filelist" %
+ (incoming_dir + arch + '/' + rpmfile, noarchcachedir, rpmfile))
+ os.system("rpm -qRp %s | LC_ALL=C sort | LC_ALL=C uniq > %s/%s.reqlist" %
+ (incoming_dir + arch + '/' + rpmfile, noarchcachedir, rpmfile))
+ if not dstpkg.files.has_key(arch):
+ f.write("file:noarch:%s\ninfo:noarch_arch:%s:%s\n" % (rpmfile, rpmfile, arch))
+ mv(incoming_dir + arch + '/' + rpmfile, default_to + 'noarch/RPMS')
+
+def send_vr_msg(snvr, anvr, pkg, arch):
+ req_email=pkg.build[pkg.lastbid].requester_email
+ req_bid=pkg.lastbid
+ cc_list=[]
+ if 'logs_list' in cval:
+ cc_list.append(cval['logs_list'])
+ m_subject="NVR error: %s version or relese differ among subpackages" % snvr[0]
+ bids=pkg.build.keys()
+ if len(bids)>1:
+ for bid in bids:
+ newcc=pkg.build[bid].requester_email
+ if req_email!=newcc and newcc not in cc_list:
+ cc_list.append(newcc)
+
+ msg="From: %s\nTo: %s\n" % (cval['from_field'], req_email)
+ if cc_list:
+ msg=msg+"Cc: %s\n" % ", ".join(cc_list)
+ msg=msg+"""X-PLD-Builder: %s
+References: <%s@pld.src.builder>
+In-Reply-To: <%s@pld.src.builder>
+Subject: %s
+
+""" % (cval['xpldbuilder'], req_bid, req_bid, m_subject)
+
+ sm = os.popen("/usr/sbin/sendmail -t", "w")
+
+ sm.write(msg)
+
+ sm.write("Difference between %s SRPM (currently in %s) and %s RPM NVR:\n\n" %
+ (snvr[0], `ftptree`, arch)),
+ sm.write("Expected (%s):\nV: %s\nR: %s\n\n" % snvr)
+ sm.write("RPM:\nN: %s\nV: %s\nR: %s\n" % anvr)
+ sm.write('\n')
+
+ sm.close()
+
+# main()
+try:
+ ftpio.connect('from-incoming-pid-%s' % os.getpid())
+except:
+ print "Can't get ftpiod connection"
+ sys.exit(1)
+
+ftptree = BaseFtpTree(cval['default_to'])
+
+if not ftpio.lock(cval['default_to']):
+ print "Can't get lock: %s" % cval['default_to']
+ sys.exit(1)
+
+moved_anything = False
+
+for uploadinfo in findfiles(incoming_dir + 'SRPMS'):
+ content = getcontent(incoming_dir + 'SRPMS/' + uploadinfo)
+ if not content:
+ continue # Uploading not finished
+
+ pkg = BasePkg(uploadinfo[:-19], content = content)
+ srpm = pkg.files['SRPMS'][0]
+
+ if not os.path.exists(incoming_dir + 'SRPMS/' + srpm):
+ ftpio.log("%s file missing; skipping move until next round" % (srpm))
+ continue
+
+ if ftptree.has_key(`pkg`):
+ ftpio.log("%s already present in %s; removing older files" % (srpm, ftptree))
+ rm(default_to + 'SRPMS/RPMS/' + srpm)
+ f = open(default_to + 'SRPMS/.metadata/' + srpm+'.info', 'a')
+ bid = pkg.build.keys()[0]
+ build = pkg.build[bid]
+ f.write("info:build:%s:requester:%s\ninfo:build:%s:requester_email:%s\n"
+ % (bid, build.requester, bid, build.requester_email))
+ f.close()
+ else:
+ f = open(default_to + 'SRPMS/.metadata/' + srpm + '.info', 'w')
+ f.write(content)
+ f.close()
+
+ mv(incoming_dir + 'SRPMS/' + srpm, default_to + 'SRPMS/RPMS')
+ rm(incoming_dir + 'SRPMS/' + uploadinfo)
+
+for arch in ftp_archs:
+ for uploadinfo in findfiles(incoming_dir + arch):
+ content = getcontent(incoming_dir + arch + '/' + uploadinfo)
+ if not content:
+ ftpio.log("%s not finished uploading" % uploadinfo)
+ continue # Uploading not finished
+
+ srcpkg = BasePkg(uploadinfo[:-19], content = content)
+ srpm = srcpkg.files['SRPMS'][0]
+
+ if not ftptree.has_key(`srcpkg`):
+ continue # We require the src.rpm to be present
+
+ renvr = re.compile(r'(.*)-(.*)-(.*)\.[^.]*\.rpm')
+ srcnvr = renvr.match(srpm).groups()
+
+ rpmfile_missing = [f for f in srcpkg.files['ARCH'] if not os.path.exists(incoming_dir + arch + '/'+f)]
+ if len(rpmfile_missing):
+ for filem in rpmfile_missing:
+ ftpio.log("%s file missing; skipping move until next round" % (filem))
+ continue
+
+ dstpkg = BasePkg(`srcpkg`, ftptree)
+
+ if dstpkg.files.has_key(arch):
+ ftpio.log("files from %s for arch %s already present in %s; removing older files" % (`srcpkg`, arch, ftptree))
+ for rpmfile in dstpkg.files[arch]:
+ if is_debuginfo(rpmfile):
+ dstfile = default_to + arch + '/debuginfo'
+ else:
+ dstfile = default_to + arch + '/RPMS'
+ try:
+ rm(dstfile + '/' + rpmfile)
+ except OSError, e:
+ l = "Removing %s problem: %s" % (dstfile + '/' + rpmfile, e)
+ ftpio.log(l)
+ print l
+
+ f = open(default_to + 'SRPMS/.metadata/' + srpm + '.info', 'a')
+ for rpmfile in srcpkg.files['ARCH']:
+ moved_anything = True
+
+# Too much noise, too little use
+# archnvr = renvr.match(rpmfile).groups()
+# if srcnvr[1] != archnvr[1] or srcnvr[2] != archnvr[2]:
+# send_vr_msg(srcnvr, archnvr, dstpkg, arch)
+
+ if rpmfile[-11:] == '.noarch.rpm' and config.separate_noarch:
+ move_noarch(f, arch, rpmfile, dstpkg)
+ else:
+ if not dstpkg.files.has_key(arch):
+ f.write("file:%s:%s\n" % (arch, rpmfile))
+ srcfile = incoming_dir + arch + '/' + rpmfile
+
+ if is_debuginfo(rpmfile):
+ dstfile = default_to + arch + '/debuginfo'
+ else:
+ dstfile = default_to + arch + '/RPMS'
+
+ try:
+ mv(srcfile, dstfile)
+ except OSError, e:
+ l = "Moving %s to %s problem: %s" % (srcfile, dstfile, e)
+ ftpio.log(l)
+ print l
+ f.close()
+
+ rm(incoming_dir + arch + '/' + uploadinfo)
+
+ftpio.unlock(cval['default_to'])
+
+if moved_anything:
+ os.system("%s/pld-ftp-admin/bin/pfa-genindex --quiet test > /dev/null" % (os.getenv("HOME")))
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import getopt
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+from common import checkdir
+from config import ftp_dir,all_ftp_archs
+import config
+import ftpio
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], 'q',
+ [
+ "quiet", "index=",
+ "nopoldek", "noyum", "norpmrepo",
+ "poldek", "yum", "rpmrepo"
+ ]
+ )
+except getopt.GetoptError:
+ print >>sys.stderr, "ERR: not enough parameters given"
+ print >>sys.stderr, "gen-indexes.py [--quiet] [--[no]poldek] [--[no]yum] [--[no]rpmrepo] tree [tree2...]"
+ sys.exit(1)
+
+do_poldek = True
+do_yum = False
+do_rpmrepo = False
+quiet = False
+# update only if changed (applicable to yum)
+freshen = True
+
+for o, a in opts:
+ if o == "--nopoldek":
+ do_poldek = False
+ if o == "--noyum":
+ do_yum = False
+ if o == "--norpmrepo":
+ do_rpmrepo = False
+
+ if o == "--poldek":
+ do_poldek = True
+ if o == "--yum":
+ do_yum = True
+ if o == "--rpmrepo":
+ do_rpmrepo = True
+
+ if o == "-q" or o == "--quiet":
+ quiet = True
+
+ if o == "--index":
+ do_poldek = do_yum = do_rpmrepo = False
+ for v in a.split(','):
+ if v == 'poldek':
+ do_poldek = True
+ if v == 'yum':
+ do_yum = True
+ if v == 'rpmrepo':
+ do_rpmrepo = True
+
+if not quiet:
+ print "poldek: %s; yum: %s; rpmrepo: %s" % (do_poldek, do_yum, do_rpmrepo)
+
+if not do_poldek and not do_yum and not do_rpmrepo:
+ print >>sys.stderr, "ERR: speciy at least one action"
+ sys.exit(1)
+
+trees = args
+
+for tree in trees:
+ checkdir(tree)
+
+ftpio.connect('gen-indexes')
+
+locked = []
+
+for tree in trees:
+ if ftpio.lock(tree, True):
+ locked.append(tree)
+ else:
+ if not quiet:
+ print >>sys.stderr, "ERR: %s tree already locked" % tree
+ for i in locked:
+ ftpio.unlock(i)
+ sys.exit(1)
+
+home = os.environ['HOME']
+
+os.umask(022)
+os.nice(19)
+
+if do_poldek:
+ poldek = '%s.stat/bin/poldek-new --cachedir=%s/tmp/poldek --conf %s.stat/etc/poldek.conf --mkidxz' % (ftp_dir, home, ftp_dir)
+
+ for tree in trees:
+ print '\n-------------------------- %s --------------------------' % tree
+ for arch in all_ftp_archs:
+ print '\ngenerate poldek index for %s' % arch
+ print '%s -s %s%s/%s/RPMS/ --mkidxz --mkidx-type pndir' % (poldek, ftp_dir, tree, arch)
+ os.system('%s -s %s%s/%s/RPMS/ --mkidxz --mkidx-type pndir' % (poldek, ftp_dir, tree, arch))
+ if arch != 'noarch' and config.separate_debuginfo:
+ os.system('%s -s %s%s/%s/debuginfo/ --mkidxz --mkidx-type pndir' % (poldek, ftp_dir, tree, arch))
+
+if do_yum:
+ os.system('%s cd %s.stat/repodata && cvs %s up comps.xml' % ("" if quiet else "set -x;", ftp_dir, "" if quiet else "-Q"))
+ yum = '%s.stat/bin/createrepo -d -v --update --checkts --skip-stat --workers=12 -g %s.stat/repodata/comps.xml' % (ftp_dir, ftp_dir)
+ comps_file = '%s.stat/repodata/comps.xml' % ftp_dir
+ for tree in trees:
+ print '\n-------------------------- %s --------------------------' % tree
+ cachedir = '%s/tmp/createrepo/%s' % (home, tree)
+ treedir = "%s%s" % (ftp_dir, tree)
+ for arch in all_ftp_archs:
+ print '\ngenerate repodata for %s using createrepo' % arch
+ archdir = "%s/%s" % (treedir, arch)
+ poldek_idx = "%s/RPMS/packages.ndir.md" % archdir
+ repodata_idx = "%s/RPMS/repodata/repomd.xml" % archdir
+ if freshen and os.path.exists(poldek_idx) and os.path.exists(repodata_idx) \
+ and not os.path.getmtime(comps_file) > os.path.getmtime(repodata_idx) \
+ and not os.path.getmtime(poldek_idx) > os.path.getmtime(repodata_idx):
+ print "repodata indexes already fresh"
+ continue
+ print ('%s %s --cache %s-%s %s/RPMS' % ("" if quiet else "time", yum, cachedir, arch, archdir))
+ os.system('%s %s --cache %s-%s %s/RPMS' % ("" if quiet else "time", yum, cachedir, arch, archdir))
+ if arch != 'noarch' and config.separate_debuginfo:
+ os.system('%s %s --cache %s-%s %s/debuginfo' % ("" if quiet else "time", yum, cachedir, arch, archdir))
+
+if do_rpmrepo:
+ os.system('%s cd %s.stat/repodata && cvs %s up comps.xml' % ("" if quiet else "set -x;", ftp_dir, "" if quiet else "-Q"))
+ for tree in trees:
+ print '\n-------------------------- %s --------------------------' % tree
+ for arch in all_ftp_archs:
+ dir = '%s/%s/%s/RPMS' % (ftp_dir, tree, arch)
+ if not quiet:
+ print '\ngenerate repodata for %s using rpmrepo (in %s)' % (arch, dir)
+ os.system('%s rpmrepo %s -o %s' % ("" if quiet else "set -x;", dir, dir))
+ if not quiet:
+ print 'copy comps.xml'
+ comps = '%s.stat/repodata/comps.xml' % ftp_dir
+ os.system('%s cp -p %s %s/repodata' % ("" if quiet else "set -x;", comps, dir))
+
+for tree in trees:
+ ftpio.unlock(tree)
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os, re
+import getopt
+import subprocess
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+from common import checkdir
+import ftpio
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], 'qsdo:', [ "quiet" ])
+except getopt.GetoptError:
+ print >>sys.stderr, "ERR: options error"
+ print >>sys.stderr, "rpmlint.py tree package1 [package2...]"
+ sys.exit(1)
+
+quiet = False
+show = False
+debugfiles = False
+outstream = sys.stdout
+for o, a in opts:
+ if o == "-q" or o == "--quiet":
+ quiet = True
+ if o == "-s":
+ show = True
+ if o == "-d":
+ debugfiles = True
+ if o == "-o":
+ outstream = open(a, 'w')
+
+if len(args) < 1:
+ print >>sys.stderr, "ERR: missing tree name"
+ print >>sys.stderr, "rpmlint.py tree package1 [package2...]"
+ sys.exit(1)
+
+treename = args[0]
+packages = args[1:]
+
+checkdir(treename)
+
+ftpio.connect('rpmlint')
+
+if not ftpio.lock(treename, True):
+ print >>sys.stderr, "ERR: %s tree already locked" % treename
+ sys.exit(1)
+
+files = []
+try:
+ if len(packages) < 1:
+ loadall = True
+ else:
+ loadall = False
+
+ # if no files specified, grab whole tree contents
+ tree = ftptree.FtpTree(treename, loadall = loadall)
+ tree.do_checkbuild = False
+ if loadall:
+ # this is hack, should be a param, not access private .loadedpkgs element
+ tree.mark4moving(tree.loadedpkgs)
+ else:
+ tree.mark4moving(packages)
+ files = tree.rpmfiles(debugfiles = debugfiles, sourcefiles = False)
+
+except (ftptree.SomeError, KeyboardInterrupt), e:
+ # In case of problems we need to unlock the tree before exiting
+ ftpio.unlock(treename)
+ sys.exit(1)
+
+ftpio.unlock(treename)
+
+class LintPkg:
+ def __init__(self, cachedir):
+ self.outstream = sys.stdout
+
+ # for rpmlint stats
+ self.packages = self.specfiles = self.errors = self.warnings = 0
+ # 1 packages and 0 specfiles checked; 0 errors, 0 warnings.
+ self.lintre = re.compile('(?P<packages>\d+) packages and (?P<specfiles>\d+) specfiles checked; (?P<errors>\d+) errors, (?P<warnings>\d+) warnings.')
+
+ self._rpmlint = '/usr/bin/rpmlint'
+
+ # mtime, which invalidates all caches
+ self.mtime = None
+ rpmlintrc = os.path.expanduser("~/.config/rpmlint")
+ if os.path.exists(rpmlintrc):
+ self.mtime = os.stat(rpmlintrc).st_mtime
+
+ self.cachedir = os.path.expanduser(cachedir)
+ if not os.path.isdir(self.cachedir):
+ os.makedirs(self.cachedir)
+
+ def cachefile(self, file):
+ (dirname, filename) = os.path.split(file)
+ return os.path.join(self.cachedir, filename+'.txt')
+
+ def get_stats(self, file):
+ cachefile = self.cachefile(file)
+ if not os.path.exists(cachefile):
+ return None
+
+ # show last line (that contains status)
+ l = (open(cachefile, 'r').readlines())[-1]
+ m = self.lintre.match(l)
+ if not m:
+ return None
+
+ return {
+ 'packages': int(m.group('packages')),
+ 'specfiles': int(m.group('specfiles')),
+ 'errors': int(m.group('errors')),
+ 'warnings': int(m.group('warnings')),
+ }
+
+ """
+ update stats from cachefile
+ """
+ def update_stats(self, file):
+ m = self.get_stats(file)
+ if not m:
+ return False
+ self.packages += m['packages']
+ self.specfiles += m['specfiles']
+ self.errors += m['errors']
+ self.warnings += m['warnings']
+ return True
+
+ def print_stats(self, file = None):
+ if file:
+ (dirname, filename) = os.path.split(file)
+ print >>self.outstream, "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings. [%s]" % (self.packages, self.specfiles, self.errors, self.warnings, filename),
+ else:
+ print >>self.outstream, "\r\033[0K%d packages and %d specfiles checked; %d errors, %d warnings." % (self.packages, self.specfiles, self.errors, self.warnings)
+ sys.stdout.flush()
+
+ def cat(self, file):
+ print >>self.outstream, "".join(open(file, 'r').readlines())
+
+ def show_results(self, file):
+ m = self.get_stats(file)
+ if not m:
+ return False
+
+ cachefile = self.cachefile(file)
+ if not os.path.exists(cachefile):
+ print >>self.outsteram, "MISSING: report: %s" % file
+
+ if m['errors'] > 0 or m['warnings'] > 0:
+ (dirname, filename) = os.path.split(file)
+ print >>self.outstream, "rpmlint: %s" % filename
+ self.cat(cachefile)
+
+ def rpmlint(self, file):
+ cachefile = self.cachefile(file)
+
+ rc = None
+ if not os.path.exists(cachefile) \
+ or os.stat(file).st_mtime > os.stat(cachefile).st_mtime \
+ or (self.mtime and self.mtime > os.stat(cachefile).st_mtime):
+ cmd = [self._rpmlint, file]
+ outfd = open(cachefile, 'w')
+ try:
+ env = {'TZ': 'GMT'}
+ rc = subprocess.call(cmd, stdin = subprocess.PIPE, stdout = outfd, stderr = outfd, env = env, close_fds = True)
+ except KeyboardInterrupt:
+ os.unlink(cachefile)
+ raise
+ outfd.close()
+ if not self.update_stats(file):
+ # update failed, dump cache and remove it
+ self.cat(cachefile)
+ os.unlink(cachefile)
+ rc = 1
+ return rc == 0
+
+try:
+ lock = 'rpmlint:'+treename
+ if not ftpio.lock(lock, True):
+ print >>sys.stderr, "ERR: %s tree already locked for rpmlint" % treename
+ sys.exit(1)
+
+ if not quiet:
+ print >>outstream, "rpmlint of %d files from %d packages" % (len(files), len(tree.loadedpkgs))
+ lint = LintPkg("~/tmp/rpmlint")
+ lint.outstream = outstream
+ for file in files:
+ lint.rpmlint(file)
+ if not quiet:
+ lint.print_stats(file)
+ if show:
+ lint.show_results(file)
+
+ if not quiet:
+ lint.print_stats()
+
+ ftpio.unlock(lock)
+except (Exception, KeyboardInterrupt):
+ ftpio.unlock(lock)
+ raise
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import time
+from config import test_builds_dir, ftp_archs
+
+def clean_dir(path, max):
+ curtime=time.time()
+ for i in os.listdir(path):
+ if curtime - os.path.getmtime(path+'/'+i) > max:
+ os.unlink(path+'/'+i)
+
+for arch in ftp_archs + ['SRPMS']:
+ clean_dir(test_builds_dir+arch, 60*60*24*3)
+
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+from common import checkdir
+import ftpio
+from mailer import Message
+from config import archived_trees, logs_list
+
+os.umask(022)
+
+nocheckbuild = False
+if len(sys.argv) > 4 and sys.argv[1] == '-nb':
+ nocheckbuild = True
+ sys.argv = sys.argv[1:]
+
+if len(sys.argv) < 4:
+ print >>sys.stderr, "ERR: not enough parameters given"
+ print >>sys.stderr, "move.py [options] src-tree dst-tree package [package2 package3 ...]"
+ print >>sys.stderr, "\nOptions:"
+ print >>sys.stderr, " -nb Do not check if builds are finished.\n"
+ sys.exit(1)
+
+checkdir(sys.argv[1])
+checkdir(sys.argv[2])
+
+if sys.argv[2] in archived_trees:
+ archivetreename = ".archive/" + sys.argv[2]
+ checkdir(archivetreename)
+else:
+ archivetreename = None
+
+ftpio.connect('move')
+
+if not ftpio.lock(sys.argv[1], True):
+ print >>sys.stderr, "ERR: %s tree already locked" % sys.argv[1]
+ sys.exit(1)
+
+if not ftpio.lock(sys.argv[2], True):
+ ftpio.unlock(sys.argv[1])
+ print >>sys.stderr, "ERR: %s tree already locked" % sys.argv[2]
+ sys.exit(1)
+
+if archivetreename != None and archivetreename != sys.argv[1] and not ftpio.lock(archivetreename, True):
+ ftpio.unlock(sys.argv[2])
+ ftpio.unlock(sys.argv[1])
+ print "ERR: %s tree already locked" % archivetreename
+ sys.exit(1)
+
+try:
+ srctree = ftptree.FtpTree(sys.argv[1], loadall = True)
+ dsttree = ftptree.FtpTree(sys.argv[2])
+ if archivetreename != None:
+ archivetree = ftptree.FtpTree(archivetreename)
+ else:
+ archivetree = None
+ if nocheckbuild:
+ srctree.do_checkbuild = False
+ pkgs = list(set(sys.argv[3:]))
+ srctree.mark4moving(pkgs)
+
+ srctree.movepkgs(dsttree, archivetree = archivetree)
+except ftptree.SomeError:
+ # In case of problems we need to unlock the trees before exiting
+ ftpio.unlock(sys.argv[1])
+ ftpio.unlock(sys.argv[2])
+ if archivetreename != None:
+ ftpio.unlock(archivetreename)
+ sys.exit(1)
+
+ftpio.unlock(sys.argv[1])
+ftpio.unlock(sys.argv[2])
+if archivetreename != None and archivetreename != sys.argv[1]:
+ ftpio.unlock(archivetreename)
+
+if logs_list == None:
+ sys.exit(0)
+
+print 'Sending mail notification to %s...' % logs_list
+
+pkgs = {}
+
+for pkg in srctree.marked4moving:
+ requesters = []
+ for bid in pkg.build.keys():
+ if pkg.build[bid].requester not in requesters:
+ requesters.append(pkg.build[bid].requester)
+ pkgs[pkg.nvr] = requesters
+
+ftpadmin = "(unknown)"
+try:
+ ftpadmin = os.environ['FTPADM']
+except KeyError, e:
+ pass
+m = Message()
+m.set_headers(
+ to = logs_list,
+ subject = 'MOVED: %s => %s... %d packages' % (sys.argv[1], sys.argv[2], len(pkgs))
+)
+
+m.write(
+ (
+ 'FTP admin %(ftpadmin)s moved from *%(srctree)s* to *%(dsttree)s* %(count)d packages\n\n' +
+ '---- Package name ---- Package built by:\n\n'
+ ) % {
+ 'ftpadmin' : ftpadmin,
+ 'srctree' : sys.argv[1],
+ 'dsttree' : sys.argv[2],
+ 'count' : len(pkgs),
+ }
+)
+
+for nvr in sorted(pkgs.keys()):
+ m.write_line('%s ---- %s' % (nvr, ', '.join(pkgs[nvr])))
+
+m.send()
+
+print 'done.'
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+from common import checkdir
+import ftpio
+
+if len(sys.argv) < 3:
+ print "ERR: not enough parameters given"
+ print "remove.py tree package1 [package2...]"
+ sys.exit(1)
+
+checkdir(sys.argv[1])
+
+ftpio.connect('remove')
+
+if not ftpio.lock(sys.argv[1], True):
+ print "ERR: %s tree already locked" % sys.argv[1]
+ sys.exit(1)
+
+try:
+ tree=ftptree.FtpTree(sys.argv[1])
+ #tree.do_checkbuild=False
+ pkgs = list(set(sys.argv[2:]))
+ tree.mark4removal(pkgs)
+ tree.removepkgs()
+except ftptree.SomeError:
+ # In case of problems we need to unlock the tree before exiting
+ ftpio.unlock(sys.argv[1])
+ sys.exit(1)
+
+ftpio.unlock(sys.argv[1])
+
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+import getopt
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+import getpass
+from common import checkdir
+import ftpio
+from config import sign_key
+from sign import is_signed, signpkgs
+
+os.umask(022)
+
+try:
+ opts, args = getopt.getopt(sys.argv[1:], '')
+except getopt.GetoptError:
+ print >>sys.stderr, "ERR: options error"
+ print >>sys.stderr, "sign.py tree package1 [package2...]"
+ sys.exit(1)
+
+if len(args) < 1:
+ print >>sys.stderr, "ERR: missing tree name"
+ print >>sys.stderr, "sign.py tree package1 [package2...]"
+ sys.exit(1)
+
+if sign_key == None:
+ print >>sys.stderr, "ERR: sign_key not defined in config"
+ sys.exit(1)
+
+treename = args[0]
+packages = args[1:]
+
+checkdir(treename)
+
+ftpio.connect('sign')
+
+if not ftpio.lock(treename, True):
+ print >>sys.stderr, "ERR: %s tree already locked" % treename
+ sys.exit(1)
+
+files = []
+try:
+ if len(packages) < 1:
+ loadall = True
+ else:
+ loadall = False
+
+ # if no files specified, grab whole tree contents
+ tree = ftptree.FtpTree(treename, loadall = loadall)
+ if loadall:
+ # this is hack, should be a param, not access private .loadedpkgs element
+ tree.mark4moving(tree.loadedpkgs)
+ else:
+ tree.mark4moving(packages)
+ files = tree.rpmfiles()
+
+except ftptree.SomeError:
+ # In case of problems we need to unlock the tree before exiting
+ ftpio.unlock(treename)
+ sys.exit(1)
+
+ftpio.unlock(treename)
+
+print "Checking signatures of %d files from %d packages" % (len(files), len(tree.loadedpkgs))
+sign = []
+n = c = 0
+for file in files:
+ if not is_signed(file):
+ sign.append(file)
+ c += 1
+ n += 1
+ print "\r%d/%d %s\033[0K" % (n, c, file),
+
+print ""
+
+if len(sign) == 0:
+ print "No files to sign"
+ sys.exit(0)
+
+# http://mail.python.org/pipermail/python-list/2009-February/700658.html
+def chunk(seq, size, pad=None):
+ '''
+ Slice a list into consecutive disjoint 'chunks' of
+ length equal to size. The last chunk is padded if necessary.
+
+ >>> list(chunk(range(1,10),3))
+ [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
+ >>> list(chunk(range(1,9),3))
+ [[1, 2, 3], [4, 5, 6], [7, 8, None]]
+ >>> list(chunk(range(1,8),3))
+ [[1, 2, 3], [4, 5, 6], [7, None, None]]
+ >>> list(chunk(range(1,10),1))
+ [[1], [2], [3], [4], [5], [6], [7], [8], [9]]
+ >>> list(chunk(range(1,10),9))
+ [[1, 2, 3, 4, 5, 6, 7, 8, 9]]
+ >>> for X in chunk([],3): print X
+ >>>
+ '''
+ n = len(seq)
+ mod = n % size
+ for i in xrange(0, n - mod, size):
+ yield seq[i : i + size]
+ if mod:
+ yield seq[-mod:]
+
+print "Total %d files to sign" % len(sign)
+password = getpass.getpass("Enter signing password: ")
+try:
+ for x in chunk(sign, 512):
+ print "Signing %d files" % len(x)
+ signpkgs(x, password)
+except OSError, e:
+ print >>sys.stderr, "ERR: %s" % e
+ exit(1)
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+from common import checkdir
+import ftpio
+from config import archived_trees, logs_list
+
+if len(sys.argv) < 4:
+ print "ERR: not enough parameters given"
+ print "test-move.py src-tree dst-tree package [package2 package3 ...]"
+ sys.exit(1)
+
+checkdir(sys.argv[1])
+checkdir(sys.argv[2])
+
+if sys.argv[2] in archived_trees:
+ archivetreename = ".archive/" + sys.argv[2]
+ checkdir(archivetreename)
+else:
+ archivetreename = None
+
+ftpio.connect('test-move')
+
+if not ftpio.lock(sys.argv[1], True):
+ print "ERR: %s tree already locked" % sys.argv[1]
+ sys.exit(1)
+
+if not ftpio.lock(sys.argv[2], True):
+ ftpio.unlock(sys.argv[1])
+ print "ERR: %s tree already locked" % sys.argv[2]
+ sys.exit(1)
+
+if archivetreename != None and archivetreename != sys.argv[1] and not ftpio.lock(archivetreename, True):
+ ftpio.unlock(sys.argv[2])
+ ftpio.unlock(sys.argv[1])
+ print "ERR: %s tree already locked" % archivetreename
+ sys.exit(1)
+
+try:
+ srctree = ftptree.FtpTree(sys.argv[1], loadall = True)
+ dsttree = ftptree.FtpTree(sys.argv[2])
+ if archivetreename != None:
+ archivetree = ftptree.FtpTree(archivetreename)
+ else:
+ archivetree = None
+ pkgs = list(set(sys.argv[3:]))
+ srctree.mark4moving(pkgs)
+except ftptree.SomeError:
+ # In case of problems we need to unlock the trees before exiting
+ ftpio.unlock(sys.argv[1])
+ ftpio.unlock(sys.argv[2])
+ if archivetreename != None:
+ ftpio.unlock(archivetreename)
+ sys.exit(1)
+
+# We don't 'try' as in move.py cause this function doesn't force exit
+srctree.testmove(dsttree, archivetree = archivetree)
+
+ftpio.unlock(sys.argv[1])
+ftpio.unlock(sys.argv[2])
+if archivetreename != None and archivetreename != sys.argv[1]:
+ ftpio.unlock(archivetreename)
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import ftptree
+import ftpio
+import config
+
+if len(sys.argv) < 2:
+ print "ERR: not enough parameters given"
+ print "unlock.py tree"
+ sys.exit(1)
+
+for tree in sys.argv[1:]:
+ ftpio.connect()
+ print "Unlock %s: %s" % (tree, ftpio.unlock(sys.argv[1]))
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+# Printing errors (no SyntaxErrors though, but that's not a problem)
+import sys, os
+sys.stderr=sys.stdout
+
+contenttypesent=False
+
+def myexceptionhandler(type, value, traceback):
+ if contenttypesent:
+ print '<pre>'
+ sys.__excepthook__(type, value, traceback)
+ print '</pre>'
+ else:
+ print "Content-Type: text/plain\n"
+ sys.__excepthook__(type, value, traceback)
+ sys.exit(1)
+
+sys.excepthook=myexceptionhandler
+# End printing errors
+
+sys.path.insert(0, '../modules')
+
+import wwwiface, user
+
+opts, cks = wwwiface.getopts()
+u=user.User(cks, opts)
+
+if u.loggedin:
+ wwwiface.addheader('Logged in: '+u.login)
+ wwwiface.addmenu(file='loggedinmenu')
+ import wwwcmds
+ wwwcmds.handlecmds(opts)
+else:
+ wwwiface.addheader('Login form')
+ wwwiface.addcontent(file='regform')
+
+wwwiface.sendhttpheaders()
+contenttypesent=True
+
+wwwiface.sendhtml()
+
--- /dev/null
+You can find a comprehensive description of current features at
+http://cvs.pld-linux.org/cgi-bin/cvsweb/PLD-doc/PLD_2.0_ftp_administration
+
--- /dev/null
+# vim:ft=python
+# see global config for more options: /etc/rpmlint/config
+
+# Configure the checks if you don't want the default ones.
+# --------------------------------------------------------
+
+#addCheck("FHSCheck")
+#addCheck("BinariesCheck")
+
+# Configuration options used by the checks shipped with rpmlint.
+# The values in the commented out setOption() calls represent default
+# or typical example values for the option.
+# -------------------------------------------------------------------
+setOption("UseEnchant", False)
+setOption("UseVersionInChangelog", False)
+
+# Base directory where to extract uninstalled packages while checking.
+# Type: string, default: tempfile.gettempdir()
+#setOption("ExtractDir", "/tmp")
+
+# Output filters.
+# ---------------
+#UseVersionInChangelog
+
+# these are against pld own policy
+addFilter("E: incoherent-version-in-name")
+addFilter("E: no-packager-tag")
+addFilter("E: no-signature")
+addFilter("W: macro-in-%changelog")
+addFilter("W: no-major-in-name")
+addFilter("W: python-bytecode-without-source")
+addFilter("W: requires-on-release")
+addFilter("E: init-script-non-executable /etc/rc.d/init.d/functions")
+
+# hard to fix at this time
+addFilter("E: non-executable-script")
+
+setOption("ValidLicenses", (
+ # These are the short names for all of the PLD Linux approved licenses.
+ 'BSD',
+ 'GPL, Open Data License',
+ 'GPL v2',
+ 'LGPL v2.1',
+ 'LGPL v3',
+ 'MPL v1.1',
+ 'LGPL',
+))
+
+# filter out stuff that is not critical for pkg move bypass
+addFilter("W: no-documentation")
+addFilter("W: no-manual-page-for-binary")
+
+# epoch match error or sth
+#dirac-libs.i486: W: ghost-files-without-postin
+#dirac-devel.i486: W: incoherent-version-dependency-on dirac/dirac-libs/libdirac 1.0.2 0:1.0.2
+addFilter("W: ghost-files-without-postin")
+addFilter("W: incoherent-version-dependency-on")
+
+# we have no strict lib package policy
+addFilter("E: outside-libdir-files")
+addFilter("E: executable-in-library-package")
+
+# not our problem to fix
+addFilter("E: incorrect-fsf-address")
+
+#addFilter("E: backup-file-in-package")
+#addFilter("E: arch-dependent-file-in-usr-share")
+#addFilter("E: world-writable")
+#addFilter("W: unexpanded-macro")
+#addFilter("E: init-script-non-executable")
+#addFilter("E: filename-not-utf8")
+#addFilter("E: info-dir-file")
+#addFilter("E: info-files-without-install-info-post")
+#addFilter("E: init-script-without-chkconfig-postin")
+#addFilter("E: init-script-without-chkconfig-preun")
+#addFilter("E: invalid-desktopfile /usr/share/applications")
+#addFilter("E: invalid-ldconfig-symlink")
+#addFilter("E: invalid-shell-in-")
+#addFilter("E: no-chkconfig-line")
+#addFilter("E: no-description-tag")
+#addFilter("E: no-ldconfig-symlink")
+#addFilter("E: non-empty-%postun")
+#addFilter("E: non-executable-script")
+#addFilter("E: non-ghost-file")
+#addFilter("E: non-root-group-log-file")
+#addFilter("E: non-utf8-desktopfile")
+#addFilter("E: tag-not-utf8")
+#addFilter("W: non-etc-or-var-file-marked-as-conffile")
+#addFilter("W: one-line-command-in-%post")
+#addFilter("W: one-line-command-in-%postun")
+#addFilter("W: one-line-command-in-%trigger")
+#addFilter("W: spurious-bracket-in-%post")
+#addFilter("W: spurious-bracket-in-%trigger")
+#addFilter("W: spurious-executable-perm")
+
+# to get important errors out
+addFilter("E: arch-dependent-file-in-usr-share")
+addFilter("E: arch-independent-package-contains-binary-or-object")
+addFilter("E: binary-or-shlib-defines-rpath")
+addFilter("E: compressed-symlink-with-wrong-ext")
+addFilter("E: description-line-too-long")
+addFilter("E: devel-dependency")
+addFilter("E: dir-or-file-in-home")
+addFilter("E: dir-or-file-in-tmp")
+addFilter("E: dir-or-file-in-usr-local")
+addFilter("E: executable-crontab-file")
+addFilter("E: executable-marked-as-config-file")
+addFilter("E: executable-sourced-script")
+addFilter("E: explicit-lib-dependency")
+addFilter("E: htaccess-file")
+addFilter("E: incoherent-logrotate-file")
+addFilter("E: incoherent-subsys")
+addFilter("E: incorrect-locale-subdir")
+addFilter("E: invalid-directory-reference")
+addFilter("E: invalid-soname")
+addFilter("E: invalid-version")
+addFilter("E: library-not-linked-against-libc")
+addFilter("E: library-without-ldconfig-postin")
+addFilter("E: library-without-ldconfig-postun")
+addFilter("E: menu-in-wrong-dir")
+addFilter("E: missing-PT_GNU_STACK-section")
+addFilter("E: no-binary")
+addFilter("E: no-dependency-on")
+addFilter("E: no-dependency-on locales-")
+addFilter("E: non-root-user-log-file")
+addFilter("E: non-standard-dir-perm")
+addFilter("E: non-standard-executable-perm")
+addFilter("E: non-standard-executable-perm /etc/rc.d/init.d/")
+addFilter("E: non-versioned-file-in-library-package")
+addFilter("E: no-signature")
+addFilter("E: no-status-entry")
+addFilter("E: no-summary-tag")
+addFilter("E: postin-without-chkconfig")
+addFilter("E: postin-without-install-info /usr/share/info")
+addFilter("E: postin-without-ldconfig")
+addFilter("E: postun-without-ldconfig")
+addFilter("E: preun-without-chkconfig")
+addFilter("E: python-bytecode-inconsistent-mtime")
+addFilter("E: rpath-in-buildconfig")
+addFilter("E: script-without-shebang")
+addFilter("E: setgid-binary")
+addFilter("E: setuid-binary")
+addFilter("E: shared-lib-without-dependency-information")
+addFilter("E: shlib-with-non-pic-code")
+addFilter("E: sourced-script-with-shebang")
+addFilter("E: standard-dir-owned-by-package")
+addFilter("E: statically-linked-binary")
+addFilter("E: subdir-in-bin")
+addFilter("E: subsys-not-used")
+addFilter("E: summary-too-long")
+addFilter("E: unknown-key GPG#e4f1bc2d")
+addFilter("E: unknown-lsb-keyword")
+addFilter("E: useless-provides")
+addFilter("E: use-of-home-in-%post")
+addFilter("E: use-old-pam-stack")
+addFilter("E: use-tmp-in-%pre")
+addFilter("E: version-control-internal-file")
+addFilter("E: wrong-script-end-of-line-encoding")
+addFilter("E: wrong-script-interpreter")
+addFilter("E: zero-length")
+addFilter("W: binaryinfo-readelf-failed")
+addFilter("W: binaryinfo-tail-failed")
+addFilter("W: class-path-in-manifest")
+addFilter("W: conffile-without-noreplace-flag")
+addFilter("W: cross-directory-hard-link")
+addFilter("W: dangerous-command-in-")
+addFilter("W: dangling-relative-symlink")
+addFilter("W: dangling-symlink")
+addFilter("W: devel-file-in-non-devel-package")
+addFilter("W: doc-file-dependency")
+addFilter("W: duplicate-executable")
+addFilter("W: executable-stack")
+addFilter("W: filename-too-long-for-joliet")
+addFilter("W: file-not-in-%lang")
+addFilter("W: file-not-utf8")
+addFilter("W: file-not-utf8 /usr/share/doc/")
+addFilter("W: file-not-utf8 /usr/share/man/")
+addFilter("W: hidden-file-or-dir")
+addFilter("W: incoherent-init-script-name")
+addFilter("W: incoherent-subsys")
+addFilter("W: infopage-not-compressed")
+addFilter("W: invalid-license")
+addFilter("W: invalid-url")
+addFilter("W: jar-not-indexed")
+addFilter("W: log-files-without-logrotate")
+addFilter("W: manpage-not-compressed")
+addFilter("W: manual-page-warning /usr/share/man/")
+addFilter("W: missing-lsb-keyword")
+addFilter("W: name-repeated-in-summary")
+addFilter("W: no-default-runlevel")
+addFilter("W: no-dependency-on")
+addFilter("W: non-conffile-in-etc")
+addFilter("W: non-executable-in-bin")
+addFilter("W: non-standard-dir-in-usr")
+addFilter("W: non-standard-dir-in-var")
+addFilter("W: non-standard-gid")
+addFilter("W: non-standard-group")
+addFilter("W: non-standard-uid")
+addFilter("W: no-provides")
+addFilter("W: no-reload-entry")
+addFilter("W: no-soname")
+addFilter("W: no-url-tag")
+addFilter("W: no-version-in-last-changelog")
+addFilter("W: obsolete-not-provided")
+addFilter("W: ocaml-naming-policy-not-applied")
+addFilter("W: only-non-binary-in-usr-lib")
+addFilter("W: percent-in-%post")
+addFilter("W: percent-in-%trigger")
+addFilter("W: perl5-naming-policy-not-applied")
+addFilter("W: postin-without-ghost-file-creation")
+addFilter("W: private-shared-object-provides")
+addFilter("W: python-naming-policy-not-applied")
+addFilter("W: read-error")
+addFilter("W: requires-on-release")
+addFilter("W: service-default-enabled")
+addFilter("W: shared-lib-calls-exit")
+addFilter("W: spelling-error")
+addFilter("W: summary-ended-with-dot")
+addFilter("W: summary-not-capitalized")
+addFilter("W: symlink-should-be-relative")
+addFilter("W: tag-in-description")
+addFilter("W: unable-to-read-zip")
+addFilter("W: uncompressed-zip")
+addFilter("W: unexpanded-macro /usr/share/ri/");
+addFilter("W: unexpanded-macro /var/lib/gdm/.gconf.mandatory/%gconf-tree.xml")
+addFilter("W: unstripped-binary-or-object")
+addFilter("W: wrong-file-end-of-line-encoding")
+addFilter("W: xmms-naming-policy-not-applied")
+addFilter("E: non-readable")
+# kde4-kdenetwork-kppp.x86_64
+addFilter("W: unexpanded-macro /usr/share/apps/kppp/");
+addFilter("kde4-.* W: self-obsoletion");
+
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import sys, os
+sys.path.insert(0, os.environ['HOME']+'/pld-ftp-admin/modules')
+import cons
+
+def daemonize():
+ sys.stdin.close()
+ sys.stdout.close()
+ sys.stderr.close()
+ for fd in range(256):
+ try:
+ os.close(fd)
+ except:
+ pass
+ pid=os.fork()
+ if pid!=0:
+ sys.exit(0)
+ os.setsid()
+
+
+#daemonize()
+
+
+while True:
+ for readable in cons.readables():
+ if readable==cons.privlistener:
+ newsock,addr=readable.accept()
+ cons.add(cons.Connection(newsock, True))
+ elif readable==cons.publistener:
+ newsock,addr=readable.accept()
+ cons.add(cons.Connection(newsock, False))
+ else:
+ readable.handleinput()
+
--- /dev/null
+</body>
+</html>
+
--- /dev/null
+<html>
+
+<head>
+<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
+<title>PLD ftp manager - Th</title>
+<style type="text/css" media="all">@import "../html/layout.css";</style>
+</head>
+
+<body>
+
--- /dev/null
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <link rel="StyleSheet" href="styles.css" type="text/css">
+ <title>PLD Th :: Info Page</title>
+</head>
+<body>
+
+<h3>
+ <a href="http://www.pld-linux.org/ThInfo">About PLD Th</a>
+</h3>
+
+<h3>Builder queue</h3>
+<p>
+<li><a href="http://src.th.pld-linux.org/queue.html">PLD Th</a></li>
+</p>
+
+<h3>Dep checks</h3>
+<p>
+<li><a href="qa.php?q=main">Main deps x86_64</a></li>
+<li><a href="qa.php?q=main-ready">Main ready deps x86_64</a></li>
+<li><a href="qa.php?q=main-ready-test">Main+ready+test deps x86_64</a></li>
+
+<li><a href="qa.php?q=main-i686">Main deps i686</a></li>
+<li><a href="qa.php?q=main-ready-i686">Main ready deps i686</a></li>
+<li><a href="qa.php?q=main-ready-test-i686">Main+ready+test deps i686</a></li>
+
+<li><a href="qa.php?q=main-x32">Main deps x32</a></li>
+<li><a href="qa.php?q=main-ready-x32">Main ready deps x32</a></li>
+<li><a href="qa.php?q=main-ready-test-x32">Main+ready+test deps x32</a></li>
+
+</p>
+
+<h3>Freshness checks</h3>
+<p>
+<li><a href="qa.php?q=ac-th-diff">Differences between AC and TH</a></li>
+<li><a href="qa.php?q=freshness">Th main+test freshness (compare to git)</a></li>
+</p>
+
+<h3>Rpmlint checks</h3>
+<p>
+<li><a href="qa.php?q=lint-PLD">rpmlint: PLD tree</a></li>
+<li><a href="qa.php?q=lint-ready">rpmlint: ready tree</a></li>
+<li><a href="qa.php?q=lint-test">rpmlint: test tree</a></li>
+</p>
+</body>
+</html>
--- /dev/null
+body {\r
+ margin:0px;\r
+ padding:0px;\r
+ font-family:verdana, arial, helvetica, sans-serif;\r
+ color:#333;\r
+ background-color:white;\r
+ }\r
+h1 {\r
+ margin:0px 0px 15px 0px;\r
+ padding:0px;\r
+ font-size:28px;\r
+ line-height:28px;\r
+ font-weight:900;\r
+ color:#ccc;\r
+ }\r
+p {\r
+ font:11px/20px verdana, arial, helvetica, sans-serif;\r
+ margin:0px 0px 16px 0px;\r
+ padding:0px;\r
+ }\r
+#Content>p {margin:0px;}\r
+#Content>p+p {text-indent:30px;}\r
+\r
+a {\r
+ color:#09c;\r
+ font-size:11px;\r
+ text-decoration:none;\r
+ font-weight:600;\r
+ font-family:verdana, arial, helvetica, sans-serif;\r
+ }\r
+a:link {color:#09c;}\r
+a:visited {color:#07a;}\r
+a:hover {background-color:#eee;}\r
+\r
+#Header {\r
+ margin:25px 0px 10px 0px;\r
+ padding:17px 0px 0px 20px;\r
+ /* For IE5/Win's benefit height = [correct height] + [top padding] + [top and bottom border widths] */\r
+ height:33px; /* 14px + 17px + 2px = 33px */\r
+ border-style:solid;\r
+ border-color:black;\r
+ border-width:1px 0px; /* top and bottom borders: 1px; left and right borders: 0px */\r
+ line-height:11px;\r
+ background-color:#eee;\r
+\r
+/* Here is the ugly brilliant hack that protects IE5/Win from its own stupidity. \r
+Thanks to Tantek Celik for the hack and to Eric Costello for publicizing it. \r
+IE5/Win incorrectly parses the "\"}"" value, prematurely closing the style \r
+declaration. The incorrect IE5/Win value is above, while the correct value is \r
+below. See http://glish.com/css/hacks.asp for details. */\r
+ voice-family: "\"}\"";\r
+ voice-family:inherit;\r
+ height:14px; /* the correct height */\r
+ }\r
+/* I've heard this called the "be nice to Opera 5" rule. Basically, it feeds correct \r
+length values to user agents that exhibit the parsing error exploited above yet get \r
+the CSS box model right and understand the CSS2 parent-child selector. ALWAYS include\r
+a "be nice to Opera 5" rule every time you use the Tantek Celik hack (above). */\r
+body>#Header {height:14px;}\r
+\r
+#Content {\r
+ margin:0px 50px 50px 200px;\r
+ padding:10px;\r
+ }\r
+\r
+#Menu {\r
+ position:absolute;\r
+ top:100px;\r
+ left:20px;\r
+ width:172px;\r
+ padding:10px;\r
+ background-color:#eee;\r
+ border:1px dashed #999;\r
+ line-height:17px;\r
+/* Again, the ugly brilliant hack. */\r
+ voice-family: "\"}\"";\r
+ voice-family:inherit;\r
+ width:150px;\r
+ }\r
+/* Again, "be nice to Opera 5". */\r
+body>#Menu {width:150px;}\r
+\r
--- /dev/null
+<a href="index.py?action=logout">Logout</a><br/>
--- /dev/null
+<a href="http://bugs.pld-linux.org/index.php?tasks=all&project=3">Th bugs</a><br/>
+<a href="http://buildlogs.pld-linux.org/">Buildlogs</a><br/>
--- /dev/null
+<html>
+<head>
+<link rel="Shortcut Icon" href="//www.pld-linux.org/favicon.ico"/>
+ <title>PLD QA Reports</title>
+ <link rel="stylesheet" type="text/css" charset="utf-8" media="all" href="//srcbuilder.pld-linux.org/th/style.css">
+ <style>
+ .hidden { display: none; }
+ span#count { font-weight: bold; }
+ </style>
+</head>
+<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
+<script>
+jQuery(function($) {
+ $('#q').on('change', function(e) {
+ var el = e.target;
+ var o = el.options;
+ var v = o[o.selectedIndex].value;
+ location.href = "?q=" + v;
+ });
+
+ var $lines = $('#lines>li');
+ var $count = $('#count');
+ $('#filter').on('keyup', function() {
+ var search = $(this).val();
+ var count = 0;
+ $lines.each(function() {
+ var $line = $(this);
+ var text = $line.text();
+ var fn = text.match(search) && ++count ? 'removeClass' : 'addClass';
+ $line[fn]('hidden');
+ });
+ $count.html(count);
+ });
+ $count.html($lines.length);
+});
+</script>
+<body>
+<?php
+
+$report = isset($_GET['q']) ? basename($_GET['q']) : null;
+$reports = array(
+ "main" => "Main deps x86_64",
+ "main-ready" => "Main ready deps x86_64",
+ "main-ready-test" => "Main+ready+test deps x86_64",
+
+ "main-i686" => "Main deps i686",
+ "main-ready-i686" => "Main ready deps i686",
+ "main-ready-test-i686" => "Main+ready+test deps i686",
+
+ "main-x32" => "Main deps x32",
+ "main-ready-x32" => "Main ready deps x32",
+ "main-ready-test-x32" => "Main+ready+test deps x32",
+
+ "freshness" => "GIT vs FTP freshness",
+
+ "lint-PLD" => "rpmlint: main",
+ "lint-test" => "rpmlint: test",
+ "lint-ready" => "rpmlint: ready",
+);
+
+function reports_selection($reports) {
+ global $report;
+ echo "Select report:";
+ echo "<select id=q name=q>\n";
+ foreach ($reports as $q => $title) {
+ printf("<option value=%s %s>%s</option>\n", $q, $q == $report ? 'selected' :'', $title);
+ }
+ echo "</select>\n";
+}
+
+/**
+ * Create text input for filtering results
+ */
+function filter_box() {
+ echo '<br>Filter results: <input id="filter">';
+ echo '<br><span id="count">?</span> errors';
+}
+
+function format_report($report) {
+ echo "<br>View the <a href=$report.txt>raw</a> report<br/>\n";
+ $file = "$report.txt";
+ $giturl = 'http://git.pld-linux.org/gitweb.cgi?p=packages/%1$s.git;f=%1$s.spec;h=HEAD;a=shortlog';
+ echo '<ol id="lines">';
+ foreach (file($file) as $line) {
+ $line = preg_replace_callback('/^(?P<prefix>error:|GIT:)\s*\[(?P<spec>[^]]+)\]\s*(?P<msg>.+)$/', function($m) use ($giturl) {
+ $package = basename($m['spec'], '.spec');
+ $url = sprintf($giturl, $package);
+ return sprintf('<li><font color=red>%s</font> [<a href="%s">%s</a>] %s', $m['prefix'], $url, $m['spec'], $m['msg']);
+ }, $line);
+ echo $line, "<br/>\n";
+ }
+ echo '</ol>';
+}
+
+reports_selection($reports);
+filter_box();
+if (isset($reports[$report])) {
+ format_report($report);
+}
+
+?>
+</body>
+</html>
--- /dev/null
+<form action="index.py" method="post">
+<input type="hidden" name="action" value="register">
+<label for="login">Username:</label>
+<input type="text" name="login"><br>
+<label for="pass">Password:</label>
+<input type="password" name="pass"><br>
+<input type="submit" value="Log in">
+</form>
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import string, config
+from common import fileexists
+
+class Build:
+ def __init__(self):
+ self.requester=''
+ self.requester_email=''
+
+class BasePkg:
+ def __init__(self, nvr, tree=None, content=None):
+ self.files={}
+ self.info={}
+ self.build={}
+ self.noarch_arch={}
+ self.tree=tree
+ self.nvr=nvr
+ self.load(content)
+
+ def __repr__(self):
+ return self.nvr
+
+ def load(self, content=None):
+ if content:
+ lines=content.splitlines()
+ else:
+ f=open("%s/SRPMS/.metadata/%s.src.rpm.info" %
+ (self.tree.basedir, self.nvr), 'r')
+ lines=f.readlines()
+ f.close()
+
+ for entry in lines:
+ i=string.split(string.strip(entry), ':')
+ if i[0] == 'info':
+ if len(i)==3:
+ self.info[i[1]]=i[2]
+ elif i[1]=='build':
+ if not self.build.has_key(i[2]):
+ self.build[i[2]]=Build()
+ self.lastbid=i[2]
+ if i[3]=='requester':
+ self.build[i[2]].requester=i[4]
+ elif i[3]=='requester_email':
+ self.build[i[2]].requester_email=i[4]
+ elif i[1]=='noarch_arch':
+ self.noarch_arch[i[2]]=i[3]
+ else:
+ self.info[i[1]]=i[2:]
+ elif i[0] == 'file':
+ if not self.files.has_key(i[1]):
+ self.files[i[1]]=[]
+ self.files[i[1]].append(i[2])
+
+class BaseFtpTree:
+ def __init__(self, tree):
+ self.basedir=config.value['ftp_dir']+'/'+tree
+ self.treename=tree
+
+ def __repr__(self):
+ return self.treename
+
+ def has_key(self, key):
+ if fileexists(self.basedir+'/SRPMS/.metadata/'+key+'.src.rpm.info'):
+ return True
+ else:
+ return False
+
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import os
+import time
+import config
+import common
+import md5
+import ftptree
+
+
+def parse(con):
+ if '\0' not in con.data:
+ return
+ cmds=con.data.split('\0')[:-1]
+
+ for cmd in cmds:
+ con.data=con.data[len(cmd)+1:]
+ cmdname=cmd[:4]
+ if not con.authorized and cmdname not in ('linp', 'linc', 'name'):
+ raise BailOut
+ # TODO: log unauthorized access
+ if cmdname in cmdlist_noargs:
+ if len(cmd)==4:
+ cmdlist_noargs[cmdname](con)
+ else:
+ pass
+ # TODO: log malicious msg
+ elif cmdname in cmdlist_args:
+ if len(cmd)>5:
+ cmdlist_args[cmdname](con, cmd[5:])
+ else:
+ pass
+ # TODO: log malicious msg
+ else:
+ raise BailOut
+ # TODO: log this
+
+def lock(con, arg, hard):
+ if arg not in locks:
+ locks[arg]={'hard': hard, 'name': con.name, 'time': int(time.time())}
+ con.sock.send("OK")
+ elif locks[arg]['hard']:
+ con.sock.send("HARD") # Hard lock - you can go get a cup of tea
+ else:
+ con.sock.send("SOFT") # Soft lock - try in a second or two
+
+def cmd_unlock(con, arg):
+ if arg in locks:
+ del locks[arg]
+ con.sock.send("OK")
+ else:
+ con.sock.send("FAIL")
+
+def cmd_lock_soft(con, arg):
+ lock(con, arg, False)
+
+def cmd_lock_hard(con, arg):
+ lock(con, arg, True)
+
+def cmd_show_locks(con):
+ cmd_log(con, "Dumping locks data:");
+ if len(locks):
+ res = ""
+ for lockdata in locks.iteritems():
+ tree, data = lockdata
+ msg = "Tree: %s, Conn name: %s, Hard Lock: %s, Time: %s" % (
+ tree, data['name'], data['hard'], time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(data['time'])))
+ cmd_log(con, msg)
+ res = res + msg
+# con.sock.send("BLOB:%d" % len(res))
+ con.sock.send(res)
+ else:
+ cmd_log(con, "No locks found.");
+ con.sock.send("NLCK");
+
+def cmd_log(con, msg):
+ logfile.write('%s [%s] -- %s\n' % (time.strftime('%Y-%m-%d %H:%M:%S'), con.name, msg))
+ logfile.flush()
+
+def cmd_name(con, name):
+ con.name=name
+
+def load_creds():
+ global users, cookies
+ users={}
+ cookies={}
+ if not common.fileexists(common.ftpadmdir+'/var/passwd'):
+ return
+ else:
+ f=open(common.ftpadmdir+'/var/passwd', 'r')
+ for line in f.xreadlines():
+ x=line.strip().split(':')
+ if len(x)>=2:
+ users[x[0]]=x[1]
+ f.close()
+ if not common.fileexists(common.ftpadmdir+'/var/cookies'):
+ return
+ else:
+ f=open(common.ftpadmdir+'/var/cookies', 'r')
+ for line in f.xreadlines():
+ x=line.strip().split(':')
+ if len(x)>=2:
+ users[x[0]]=x[1]
+ f.close()
+
+def write_cookies():
+ f=open(common.ftpadmdir+'/var/cookies', 'w')
+ for key in cookies.keys():
+ f.write('%s:%s\n' % (key, cookies[key]))
+ f.close()
+
+def cmd_login_passwd(con, data):
+ tmp=data.split('\n')
+ if len(tmp)!=2:
+ raise BailOut
+ login=tmp[0]
+ passwd=tmp[1]
+ md5pass=md5.new(passwd).hexdigest()
+ if login in users and users[login]==md5pass:
+ cookie=`time.time()`.split('.')[0]+'_'+md5.new(md5pass+salt).hexdigest()
+ cookies[cookie]=login
+ write_cookies()
+ con.username=login
+ con.authorized=True
+ con.sock.send('OK '+cookie)
+ else:
+ # TODO: log this
+ con.sock.send('FAIL')
+ raise BailOut
+
+def cmd_login_cookie(con, cookie):
+ if cookie in cookies:
+ con.cookie=cookie
+ con.authorized=True
+ con.username=cookies[cookie]
+ con.sock.send('OK '+cookies[cookie])
+ else:
+ # TODO: log this (or not)
+ con.sock.send('FAIL')
+
+def cmd_logout(con):
+ if con.cookie in cookies:
+ del cookies[con.cookie]
+ write_cookies()
+
+def reloadftptree():
+ global srctree, pkglist
+ srctree=ftptree.FtpTree(config.value['default_to'], loadall=True)
+ pkglist=srctree.keys()
+ pkglist.sort()
+
+def cmd_gettree(con):
+ buf=''
+ for pkgnvr in pkglist:
+ # TODO: show only user's own pkgs
+ pkg=srctree[pkgnvr]
+ line=pkgnvr
+ if pkg.marked4moving:
+ line=line+'\n1'
+ else:
+ line=line+'\n0'
+ if pkg.marked4removal:
+ line=line+'\n1'
+ else:
+ line=line+'\n0'
+ buf=buf+'\0'+line
+ if buf:
+ con.sock.send('%.6d' % (len(buf)-1))
+ con.sock.send(buf[1:])
+ else:
+ con.sock.send('000000')
+
+
+cmdlist_args={'lcks':cmd_lock_soft, 'lckh':cmd_lock_hard, 'ulck':cmd_unlock,
+ 'log1':cmd_log, 'name':cmd_name, 'linp':cmd_login_passwd,
+ 'linc':cmd_login_cookie}
+
+cmdlist_noargs={'lout':cmd_logout, 'gett':cmd_gettree, 'slck':cmd_show_locks}
+
+# Global stuff and initializations
+
+BailOut="BailOut"
+locks={}
+logfile=open(common.ftpadmdir+'/var/log', 'a')
+load_creds()
+reloadftptree()
+salt=md5.new(`time.time()`).hexdigest()
+
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import os, sys, config
+
+def fileexists(path):
+ if path[0] == '/':
+ fullpath = path
+ else:
+ fullpath = config.ftp_dir + path
+ return os.path.exists(fullpath)
+
+def checkdir(dir):
+ if not fileexists(dir):
+ print >>sys.stderr, 'ERR: ' + config.value['ftp_dir']+'/' + dir + " does not exist"
+ sys.exit(1)
+
+if 'HOME' in os.environ:
+ ftpadmdir = os.environ['HOME'] + '/pld-ftp-admin'
+else:
+ ftpadmdir = '..'
+
+# noarchcachedir is dir where noarch files contents are stored for AI
+# XXX: file reference where the AI resides
+noarchcachedir = ftpadmdir + '/var/noarch-cache/'
+
+tmpdir = ftpadmdir + '/var/tmp/'
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import string, os
+
+value = {}
+
+if os.environ.has_key('HOME'):
+ path = os.environ['HOME']
+else:
+ path = '../../' # cgi-bin interface
+
+f = open(path + '/.ftpadmrc', 'r')
+
+for line in f.readlines():
+ if line[0] == '#' or string.find(line, '=') == -1:
+ continue
+ tuple = string.split(string.strip(line), '=')
+ if tuple[1][0] == '"':
+ value[string.strip(tuple[0])] = tuple[1][1:-1]
+ else:
+ value[string.strip(tuple[0])] = string.strip(tuple[1])
+
+f.close()
+
+default_to = value['ftp_dir'] + '/' + value['default_to'] + '/'
+ftp_dir = value['ftp_dir'] + '/'
+incoming_dir = value['ftp_dir'] + '/' + value['incoming_dir'] + '/'
+test_builds_dir = value['ftp_dir'] + '/' + value['test_builds_dir'] + '/'
+ftp_archs = value['ftp_archs'].split(' ')
+
+builderqueue = value['builderqueue']
+
+if 'sign_key' in value:
+ sign_key = value['sign_key']
+else:
+ sign_key = None
+
+if 'logs_list' in value:
+ logs_list = value['logs_list']
+else:
+ logs_list = None
+
+if 'signed_trees' in value:
+ signed_trees = value['signed_trees'].split(' ')
+else:
+ signed_trees = None
+
+if 'archived_trees' in value:
+ archived_trees = value['archived_trees'].split(' ')
+else:
+ archived_trees = None
+
+if 'old_poldek' in value and value['old_poldek'] == 'yes':
+ old_poldek = True
+else:
+ old_poldek = False
+
+if value['separate_noarch'] == 'yes':
+ separate_noarch = True
+else:
+ separate_noarch = False
+
+if value['separate_debuginfo'] == 'yes':
+ separate_debuginfo = True
+else:
+ separate_debuginfo = False
+
+if separate_noarch:
+ all_ftp_archs = ['noarch'] + ftp_archs
+else:
+ all_ftp_archs = ftp_archs
+
+if 'ftp_dist' in value:
+ ftp_dist = value['ftp_dist']
+else:
+ ftp_dist = 'pld'
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import socket
+import os
+import select
+from common import fileexists
+import ftpio
+import cmds
+
+class Connection:
+ def __init__(self, sock, authorized):
+ sock.setblocking(False)
+ self.sock=sock
+ self.authorized=authorized
+ self.fileno=sock.fileno
+ self.name=""
+ self.data=""
+
+ def destroy(self):
+ self.sock.close()
+ rm(self)
+
+ def handleinput(self):
+ newdata = None
+ try:
+ newdata = self.sock.recv(8192)
+ except:
+ self.destroy()
+
+ if not newdata:
+ self.destroy()
+ else:
+ self.data = self.data + newdata
+
+ try:
+ cmds.parse(self)
+ except cmds.BailOut:
+ self.destroy()
+
+def add(con):
+ cons.append(con)
+
+def rm(con):
+ cons.remove(con)
+
+def readables():
+ lst=cons[:]
+ lst.append(privlistener)
+ lst.append(publistener)
+ inlst,outlst,errlst = select.select(lst, [], [], 0.1)
+ return inlst
+
+def createlistener(path):
+ if fileexists(path):
+ os.remove(path)
+
+ s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ s.setblocking(False)
+ s.bind(path)
+ if path==ftpio.pubsock:
+ os.chmod(path, 0606)
+ else:
+ os.chmod(path, 0600)
+ s.listen(3)
+ return s
+
+cons=[]
+
+privlistener=createlistener(ftpio.privsock)
+publistener=createlistener(ftpio.pubsock)
+
+
+
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import os
+import sys
+import socket
+import time
+import config
+
+pubsock=config.value['pubsock']
+
+if os.environ.has_key('HOME'):
+ privsock=os.environ['HOME']+'/pld-ftp-admin/var/privsock'
+ socketname=privsock
+else:
+ socketname=pubsock
+
+def connect(name=None):
+ global sock
+ sock=socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+ sock.connect(socketname)
+ if not name:
+ name = "pid_%d_name_%s" % (os.getpid(), sys.argv[0])
+ sock.send('name %s\0' % name)
+
+def login_passwd(login, passwd):
+ 'Return cookie if ok'
+ sock.send('linp %s\n%s\0' % (login, passwd))
+ retval=sock.recv(256)
+ if retval=='FAIL':
+ return ''
+ else:
+ return retval[3:]
+
+def login_cookie(cookie):
+ 'Return login if ok'
+ sock.send('linc %s\0' % cookie)
+ retval=sock.recv(256)
+ if retval=='FAIL':
+ return ''
+ else:
+ return retval[3:]
+
+def logout():
+ sock.send('lout\0')
+
+def lock(path, hard=False):
+ def dolock():
+ if hard:
+ sock.send('lckh %s\0' % path)
+ else:
+ sock.send('lcks %s\0' % path)
+ return sock.recv(20)
+ for i in range(3):
+ retcode=dolock()
+ if retcode=="OK":
+ return True
+ elif retcode=="HARD":
+ return False
+ if i!=2:
+ time.sleep(1)
+ return False
+
+def unlock(path):
+ sock.send('ulck %s\0' % path)
+ ret = sock.recv(20)
+ if ret == "OK":
+ return True
+ return False
+
+def log(msg):
+ sock.send('log1 %s\0' % msg)
+
+def locks_dump():
+ sock.send('slck\0')
+ ret = sock.recv(4096)
+ if ret == "NLCK":
+ return "No locks held"
+
+# nbytes = int(ret.split("BLOB:")[1])
+# ret = sock.recv(nbytes)
+ return ret
+
+def gettree():
+ sock.send('gett\0')
+ pkgs=[]
+ len=int(sock.recv(6))
+ if len:
+ for pkg in sock.recv(len).split('\0'):
+ tmp=pkg.split('\n')
+ pkgs.append((tmp[0], int(tmp[1]), int(tmp[2])))
+ return pkgs
+
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import os, config, string, urllib, re, rpm
+from common import fileexists, noarchcachedir
+from baseftptree import BasePkg, BaseFtpTree
+from sign import is_signed
+
+errnum = 0
+quietmode = False
+
+class SomeError(Exception):
+ def __init__(self):
+ return
+
+ def __str__(self):
+ print "","An Error occured!"
+
+def bailoutonerror():
+ if not errnum == 0:
+ print "%d error(s) encountered... aborting" % errnum
+ raise SomeError
+
+def pinfo(msg):
+ print 'INFO: ' + msg
+
+def perror(msg):
+ global errnum
+ errnum = errnum + 1
+ print 'ERR: ' + msg
+
+def pwarning(msg):
+ print 'WARN: ' + msg
+
+def rm(file, test = False):
+ if test:
+ if not os.path.exists(file):
+ pinfo("TEST os.remove(%s): file doesn't exists" % file)
+ else:
+ try:
+ os.remove(file)
+ except OSError, e:
+ pinfo("os.remove(%s): %s" % (file, e))
+ #raise
+
+def mv(src, dst, test = False):
+ fsrc = src
+ fdst = dst + '/' + src.split('/')[-1]
+ if test:
+ if not os.path.exists(fsrc):
+ pinfo("TEST os.rename(%s, %s): source doesn't exists" % (fsrc, fdst))
+ if not os.path.exists(dst):
+ pinfo("TEST destination doesn't exist: %s" % dst)
+ else:
+ try:
+ os.rename(fsrc, fdst)
+ except OSError, e:
+ pinfo("os.rename(%s, %s): %s" % (fsrc, fdst, e))
+ raise
+
+class Pkg(BasePkg):
+ def __init__(self, nvr, tree):
+ BasePkg.__init__(self, nvr, tree)
+ self.name = string.join(nvr.split('-')[:-2], '-')
+ self.version = nvr.split('-')[-2]
+ self.release = nvr.split('-')[-1]
+ self.marked4removal = False
+ self.marked4moving = False
+ self.marked4movingpool = []
+ self.errors = []
+ self.warnings = []
+
+ def __cmp__(self, pkg):
+ if self.name > pkg.name:
+ return 1
+ elif self.name < pkg.name:
+ return -1
+ else:
+ return rpm.labelCompare(('0', self.version, self.release),
+ ('0', pkg.version, pkg.release))
+
+
+ # unfortunately can't do new Pkg(NVR), and have no "tree" in this pkg context
+ # so this static function
+ def is_debuginfo(self, nvr):
+ """
+ returns true if NVR is debuginfo package and separate debuginfo is enabled
+ """
+ if not config.separate_debuginfo:
+ return False
+ pkg = nvr.split('-')[:-2]
+ return pkg[-1] == 'debuginfo'
+
+ def is_sourcefile(self, file):
+ """
+ returns true if file is source package
+ """
+ return file[-8:] == '.src.rpm'
+
+ # returns true if package build is integer
+ def is_release(self):
+ """
+ To account Release tags with subver macros, we consider integer release
+ if it contains odd number of dots:
+
+ 1 -> True
+ 0.1 -> False
+ 0.%{subver}.%{rel}, %{rel} = 1 -> 0.20010.1 -> True
+ 0.%{subver}.%{rel}, %{rel} = 0.1 -> 0.20010.0.1 -> False
+ """
+ return self.release.count('.') % 2 == 0
+
+ def mark4moving(self):
+ if not self.marked4moving:
+ # Only one pkg in this pool can be marked for moving
+ for pkg in self.marked4movingpool:
+ pkg.unmark4moving()
+ self.tree.marked4moving.append(self)
+ self.marked4moving=True
+
+ def unmark4moving(self):
+ if self.marked4moving:
+ self.tree.marked4moving.remove(self)
+ self.marked4moving=False
+
+ def mark4removal(self):
+ if not self.marked4removal:
+ self.tree.marked4removal.append(self)
+ self.marked4removal=True
+
+ def error(self, msg):
+ self.errors.append(msg)
+ if not quietmode:
+ perror('%s %s' % (self.nvr, msg))
+
+ def warning(self, msg):
+ self.warnings.append(msg)
+ if not quietmode:
+ pwarning('%s %s' % (self.nvr, msg))
+
+ def load(self, content=None):
+ BasePkg.load(self, content)
+ if self.info.has_key('move'):
+ self.mark4moving()
+
+ def writeinfo(self):
+ f = open(self.tree.basedir+'/SRPMS/.metadata/'+self.nvr+'.src.rpm.info', 'w')
+ for bid in self.build.keys():
+ f.write("info:build:%s:requester:%s\ninfo:build:%s:requester_email:%s\n" % (bid, self.build[bid].requester, bid, self.build[bid].requester_email))
+ for key in self.info.keys():
+ f.write("info:%s:%s\n" % (key, string.join(self.info[key], ':')))
+ for arch in self.files.keys():
+ for rpm in self.files[arch]:
+ f.write("file:%s:%s\n" % (arch, rpm))
+
+ def remove(self, test = False):
+ """
+ Remove package from ftp
+ """
+ for arch in self.files.keys():
+ for rpm in self.files[arch]:
+ if self.is_debuginfo(rpm):
+ rm(self.tree.basedir + '/' + arch + '/debuginfo/' + rpm, test)
+ else:
+ rm(self.tree.basedir + '/' + arch + '/RPMS/' + rpm, test)
+ if arch == 'noarch':
+ if fileexists(noarchcachedir + rpm + '.filelist'):
+ rm(noarchcachedir + rpm + '.filelist', test)
+ if fileexists(noarchcachedir + rpm + '.reqlist'):
+ rm(noarchcachedir + rpm + '.reqlist', test)
+ rm(self.tree.basedir + '/SRPMS/.metadata/' + self.nvr + '.src.rpm.info', test)
+
+ def rpmfiles(self, debugfiles = True, sourcefiles = True):
+ """
+ Return rpm files related to this package
+ """
+ files = []
+ for arch, rpms in self.files.items():
+ for nvr in rpms:
+ if self.is_debuginfo(nvr):
+ if debugfiles:
+ files.append(self.tree.basedir + '/' + arch + '/debuginfo/' + nvr)
+ else:
+ if self.is_sourcefile(nvr):
+ if sourcefiles:
+ files.append(self.tree.basedir + '/' + arch + '/RPMS/' + nvr)
+ else:
+ files.append(self.tree.basedir + '/' + arch + '/RPMS/' + nvr)
+ return files
+
+ def obsoletes(self):
+ """
+ Return obsoletes for all packages in Pkg:
+
+ {'php-geshi': set(['geshi'])}
+
+ """
+ def rpmhdr(pkg):
+ ts = rpm.ts()
+ ts.setVSFlags(rpm.RPMVSF_NODSAHEADER)
+ fdno = os.open(pkg, os.O_RDONLY)
+ hdr = ts.hdrFromFdno(fdno)
+ os.close(fdno)
+ return hdr
+
+ obsoletes = {}
+ for rpmfile in self.rpmfiles():
+ if not os.path.exists(rpmfile):
+ continue
+ hdr = rpmhdr(rpmfile)
+ if not hdr[rpm.RPMTAG_OBSOLETES]:
+ continue
+
+ name = hdr[rpm.RPMTAG_NAME]
+ if not name in obsoletes:
+ obsoletes[name] = set()
+
+ for tag in hdr[rpm.RPMTAG_OBSOLETES]:
+ obsoletes[name].add(tag)
+
+ return obsoletes
+
+ def move(self, dsttree, test = False):
+ if dsttree.has_key(self.nvr):
+ movedany = False
+ for arch in self.files.keys():
+ if arch in dsttree[self.nvr].files.keys():
+ msg = ""
+ if test:
+ msg = "TEST "
+ pinfo("%sArch %s for %s is already present in dest tree; removing from srctree" % (msg, arch, self.nvr))
+ for rpm in self.files[arch]:
+ if self.is_debuginfo(rpm):
+ rm(self.tree.basedir + '/' + arch + '/debuginfo/' + rpm, test)
+ else:
+ rm(self.tree.basedir + '/' + arch + '/RPMS/' + rpm, test)
+ else:
+ movedany = True
+ dsttree[self.nvr].files[arch] = self.files[arch]
+ for rpm in self.files[arch]:
+ if self.is_debuginfo(rpm):
+ mv(self.tree.basedir + '/' + arch + '/debuginfo/' + rpm, dsttree.basedir + '/' + arch + '/debuginfo/', test)
+ else:
+ mv(self.tree.basedir + '/' + arch + '/RPMS/' + rpm, dsttree.basedir + '/' + arch + '/RPMS/', test)
+ if not test and movedany:
+ for bid in self.build.keys():
+ dsttree[self.nvr].build[bid] = self.build[bid]
+ dsttree[self.nvr].writeinfo()
+ rm(self.tree.basedir + '/SRPMS/.metadata/' + self.nvr + '.src.rpm.info', test)
+ else:
+ # move files
+ for arch in self.files.keys():
+ for rpm in self.files[arch]:
+ if self.is_debuginfo(rpm):
+ mv(self.tree.basedir + '/' + arch + '/debuginfo/' + rpm, dsttree.basedir + '/' + arch + '/debuginfo/', test)
+ else:
+ mv(self.tree.basedir + '/' + arch + '/RPMS/' + rpm, dsttree.basedir + '/' + arch + '/RPMS/', test)
+
+ # move metadata
+ mv(self.tree.basedir + '/SRPMS/.metadata/' + self.nvr + '.src.rpm.info', dsttree.basedir + '/SRPMS/.metadata/', test)
+
+class FtpTree(BaseFtpTree):
+ def __init__(self, tree, loadall=False):
+ BaseFtpTree.__init__(self, tree)
+ self.loadedpkgs = {}
+ self.marked4removal = []
+ self.marked4moving = []
+ self.pkgnames = []
+ self.__loadpkgnames()
+ if loadall:
+ for pkgname in self.pkgnames:
+ self.loadedpkgs[pkgname] = Pkg(pkgname, self)
+ # Tests:
+ self.do_checkbuild = True
+
+ def __getitem__(self, key):
+ if self.loadedpkgs.has_key(key):
+ return self.loadedpkgs[key]
+ elif key in self.pkgnames:
+ pkg=Pkg(key, self)
+ self.loadedpkgs[key]=pkg
+ return pkg
+ else:
+ raise KeyError, key
+
+ def has_key(self, key):
+ if key in self.pkgnames:
+ return True
+ else:
+ return False
+
+ def keys(self):
+ return self.pkgnames
+
+ def values(self):
+ return self.loadedpkgs.values()
+
+ def checktree(self, dsttree):
+ self.__checkbuild(self.loadedpkgs.values())
+ self.__checkarchs(dsttree, self.loadedpkgs.values())
+
+ def testmove(self, dsttree, archivetree = None):
+ self.__checkbuild(self.marked4moving)
+ self.__checkarchs(dsttree, self.marked4moving)
+ if not self.treename.count("archive"):
+ self.__checkduplicates(self.marked4moving)
+
+ self.__checksigns(dsttree, self.marked4moving, test = True)
+ self.__checkforobsoletes(dsttree, self.marked4moving, test = True)
+ self.__checkforrelease(dsttree, self.marked4moving, test = True)
+
+ if not self.treename.count("archive"):
+ self.__rmolderfromsrc(test = True)
+ self.__rmotherfromdst(dsttree, test = True, archivetree = archivetree)
+
+ for pkg in self.marked4moving:
+ pkg.move(dsttree, test = True)
+
+ def movepkgs(self, dsttree, archivetree = None):
+ if self.do_checkbuild:
+ self.__checkbuild(self.marked4moving)
+ bailoutonerror()
+
+ self.__checkarchs(dsttree, self.marked4moving)
+ bailoutonerror()
+
+ self.__checksigns(dsttree, self.marked4moving)
+ bailoutonerror()
+
+ if not self.treename.count("archive"):
+ self.__rmolderfromsrc()
+ self.__rmotherfromdst(dsttree, archivetree = archivetree)
+
+ for pkg in self.marked4moving:
+ pkg.move(dsttree)
+
+ def rpmfiles(self, debugfiles = True, sourcefiles = True):
+ if self.do_checkbuild:
+ self.__checkbuild(self.marked4moving)
+
+ files = []
+ for pkg in self.marked4moving:
+ files += pkg.rpmfiles(debugfiles = debugfiles, sourcefiles = sourcefiles)
+ return files
+
+ def removepkgs(self):
+ if self.do_checkbuild:
+ self.__checkbuild(self.marked4removal)
+ bailoutonerror()
+ for pkg in self.marked4removal:
+ pkg.remove()
+
+ def mark4removal(self, wannabepkgs):
+ self.__mark4something(wannabepkgs, Pkg.mark4removal)
+
+ def mark4moving(self, wannabepkgs):
+ self.__mark4something(wannabepkgs, Pkg.mark4moving)
+
+ # Internal functions below
+ def __arch_stringify(self, list):
+ ret = []
+ dist = config.ftp_dist;
+ for arch in list:
+ ret.append(dist + '-' + arch)
+ return ' '.join(ret)
+
+ def __loadpkgnames(self):
+ def checkfiletype(name):
+ if name[-13:]=='.src.rpm.info':
+ return True
+ else:
+ return False
+ list = filter(checkfiletype, os.listdir(self.basedir+'/SRPMS/.metadata'))
+ self.pkgnames = map((lambda x: x[:-13]), list)
+
+ def __mark4something(self, wannabepkgs, markfunction):
+ def chopoffextension(pkg):
+ found = pkg.find('.src.rpm')
+ if found == -1:
+ return pkg
+ else:
+ return pkg[:found]
+
+ for wannabepkg in wannabepkgs:
+ pkgname = chopoffextension(wannabepkg)
+ if pkgname in self.pkgnames:
+ if not pkgname in self.loadedpkgs.keys():
+ self.loadedpkgs[pkgname]=Pkg(pkgname, self)
+ markfunction(self.loadedpkgs[pkgname])
+ else:
+ perror('%s not found in source tree' % pkgname)
+ bailoutonerror()
+
+ def __checkbuild(self, marked):
+ """
+ Checks queue file if all arches are built
+
+ Reads config.builderqueue to grab the info
+ """
+ f = urllib.urlopen(config.builderqueue)
+ requests = {}
+ reid = re.compile(r'^.*id=(.*) pri.*$')
+ regb = re.compile(r'^group:.*$|builders:.*$', re.M)
+ for i in re.findall(regb, f.read()):
+ if i[0] == 'g':
+ id = reid.sub(r'\1', i)
+ requests[id] = ""
+ elif i[0]=='b':
+ requests[id] = requests[id] + i
+ f.close()
+
+ for pkg in marked:
+ for bid in pkg.build.keys():
+ if requests.has_key(bid) and not requests[bid].find('?') == -1:
+ pkg.error("(buildid %s) building not finished" % bid)
+
+ def __checkarchs(self, dsttree, marked):
+ """
+ Checks marked pkgs it is built on all archs.
+ """
+ for pkg in marked:
+ if len(pkg.files.keys()) <= 1:
+ pkg.error('has only src.rpm built')
+ continue
+ otherpkgnames = self.__find_other_pkgs(pkg, dsttree)
+
+ # check if we're not removing some archs
+ if otherpkgnames:
+ curarchs = []
+ missingarchs = []
+ for somepkg in otherpkgnames:
+ curarchs.extend(Pkg(somepkg, dsttree).files.keys())
+ for arch in curarchs:
+ if arch not in pkg.files.keys():
+ missingarchs.append(arch)
+ if missingarchs:
+ pkg.error('moving would remove archs: %s' % self.__arch_stringify(missingarchs))
+ else:
+ # warn if a package isn't built for all archs
+ # ftp_archs + SRPMS
+ ftp_archs_num = len(config.ftp_archs) + 1
+ if (config.separate_noarch and 'noarch' in pkg.files.keys()):
+ # ftp_archs + SRPMS + noarch subpackages
+ ftp_archs_num += 1
+ # plain simple noarch package
+ if (len(pkg.files.keys()) == 2):
+ continue
+
+ if len(pkg.files.keys()) != ftp_archs_num:
+ missingarchs = []
+ for arch in config.ftp_archs:
+ if arch not in pkg.files.keys():
+ missingarchs.append(arch)
+ pkg.warning('not built for archs: %s' % self.__arch_stringify(missingarchs))
+
+ def __checkduplicates(self, marked):
+ """
+ Checks if marked packages contain duplicate packages (with different versions)
+ """
+ for pkg in marked:
+ olderpkgnames = self.__find_older_pkgs(pkg)
+ for i in olderpkgnames:
+ markednames = [str(x) for x in marked]
+ if i in markednames:
+ pkg.error('duplicate package: %s' % i)
+
+ def __rmolderfromsrc(self, test = False):
+ for pkg in self.marked4moving:
+ olderpkgnames = self.__find_older_pkgs(pkg)
+ for i in olderpkgnames:
+ Pkg(i, self).remove(test)
+
+ def __rmotherfromdst(self, dsttree, test = False, archivetree = None):
+ for pkg in self.marked4moving:
+ pkgnames = self.__find_other_pkgs(pkg, dsttree)
+ for i in pkgnames:
+ if archivetree == None:
+ Pkg(i, dsttree).remove(test)
+ else:
+ Pkg(i, dsttree).move(archivetree, test = test)
+
+ # Used more than once filter functions
+ def __find_other_pkgs(self, pkg, tree):
+ escapedpkgname = pkg.name.replace('.', '\.').replace('+', '\+')
+ ziewre = re.compile(escapedpkgname + '-[^-]*-[^-]*$')
+ def filter_other_pkgs(x):
+ if ziewre.match(x) and not x == pkg.nvr:
+ return True
+ else:
+ return False
+ return filter(filter_other_pkgs, tree.pkgnames)
+
+ def __find_older_pkgs(self, pkg):
+ def filter_older_pkgs(x):
+ c = x.split('-')
+ rc = rpm.labelCompare(('0', pkg.version, pkg.release),
+ ('0', c[-2], c[-1]))
+ if rc == 1: # pkg > x
+ return True
+ else:
+ return False
+ return filter(filter_older_pkgs, self.__find_other_pkgs(pkg, self))
+
+ def __checksigns(self, tree, pkgs, test = False):
+ """
+ Checks if pkgs in tree are all signed.
+
+ in case of test = true, error flag is set for unsigned packages
+ """
+ if not tree.treename in config.signed_trees:
+ return
+
+ for pkg in pkgs:
+ unsigned = 0
+ for file in pkg.rpmfiles():
+ if not is_signed(file):
+ unsigned += 1
+
+ if unsigned != 0:
+ if test == True:
+ if not quietmode:
+ pkg.warning('%d files not signed' % unsigned)
+ else:
+ pkg.error('%d files not signed' % unsigned)
+
+ def __checkforobsoletes(self, tree, pkgs, test = False):
+ """
+ Checks queue file if package obsoletes something in destination tree and suggest for removal.
+
+ Only NAME tag is compared, i.e virtual packages do not get reported.
+
+ """
+ if test != True:
+ return
+
+ def findbyname(name):
+ def x(nvr):
+ return '-'.join(nvr.split('-')[:-2]) == name
+ return filter(x, tree.pkgnames)
+
+ for pkg in pkgs:
+ obsoletes = pkg.obsoletes()
+ if not obsoletes:
+ continue
+
+ for pn, setlist in obsoletes.items():
+ for item in setlist:
+ p = findbyname(item)
+ if p:
+ pkg.warning('obsoletes %s (via %s) in dest tree, perhaps you want rmpkg' % (p,pn))
+
+ def __checkforrelease(self, tree, pkgs, test = False):
+ """
+ Checks queue file if package release is non integer.
+
+ """
+ if test != True:
+ return
+
+ for pkg in pkgs:
+ if not pkg.is_release():
+ pkg.warning('non-integer release: %s' % pkg.release)
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import time
+import os
+import sys
+import StringIO
+
+import config
+cval=config.value
+
+class Message:
+ def __init__(self):
+ self.headers = {}
+ self.body = StringIO.StringIO()
+ self.__set_std_headers()
+
+ def set_header(self, n, v):
+ self.headers[n] = v
+
+ def set_headers(self, to = None, cc = None, subject = None):
+ if to != None:
+ self.set_header("To", to)
+ if cc != None:
+ self.set_header("Cc", cc)
+ if subject != None:
+ self.set_header("Subject", subject)
+
+ def write_line(self, l):
+ self.body.write("%s\n" % l)
+
+ def write(self, s):
+ self.body.write(s)
+
+ def send(self):
+ send_sendmail = "/usr/sbin/sendmail -t"
+ f = os.popen(send_sendmail, "w")
+ self.__write_to(f)
+ f.close()
+
+ def __set_std_headers(self):
+ self.headers["Date"] = time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime())
+ self.headers["Message-ID"] = "<pld-builder.%f.%d@%s>" \
+ % (time.time(), os.getpid(), os.uname()[1])
+ self.headers["From"] = cval['from_field']
+ self.headers["X-PLD-Builder"] = cval['xpldbuilder']
+
+ def __write_to(self, f):
+ for k, v in self.headers.items():
+ f.write("%s: %s\n" % (k, v))
+ f.write("\n")
+ self.body.seek(0)
+ self.__sendfile(self.body, f)
+
+ def __sendfile(self, src, dst):
+ cnt = 0
+ while 1:
+ s = src.read(10000)
+ if s == "": break
+ cnt += len(s)
+ dst.write(s)
+ return cnt
+
+
--- /dev/null
+#!/usr/bin/env python
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import os
+import sys
+import rpm
+import pexpect
+from config import sign_key
+
+def getSigInfo(hdr):
+ """checks signature from an hdr hand back signature information and/or
+ an error code"""
+ # yum-3.2.22/rpmUtils/miscutils.py
+
+ string = '%|DSAHEADER?{%{DSAHEADER:pgpsig}}:{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:{%|SIGGPG?{%{SIGGPG:pgpsig}}:{%|SIGPGP?{%{SIGPGP:pgpsig}}:{(none)}|}|}|}|'
+ siginfo = hdr.sprintf(string)
+ if siginfo == '(none)':
+ return None
+
+ return siginfo.split(',')[2].lstrip()
+
+def is_signed(rpm_file):
+ """Returns rpm information is package signed by the same key"""
+ # http://code.activestate.com/recipes/306705/
+
+ if sign_key == None:
+ return None
+
+ ts = rpm.ts()
+ ts.setVSFlags(rpm.RPMVSF_NODSAHEADER)
+ fdno = os.open(rpm_file, os.O_RDONLY)
+ hdr = ts.hdrFromFdno(fdno)
+ os.close(fdno)
+
+ sigid = getSigInfo(hdr)
+ if sigid == None:
+ return None
+
+ return sign_key == sigid[-len(sign_key):]
+
+def signpkgs(files, password):
+ if not os.path.isfile('/usr/bin/gpg'):
+ raise OSError, 'Missing gnupg binary'
+ if not os.path.isfile('/bin/rpm'):
+ raise OSError, 'Missing rpm binary'
+
+ os.putenv('LC_ALL', 'C')
+ args = ['--resign', '--define', '_signature gpg', '--define', '_gpg_name ' + sign_key] + files
+ child = pexpect.spawn('/bin/rpm', args)
+ child.logfile_read = sys.stderr
+ child.expect('Enter pass phrase:', timeout=30)
+ child.sendline(password)
+ child.expect(pexpect.EOF, timeout=None)
+ child.close()
+ rc = child.exitstatus
+ if rc != 0:
+ raise OSError, 'package signing failed'
+ for rpm in files:
+ os.chmod(rpm, 0644)
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import Cookie, time, ftpio
+
+UserNotLoggedIn="UserNotLoggedIn"
+
+class User:
+ def __init__(self, cookies, options):
+ self.loggedin=False
+ ftpio.connect('wwwiface')
+ if 'ftpsessid' in cookies and cookies['ftpsessid']:
+ self.login=ftpio.login_cookie(cookies['ftpsessid'])
+ if self.login:
+ self.loggedin=True
+
+ if 'action' in options:
+ if options['action'] == 'register':
+ self.checkloginpass(options)
+ elif options['action'] == 'logout':
+ self.logout()
+
+ def checkloginpass(self, options):
+ if 'login' not in options or 'pass' not in options:
+ return
+ self.cookie=ftpio.login_passwd(options['login'], options['pass'])
+ if self.cookie:
+ self.login=options['login']
+ self.loggedin=True
+ C = Cookie.SimpleCookie()
+ C['ftpsessid']=self.cookie
+ #C['ftpsessid']['expires']=time.strftime(
+ #"%a, %d-%b-%y %H:%M:%S GMT",
+ #time.gmtime(time.time()+86400))
+ print C
+
+ def logout(self):
+ self.loggedin=False
+ ftpio.logout()
+ C = Cookie.SimpleCookie()
+ C['ftpsessid']=''
+ C['ftpsessid']['expires']=time.strftime("%a, %d-%b-%y %H:%M:%S GMT",
+ time.gmtime(time.time()-31536000))
+ print C
+
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import wwwiface, ftpio
+
+
+def handlecmds(options):
+ def chkbox(pkgname, value):
+ retval='<input type="checkbox" name="%s"' % pkgname
+ if value:
+ retval=retval+' checked="yes"'
+ retval=retval+'>'
+ return retval
+
+ if 'action' in options and options['action'] in actions:
+ pass
+ else:
+ wwwiface.addcontent('<form action="index.py" method="post"><table border="1">')
+ wwwiface.addcontent('<tr><td>Mv</td><td>Rm</td><td>Package</td></tr>')
+ for pkg in ftpio.gettree():
+ wwwiface.addcontent('<tr><td>%s</td><td>%s</td><td>%s</td></tr>' % (chkbox(pkg[0], pkg[1]), chkbox(pkg[0], pkg[2]), pkg[0]))
+ wwwiface.addcontent('<tr><td> </td><td> </td><td><input type="submit" value="Commit"></td></tr>')
+ wwwiface.addcontent('</table></form>')
+
+
+actions={}
+
--- /dev/null
+# vi: encoding=utf-8 ts=8 sts=4 sw=4 et
+
+import cgi, Cookie, os
+
+menu=[]
+content=[]
+header=[]
+
+def getfile(file):
+ f=open("../html/" + file + ".html", 'r')
+ s=f.read()
+ f.close()
+ return s
+
+def catfile(file):
+ f=open("../html/" + file + ".html", 'r')
+ print f.read()
+ f.close()
+
+def sendhttpheaders():
+ print "Content-Type: text/html\n"
+
+def getopts():
+ form = cgi.FieldStorage()
+ opts = {}
+ for key in form.keys():
+ opts[key] = form[key].value
+
+ cookies = {}
+
+ if os.environ.has_key('HTTP_COOKIE'):
+ c = Cookie.SimpleCookie()
+ c.load(os.environ['HTTP_COOKIE'])
+ for key in c.keys():
+ cookies[key] = c[key].value
+
+ return (opts, cookies)
+
+def sendhtml():
+ catfile('header')
+
+ print '<div id="Header">'
+ for i in header:
+ print i
+ print '</div>'
+
+ print '<div id="Menu">'
+ for i in menu:
+ print i
+ catfile('menufooter')
+ print '</div>'
+
+ print '<div id="Content">'
+ for i in content:
+ print i
+ print '</div>'
+
+ catfile('footer')
+
+def addmenu(text=None, file=None):
+ if text:
+ menu.append(text)
+ else:
+ menu.append(getfile(file))
+
+def addheader(text=None, file=None):
+ if text:
+ header.append(text)
+ else:
+ header.append(getfile(file))
+
+def addcontent(text=None, file=None):
+ if text:
+ content.append(text)
+ else:
+ content.append(getfile(file))
+
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd">
+<comps>
+ <group>
+ <id>base</id>
+ <name>Base packages</name>
+ <default>true</default>
+ <uservisible>true</uservisible>
+ <description>Base packages</description>
+ <packagelist>
+ <packagereq type="default">ntp-client</packagereq>
+ <packagereq type="mandatory">FHS</packagereq>
+ <packagereq type="mandatory">SysVinit</packagereq>
+ <packagereq type="mandatory">basesystem</packagereq>
+ <packagereq type="mandatory">chkconfig</packagereq>
+ <packagereq type="mandatory">cpio</packagereq>
+ <packagereq type="default">cracklib</packagereq>
+ <packagereq type="default">cracklib-dicts</packagereq>
+ <packagereq type="default">dhcp-client</packagereq>
+ <packagereq type="default">findutils</packagereq>
+ <packagereq type="mandatory">fix-info-dir</packagereq>
+ <packagereq type="default">geninitrd</packagereq>
+ <packagereq type="default">genromfs</packagereq>
+ <packagereq type="default">gettext</packagereq>
+ <packagereq type="mandatory">glibc</packagereq>
+ <packagereq type="default">glibc-localedb-all</packagereq>
+ <packagereq type="default">grep</packagereq>
+ <packagereq type="default">grubby</packagereq>
+ <packagereq type="default">gzip</packagereq>
+ <packagereq type="default">iproute2</packagereq>
+ <packagereq type="mandatory">issue</packagereq>
+ <packagereq type="default">kbd</packagereq>
+ <packagereq type="default">kernel</packagereq>
+ <packagereq type="optional">libstdc++</packagereq>
+ <packagereq type="default">login</packagereq>
+ <packagereq type="mandatory">logrotate</packagereq>
+ <packagereq type="optional">losetup</packagereq>
+ <packagereq type="optional">mawk</packagereq>
+ <packagereq type="mandatory">mingetty</packagereq>
+ <packagereq type="mandatory">mktemp</packagereq>
+ <packagereq type="mandatory">module-init-tools</packagereq>
+ <packagereq type="mandatory">mount</packagereq>
+ <packagereq type="default">net-tools</packagereq>
+ <packagereq type="mandatory">pam</packagereq>
+ <packagereq type="mandatory">pciutils</packagereq>
+ <packagereq type="mandatory">pdksh</packagereq>
+ <packagereq type="default">poldek</packagereq>
+ <packagereq type="default">procps</packagereq>
+ <packagereq type="mandatory">rc-scripts</packagereq>
+ <packagereq type="default">rpm</packagereq>
+ <packagereq type="default">sed</packagereq>
+ <packagereq type="optional">setserial</packagereq>
+ <packagereq type="mandatory">setup</packagereq>
+ <packagereq type="default">syslog-ng</packagereq>
+ <packagereq type="mandatory">pwdutils</packagereq>
+ <packagereq type="optional">tar</packagereq>
+ <packagereq type="mandatory">tzdata</packagereq>
+ <packagereq type="optional">tzdata-zoneinfo_right</packagereq>
+ <packagereq type="mandatory">udev</packagereq>
+ <packagereq type="default">utempter</packagereq>
+ <packagereq type="mandatory">util-linux-ng</packagereq>
+ <packagereq type="optional">vim-static</packagereq>
+ <packagereq type="default">vixie-cron</packagereq>
+ <packagereq type="default">which</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>basic</id>
+ <name>Programs you're unlikely not to need.</name>
+ <default>true</default>
+ <uservisible>true</uservisible>
+ <description>Programs you're unlikely not to need.</description>
+ <packagelist>
+ <packagereq type="default">mailx</packagereq>
+ <packagereq type="default">nc</packagereq>
+ <packagereq type="default">psmisc</packagereq>
+ <packagereq type="default">terminfo</packagereq>
+ <packagereq type="optional">rpm-utils</packagereq>
+ <packagereq type="default">telnet</packagereq>
+ <packagereq type="default">tcp_wrappers</packagereq>
+ <packagereq type="optional">sharutils</packagereq>
+ <packagereq type="default">file</packagereq>
+ <packagereq type="optional">ftp</packagereq>
+ <packagereq type="default">less</packagereq>
+ <packagereq type="optional">time</packagereq>
+ <packagereq type="optional">iputils</packagereq>
+ <packagereq type="default">iputils-ping</packagereq>
+ <packagereq type="default">mtr</packagereq>
+ <packagereq type="default">bash</packagereq>
+ <packagereq type="default">bzip2</packagereq>
+ <packagereq type="default">vim</packagereq>
+ <packagereq type="default">vim-rt</packagereq>
+ <packagereq type="default">openssh-clients</packagereq>
+ <packagereq type="default">tmpwatch</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>backup_tools</id>
+ <name>Backup tools</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Backup tools</description>
+ <packagelist>
+ <packagereq type="default">afio</packagereq>
+ <packagereq type="default">amanda-client</packagereq>
+ <packagereq type="default">amanda-server</packagereq>
+ <packagereq type="default">mt-st</packagereq>
+ <packagereq type="default">dump</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>extras1</id>
+ <name>Not essential, but *very* often needed.</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Not essential, but *very* often needed.</description>
+ <packagelist>
+ <packagereq type="optional">dhcpcd</packagereq>
+ <packagereq type="optional">pump</packagereq>
+ <packagereq type="default">MAKEDEV</packagereq>
+ <packagereq type="default">bind-utils</packagereq>
+ <packagereq type="default">hexedit</packagereq>
+ <packagereq type="default">info</packagereq>
+ <packagereq type="default">lftp</packagereq>
+ <packagereq type="default">ltrace</packagereq>
+ <packagereq type="default">lsof</packagereq>
+ <packagereq type="default">lynx</packagereq>
+ <packagereq type="default">man</packagereq>
+ <packagereq type="default">man-pages</packagereq>
+ <packagereq type="default">mc</packagereq>
+ <packagereq type="optional">mutt</packagereq>
+ <packagereq type="default">ncftp</packagereq>
+ <packagereq type="optional">ncompress</packagereq>
+ <packagereq type="optional">nmap</packagereq>
+ <packagereq type="default">openssh-server</packagereq>
+ <packagereq type="default">pcregrep</packagereq>
+ <packagereq type="default">perl</packagereq>
+ <packagereq type="default">pinfo</packagereq>
+ <packagereq type="optional">pine</packagereq>
+ <packagereq type="optional">acpid</packagereq>
+ <packagereq type="optional">quota</packagereq>
+ <packagereq type="optional">rsync</packagereq>
+ <packagereq type="default">slocate</packagereq>
+ <packagereq type="default">strace</packagereq>
+ <packagereq type="default">tcpdump</packagereq>
+ <packagereq type="default">unzip</packagereq>
+ <packagereq type="default">wget</packagereq>
+ <packagereq type="optional">zsh</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>nfs</id>
+ <name>Network File Systems stuff</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Network File Systems stuff</description>
+ <packagelist>
+ <packagereq type="default">portmap</packagereq>
+ <packagereq type="default">nfs-utils</packagereq>
+ <packagereq type="default">nfs-utils-clients</packagereq>
+ <packagereq type="default">nfs-utils-lock</packagereq>
+ <packagereq type="optional">samba</packagereq>
+ <packagereq type="optional">samba-client</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>servers</id>
+ <name>Various servers</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Various servers</description>
+ <packagelist>
+ <packagereq type="optional">proftpd-standalone</packagereq>
+ <packagereq type="optional">proftpd-inetd</packagereq>
+ <packagereq type="optional">pure-ftpd</packagereq>
+ <packagereq type="optional">ftpd-BSD</packagereq>
+ <packagereq type="optional">exim</packagereq>
+ <packagereq type="optional">postfix</packagereq>
+ <packagereq type="optional">sendmail</packagereq>
+ <packagereq type="optional">omta</packagereq>
+ <packagereq type="optional">cfingerd</packagereq>
+ <packagereq type="optional">efingerd</packagereq>
+ <packagereq type="optional">ffingerd</packagereq>
+ <packagereq type="optional">bsd-fingerd</packagereq>
+ <packagereq type="optional">xinetd</packagereq>
+ <packagereq type="optional">rlinetd</packagereq>
+ <packagereq type="optional">inetd</packagereq>
+ <packagereq type="optional">telnetd</packagereq>
+ <packagereq type="optional">cvs-pserver</packagereq>
+ <packagereq type="optional">rsyncd-standalone</packagereq>
+ <packagereq type="optional">rsyncd-inetd</packagereq>
+ <packagereq type="optional">cups</packagereq>
+ <packagereq type="optional">dhcp</packagereq>
+ <packagereq type="optional">bircd</packagereq>
+ <packagereq type="optional">ircd</packagereq>
+ <packagereq type="optional">ircd-hybrid</packagereq>
+ <packagereq type="optional">ircd-ptlink</packagereq>
+ <packagereq type="optional">inn</packagereq>
+ <packagereq type="optional">imap</packagereq>
+ <packagereq type="optional">courier-imap</packagereq>
+ <packagereq type="optional">cyrus-imapd</packagereq>
+ <packagereq type="optional">imap-pop3</packagereq>
+ <packagereq type="optional">courier-imap-pop3</packagereq>
+ <packagereq type="optional">solid-pop3d</packagereq>
+ <packagereq type="optional">tpop3d</packagereq>
+ <packagereq type="optional">vm-pop3d-standalone</packagereq>
+ <packagereq type="optional">bind</packagereq>
+ <packagereq type="optional">pdns</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>irc</id>
+ <name>Client packages for IRC</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Client packages for IRC</description>
+ <packagelist>
+ <packagereq type="optional">ircii</packagereq>
+ <packagereq type="optional">irssi</packagereq>
+ <packagereq type="optional">BitchX</packagereq>
+ <packagereq type="optional">epic4</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>console</id>
+ <name>Utilites usable at Linux' console</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Utilites usable at Linux' console</description>
+ <packagelist>
+ <packagereq type="optional">open</packagereq>
+ <packagereq type="optional">SVGATextMode</packagereq>
+ <packagereq type="optional">fbset</packagereq>
+ <packagereq type="default">gpm</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>mp3</id>
+ <name>MPEG II Layer 3 encoding/decoding</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>MPEG II Layer 3 encoding/decoding</description>
+ <packagelist>
+ <packagereq type="optional">mpg123</packagereq>
+ <packagereq type="optional">bladeenc</packagereq>
+ <packagereq type="optional">lame</packagereq>
+ <packagereq type="optional">cdparanoia-III</packagereq>
+ <packagereq type="optional">cdrtools-cdda2wav</packagereq>
+ <packagereq type="optional">mp3blaster</packagereq>
+ <packagereq type="optional">ripenc</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>apache_base</id>
+ <name>Apache 2.2.x web server base packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Apache 2.2.x web server base packages</description>
+ <packagelist>
+ <packagereq type="default">apache</packagereq>
+ <packagereq type="default">apache-errordocs</packagereq>
+ <packagereq type="default">apache-index</packagereq>
+ <packagereq type="default">apache-mod_alias</packagereq>
+ <packagereq type="default">apache-mod_auth</packagereq>
+ <packagereq type="default">apache-mod_auth_basic</packagereq>
+ <packagereq type="default">apache-mod_authn_default</packagereq>
+ <packagereq type="default">apache-mod_authn_file</packagereq>
+ <packagereq type="default">apache-mod_authz_default</packagereq>
+ <packagereq type="default">apache-mod_authz_groupfile</packagereq>
+ <packagereq type="default">apache-mod_authz_host</packagereq>
+ <packagereq type="default">apache-mod_authz_owner</packagereq>
+ <packagereq type="default">apache-mod_authz_user</packagereq>
+ <packagereq type="default">apache-mod_autoindex</packagereq>
+ <packagereq type="default">apache-mod_deflate</packagereq>
+ <packagereq type="default">apache-mod_dir</packagereq>
+ <packagereq type="default">apache-mod_env</packagereq>
+ <packagereq type="default">apache-mod_include</packagereq>
+ <packagereq type="default">apache-mod_log_config</packagereq>
+ <packagereq type="default">apache-mod_mime</packagereq>
+ <packagereq type="default">apache-mod_mime_magic</packagereq>
+ <packagereq type="default">apache-mod_negotiation</packagereq>
+ <packagereq type="default">apache-mod_rewrite</packagereq>
+ <packagereq type="default">apache-mod_setenvif</packagereq>
+ <packagereq type="default">apache-mod_speling</packagereq>
+ <packagereq type="default">apache-mod_userdir</packagereq>
+ <packagereq type="default">apache-mod_version</packagereq>
+ <packagereq type="default">apache-mod_vhost_alias</packagereq>
+ <packagereq type="default">apache-tools</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>apache_mod</id>
+ <name>Apache 2.2.x additional packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Apache 2.2.x additional packages</description>
+ <packagelist>
+ <packagereq type="optional">apache-apxs</packagereq>
+ <packagereq type="optional">apache-cgi_test</packagereq>
+ <packagereq type="optional">apache-dbmtools</packagereq>
+ <packagereq type="optional">apache-doc</packagereq>
+ <packagereq type="optional">apache-mod_actions</packagereq>
+ <packagereq type="optional">apache-mod_cern_meta</packagereq>
+ <packagereq type="optional">apache-mod_asis</packagereq>
+ <packagereq type="optional">apache-mod_auth_dbm</packagereq>
+ <packagereq type="optional">apache-mod_auth_digest</packagereq>
+ <packagereq type="optional">apache-mod_authn_alias</packagereq>
+ <packagereq type="optional">apache-mod_authn_anon</packagereq>
+ <packagereq type="optional">apache-mod_authn_dbd</packagereq>
+ <packagereq type="optional">apache-mod_authn_dbm</packagereq>
+ <packagereq type="optional">apache-mod_authnz_ldap</packagereq>
+ <packagereq type="optional">apache-mod_authz_dbm</packagereq>
+ <packagereq type="optional">apache-mod_cache</packagereq>
+ <packagereq type="optional">apache-mod_case_filter</packagereq>
+ <packagereq type="optional">apache-mod_case_filter_in</packagereq>
+ <packagereq type="optional">apache-mod_cgi</packagereq>
+ <packagereq type="optional">apache-mod_cgid</packagereq>
+ <packagereq type="optional">apache-mod_charset_lite</packagereq>
+ <packagereq type="optional">apache-mod_dav</packagereq>
+ <packagereq type="optional">apache-mod_dbd</packagereq>
+ <packagereq type="optional">apache-mod_dumpio</packagereq>
+ <packagereq type="optional">apache-mod_echo</packagereq>
+ <packagereq type="optional">apache-mod_expires</packagereq>
+ <packagereq type="optional">apache-mod_ext_filter</packagereq>
+ <packagereq type="optional">apache-mod_file_cache</packagereq>
+ <packagereq type="optional">apache-mod_filter</packagereq>
+ <packagereq type="optional">apache-mod_headers</packagereq>
+ <packagereq type="optional">apache-mod_ident</packagereq>
+ <packagereq type="optional">apache-mod_imagemap</packagereq>
+ <packagereq type="optional">apache-mod_info</packagereq>
+ <packagereq type="optional">apache-mod_ldap</packagereq>
+ <packagereq type="optional">apache-mod_log_forensic</packagereq>
+ <packagereq type="optional">apache-mod_logio</packagereq>
+ <packagereq type="optional">apache-mod_proxy</packagereq>
+ <packagereq type="optional">apache-mod_ssl</packagereq>
+ <packagereq type="optional">apache-mod_status</packagereq>
+ <packagereq type="optional">apache-mod_unique_id</packagereq>
+ <packagereq type="optional">apache-mod_usertrack</packagereq>
+ <packagereq type="optional">apache-suexec</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>apache1_base</id>
+ <name>Apache 1.3.x web server base packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Apache 1.3.x web server base packages</description>
+ <packagelist>
+ <packagereq type="default">apache1</packagereq>
+ <packagereq type="default">apache1-errordocs</packagereq>
+ <packagereq type="default">apache1-index</packagereq>
+ <packagereq type="default">apache1-mod_access</packagereq>
+ <packagereq type="default">apache1-mod_asis</packagereq>
+ <packagereq type="default">apache1-mod_auth</packagereq>
+ <packagereq type="default">apache1-mod_autoindex</packagereq>
+ <packagereq type="default">apache1-mod_cern_meta</packagereq>
+ <packagereq type="default">apache1-mod_cgi</packagereq>
+ <packagereq type="default">apache1-mod_dir</packagereq>
+ <packagereq type="default">apache1-mod_env</packagereq>
+ <packagereq type="default">apache1-mod_log_config</packagereq>
+ <packagereq type="default">apache1-mod_mime</packagereq>
+ <packagereq type="default">apache1-mod_mime_magic</packagereq>
+ <packagereq type="default">apache1-mod_negotiation</packagereq>
+ <packagereq type="default">apache1-mod_rewrite</packagereq>
+ <packagereq type="default">apache1-mod_setenvif</packagereq>
+ <packagereq type="default">apache1-mod_speling</packagereq>
+ <packagereq type="default">apache1-mod_ssl</packagereq>
+ <packagereq type="default">apache1-mod_userdir</packagereq>
+ <packagereq type="default">apache1-mod_vhost_alias</packagereq>
+ <packagereq type="default">apache1-tools</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>apache1_mod</id>
+ <name>Apache 1.3.x additional packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Apache 1.3.x additional packages</description>
+ <packagelist>
+ <packagereq type="optional">apache1-apxs</packagereq>
+ <packagereq type="optional">apache1-doc</packagereq>
+ <packagereq type="optional">apache1-mod_actions</packagereq>
+ <packagereq type="optional">apache1-mod_alias</packagereq>
+ <packagereq type="optional">apache1-mod_auth_anon</packagereq>
+ <packagereq type="optional">apache1-mod_auth_db</packagereq>
+ <packagereq type="optional">apache1-mod_auth_digest</packagereq>
+ <packagereq type="optional">apache1-mod_define</packagereq>
+ <packagereq type="optional">apache1-mod_digest</packagereq>
+ <packagereq type="optional">apache1-mod_expires</packagereq>
+ <packagereq type="optional">apache1-mod_headers</packagereq>
+ <packagereq type="optional">apache1-mod_imap</packagereq>
+ <packagereq type="optional">apache1-mod_include</packagereq>
+ <packagereq type="optional">apache1-mod_info</packagereq>
+ <packagereq type="optional">apache1-mod_log_agent</packagereq>
+ <packagereq type="optional">apache1-mod_log_forensic</packagereq>
+ <packagereq type="optional">apache1-mod_log_referer</packagereq>
+ <packagereq type="optional">apache1-mod_mmap_static</packagereq>
+ <packagereq type="optional">apache1-mod_proxy</packagereq>
+ <packagereq type="optional">apache1-mod_status</packagereq>
+ <packagereq type="optional">apache1-mod_sxnet</packagereq>
+ <packagereq type="optional">apache1-mod_unique_id</packagereq>
+ <packagereq type="optional">apache1-mod_usertrack</packagereq>
+ <packagereq type="optional">apache1-suexec</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>php_base</id>
+ <name>PHP 5.x, base packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>PHP 5.x, base packages</description>
+ <packagelist>
+ <packagereq type="optional">apache-mod_php</packagereq>
+ <packagereq type="optional">apache1-mod_php</packagereq>
+ <packagereq type="optional">php-cgi</packagereq>
+ <packagereq type="optional">php-cli</packagereq>
+ <packagereq type="default">php-common</packagereq>
+ <packagereq type="optional">php-curl</packagereq>
+ <packagereq type="optional">php-gettext</packagereq>
+ <packagereq type="optional">php-iconv</packagereq>
+ <packagereq type="optional">php-mbstring</packagereq>
+ <packagereq type="optional">php-mime_magic</packagereq>
+ <packagereq type="optional">php-msession</packagereq>
+ <packagereq type="optional">php-openssl</packagereq>
+ <packagereq type="optional">php-readline</packagereq>
+ <packagereq type="optional">php-sysvmsg</packagereq>
+ <packagereq type="optional">php-sysvsem</packagereq>
+ <packagereq type="optional">php-sysvshm</packagereq>
+ <packagereq type="optional">php-tokenizer</packagereq>
+ <packagereq type="optional">php-zlib</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>php_add</id>
+ <name>PHP 5.x, additional packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>PHP 5.x, additional packages</description>
+ <packagelist>
+ <packagereq type="optional">php-bcmath</packagereq>
+ <packagereq type="optional">php-bzip2</packagereq>
+ <packagereq type="optional">php-calendar</packagereq>
+ <packagereq type="optional">php-ctype</packagereq>
+ <packagereq type="optional">php-dba</packagereq>
+ <packagereq type="optional">php-dbase</packagereq>
+ <packagereq type="optional">php-dom</packagereq>
+ <packagereq type="optional">php-exif</packagereq>
+ <packagereq type="optional">php-fcgi</packagereq>
+ <packagereq type="optional">php-filepro</packagereq>
+ <packagereq type="optional">php-ftp</packagereq>
+ <packagereq type="optional">php-gd</packagereq>
+ <packagereq type="optional">php-gmp</packagereq>
+ <packagereq type="optional">php-imap</packagereq>
+ <packagereq type="optional">php-interbase</packagereq>
+ <packagereq type="optional">php-ldap</packagereq>
+ <packagereq type="optional">php-mcrypt</packagereq>
+ <packagereq type="optional">php-mhash</packagereq>
+ <packagereq type="optional">php-ming</packagereq>
+ <packagereq type="optional">php-mssql</packagereq>
+ <packagereq type="optional">php-mysql</packagereq>
+ <packagereq type="optional">php-mysqli</packagereq>
+ <packagereq type="optional">php-ncurses</packagereq>
+ <packagereq type="optional">php-odbc</packagereq>
+ <packagereq type="optional">php-pcntl</packagereq>
+ <packagereq type="optional">php-pdo</packagereq>
+ <packagereq type="optional">php-pdo-dblib</packagereq>
+ <packagereq type="optional">php-pdo-firebird</packagereq>
+ <packagereq type="optional">php-pdo-mysql</packagereq>
+ <packagereq type="optional">php-pdo-odbc</packagereq>
+ <packagereq type="optional">php-pdo-pgsql</packagereq>
+ <packagereq type="optional">php-pdo-sqlite</packagereq>
+ <packagereq type="optional">php-pgsql</packagereq>
+ <packagereq type="optional">php-posix</packagereq>
+ <packagereq type="optional">php-program</packagereq>
+ <packagereq type="optional">php-pspell</packagereq>
+ <packagereq type="optional">php-recode</packagereq>
+ <packagereq type="optional">php-shmop</packagereq>
+ <packagereq type="optional">php-snmp</packagereq>
+ <packagereq type="optional">php-soap</packagereq>
+ <packagereq type="optional">php-sockets</packagereq>
+ <packagereq type="optional">php-sqlite</packagereq>
+ <packagereq type="optional">php-sybase-ct</packagereq>
+ <packagereq type="optional">php-sybase</packagereq>
+ <packagereq type="optional">php-tidy</packagereq>
+ <packagereq type="optional">php-wddx</packagereq>
+ <packagereq type="optional">php-xml</packagereq>
+ <packagereq type="optional">php-xmlreader</packagereq>
+ <packagereq type="optional">php-xmlrpc</packagereq>
+ <packagereq type="optional">php-xsl</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>mysql</id>
+ <name>MySQL database server</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>MySQL database server</description>
+ <packagelist>
+ <packagereq type="default">mysql</packagereq>
+ <packagereq type="default">mysql-client</packagereq>
+ <packagereq type="default">mysql-libs</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>mysql_extras</id>
+ <name>MySQL extras</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>MySQL extras</description>
+ <packagelist>
+ <packagereq type="optional">mysql-bench</packagereq>
+ <packagereq type="optional">mysql-extras</packagereq>
+ <packagereq type="optional">mysql-extras-perl</packagereq>
+ <packagereq type="optional">mysql-ndb</packagereq>
+ <packagereq type="optional">mysql-ndb-client</packagereq>
+ <packagereq type="optional">mysql-ndb-cpc</packagereq>
+ <packagereq type="optional">mysql-ndb-mgm</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>pgsql</id>
+ <name>PostgreSQL database server</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>PostgreSQL database server</description>
+ <packagelist>
+ <packagereq type="default">postgresql</packagereq>
+ <packagereq type="default">postgresql-clients</packagereq>
+ <packagereq type="default">postgresql-libs</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>pgsql_extras</id>
+ <name>PostgreSQL extras</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>PostgreSQL extras</description>
+ <packagelist>
+ <packagereq type="optional">postgresql-doc</packagereq>
+ <packagereq type="optional">postgresql-ecpg</packagereq>
+ <packagereq type="optional">postgresql-module-lo</packagereq>
+ <packagereq type="optional">postgresql-module-pgcrypto</packagereq>
+ <packagereq type="optional">postgresql-module-plperl</packagereq>
+ <packagereq type="optional">postgresql-module-plpgsql</packagereq>
+ <packagereq type="optional">postgresql-module-plpython</packagereq>
+ <packagereq type="optional">postgresql-module-pltcl</packagereq>
+ <packagereq type="optional">postgresql-module-tsearch2</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>crunchers</id>
+ <name>Packages for (de)compressing using strange formats</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Packages for (de)compressing using strange formats</description>
+ <packagelist>
+ <packagereq type="default">zip</packagereq>
+ <packagereq type="optional">unzip</packagereq>
+ <packagereq type="default">unace</packagereq>
+ <packagereq type="default">unrar</packagereq>
+ <packagereq type="default">unarj</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>xemacs</id>
+ <name>XEmacs editor/environment</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>XEmacs editor/environment</description>
+ <packagelist>
+ <packagereq type="default">xemacs</packagereq>
+ <packagereq type="optional">xemacs-Sun-pkg</packagereq>
+ <packagereq type="default">xemacs-auctex-pkg</packagereq>
+ <packagereq type="default">xemacs-cc-mode-pkg</packagereq>
+ <packagereq type="default">xemacs-common</packagereq>
+ <packagereq type="default">xemacs-debug-pkg</packagereq>
+ <packagereq type="default">xemacs-dired-pkg</packagereq>
+ <packagereq type="default">xemacs-edit-utils-pkg</packagereq>
+ <packagereq type="default">xemacs-eterm-pkg</packagereq>
+ <packagereq type="default">xemacs-extras</packagereq>
+ <packagereq type="default">xemacs-fsf-compat-pkg</packagereq>
+ <packagereq type="default">xemacs-games-pkg</packagereq>
+ <packagereq type="default">xemacs-ispell-pkg</packagereq>
+ <packagereq type="default">xemacs-jde-pkg</packagereq>
+ <packagereq type="default">xemacs-mail-lib-pkg</packagereq>
+ <packagereq type="default">xemacs-mailcrypt-pkg</packagereq>
+ <packagereq type="default">xemacs-mh-e-pkg</packagereq>
+ <packagereq type="optional">xemacs-nox</packagereq>
+ <packagereq type="default">xemacs-parigp-mode-pkg</packagereq>
+ <packagereq type="default">xemacs-pc-pkg</packagereq>
+ <packagereq type="default">xemacs-psgml-pkg</packagereq>
+ <packagereq type="default">xemacs-sgml-pkg</packagereq>
+ <packagereq type="default">xemacs-spec-mode-pkg</packagereq>
+ <packagereq type="default">xemacs-speedbar-pkg</packagereq>
+ <packagereq type="default">xemacs-text-modes-pkg</packagereq>
+ <packagereq type="default">xemacs-vc-pkg</packagereq>
+ <packagereq type="default">xemacs-w3-pkg</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>devel</id>
+ <name>Basic programs needed for compilation.</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Basic programs needed for compilation.</description>
+ <packagelist>
+ <packagereq type="default">glibc-devel</packagereq>
+ <packagereq type="default">autoconf</packagereq>
+ <packagereq type="default">automake</packagereq>
+ <packagereq type="default">bison</packagereq>
+ <packagereq type="default">cpp</packagereq>
+ <packagereq type="optional">cproto</packagereq>
+ <packagereq type="default">ctags</packagereq>
+ <packagereq type="default">cvs</packagereq>
+ <packagereq type="default">gcc</packagereq>
+ <packagereq type="default">make</packagereq>
+ <packagereq type="default">binutils</packagereq>
+ <packagereq type="default">flex</packagereq>
+ <packagereq type="default">kernel-headers</packagereq>
+ <packagereq type="optional">gcc-c++</packagereq>
+ <packagereq type="optional">objc</packagereq>
+ <packagereq type="optional">gcc-objc</packagereq>
+ <packagereq type="default">patch</packagereq>
+ <packagereq type="default">diffutils</packagereq>
+ <packagereq type="default">m4</packagereq>
+ <packagereq type="default">perl-devel</packagereq>
+ <packagereq type="optional">rpm-build</packagereq>
+ <packagereq type="default">ncurses-devel</packagereq>
+ <packagereq type="default">bin86</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>devel_extras</id>
+ <name>Packages needed for real development.</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Packages needed for real development.</description>
+ <packagelist>
+ <packagereq type="default">gdb</packagereq>
+ <packagereq type="optional">lcc</packagereq>
+ <packagereq type="default">ElectricFence</packagereq>
+ <packagereq type="optional">ddd</packagereq>
+ <packagereq type="default">diffstat</packagereq>
+ <packagereq type="default">doxygen</packagereq>
+ <packagereq type="default">indent</packagereq>
+ <packagereq type="default">nasm</packagereq>
+ <packagereq type="optional">ocaml</packagereq>
+ <packagereq type="optional">python</packagereq>
+ <packagereq type="optional">python-devel</packagereq>
+ <packagereq type="optional">python-doc</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>java</id>
+ <name>Packages needed for JAVA development.</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Packages needed for JAVA development.</description>
+ <packagelist>
+ <packagereq type="default">kaffe</packagereq>
+ <packagereq type="default">jikes</packagereq>
+ <packagereq type="optional">gcc-java</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>xwindow</id>
+ <name>X Window System</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>X Window System</description>
+ <packagelist>
+ <packagereq type="default">xinitrc-ng</packagereq>
+ <packagereq type="default">xorg-app-appres</packagereq>
+ <packagereq type="default">xorg-app-bitmap</packagereq>
+ <packagereq type="default">xorg-app-editres</packagereq>
+ <packagereq type="default">xorg-app-iceauth</packagereq>
+ <packagereq type="default">xorg-app-lbxproxy</packagereq>
+ <packagereq type="default">xorg-app-luit</packagereq>
+ <packagereq type="default">xorg-app-mkfontdir</packagereq>
+ <packagereq type="default">xorg-app-mkfontscale</packagereq>
+ <packagereq type="default">xorg-app-proxymngr</packagereq>
+ <packagereq type="default">xorg-app-rgb</packagereq>
+ <packagereq type="default">xorg-app-rstart</packagereq>
+ <packagereq type="default">xorg-app-scripts</packagereq>
+ <packagereq type="default">xorg-app-setxkbmap</packagereq>
+ <packagereq type="default">xorg-app-smproxy</packagereq>
+ <packagereq type="default">xorg-app-x11perf</packagereq>
+ <packagereq type="default">xorg-app-xclipboard</packagereq>
+ <packagereq type="default">xorg-app-xcmsdb</packagereq>
+ <packagereq type="default">xorg-app-xconsole</packagereq>
+ <packagereq type="default">xorg-app-xcursorgen</packagereq>
+ <packagereq type="default">xorg-app-xditview</packagereq>
+ <packagereq type="default">xorg-app-xdpyinfo</packagereq>
+ <packagereq type="default">xorg-app-xf86dga</packagereq>
+ <packagereq type="default">xorg-app-xfindproxy</packagereq>
+ <packagereq type="default">xorg-app-xfwp</packagereq>
+ <packagereq type="default">xorg-app-xgamma</packagereq>
+ <packagereq type="default">xorg-app-xhost</packagereq>
+ <packagereq type="default">xorg-app-xinit</packagereq>
+ <packagereq type="default">xorg-app-xkbevd</packagereq>
+ <packagereq type="default">xorg-app-xkbprint</packagereq>
+ <packagereq type="default">xorg-app-xkbutils</packagereq>
+ <packagereq type="default">xorg-app-xlsatoms</packagereq>
+ <packagereq type="default">xorg-app-xlsclients</packagereq>
+ <packagereq type="default">xorg-app-xlsfonts</packagereq>
+ <packagereq type="default">xorg-app-xmh</packagereq>
+ <packagereq type="default">xorg-app-xmodmap</packagereq>
+ <packagereq type="default">xorg-app-xprop</packagereq>
+ <packagereq type="default">xorg-app-xrandr</packagereq>
+ <packagereq type="default">xorg-app-xrdb</packagereq>
+ <packagereq type="default">xorg-app-xrefresh</packagereq>
+ <packagereq type="default">xorg-app-xrx</packagereq>
+ <packagereq type="default">xorg-app-xset</packagereq>
+ <packagereq type="default">xorg-app-xsetmode</packagereq>
+ <packagereq type="default">xorg-app-xsetpointer</packagereq>
+ <packagereq type="default">xorg-app-xsetroot</packagereq>
+ <packagereq type="default">xorg-app-xsm</packagereq>
+ <packagereq type="default">xorg-app-xstdcmap</packagereq>
+ <packagereq type="default">xorg-app-xvidtune</packagereq>
+ <packagereq type="default">xorg-app-xvinfo</packagereq>
+ <packagereq type="default">xorg-app-xwd</packagereq>
+ <packagereq type="default">xorg-app-xwud</packagereq>
+ <packagereq type="default">xorg-data-xbitmaps</packagereq>
+ <packagereq type="default">xorg-docs</packagereq>
+ <packagereq type="default">xorg-lib-libXpm-utils</packagereq>
+ <packagereq type="default">xorg-util-imake</packagereq>
+ <packagereq type="default">xorg-util-lndir</packagereq>
+ <packagereq type="default">xorg-xserver-Xprt</packagereq>
+ <packagereq type="default">xorg-xserver-server</packagereq>
+ <packagereq type="default">Mesa-libGL</packagereq>
+ <packagereq type="default">Mesa-libGLU</packagereq>
+ <packagereq type="default">Mesa-utils</packagereq>
+ <packagereq type="default">Mesa-libGL-devel</packagereq>
+ <packagereq type="default">Mesa-libGL-static</packagereq>
+ <packagereq type="default">xorg-xserver-Xnest</packagereq>
+ <packagereq type="default">xorg-xserver-Xprt</packagereq>
+ <packagereq type="default">xorg-xserver-server</packagereq>
+ <packagereq type="default">xorg-xserver-Xvfb</packagereq>
+ <packagereq type="default">xorg-app-bdftopcf</packagereq>
+ <packagereq type="default">xorg-lib-libFS-devel</packagereq>
+ <packagereq type="default">xorg-lib-libICE-devel</packagereq>
+ <packagereq type="default">xorg-lib-libSM-devel</packagereq>
+ <packagereq type="default">xorg-lib-libX11-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXau-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXaw-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXcomposite-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXcursor-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXdamage-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXdmcp-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXevie-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXfixes-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXfont-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXft-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXmu-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXpm-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXprintAppUtil-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXprintUtil-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXrandr-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXrender-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXres-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXt-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXv-devel</packagereq>
+ <packagereq type="default">xorg-lib-libXvMC-devel</packagereq>
+ <packagereq type="default">xorg-lib-libfontenc-devel</packagereq>
+ <packagereq type="default">xorg-lib-liboldX-devel</packagereq>
+ <packagereq type="default">xorg-lib-libxkbfile-devel</packagereq>
+ <packagereq type="default">xorg-lib-libxkbui-devel</packagereq>
+ <packagereq type="default">xorg-proto-applewmproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-bigreqsproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-compositeproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-damageproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-dmxproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-evieext-devel</packagereq>
+ <packagereq type="default">xorg-proto-fixesproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-fontcacheproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-fontsproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-inputproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-kbproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-printproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-randrproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-recordproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-renderproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-resourceproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-scrnsaverproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-trapproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-videoproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-windowswmproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xcmiscproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xextproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xf86bigfontproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xf86dgaproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xf86miscproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xf86rushproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xf86vidmodeproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xineramaproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xproto-devel</packagereq>
+ <packagereq type="default">xorg-proto-xproxymanagementprotocol-devel</packagereq>
+ <packagereq type="default">xorg-xserver-server-devel</packagereq>
+ <packagereq type="default">xorg-driver-video-apm</packagereq>
+ <packagereq type="default">xorg-driver-video-ark</packagereq>
+ <packagereq type="default">xorg-driver-video-ati</packagereq>
+ <packagereq type="default">xorg-driver-video-ati</packagereq>
+ <packagereq type="default">xorg-driver-video-ati</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-rage128</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-radeon-R100</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-radeon-R200</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-radeon-R300</packagereq>
+ <packagereq type="default">xorg-driver-video-chips</packagereq>
+ <packagereq type="default">xorg-driver-video-cirrus</packagereq>
+ <packagereq type="default">xorg-driver-video-cyrix</packagereq>
+ <packagereq type="default">xorg-driver-video-fbdev</packagereq>
+ <packagereq type="default">xorg-driver-video-voodoo</packagereq>
+ <packagereq type="default">xorg-driver-video-glint</packagereq>
+ <packagereq type="default">xorg-driver-video-i128</packagereq>
+ <packagereq type="default">xorg-xserver-server</packagereq>
+ <packagereq type="default">xorg-driver-video-i740</packagereq>
+ <packagereq type="default">xorg-driver-video-i810</packagereq>
+ <packagereq type="default">Mesa-dri-driver-intel-i810</packagereq>
+ <packagereq type="default">Mesa-dri-driver-intel-i915</packagereq>
+ <packagereq type="default">Mesa-dri-driver-intel-i965</packagereq>
+ <packagereq type="default">xorg-driver-video-mga</packagereq>
+ <packagereq type="default">Mesa-dri-driver-matrox</packagereq>
+ <packagereq type="default">xorg-driver-video-neomagic</packagereq>
+ <packagereq type="default">xorg-driver-video-newport</packagereq>
+ <packagereq type="default">xorg-driver-video-nsc</packagereq>
+ <packagereq type="default">xorg-driver-video-nv</packagereq>
+ <packagereq type="default">xorg-driver-video-rendition</packagereq>
+ <packagereq type="default">Mesa-dri-driver-s3virge</packagereq>
+ <packagereq type="default">xorg-driver-video-s3virge</packagereq>
+ <packagereq type="default">xorg-driver-video-s3</packagereq>
+ <packagereq type="default">Mesa-dri-driver-savage</packagereq>
+ <packagereq type="default">xorg-driver-video-savage</packagereq>
+ <packagereq type="default">xorg-driver-video-siliconmotion</packagereq>
+ <packagereq type="default">xorg-driver-video-sis</packagereq>
+ <packagereq type="default">Mesa-dri-driver-sis</packagereq>
+ <packagereq type="default">xorg-driver-video-sisusb</packagereq>
+ <packagereq type="default">xorg-driver-video-sunbw2</packagereq>
+ <packagereq type="default">xorg-driver-video-suncg14</packagereq>
+ <packagereq type="default">xorg-driver-video-suncg3</packagereq>
+ <packagereq type="default">xorg-driver-video-suncg6</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ffb</packagereq>
+ <packagereq type="default">xorg-driver-video-sunffb</packagereq>
+ <packagereq type="default">xorg-driver-video-sunleo</packagereq>
+ <packagereq type="default">xorg-driver-video-suntcx</packagereq>
+ <packagereq type="default">xorg-driver-video-tdfx</packagereq>
+ <packagereq type="default">Mesa-dri-driver-tdfx</packagereq>
+ <packagereq type="default">xorg-driver-video-tga</packagereq>
+ <packagereq type="default">Mesa-dri-driver-trident</packagereq>
+ <packagereq type="default">xorg-driver-video-trident</packagereq>
+ <packagereq type="default">xorg-driver-video-tseng</packagereq>
+ <packagereq type="default">Mesa-dri-driver-via-unichrome</packagereq>
+ <packagereq type="default">xorg-driver-video-via</packagereq>
+ <packagereq type="default">xorg-driver-video-vmware</packagereq>
+ <packagereq type="default">xorg-app-bitmap</packagereq>
+ <packagereq type="default">xorg-app-xditview</packagereq>
+ <packagereq type="default">xorg-app-xmh</packagereq>
+ <packagereq type="default">xorg-data-xbitmaps</packagereq>
+ <packagereq type="default">xorg-app-xkbcomp</packagereq>
+ <packagereq type="default">xorg-driver-input-keyboard</packagereq>
+ <packagereq type="default">xorg-driver-input-mouse</packagereq>
+ <packagereq type="default">xorg-driver-video-v4l</packagereq>
+ <packagereq type="default">xorg-driver-video-vesa</packagereq>
+ <packagereq type="default">xorg-driver-video-vga</packagereq>
+ <packagereq type="default">xorg-xserver-server</packagereq>
+ <packagereq type="default">xorg-lib-libFS-static</packagereq>
+ <packagereq type="default">xorg-lib-libICE-static</packagereq>
+ <packagereq type="default">xorg-lib-libSM-static</packagereq>
+ <packagereq type="default">xorg-lib-libX11-static</packagereq>
+ <packagereq type="default">xorg-lib-libXScrnSaver-static</packagereq>
+ <packagereq type="default">xorg-lib-libXTrap-static</packagereq>
+ <packagereq type="default">xorg-lib-libXau-static</packagereq>
+ <packagereq type="default">xorg-lib-libXcomposite-static</packagereq>
+ <packagereq type="default">xorg-lib-libXcursor-static</packagereq>
+ <packagereq type="default">xorg-lib-libXdamage-static</packagereq>
+ <packagereq type="default">xorg-lib-libXdmcp-static</packagereq>
+ <packagereq type="default">xorg-lib-libXevie-static</packagereq>
+ <packagereq type="default">xorg-lib-libXext-static</packagereq>
+ <packagereq type="default">xorg-lib-libXfixes-static</packagereq>
+ <packagereq type="default">xorg-lib-libXfont-static</packagereq>
+ <packagereq type="default">xorg-lib-libXfontcache-static</packagereq>
+ <packagereq type="default">xorg-lib-libXft-static</packagereq>
+ <packagereq type="default">xorg-lib-libXi-static</packagereq>
+ <packagereq type="default">xorg-lib-libXinerama-static</packagereq>
+ <packagereq type="default">xorg-lib-libXmu-static</packagereq>
+ <packagereq type="default">xorg-lib-libXp-static</packagereq>
+ <packagereq type="default">xorg-lib-libXpm-static</packagereq>
+ <packagereq type="default">xorg-lib-libXrandr-static</packagereq>
+ <packagereq type="default">xorg-lib-libXrender-static</packagereq>
+ <packagereq type="default">xorg-lib-libXres-static</packagereq>
+ <packagereq type="default">xorg-lib-libXt-static</packagereq>
+ <packagereq type="default">xorg-lib-libXtst-static</packagereq>
+ <packagereq type="default">xorg-lib-libXv-static</packagereq>
+ <packagereq type="default">xorg-lib-libXvMC-static</packagereq>
+ <packagereq type="default">xorg-lib-libXxf86dga-static</packagereq>
+ <packagereq type="default">xorg-lib-libXxf86misc-static</packagereq>
+ <packagereq type="default">xorg-lib-libXxf86vm-static</packagereq>
+ <packagereq type="default">xorg-lib-libfontenc-static</packagereq>
+ <packagereq type="default">xorg-lib-libxkbfile-static</packagereq>
+ <packagereq type="default">xorg-lib-libxkbui-static</packagereq>
+ <packagereq type="default">xorg-app-beforelight</packagereq>
+ <packagereq type="default">xorg-app-ico</packagereq>
+ <packagereq type="default">xorg-app-listres</packagereq>
+ <packagereq type="default">xorg-app-oclock</packagereq>
+ <packagereq type="default">xorg-app-showfont</packagereq>
+ <packagereq type="default">xorg-app-viewres</packagereq>
+ <packagereq type="default">xorg-app-x11perf</packagereq>
+ <packagereq type="default">xorg-app-xbiff</packagereq>
+ <packagereq type="default">xorg-app-xcalc</packagereq>
+ <packagereq type="default">xorg-app-xclipboard</packagereq>
+ <packagereq type="default">xorg-app-xclock</packagereq>
+ <packagereq type="default">xorg-app-xdbedizzy</packagereq>
+ <packagereq type="default">xorg-app-xditview</packagereq>
+ <packagereq type="default">xorg-app-xdriinfo</packagereq>
+ <packagereq type="default">xorg-app-xedit</packagereq>
+ <packagereq type="default">xorg-app-xev</packagereq>
+ <packagereq type="default">xorg-app-xeyes</packagereq>
+ <packagereq type="default">xorg-app-xfd</packagereq>
+ <packagereq type="default">xorg-app-xfontsel</packagereq>
+ <packagereq type="default">xorg-app-xgc</packagereq>
+ <packagereq type="default">xorg-app-xkill</packagereq>
+ <packagereq type="default">xorg-app-xload</packagereq>
+ <packagereq type="default">xorg-app-xlogo</packagereq>
+ <packagereq type="default">xorg-app-xmag</packagereq>
+ <packagereq type="default">xorg-app-xman</packagereq>
+ <packagereq type="default">xorg-app-xmessage</packagereq>
+ <packagereq type="default">xorg-app-xmh</packagereq>
+ <packagereq type="default">xorg-app-xmore</packagereq>
+ <packagereq type="default">xorg-app-xphelloworld</packagereq>
+ <packagereq type="default">xorg-app-xplsprinters</packagereq>
+ <packagereq type="default">xorg-app-xpr</packagereq>
+ <packagereq type="default">xorg-app-xprehashprinterlist</packagereq>
+ <packagereq type="default">xorg-app-xprop</packagereq>
+ <packagereq type="default">xorg-app-xtrap</packagereq>
+ <packagereq type="default">xorg-app-xwininfo</packagereq>
+ <packagereq type="default">xorg-util-gccmakedep</packagereq>
+ <packagereq type="default">xorg-util-imake</packagereq>
+ <packagereq type="default">xorg-app-sessreg</packagereq>
+ <packagereq type="default">xorg-app-twm</packagereq>
+ <packagereq type="default">xorg-app-xauth</packagereq>
+ <packagereq type="default">xorg-app-xdm</packagereq>
+ <packagereq type="default">xorg-app-xfs</packagereq>
+ <packagereq type="default">xorg-font-encodings</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-type1</packagereq>
+ <packagereq type="default">xorg-font-font-arabic-misc</packagereq>
+ <packagereq type="default">xorg-font-font-bh-ttf</packagereq>
+ <packagereq type="default">xorg-font-font-bh-type1</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-type1</packagereq>
+ <packagereq type="default">xorg-font-font-daewoo-misc</packagereq>
+ <packagereq type="default">xorg-font-font-dec-misc</packagereq>
+ <packagereq type="default">xorg-font-font-ibm-type1</packagereq>
+ <packagereq type="default">xorg-font-font-isas-misc</packagereq>
+ <packagereq type="default">xorg-font-font-micro-misc</packagereq>
+ <packagereq type="default">xorg-font-font-misc-ethiopic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-meltho</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc</packagereq>
+ <packagereq type="default">xorg-font-font-mutt-misc</packagereq>
+ <packagereq type="default">xorg-font-font-schumacher-misc</packagereq>
+ <packagereq type="default">xorg-font-font-sony-misc</packagereq>
+ <packagereq type="default">xorg-font-font-sun-misc</packagereq>
+ <packagereq type="default">xorg-font-font-xfree86-type1</packagereq>
+ <packagereq type="default">xorg-font-font-util</packagereq>
+ <packagereq type="default">xorg-font-font-cursor-misc</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-base</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-1</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-2</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-3</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-4</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-5</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-7</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-8</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-9</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-10</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-11</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-13</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-14</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-15</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-16</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-lucidatypewriter-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-lucidatypewriter-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-jis-misc</packagereq>
+ <packagereq type="default">xorg-font-font-cronyx-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-screen-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-winitzki-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-ethiopic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-meltho</packagereq>
+ <packagereq type="default">X11-DPS</packagereq>
+ <packagereq type="default">xorg-xserver-server</packagereq>
+ <packagereq type="default">Mesa-libGL</packagereq>
+ <packagereq type="default">Mesa-libGLU</packagereq>
+ <packagereq type="default">Mesa-utils</packagereq>
+ <packagereq type="default">xorg-xserver-Xnest</packagereq>
+ <packagereq type="default">xorg-xserver-Xprt</packagereq>
+ <packagereq type="default">xorg-xserver-Xprt</packagereq>
+ <packagereq type="default">xorg-xserver-server</packagereq>
+ <packagereq type="default">xorg-xserver-server-devel</packagereq>
+ <packagereq type="default">xorg-xserver-Xvfb</packagereq>
+ <packagereq type="default">X11-common</packagereq>
+ <packagereq type="default">xorg-driver-video-apm</packagereq>
+ <packagereq type="default">xorg-driver-video-ark</packagereq>
+ <packagereq type="default">xorg-driver-video-ati</packagereq>
+ <packagereq type="default">xorg-driver-video-chips</packagereq>
+ <packagereq type="default">xorg-driver-video-cirrus</packagereq>
+ <packagereq type="default">xorg-driver-video-cyrix</packagereq>
+ <packagereq type="default">X11-driver-evdev</packagereq>
+ <packagereq type="default">xorg-driver-video-fbdev</packagereq>
+ <packagereq type="default">xorg-driver-video-voodoo</packagereq>
+ <packagereq type="default">xorg-driver-video-glint</packagereq>
+ <packagereq type="default">xorg-driver-video-i128</packagereq>
+ <packagereq type="default">xorg-driver-video-i740</packagereq>
+ <packagereq type="default">xorg-driver-video-i810</packagereq>
+ <packagereq type="default">Mesa-dri-driver-intel-i810</packagereq>
+ <packagereq type="default">Mesa-dri-driver-intel-i915</packagereq>
+ <packagereq type="default">Mesa-dri-driver-intel-i965</packagereq>
+ <packagereq type="default">xorg-driver-video-mga</packagereq>
+ <packagereq type="default">Mesa-dri-driver-matrox</packagereq>
+ <packagereq type="default">xorg-driver-video-neomagic</packagereq>
+ <packagereq type="default">xorg-driver-video-nsc</packagereq>
+ <packagereq type="default">xorg-driver-video-nv</packagereq>
+ <packagereq type="default">xorg-driver-video-ati</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-rage128</packagereq>
+ <packagereq type="default">xorg-driver-video-ati</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-radeon-R100</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-radeon-R200</packagereq>
+ <packagereq type="default">Mesa-dri-driver-ati-radeon-R300</packagereq>
+ <packagereq type="default">xorg-driver-video-rendition</packagereq>
+ <packagereq type="default">Mesa-dri-driver-s3virge</packagereq>
+ <packagereq type="default">xorg-driver-video-s3virge</packagereq>
+ <packagereq type="default">xorg-driver-video-s3</packagereq>
+ <packagereq type="default">Mesa-dri-driver-s3virge</packagereq>
+ <packagereq type="default">xorg-driver-video-s3virge</packagereq>
+ <packagereq type="default">Mesa-dri-driver-savage</packagereq>
+ <packagereq type="default">xorg-driver-video-savage</packagereq>
+ <packagereq type="default">xorg-driver-video-siliconmotion</packagereq>
+ <packagereq type="default">xorg-driver-video-sis</packagereq>
+ <packagereq type="default">Mesa-dri-driver-sis</packagereq>
+ <packagereq type="default">xorg-driver-video-sisusb</packagereq>
+ <packagereq type="default">xorg-driver-video-tdfx</packagereq>
+ <packagereq type="default">Mesa-dri-driver-tdfx</packagereq>
+ <packagereq type="default">xorg-driver-video-tga</packagereq>
+ <packagereq type="default">Mesa-dri-driver-trident</packagereq>
+ <packagereq type="default">xorg-driver-video-trident</packagereq>
+ <packagereq type="default">xorg-driver-video-tseng</packagereq>
+ <packagereq type="default">Mesa-dri-driver-via-unichrome</packagereq>
+ <packagereq type="default">xorg-driver-video-via</packagereq>
+ <packagereq type="default">xorg-driver-video-vmware</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-lucidatypewriter-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-100dpi</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-1</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-10</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-13</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-14</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-15</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-2</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-3</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-4</packagereq>
+ <packagereq type="default">X11-fonts-100dpi-ISO8859-9</packagereq>
+ <packagereq type="default">xorg-font-encodings</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-type1</packagereq>
+ <packagereq type="default">xorg-font-font-arabic-misc</packagereq>
+ <packagereq type="default">xorg-font-font-bh-ttf</packagereq>
+ <packagereq type="default">xorg-font-font-bh-type1</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-type1</packagereq>
+ <packagereq type="default">xorg-font-font-daewoo-misc</packagereq>
+ <packagereq type="default">xorg-font-font-dec-misc</packagereq>
+ <packagereq type="default">xorg-font-font-ibm-type1</packagereq>
+ <packagereq type="default">xorg-font-font-isas-misc</packagereq>
+ <packagereq type="default">xorg-font-font-micro-misc</packagereq>
+ <packagereq type="default">xorg-font-font-misc-ethiopic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-meltho</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc</packagereq>
+ <packagereq type="default">xorg-font-font-mutt-misc</packagereq>
+ <packagereq type="default">xorg-font-font-schumacher-misc</packagereq>
+ <packagereq type="default">xorg-font-font-sony-misc</packagereq>
+ <packagereq type="default">xorg-font-font-sun-misc</packagereq>
+ <packagereq type="default">xorg-font-font-xfree86-type1</packagereq>
+ <packagereq type="default">xorg-font-font-util</packagereq>
+ <packagereq type="default">xorg-font-font-cursor-misc</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-base</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-1</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-2</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-3</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-4</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-5</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-7</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-8</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-9</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-10</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-11</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-13</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-14</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-15</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-16</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-lucidatypewriter-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-lucidatypewriter-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-100dpi</packagereq>
+ <packagereq type="default">xorg-font-font-jis-misc</packagereq>
+ <packagereq type="default">xorg-font-font-cronyx-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-screen-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-winitzki-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-ethiopic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-meltho</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-adobe-utopia-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bh-lucidatypewriter-75dpi</packagereq>
+ <packagereq type="default">xorg-font-font-bitstream-75dpi</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-1</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-10</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-13</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-14</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-15</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-2</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-3</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-4</packagereq>
+ <packagereq type="default">X11-fonts-75dpi-ISO8859-9</packagereq>
+ <packagereq type="default">xorg-font-font-misc-ethiopic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-1</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-10</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-11</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-13</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-14</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-15</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-16</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-10</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-11</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-13</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-14</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-15</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-16</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-2</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-3</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-4</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-5</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-7</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-8</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-ISO8859-9</packagereq>
+ <packagereq type="default">xorg-font-font-jis-misc</packagereq>
+ <packagereq type="default">xorg-font-font-cronyx-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-screen-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-winitzki-cyrillic</packagereq>
+ <packagereq type="default">xorg-font-font-misc-meltho</packagereq>
+ <packagereq type="default">xorg-font-font-cursor-misc</packagereq>
+ <packagereq type="default">xorg-font-font-misc-misc-base</packagereq>
+ <packagereq type="default">xorg-font-font-util</packagereq>
+ <packagereq type="default">xorg-util-gccmakedep</packagereq>
+ <packagereq type="default">xorg-util-imake</packagereq>
+ <packagereq type="default">X11-input-synaptics</packagereq>
+ <packagereq type="default">xorg-app-bitmap</packagereq>
+ <packagereq type="default">xorg-app-xditview</packagereq>
+ <packagereq type="default">xorg-app-xmh</packagereq>
+ <packagereq type="default">xorg-data-xbitmaps</packagereq>
+ <packagereq type="default">xorg-app-xkbcomp</packagereq>
+ <packagereq type="default">xorg-driver-input-keyboard</packagereq>
+ <packagereq type="default">xorg-driver-input-mouse</packagereq>
+ <packagereq type="default">xorg-driver-video-v4l</packagereq>
+ <packagereq type="default">xorg-driver-video-vesa</packagereq>
+ <packagereq type="default">xorg-driver-video-vga</packagereq>
+ <packagereq type="default">xorg-app-sessreg</packagereq>
+ <packagereq type="default">xorg-xserver-server</packagereq>
+ <packagereq type="default">X11-synaptics</packagereq>
+ <packagereq type="default">xorg-app-beforelight</packagereq>
+ <packagereq type="default">xorg-app-ico</packagereq>
+ <packagereq type="default">xorg-app-listres</packagereq>
+ <packagereq type="default">xorg-app-oclock</packagereq>
+ <packagereq type="default">xorg-app-showfont</packagereq>
+ <packagereq type="default">xorg-app-viewres</packagereq>
+ <packagereq type="default">xorg-app-x11perf</packagereq>
+ <packagereq type="default">xorg-app-xbiff</packagereq>
+ <packagereq type="default">xorg-app-xcalc</packagereq>
+ <packagereq type="default">xorg-app-xclipboard</packagereq>
+ <packagereq type="default">xorg-app-xclock</packagereq>
+ <packagereq type="default">xorg-app-xdbedizzy</packagereq>
+ <packagereq type="default">xorg-app-xditview</packagereq>
+ <packagereq type="default">xorg-app-xdriinfo</packagereq>
+ <packagereq type="default">xorg-app-xedit</packagereq>
+ <packagereq type="default">xorg-app-xev</packagereq>
+ <packagereq type="default">xorg-app-xeyes</packagereq>
+ <packagereq type="default">xorg-app-xfd</packagereq>
+ <packagereq type="default">xorg-app-xfontsel</packagereq>
+ <packagereq type="default">xorg-app-xgc</packagereq>
+ <packagereq type="default">xorg-app-xkill</packagereq>
+ <packagereq type="default">xorg-app-xload</packagereq>
+ <packagereq type="default">xorg-app-xlogo</packagereq>
+ <packagereq type="default">xorg-app-xmag</packagereq>
+ <packagereq type="default">xorg-app-xman</packagereq>
+ <packagereq type="default">xorg-app-xmessage</packagereq>
+ <packagereq type="default">xorg-app-xmh</packagereq>
+ <packagereq type="default">xorg-app-xmore</packagereq>
+ <packagereq type="default">xorg-app-xphelloworld</packagereq>
+ <packagereq type="default">xorg-app-xplsprinters</packagereq>
+ <packagereq type="default">xorg-app-xpr</packagereq>
+ <packagereq type="default">xorg-app-xprehashprinterlist</packagereq>
+ <packagereq type="default">xorg-app-xprop</packagereq>
+ <packagereq type="default">xorg-app-xtrap</packagereq>
+ <packagereq type="default">xorg-app-xwininfo</packagereq>
+ <packagereq type="default">xorg-app-twm</packagereq>
+ <packagereq type="default">xorg-app-xauth</packagereq>
+ <packagereq type="default">xorg-app-xfs</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>gnome</id>
+ <name>Very basic GNOME Desktop part</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Very basic GNOME Desktop part</description>
+ <packagelist>
+ <packagereq type="default">gnome-control-center</packagereq>
+ <packagereq type="default">gedit2</packagereq>
+ <packagereq type="default">gnome-menus</packagereq>
+ <packagereq type="default">gnome-panel</packagereq>
+ <packagereq type="default">gnome-session</packagereq>
+ <packagereq type="default">gnome-desktop</packagereq>
+ <packagereq type="default">gnome-terminal</packagereq>
+ <packagereq type="default">gnome-themes-Clearlooks</packagereq>
+ <packagereq type="default">metacity</packagereq>
+ <packagereq type="default">nautilus</packagereq>
+ <packagereq type="default">hal</packagereq>
+ <packagereq type="default">dbus</packagereq>
+ <packagereq type="default">gdm</packagereq>
+ <packagereq type="default">dbus-init</packagereq>
+
+ </packagelist>
+ </group>
+
+ <group>
+ <id>gnome_complete</id>
+ <name>More complete GNOME Desktop part</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>More complete GNOME Desktop part</description>
+ <packagelist>
+ <packagereq type="default">bug-buddy</packagereq>
+ <packagereq type="default">eog</packagereq>
+ <packagereq type="default">epiphany</packagereq>
+ <packagereq type="default">epiphany-extensions</packagereq>
+ <packagereq type="default">evince</packagereq>
+ <packagereq type="default">file-roller</packagereq>
+ <packagereq type="default">gcalctool</packagereq>
+ <packagereq type="default">gconf-editor</packagereq>
+ <packagereq type="default">gnome-applets-accessx-status</packagereq>
+ <packagereq type="default">gnome-applets-battstat</packagereq>
+ <packagereq type="default">gnome-applets-charpicker</packagereq>
+ <packagereq type="default">gnome-applets-cpufreq</packagereq>
+ <packagereq type="optional">gnome-applets-drivemount</packagereq>
+ <packagereq type="optional">gnome-applets-geyes</packagereq>
+ <packagereq type="optional">gnome-applets-gtik</packagereq>
+ <packagereq type="default">gnome-applets-gweather</packagereq>
+ <packagereq type="default">gnome-applets-keyboard</packagereq>
+ <packagereq type="optional">gnome-applets-minicommander</packagereq>
+ <packagereq type="default">gnome-applets-mixer</packagereq>
+ <packagereq type="optional">gnome-applets-modemlights</packagereq>
+ <packagereq type="optional">gnome-applets-multiload</packagereq>
+ <packagereq type="optional">gnome-applets-stickynotes</packagereq>
+ <packagereq type="default">gnome-applets-trash</packagereq>
+ <packagereq type="default">gnome-backgrounds</packagereq>
+ <packagereq type="default">gnome-cups-manager</packagereq>
+ <packagereq type="default">gnome-keyring-manager</packagereq>
+ <packagereq type="default">gnome-mail-notification</packagereq>
+ <packagereq type="optional">gnome-media-cd</packagereq>
+ <packagereq type="optional">gnome-media-cddb</packagereq>
+ <packagereq type="default">gnome-media-sound-recorder</packagereq>
+ <packagereq type="default">gnome-media-volume-control</packagereq>
+ <packagereq type="optional">gnome-media-vumeter</packagereq>
+ <packagereq type="default">gnome-menus-editor</packagereq>
+ <packagereq type="default">gnome-netstatus</packagereq>
+ <packagereq type="default">gnome-nettool</packagereq>
+ <packagereq type="default">gnome-system-monitor</packagereq>
+ <packagereq type="default">gnome-utils-dict</packagereq>
+ <packagereq type="optional">gnome-utils-floppy</packagereq>
+ <packagereq type="optional">gnome-utils-logview</packagereq>
+ <packagereq type="default">gnome-utils-screenshot</packagereq>
+ <packagereq type="default">gnome-utils-search-tool</packagereq>
+ <packagereq type="default">gnome-volume-manager</packagereq>
+ <packagereq type="default">nautilus-cd-burner</packagereq>
+ <packagereq type="default">rhythmbox</packagereq>
+ <packagereq type="default">sound-juicer</packagereq>
+ <packagereq type="default">totem</packagereq>
+ <packagereq type="default">cheese</packagereq>
+ <packagereq type="default">xscreensaver-gnome2</packagereq>
+ <packagereq type="default">yelp</packagereq>
+ <packagereq type="default">gnome-packagekit</packagereq>
+ <packagereq type="default">NetworkManager-applet</packagereq>
+ <packagereq type="default">gstreamer</packagereq>
+ <packagereq type="default">gstreamer-plugins-base</packagereq>
+ <packagereq type="default">gstreamer-plugins-good</packagereq>
+ <packagereq type="default">gstreamer-plugins-bad</packagereq>
+ <packagereq type="default">gstreamer-plugins-ugly</packagereq>
+ <packagereq type="default">gstreamer-audiosink-alsa</packagereq>
+ <packagereq type="default">gstreamer-imagesink-xv</packagereq>
+ <packagereq type="default">gstreamer-audio-formats</packagereq>
+ <packagereq type="default">gstreamer-cdaudio</packagereq>
+ <packagereq type="default">gstreamer-flac</packagereq>
+ <packagereq type="default">gstreamer-GConf</packagereq>
+ <packagereq type="default">gstreamer-cdio</packagereq>
+ <packagereq type="default">gstreamer-lame</packagereq>
+ <packagereq type="default">gstreamer-mad</packagereq>
+ <packagereq type="default">gstreamer-mpeg</packagereq>
+ <packagereq type="default">gstreamer-musicbrainz</packagereq>
+ <packagereq type="default">gstreamer-soup</packagereq>
+ <packagereq type="default">gstreamer-taglib</packagereq>
+ <packagereq type="default">gstreamer-theora</packagereq>
+ <packagereq type="default">gstreamer-vorbis</packagereq>
+ <packagereq type="default">gstreamer-video-effects</packagereq>
+ <packagereq type="default">gstreamer-visualisation</packagereq>
+ <packagereq type="default">gstreamer-wavpack</packagereq>
+ <packagereq type="default">gstreamer-x264</packagereq>
+ <packagereq type="default">gstreamer-ximagesrc</packagereq>
+ <packagereq type="default">gstreamer-xvid</packagereq>
+ <packagereq type="default">gstreamer-dvdread</packagereq>
+ <packagereq type="default">gstreamer-ffmpeg</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>gnome_games</id>
+ <name>GNOME Games</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>GNOME Games</description>
+ <packagelist>
+ <packagereq type="optional">gnome-games-blackjack</packagereq>
+ <packagereq type="optional">gnome-games-extra-data-glines</packagereq>
+ <packagereq type="optional">gnome-games-extra-data-gnobots2</packagereq>
+ <packagereq type="optional">gnome-games-extra-data-gnometris</packagereq>
+ <packagereq type="optional">gnome-games-extra-data-iagno</packagereq>
+ <packagereq type="optional">gnome-games-extra-data-mahjongg</packagereq>
+ <packagereq type="optional">gnome-games-extra-data-same-gnome</packagereq>
+ <packagereq type="optional">gnome-games-gataxx</packagereq>
+ <packagereq type="optional">gnome-games-glines</packagereq>
+ <packagereq type="optional">gnome-games-gnect</packagereq>
+ <packagereq type="optional">gnome-games-gnibbles</packagereq>
+ <packagereq type="optional">gnome-games-gnobots2</packagereq>
+ <packagereq type="optional">gnome-games-gnometris</packagereq>
+ <packagereq type="optional">gnome-games-gnomine</packagereq>
+ <packagereq type="optional">gnome-games-gnotravex</packagereq>
+ <packagereq type="optional">gnome-games-gnotski</packagereq>
+ <packagereq type="optional">gnome-games-gtal</packagereq>
+ <packagereq type="optional">gnome-games-iagno</packagereq>
+ <packagereq type="optional">gnome-games-mahjongg</packagereq>
+ <packagereq type="optional">gnome-games-same-gnome</packagereq>
+ <packagereq type="optional">gnome-games-sol</packagereq>
+ <packagereq type="optional">gnome-games-stones</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>gnome_themes</id>
+ <name>GNOME Themes and Icons</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>GNOME Themes and Icons</description>
+ <packagelist>
+ <packagereq type="optional">gnome-theme-aqua</packagereq>
+ <packagereq type="optional">gnome-theme-Bluecurve</packagereq>
+ <packagereq type="optional">gnome-theme-Industrial</packagereq>
+ <packagereq type="optional">gnome-themes-Crux</packagereq>
+ <packagereq type="optional">gnome-themes-Flat-Blue</packagereq>
+ <packagereq type="optional">gnome-themes-Glider</packagereq>
+ <packagereq type="optional">gnome-themes-Grand-Canyon</packagereq>
+ <packagereq type="optional">gnome-themes-HighContrast</packagereq>
+ <packagereq type="optional">gnome-themes-HighContrastInverse</packagereq>
+ <packagereq type="optional">gnome-themes-HighContrastLargePrint</packagereq>
+ <packagereq type="optional">gnome-themes-HighContrastLargePrintInverse</packagereq>
+ <packagereq type="optional">gnome-themes-LargePrint</packagereq>
+ <packagereq type="optional">gnome-themes-LowContrast</packagereq>
+ <packagereq type="optional">gnome-themes-LowContrastLargePrint</packagereq>
+ <packagereq type="optional">gnome-themes-Mist</packagereq>
+ <packagereq type="optional">gnome-themes-Ocean-Dream</packagereq>
+ <packagereq type="optional">gnome-themes-Sandwish</packagereq>
+ <packagereq type="optional">gnome-themes-Sandy</packagereq>
+ <packagereq type="optional">gnome-themes-Simple</packagereq>
+ <packagereq type="optional">gnome-themes-Smokey</packagereq>
+ <packagereq type="optional">gnome-themes-Smokey-Blue</packagereq>
+ <packagereq type="optional">gnome-themes-Smokey-Red</packagereq>
+ <packagereq type="optional">gnome-themes-Traditional</packagereq>
+ <packagereq type="optional">gnome-themes-extras-Amaranth</packagereq>
+ <packagereq type="optional">gnome-themes-extras-Gorilla</packagereq>
+ <packagereq type="optional">gnome-themes-extras-Lush</packagereq>
+ <packagereq type="optional">gnome-themes-extras-Nuvola</packagereq>
+ <packagereq type="optional">gnome-themes-extras-Wasp</packagereq>
+ <packagereq type="optional">gnome-icons-gartoon</packagereq>
+ <packagereq type="optional">gnome-icons-gperfection2</packagereq>
+ <packagereq type="optional">gnome-icons-graphite</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>gnome_office</id>
+ <name>GNOME Office Packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>GNOME Office Packages</description>
+ <packagelist>
+ <packagereq type="default">abiword</packagereq>
+ <packagereq type="optional">abiword-clipart</packagereq>
+ <packagereq type="optional">abiword-plugin-aiksaurus</packagereq>
+ <packagereq type="optional">abiword-plugin-applix</packagereq>
+ <packagereq type="optional">abiword-plugin-babelfish</packagereq>
+ <packagereq type="optional">abiword-plugin-bmp</packagereq>
+ <packagereq type="optional">abiword-plugin-bz2</packagereq>
+ <packagereq type="optional">abiword-plugin-capi</packagereq>
+ <packagereq type="optional">abiword-plugin-clarisworks</packagereq>
+ <packagereq type="optional">abiword-plugin-collab</packagereq>
+ <packagereq type="optional">abiword-plugin-command</packagereq>
+ <packagereq type="optional">abiword-plugin-dash</packagereq>
+ <packagereq type="optional">abiword-plugin-docbook</packagereq>
+ <packagereq type="optional">abiword-plugin-eml</packagereq>
+ <packagereq type="optional">abiword-plugin-freetranslation</packagereq>
+ <packagereq type="optional">abiword-plugin-gda</packagereq>
+ <packagereq type="optional">abiword-plugin-gdict</packagereq>
+ <packagereq type="optional">abiword-plugin-gimp</packagereq>
+ <packagereq type="optional">abiword-plugin-goffice</packagereq>
+ <packagereq type="optional">abiword-plugin-google</packagereq>
+ <packagereq type="optional">abiword-plugin-hancom</packagereq>
+ <packagereq type="optional">abiword-plugin-hrtext</packagereq>
+ <packagereq type="optional">abiword-plugin-iscii</packagereq>
+ <packagereq type="optional">abiword-plugin-jpeg</packagereq>
+ <packagereq type="optional">abiword-plugin-kword</packagereq>
+ <packagereq type="optional">abiword-plugin-latex</packagereq>
+ <packagereq type="optional">abiword-plugin-link-grammar</packagereq>
+ <packagereq type="optional">abiword-plugin-mathview</packagereq>
+ <packagereq type="optional">abiword-plugin-mif</packagereq>
+ <packagereq type="optional">abiword-plugin-mswrite</packagereq>
+ <packagereq type="optional">abiword-plugin-nroff</packagereq>
+ <packagereq type="optional">abiword-plugin-opendocument</packagereq>
+ <packagereq type="optional">abiword-plugin-openwritter</packagereq>
+ <packagereq type="optional">abiword-plugin-ots</packagereq>
+ <packagereq type="optional">abiword-plugin-palmdoc</packagereq>
+ <packagereq type="optional">abiword-plugin-passepartout</packagereq>
+ <packagereq type="optional">abiword-plugin-pdf</packagereq>
+ <packagereq type="optional">abiword-plugin-psion</packagereq>
+ <packagereq type="optional">abiword-plugin-rsvg</packagereq>
+ <packagereq type="optional">abiword-plugin-scripthappy</packagereq>
+ <packagereq type="optional">abiword-plugin-sdw</packagereq>
+ <packagereq type="optional">abiword-plugin-t602</packagereq>
+ <packagereq type="optional">abiword-plugin-urldict</packagereq>
+ <packagereq type="optional">abiword-plugin-wikipedia</packagereq>
+ <packagereq type="optional">abiword-plugin-wmf</packagereq>
+ <packagereq type="optional">abiword-plugin-wml</packagereq>
+ <packagereq type="optional">abiword-plugin-wordperfect</packagereq>
+ <packagereq type="optional">abiword-plugin-xhtml</packagereq>
+ <packagereq type="optional">abiword-plugin-xslfo</packagereq>
+ <packagereq type="default">dia</packagereq>
+ <packagereq type="default">evolution</packagereq>
+ <packagereq type="default">gimp</packagereq>
+ <packagereq type="default">glabels</packagereq>
+ <packagereq type="default">gnome-spell</packagereq>
+ <packagereq type="default">gnucash</packagereq>
+ <packagereq type="default">gnumeric</packagereq>
+ <packagereq type="optional">gnumeric-plugin-applix</packagereq>
+ <packagereq type="optional">gnumeric-plugin-dif</packagereq>
+ <packagereq type="optional">gnumeric-plugin-excel</packagereq>
+ <packagereq type="optional">gnumeric-plugin-gdaif</packagereq>
+ <packagereq type="optional">gnumeric-plugin-gnomedb</packagereq>
+ <packagereq type="optional">gnumeric-plugin-gnuoleo</packagereq>
+ <packagereq type="optional">gnumeric-plugin-html</packagereq>
+ <packagereq type="optional">gnumeric-plugin-lotus123</packagereq>
+ <packagereq type="optional">gnumeric-plugin-openoffice</packagereq>
+ <packagereq type="optional">gnumeric-plugin-paradox</packagereq>
+ <packagereq type="optional">gnumeric-plugin-perl</packagereq>
+ <packagereq type="optional">gnumeric-plugin-planperfect</packagereq>
+ <packagereq type="optional">gnumeric-plugin-psiconv</packagereq>
+ <packagereq type="optional">gnumeric-plugin-python</packagereq>
+ <packagereq type="optional">gnumeric-plugin-qpro</packagereq>
+ <packagereq type="optional">gnumeric-plugin-sample</packagereq>
+ <packagereq type="optional">gnumeric-plugin-sc</packagereq>
+ <packagereq type="optional">gnumeric-plugin-sylk</packagereq>
+ <packagereq type="optional">gnumeric-plugin-xbase</packagereq>
+ <packagereq type="default">gthumb</packagereq>
+ <packagereq type="default">Guppi</packagereq>
+ <packagereq type="default">inkscape</packagereq>
+ <packagereq type="default">ToutDoux</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>wmaker</id>
+ <name>WindowMaker</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>WindowMaker</description>
+ <packagelist>
+ <packagereq type="default">WindowMaker</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde</id>
+ <name>Basic KDE part</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Basic KDE part</description>
+ <packagelist>
+ <packagereq type="default">konqueror</packagereq>
+ <packagereq type="default">kdelibs</packagereq>
+ <packagereq type="default">kdebase-core</packagereq>
+ <packagereq type="default">kdebase-desktop</packagereq>
+ <packagereq type="default">kdebase-desktop-libs</packagereq>
+ <packagereq type="default">kdebase-konsole</packagereq>
+ <packagereq type="default">kdebase-kpager</packagereq>
+ <packagereq type="default">kdebase-kwrite</packagereq>
+ <packagereq type="default">kdebase-screensavers</packagereq>
+ <packagereq type="default">kdebase-common-konsole</packagereq>
+ <packagereq type="default">kdebase-common-filemanagement</packagereq>
+ <packagereq type="default">kdebase-colorschemes</packagereq>
+ <packagereq type="default">kde-logoutpic-default</packagereq>
+ <packagereq type="default">kde-splash-Default</packagereq>
+ <packagereq type="optional">kdm</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_extras1</id>
+ <name>KDE additional packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE additional packages</description>
+ <packagelist>
+ <packagereq type="default">kdeaddons-ark</packagereq>
+ <packagereq type="default">kdeaddons-atlantikdesigner</packagereq>
+ <packagereq type="default">kdeaddons-fsview</packagereq>
+ <packagereq type="default">kdeaddons-kaddressbook-plugins</packagereq>
+ <packagereq type="default">kdeaddons-kate</packagereq>
+ <packagereq type="default">kdeaddons-kicker</packagereq>
+ <packagereq type="default">kdeaddons-knewsticker</packagereq>
+ <packagereq type="default">kdeaddons-konqueror</packagereq>
+ <packagereq type="default">kdeaddons-ksig</packagereq>
+ <packagereq type="default">kdeaddons-lnkforward</packagereq>
+ <packagereq type="default">kdeaddons-noatun</packagereq>
+ <packagereq type="default">kdeartwork-kworldclock-3.5.0-1</packagereq>
+ <packagereq type="default">kdeartwork-screensavers-3.5.0-1</packagereq>
+ <packagereq type="default">kdeartwork-sounds-3.5.0-1</packagereq>
+ <packagereq type="default">kdeartwork-wallpapers-3.5.0-1</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_extras2</id>
+ <name>KDE additional packages2</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE additional packages2</description>
+ <packagelist>
+ <packagereq type="default">kdeutils-ark</packagereq>
+ <packagereq type="default">kdeutils-kcalc</packagereq>
+ <packagereq type="default">kdeutils-kcharselect</packagereq>
+ <packagereq type="default">kdeutils-kdelirc</packagereq>
+ <packagereq type="default">kdeutils-kdessh</packagereq>
+ <packagereq type="default">kdeutils-kdf</packagereq>
+ <packagereq type="default">kdeutils-kedit</packagereq>
+ <packagereq type="default">kdeutils-kfloppy</packagereq>
+ <packagereq type="default">kdeutils-kgpg</packagereq>
+ <packagereq type="default">kdeutils-khexedit</packagereq>
+ <packagereq type="default">kdeutils-kjots</packagereq>
+ <packagereq type="default">kdeutils-klaptopdaemon</packagereq>
+ <packagereq type="default">kdeutils-kmilo</packagereq>
+ <packagereq type="default">kdeutils-kmilo-thinkpad</packagereq>
+ <packagereq type="default">kdeutils-kregexpeditor</packagereq>
+ <packagereq type="default">kdeutils-ksim</packagereq>
+ <packagereq type="default">kdeutils-ktimer</packagereq>
+ <packagereq type="default">kdeutils-kwalletmanager</packagereq>
+ <packagereq type="default">kdeutils-superkaramba</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_kdepim</id>
+ <name>KDE PIM Packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE PIM Packages</description>
+ <packagelist>
+ <packagereq type="default">kdepim</packagereq>
+ <packagereq type="default">kdepim-apidocs</packagereq>
+ <packagereq type="default">kdepim-kaddressbook</packagereq>
+ <packagereq type="default">kdepim-kalarm</packagereq>
+ <packagereq type="default">kdepim-kandy</packagereq>
+ <packagereq type="default">kdepim-karm</packagereq>
+ <packagereq type="default">kdepim-kmail</packagereq>
+ <packagereq type="default">kdepim-knode</packagereq>
+ <packagereq type="default">kdepim-knotes</packagereq>
+ <packagereq type="default">kdepim-konsolekalendar</packagereq>
+ <packagereq type="default">kdepim-korn</packagereq>
+ <packagereq type="default">kdepim-kpilot</packagereq>
+ <packagereq type="default">kdepim-libs</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_kdeedu</id>
+ <name>KDE Edu Packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE Edu Packages</description>
+ <packagelist>
+ <packagereq type="default">kdeedu-blinken</packagereq>
+ <packagereq type="default">kdeedu-kalzium</packagereq>
+ <packagereq type="default">kdeedu-kanagram</packagereq>
+ <packagereq type="default">kdeedu-kbruch</packagereq>
+ <packagereq type="default">kdeedu-keduca</packagereq>
+ <packagereq type="default">kdeedu-kgeography</packagereq>
+ <packagereq type="default">kdeedu-khangman</packagereq>
+ <packagereq type="default">kdeedu-kig</packagereq>
+ <packagereq type="default">kdeedu-kiten</packagereq>
+ <packagereq type="default">kdeedu-klatin</packagereq>
+ <packagereq type="default">kdeedu-klettres</packagereq>
+ <packagereq type="default">kdeedu-kmplot</packagereq>
+ <packagereq type="default">kdeedu-kpercentage</packagereq>
+ <packagereq type="default">kdeedu-kstars</packagereq>
+ <packagereq type="default">kdeedu-ktouch</packagereq>
+ <packagereq type="default">kdeedu-kturtle</packagereq>
+ <packagereq type="default">kdeedu-kverbos</packagereq>
+ <packagereq type="default">kdeedu-kvoctrain</packagereq>
+ <packagereq type="default">kdeedu-kwordquiz</packagereq>
+ <packagereq type="default">kdeedu-libextdate</packagereq>
+ <packagereq type="default">kdeedu-libkdeeducore</packagereq>
+ <packagereq type="default">kdeedu-libkdeeduplot</packagereq>
+ <packagereq type="default">kdeedu-libkdeeduui</packagereq>
+ <packagereq type="default">kdeedu-libkiten</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_multimedia</id>
+ <name>KDE Multimedia Packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE Multimedia Packages</description>
+ <packagelist>
+ <packagereq type="default">kdemultimedia-akode</packagereq>
+ <packagereq type="default">kdemultimedia-arts</packagereq>
+ <packagereq type="default">kdemultimedia-artsbuilder</packagereq>
+ <packagereq type="default">kdemultimedia-artscontrol</packagereq>
+ <packagereq type="default">kdemultimedia-artsplugin-xine</packagereq>
+ <packagereq type="default">kdemultimedia-audiocd</packagereq>
+ <packagereq type="default">kdemultimedia-cddb</packagereq>
+ <packagereq type="default">kdemultimedia-juk</packagereq>
+ <packagereq type="default">kdemultimedia-kaboodle</packagereq>
+ <packagereq type="default">kdemultimedia-kappfinder</packagereq>
+ <packagereq type="default">kdemultimedia-kaudiocreator</packagereq>
+ <packagereq type="default">kdemultimedia-kfile</packagereq>
+ <packagereq type="default">kdemultimedia-kmid</packagereq>
+ <packagereq type="default">kdemultimedia-kmix</packagereq>
+ <packagereq type="default">kdemultimedia-krec</packagereq>
+ <packagereq type="default">kdemultimedia-kscd</packagereq>
+ <packagereq type="default">kdemultimedia-libkcddb</packagereq>
+ <packagereq type="default">kdemultimedia-mpeglib</packagereq>
+ <packagereq type="default">kdemultimedia-mpeglib-examples</packagereq>
+ <packagereq type="default">kdemultimedia-noatun</packagereq>
+ <packagereq type="default">kdemultimedia-noatun-libs</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_koffice</id>
+ <name>KOffice Packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KOffice Packages</description>
+ <packagelist>
+ <packagereq type="default">koffice-apidocs</packagereq>
+ <packagereq type="default">koffice-common</packagereq>
+ <packagereq type="default">koffice-karbon</packagereq>
+ <packagereq type="default">koffice-kchart</packagereq>
+ <packagereq type="default">koffice-kexi</packagereq>
+ <packagereq type="default">koffice-kformula</packagereq>
+ <packagereq type="default">koffice-kivio</packagereq>
+ <packagereq type="default">koffice-kpresenter</packagereq>
+ <packagereq type="default">koffice-krita</packagereq>
+ <packagereq type="default">koffice-kspread</packagereq>
+ <packagereq type="default">koffice-kugar</packagereq>
+ <packagereq type="default">koffice-kword</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_network</id>
+ <name>KDE Network Packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE Network Packages</description>
+ <packagelist>
+ <packagereq type="default">kdenetwork-filesharing</packagereq>
+ <packagereq type="default">kdenetwork-kdict</packagereq>
+ <packagereq type="default">kdenetwork-kdnssd</packagereq>
+ <packagereq type="default">kdenetwork-kfile-torrent</packagereq>
+ <packagereq type="default">kdenetwork-kget</packagereq>
+ <packagereq type="default">kdenetwork-kinetd</packagereq>
+ <packagereq type="default">kdenetwork-knewsticker</packagereq>
+ <packagereq type="default">kdenetwork-kopete</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-aim</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-gg</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-groupwise</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-icq</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-irc</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-jabber</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-meanwhile</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-msn</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-sms</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-winpopup</packagereq>
+ <packagereq type="default">kdenetwork-kopete-protocol-yahoo</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-alias</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-autoreplace</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-avdeviceconfig</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-conectionstatus</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-contactnotes</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-cryptography</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-highlight</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-history</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-latex</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-nowlistening</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-smpppdcs</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-texteffect</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-translator</packagereq>
+ <packagereq type="default">kdenetwork-kopete-tool-webpresence</packagereq>
+ <packagereq type="default">kdenetwork-kpf</packagereq>
+ <packagereq type="default">kdenetwork-kppp</packagereq>
+ <packagereq type="default">kdenetwork-krfb</packagereq>
+ <packagereq type="default">kdenetwork-ksirc</packagereq>
+ <packagereq type="default">kdenetwork-ktalkd</packagereq>
+ <packagereq type="default">kdenetwork-kwifimanager</packagereq>
+ <packagereq type="default">kdenetwork-lanbrowser</packagereq>
+ <packagereq type="default">kdenetwork-libkopete</packagereq>
+ <packagereq type="default">kdenetwork-libkopete_msn</packagereq>
+ <packagereq type="default">kdenetwork-libkopete_oscar</packagereq>
+ <packagereq type="default">kdenetwork-libkopete_videodevice</packagereq>
+ <packagereq type="default">kdenetwork-librss</packagereq>
+ <packagereq type="default">kdenetwork-rss</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_graphics</id>
+ <name>KDE Graphics</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE Graphics</description>
+ <packagelist>
+ <packagereq type="default">kdegraphics-daemonwatcher</packagereq>
+ <packagereq type="default">kdegraphics-kamera</packagereq>
+ <packagereq type="default">kdegraphics-kcolorchooser</packagereq>
+ <packagereq type="default">kdegraphics-kcoloredit</packagereq>
+ <packagereq type="default">kdegraphics-kdvi</packagereq>
+ <packagereq type="default">kdegraphics-kfax</packagereq>
+ <packagereq type="default">kdegraphics-kfile</packagereq>
+ <packagereq type="default">kdegraphics-kgamma</packagereq>
+ <packagereq type="default">kdegraphics-kghostview</packagereq>
+ <packagereq type="default">kdegraphics-kiconedit</packagereq>
+ <packagereq type="default">kdegraphics-kmrml</packagereq>
+ <packagereq type="default">kdegraphics-kolourpaint</packagereq>
+ <packagereq type="default">kdegraphics-kooka</packagereq>
+ <packagereq type="default">kdegraphics-kpdf</packagereq>
+ <packagereq type="default">kdegraphics-kpovmodeler</packagereq>
+ <packagereq type="default">kdegraphics-kruler</packagereq>
+ <packagereq type="default">kdegraphics-ksnapshot</packagereq>
+ <packagereq type="default">kdegraphics-ksvg</packagereq>
+ <packagereq type="default">kdegraphics-kuickshow</packagereq>
+ <packagereq type="default">kdegraphics-kview</packagereq>
+ <packagereq type="default">kdegraphics-kviewshell</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_admin</id>
+ <name>KDE Admin packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE Admin packages</description>
+ <packagelist>
+ <packagereq type="default">kdeadmin-kcmlilo</packagereq>
+ <packagereq type="default">kdeadmin-kcron</packagereq>
+ <packagereq type="default">kdeadmin-kdat</packagereq>
+ <packagereq type="default">kdeadmin-knetworkconf</packagereq>
+ <packagereq type="default">kdeadmin-kpackage</packagereq>
+ <packagereq type="default">kdeadmin-ksysv</packagereq>
+ <packagereq type="default">kdeadmin-kuser</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_games</id>
+ <name>Games for KDE</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Games for KDE</description>
+ <packagelist>
+ <packagereq type="default">kdegames</packagereq>
+ <packagereq type="optional">kdegames-apidocs</packagereq>
+ <packagereq type="optional">kdegames-atlantik</packagereq>
+ <packagereq type="optional">kdegames-carddecks</packagereq>
+ <packagereq type="optional">kdegames-kasteroids</packagereq>
+ <packagereq type="optional">kdegames-katomic</packagereq>
+ <packagereq type="optional">kdegames-kbackgammon</packagereq>
+ <packagereq type="optional">kdegames-kbattleship</packagereq>
+ <packagereq type="optional">kdegames-kblackbox</packagereq>
+ <packagereq type="optional">kdegames-kbounce</packagereq>
+ <packagereq type="optional">kdegames-kenolaba</packagereq>
+ <packagereq type="optional">kdegames-kfouleggs</packagereq>
+ <packagereq type="optional">kdegames-kgoldrunner</packagereq>
+ <packagereq type="optional">kdegames-kjumpingcube</packagereq>
+ <packagereq type="optional">kdegames-klickety</packagereq>
+ <packagereq type="optional">kdegames-klines</packagereq>
+ <packagereq type="optional">kdegames-kmahjongg</packagereq>
+ <packagereq type="optional">kdegames-kmines</packagereq>
+ <packagereq type="optional">kdegames-knetwalk</packagereq>
+ <packagereq type="optional">kdegames-kolf</packagereq>
+ <packagereq type="optional">kdegames-konquest</packagereq>
+ <packagereq type="optional">kdegames-kpat</packagereq>
+ <packagereq type="optional">kdegames-kpoker</packagereq>
+ <packagereq type="optional">kdegames-kreversi</packagereq>
+ <packagereq type="optional">kdegames-ksame</packagereq>
+ <packagereq type="optional">kdegames-kshisen</packagereq>
+ <packagereq type="optional">kdegames-ksirtet</packagereq>
+ <packagereq type="optional">kdegames-ksmiletris</packagereq>
+ <packagereq type="optional">kdegames-ksnake</packagereq>
+ <packagereq type="optional">kdegames-ksokoban</packagereq>
+ <packagereq type="optional">kdegames-kspaceduel</packagereq>
+ <packagereq type="optional">kdegames-ktron</packagereq>
+ <packagereq type="optional">kdegames-ktuberling</packagereq>
+ <packagereq type="optional">kdegames-kwin4</packagereq>
+ <packagereq type="optional">kdegames-lskat</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_accessibility</id>
+ <name>KDE Accessibility packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE Accessibility packages</description>
+ <packagelist>
+ <packagereq type="default">kdeaccessibility-kbstateapplet</packagereq>
+ <packagereq type="default">kdeaccessibility-kmag</packagereq>
+ <packagereq type="default">kdeaccessibility-kmousetool</packagereq>
+ <packagereq type="default">kdeaccessibility-kmouth</packagereq>
+ <packagereq type="default">kdeaccessibility-ksayit</packagereq>
+ <packagereq type="default">kdeaccessibility-kttsd</packagereq>
+ <packagereq type="default">kdeaccessibility-kttsd-akode</packagereq>
+ <packagereq type="default">kdeaccessibility-kttsd-gstreamer</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_look</id>
+ <name>Packages for changing KDE look</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Packages for changing KDE look</description>
+ <packagelist>
+ <packagereq type="default">kde-decoration-ActiveHeart</packagereq>
+ <packagereq type="default">kde-decoration-alloy</packagereq>
+ <packagereq type="default">kde-decoration-aqua</packagereq>
+ <packagereq type="default">kde-decoration-b2</packagereq>
+ <packagereq type="default">kde-decoration-baghira</packagereq>
+ <packagereq type="default">kde-decoration-cde</packagereq>
+ <packagereq type="default">kde-decoration-crystal</packagereq>
+ <packagereq type="default">kde-decoration-dotcurve</packagereq>
+ <packagereq type="default">kde-decoration-fahrenheit</packagereq>
+ <packagereq type="default">kde-decoration-glow</packagereq>
+ <packagereq type="default">kde-decoration-gorilla</packagereq>
+ <packagereq type="default">kde-decoration-icewm</packagereq>
+ <packagereq type="default">kde-decoration-icewm-Suedstern</packagereq>
+ <packagereq type="default">kde-decoration-icewm-Wasp</packagereq>
+ <packagereq type="default">kde-decoration-icewm-xp</packagereq>
+ <packagereq type="default">kde-decoration-kde1</packagereq>
+ <packagereq type="default">kde-decoration-keramik</packagereq>
+ <packagereq type="default">kde-decoration-kstep</packagereq>
+ <packagereq type="default">kde-decoration-laptop</packagereq>
+ <packagereq type="default">kde-decoration-modernsys</packagereq>
+ <packagereq type="default">kde-decoration-nvidia</packagereq>
+ <packagereq type="default">kde-decoration-openlook</packagereq>
+ <packagereq type="default">kde-decoration-quartz</packagereq>
+ <packagereq type="default">kde-decoration-redmond</packagereq>
+ <packagereq type="default">kde-decoration-ridge</packagereq>
+ <packagereq type="default">kde-decoration-riscos</packagereq>
+ <packagereq type="default">kde-decoration-smoothblend</packagereq>
+ <packagereq type="default">kde-decoration-system</packagereq>
+ <packagereq type="default">kde-decoration-thinkeramik</packagereq>
+ <packagereq type="default">kde-decoration-web</packagereq>
+ <packagereq type="default">kde-colorscheme-ActiveHeart</packagereq>
+ <packagereq type="default">kde-colorscheme-alloy</packagereq>
+ <packagereq type="default">kde-colorscheme-baghira</packagereq>
+ <packagereq type="default">kde-colorscheme-gorilla</packagereq>
+ <packagereq type="default">kde-colorscheme-konx</packagereq>
+ <packagereq type="default">kde-colorscheme-nvidia</packagereq>
+ <packagereq type="default">kde-colorscheme-ridge</packagereq>
+ <packagereq type="default">kde-colorscheme-Suedstern</packagereq>
+ <packagereq type="default">kde-colorscheme-thinkeramik</packagereq>
+ <packagereq type="default">kde-colorscheme-Wasp</packagereq>
+ <packagereq type="default">kde-colorscheme-Wasp-activeheart</packagereq>
+ <packagereq type="default">kde-colorscheme-Wasp-thinkeramik</packagereq>
+ <packagereq type="default">kde-icons-amaranth</packagereq>
+ <packagereq type="default">kde-icons-amaranth-althaea</packagereq>
+ <packagereq type="default">kde-icons-aqua</packagereq>
+ <packagereq type="default">kde-icons-aquafusion</packagereq>
+ <packagereq type="default">kde-icons-gorilla</packagereq>
+ <packagereq type="default">kde-icons-ikons</packagereq>
+ <packagereq type="default">kde-icons-kdeclassic</packagereq>
+ <packagereq type="default">kde-icons-kids</packagereq>
+ <packagereq type="default">kde-icons-Locolor</packagereq>
+ <packagereq type="default">kde-icons-mono</packagereq>
+ <packagereq type="default">kde-icons-noia</packagereq>
+ <packagereq type="default">kde-icons-Nuvola</packagereq>
+ <packagereq type="default">kde-icons-outline</packagereq>
+ <packagereq type="default">kde-icons-Realistic</packagereq>
+ <packagereq type="default">kde-icons-slick</packagereq>
+ <packagereq type="default">kde-icons-sparkling</packagereq>
+ <packagereq type="default">kde-icons-Suedstern</packagereq>
+ <packagereq type="default">kde-icons-umicons</packagereq>
+ <packagereq type="default">kde-icons-Wasp</packagereq>
+ <packagereq type="default">kde-icons-xp</packagereq>
+ <packagereq type="default">kde-splash-ac-chemician</packagereq>
+ <packagereq type="default">kde-splash-ac-oiler</packagereq>
+ <packagereq type="default">kde-splash-blue-bend</packagereq>
+ <packagereq type="default">kde-splash-BlueTribe</packagereq>
+ <packagereq type="default">kde-splash-Clock_K</packagereq>
+ <packagereq type="default">kde-splash-Gears</packagereq>
+ <packagereq type="default">kde-splash-gears_white</packagereq>
+ <packagereq type="default">kde-splash-GNU_CooL</packagereq>
+ <packagereq type="default">kde-splash-GNU_cool2</packagereq>
+ <packagereq type="default">kde-splash-gorilla</packagereq>
+ <packagereq type="default">kde-splash-heregear</packagereq>
+ <packagereq type="default">kde-splash-heregear-moodin</packagereq>
+ <packagereq type="default">kde-splash-KDEGirl</packagereq>
+ <packagereq type="default">kde-splash-keramik</packagereq>
+ <packagereq type="default">kde-splash-Lila</packagereq>
+ <packagereq type="default">kde-splash-login-scan-splash</packagereq>
+ <packagereq type="default">kde-splash-moodin</packagereq>
+ <packagereq type="default">kde-splash-MoonKDE</packagereq>
+ <packagereq type="default">kde-splash-NWN</packagereq>
+ <packagereq type="default">kde-splash-oldtimesplash</packagereq>
+ <packagereq type="default">kde-splash-PhyNet</packagereq>
+ <packagereq type="default">kde-splash-Rambo-tux</packagereq>
+ <packagereq type="default">kde-splash-safari</packagereq>
+ <packagereq type="default">kde-splash-Suedstern</packagereq>
+ <packagereq type="default">kde-splash-think-linux</packagereq>
+ <packagereq type="default">kde-splash-Wasp</packagereq>
+ <packagereq type="default">kde-style-ActiveHeart</packagereq>
+ <packagereq type="default">kde-style-alloy</packagereq>
+ <packagereq type="default">kde-style-aqua</packagereq>
+ <packagereq type="default">kde-style-baghira</packagereq>
+ <packagereq type="default">kde-style-comix</packagereq>
+ <packagereq type="default">kde-style-dotnet</packagereq>
+ <packagereq type="default">kde-style-konx</packagereq>
+ <packagereq type="default">kde-style-phase</packagereq>
+ <packagereq type="default">kde-style-thinkeramik</packagereq>
+ <packagereq type="default">kde-style-xp</packagereq>
+ <packagereq type="default">kde-theme-ActiveHeart</packagereq>
+ <packagereq type="default">kde-theme-alloy</packagereq>
+ <packagereq type="default">kde-theme-aqua</packagereq>
+ <packagereq type="default">kde-theme-baghira</packagereq>
+ <packagereq type="default">kde-theme-Bluecurve</packagereq>
+ <packagereq type="default">kde-theme-gorilla</packagereq>
+ <packagereq type="default">kde-theme-konx</packagereq>
+ <packagereq type="default">kde-theme-Suedstern</packagereq>
+ <packagereq type="default">kde-theme-thinkeramik</packagereq>
+ <packagereq type="default">kde-theme-umicons</packagereq>
+ <packagereq type="default">kde-theme-Wasp</packagereq>
+ <packagereq type="default">kde-theme-xp</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>kde_devel</id>
+ <name>KDE development tools</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>KDE development tools</description>
+ <packagelist>
+ <packagereq type="default">kdevelop</packagereq>
+ <packagereq type="default">kdesdk-cervisia</packagereq>
+ <packagereq type="default">kdesdk-completions-bash</packagereq>
+ <packagereq type="default">kdesdk-completions-zsh</packagereq>
+ <packagereq type="default">kdesdk-emacs</packagereq>
+ <packagereq type="default">kdesdk-kapptemplate</packagereq>
+ <packagereq type="default">kdesdk-kbabel</packagereq>
+ <packagereq type="default">kdesdk-kbugbuster</packagereq>
+ <packagereq type="default">kdesdk-kcachegrind</packagereq>
+ <packagereq type="default">kdesdk-kde-resource-bugzilla</packagereq>
+ <packagereq type="default">kdesdk-kde-resource-kdeaccounts</packagereq>
+ <packagereq type="default">kdesdk-kfile</packagereq>
+ <packagereq type="default">kdesdk-kmtrace</packagereq>
+ <packagereq type="default">kdesdk-kompare</packagereq>
+ <packagereq type="default">kdesdk-kprofilemethod</packagereq>
+ <packagereq type="default">kdesdk-kspy</packagereq>
+ <packagereq type="default">kdesdk-kstartperf</packagereq>
+ <packagereq type="default">kdesdk-kuiviewer</packagereq>
+ <packagereq type="default">kdesdk-kunittest</packagereq>
+ <packagereq type="default">kdesdk-libcvsservice</packagereq>
+ <packagereq type="default">kdesdk-pallette-gimp</packagereq>
+ <packagereq type="default">kdesdk-pallette-xpaint</packagereq>
+ <packagereq type="default">kdesdk-po2xml</packagereq>
+ <packagereq type="default">kdesdk-scheck</packagereq>
+ <packagereq type="default">kdesdk-scripts-cvs</packagereq>
+ <packagereq type="default">kdesdk-scripts-doc</packagereq>
+ <packagereq type="default">kdesdk-scripts-kdekillall</packagereq>
+ <packagereq type="default">kdesdk-umbrello</packagereq>
+ <packagereq type="default">kdesdk-xemacs</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>icewm</id>
+ <name>Basic IceWM</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Basic IceWM</description>
+ <packagelist>
+ <packagereq type="default">icewm</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>science_apps</id>
+ <name>Scientific applications</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Scientific applications</description>
+ <packagelist>
+ <packagereq type="default">parigp</packagereq>
+ <packagereq type="default">calc</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>science_libs</id>
+ <name>Scientific libraries</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Scientific libraries</description>
+ <packagelist>
+ <packagereq type="default">gmp</packagereq>
+ <packagereq type="default">gsl</packagereq>
+ <packagereq type="default">fftw</packagereq>
+ <packagereq type="default">pari</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>science_devel</id>
+ <name>Scientific development packages</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Scientific development packages</description>
+ <packagelist>
+ <packagereq type="default">gmp-devel</packagereq>
+ <packagereq type="default">gsl-devel</packagereq>
+ <packagereq type="default">gsl-progs</packagereq>
+ <packagereq type="default">fftw-devel</packagereq>
+ <packagereq type="default">pari-devel</packagereq>
+ <packagereq type="default">parigp-gp2c</packagereq>
+ <packagereq type="default">gcc-g77</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>games</id>
+ <name>Textmode games</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Textmode games</description>
+ <packagelist>
+ <packagereq type="default">bsd-games</packagereq>
+ <packagereq type="default">fortune-mod</packagereq>
+ <packagereq type="default">fortune-mod-bofh-excuses</packagereq>
+ </packagelist>
+ </group>
+
+ <group>
+ <id>games_x</id>
+ <name>Games for X.</name>
+ <default>false</default>
+ <uservisible>true</uservisible>
+ <description>Games for X.</description>
+ <packagelist>
+ <packagereq type="default">xbill</packagereq>
+ <packagereq type="default">prboom</packagereq>
+ <packagereq type="default">xpenguins</packagereq>
+ <packagereq type="default">xsnow</packagereq>
+ <packagereq type="default">bzflag</packagereq>
+ <packagereq type="default">tuxkart</packagereq>
+ <packagereq type="default">tuxracer</packagereq>
+ <packagereq type="default">xmoto</packagereq>
+ </packagelist>
+ </group>
+
+</comps>
--- /dev/null
+# various completions for pld-ftp-admin tools
+# Author: Elan Ruusamäe <glen@pld-linux.org>
+
+# return list of pld ftp trees
+_pfa_tree() {
+ local cur="$1"
+ if [ -z "$PFA_TREES" ]; then
+ local d
+ local -a trees
+ for d in ~/ftp/*/; do
+ d=${d%/}
+ d=${d##*/}
+ PFA_TREES+=" $d"
+ done
+ # kill leading space
+ PFA_TREES=${PFA_TREES# }
+ fi
+
+ COMPREPLY=( $( compgen -W "$PFA_TREES" -- "$cur" ) )
+}
+
+# return list of files in a tree
+_pfa_tree_files() {
+ local tree="$1" cur="$2" file i
+ local dir=~/ftp/$tree/SRPMS/.metadata
+
+ # generate reply from dir
+ COMPREPLY=( $( compgen -f -X "*.(src.rpm.info)" -- "$dir/$cur" ) )
+ # filter out dirname from results
+ for (( i=0; i < ${#COMPREPLY[@]}; i++ )); do
+ file=${COMPREPLY[$i]##*/}
+ COMPREPLY[$i]=$file
+ done
+}
+
+have pfa-genindex &&
+_pfa-genindex()
+{
+ local cur
+
+ COMPREPLY=()
+ _get_comp_words_by_ref cur
+
+ if [[ "$cur" == -* ]]; then
+ COMPREPLY=( $( compgen -W '\
+ -q --quiet --index \
+ --nopoldek --noyum --norpmrepo \
+ --poldek --yum --rpmrepo \
+ ' \
+ -- "$cur" ) )
+ else
+ _pfa_tree "$cur"
+ fi
+} &&
+complete -F _pfa-genindex pfa-genindex
+
+have pfa-lintpkg &&
+_pfa-lintpkg()
+{
+ local cur arg
+
+ COMPREPLY=()
+ _get_comp_words_by_ref cur
+
+ if [[ "$cur" == -* ]]; then
+ COMPREPLY=( $( compgen -W '-q -s --quiet' -- "$cur" ) )
+ else
+ # The first argument is an tree; the rest are files in a dir
+ _count_args :
+
+ if [[ $args == 1 ]]; then
+ _pfa_tree "$cur"
+ else
+ _get_first_arg
+ _pfa_tree_files "$arg" "$cur"
+ fi
+ fi
+} &&
+complete -F _pfa-lintpkg pfa-lintpkg
+
+have pfa-signpkg &&
+_pfa-signpkg()
+{
+ local cur
+
+ COMPREPLY=()
+ _get_comp_words_by_ref cur
+
+ # The first argument is an tree; the rest are files in a dir
+ _count_args :
+
+ if [[ $args == 1 ]]; then
+ _pfa_tree "$cur"
+ else
+ _pfa_tree_files "${COMP_WORDS[1]}" "$cur"
+ fi
+} &&
+complete -F _pfa-signpkg pfa-signpkg pfa-rmpkg
+
+have pfa-mvpkg &&
+_pfa-mvpkg()
+{
+ local cur
+
+ COMPREPLY=()
+ _get_comp_words_by_ref cur
+
+ # The first two arguments are tree names; the rest are files in a dir
+ _count_args :
+
+ if [[ $args == 1 ]] || [[ $args == 2 ]]; then
+ _pfa_tree "$cur"
+ else
+ _pfa_tree_files "${COMP_WORDS[1]}" "$cur"
+ fi
+} &&
+complete -F _pfa-mvpkg pfa-mvpkg pfa-testmvpkg
+
+# Local variables:
+# mode: shell-script
+# sh-basic-offset: 4
+# sh-indent-comment: t
+# indent-tabs-mode: nil
+# End:
+# ex: ts=4 sw=4 et filetype=sh
--- /dev/null
+# .bash_profile - file executed when logging in
+
+# identify via remote addr
+case "${SSH_CLIENT%% *}" in
+195.222.9.201) # glen ;)
+ export FTPADM=glen
+ ;;
+193.0.96.*|2001:6a0:5001:*) # baggins
+ export FTPADM=baggins
+ ;;
+esac
+
+# identify via terminal last login (su, sudo)
+if [ -z "$FTPADM" ]; then
+ LAST_TTY=$(tty)
+ LAST_LOGIN=$(last -if /var/run/utmp | awk -vtty="${LAST_TTY#/dev/}" '$2 == tty && $0 ~ /still logged in/ { print $1; exit; }')
+ export FTPADM=$LAST_LOGIN
+ unset LAST_TTY LAST_LOGIN
+fi
+
+# per-admin defaults
+case "$FTPADM" in
+glen)
+ export TZ=EET
+ case $(id -un) in
+ pldth)
+ echo -ne "\033kth@ftp\033\\"
+ ;;
+ fpldac|pldac)
+ echo -ne "\033kac@ftp\033\\"
+ ;;
+ esac
+ ;;
+'')
+ export FTPADM=$USER
+ ;;
+esac
+
+# let each ftp admin have own history file
+if [ "$FTPADM" ]; then
+ export HISTFILE=$HOME/.history-$FTPADM
+ export CDHISTFILE=$HOME/.cd_history-$FTPADM
+fi
+export EDITOR=vim
+
+PATH=$PATH:~/pld-ftp-admin/bin
--- /dev/null
+# .bashrc - file executed when executing bash
+
+# ftp admin aliases
+alias rmpkg=~/pld-ftp-admin/bin/pfa-rmpkg
+alias gen-indexes=~/pld-ftp-admin/bin/pfa-genindex
+alias dump-locks=~/pld-ftp-admin/bin/pfa-dump-locks
+alias signpkg=~/pld-ftp-admin/bin/pfa-signpkg
+alias mvpkg=~/pld-ftp-admin/bin/pfa-mvpkg
+alias testmvpkg=~/pld-ftp-admin/bin/pfa-testmvpkg
+alias lintpkg=~/pld-ftp-admin/bin/pfa-lintpkg
+
+# usual aliases to make your terminal usable
+alias ls='ls --color=auto -BFN --show-control-chars'
+alias l='ls -lh'
+alias la='ls -la'
+alias du='du -h'
+alias df='df -Th'
+alias vi='vim'
+alias h='history $(($LINES-6))'
+
+# glen ;)
+if [ "$FTPADM" = "glen" ]; then
+ [ -f /usr/share/okas/bashrc ] && . /usr/share/okas/bashrc
+fi
+
+unlocktree() {
+ for tree in "$@"; do
+ (
+ cd ~/pld-ftp-admin/modules
+ python -c "
+import ftpio
+ftpio.connect()
+ftpio.unlock('$tree')
+"
+ )
+ done
+}
--- /dev/null
+#!/bin/sh
+
+python setup.py build --build-lib ../modules
+
--- /dev/null
+from distutils.core import setup, Extension
+setup(name="ucred",#version="1.0",
+ ext_modules=[Extension("ucred", ["ucred.c"])])
+
--- /dev/null
+#include <Python.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <signal.h>
+
+PyObject *g_socketerror; // socket.error
+
+static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds);
+static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds);
+
+static PyMethodDef ucredMethods[] = {
+ {"sendcreds", (PyCFunction)ucred_sendcreds, METH_VARARGS|METH_KEYWORDS, NULL},
+ {"recvcreds", (PyCFunction)ucred_recvcreds, METH_VARARGS|METH_KEYWORDS, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+void initucred(void) {
+ PyObject *module;
+ module = Py_InitModule("ucred", ucredMethods);
+
+ if(-1 == PyModule_AddIntConstant(module, "SO_PASSCRED", SO_PASSCRED)) {
+ return;
+ }
+
+ module = PyImport_ImportModule("socket");
+ if(!module) {
+ return;
+ }
+ g_socketerror = PyObject_GetAttrString(module, "error");
+ if(!g_socketerror) {
+ return;
+ }
+}
+
+static PyObject *ucred_sendcreds(PyObject *self, PyObject *args, PyObject *keywds) {
+ int fd;
+ int ret;
+ int pid=-1, uid=-1, gid=-1;
+ struct msghdr msg;
+ struct iovec iov[1];
+ struct ucred uc;
+ unsigned char control[CMSG_SPACE(sizeof(struct ucred))];
+ struct cmsghdr *cur;
+
+ static char *kwlist[] = {"fd",
+ "pid",
+ "uid",
+ "gid",
+ NULL};
+
+// kill(0, SIGTRAP);
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|iii", kwlist,
+ &fd,
+ &pid,
+ &uid,
+ &gid)) {
+ return NULL;
+ }
+// kill(0, SIGTRAP);
+
+ if(pid!=-1)
+ uc.pid=pid;
+ else
+ uc.pid=getpid();
+ if(uid!=-1)
+ uc.uid=uid;
+ else
+ uc.uid=getuid();
+ if(gid!=-1)
+ uc.gid=gid;
+ else
+ uc.gid=getgid();
+
+ iov[0].iov_base="SCM_CREDENTIALS";
+ iov[0].iov_len=15;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = &control;
+ msg.msg_controllen = sizeof(control);
+
+ cur = CMSG_FIRSTHDR(&msg);
+ cur->cmsg_level = SOL_SOCKET;
+ cur->cmsg_type = SCM_CREDENTIALS;
+ cur->cmsg_len = CMSG_SPACE(sizeof(struct ucred));
+ memcpy(CMSG_DATA(cur), &uc, sizeof(struct ucred));
+
+ ret = sendmsg(fd, &msg, 0);
+ if(ret < 0) {
+ PyErr_SetFromErrno(g_socketerror);
+ return NULL;
+ }
+
+ return Py_BuildValue("i", ret);
+}
+
+static PyObject *ucred_recvcreds(PyObject *self, PyObject *args, PyObject *keywds) {
+ int fd;
+ int flags=0;
+ size_t maxsize=1024;
+ char control[CMSG_SPACE(sizeof(struct ucred))];
+ int ret;
+ int pid=-1, uid=-1, gid=-1;
+ struct msghdr msg;
+ struct iovec iov[1];
+ struct cmsghdr *cur;
+ struct ucred *uc;
+
+
+ static char *kwlist[] = {"fd", "flags", "maxsize", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|ii", kwlist,
+ &fd, &flags, &maxsize)) {
+ return NULL;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+
+ iov[0].iov_len = maxsize;
+ iov[0].iov_base = malloc(maxsize);
+ if (!iov[0].iov_base) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 1;
+
+ msg.msg_control = &control;
+ msg.msg_controllen = sizeof(control);
+
+ ret = recvmsg(fd, &msg, flags);
+ if (ret < 0) {
+ PyErr_SetFromErrno(g_socketerror);
+ free(iov[0].iov_base);
+ return NULL;
+ }
+
+ cur=CMSG_FIRSTHDR(&msg);
+
+ if(cur && cur->cmsg_type==SCM_CREDENTIALS && cur->cmsg_level==SOL_SOCKET)
+ {
+ assert(cur->cmsg_len >= sizeof(struct cmsghdr));
+ // no null ancillary data messages?
+
+ uc=(struct ucred*)CMSG_DATA(cur);
+ pid=uc->pid;
+ uid=uc->uid;
+ gid=uc->gid;
+ }
+
+ {
+ PyObject *r;
+ r = Py_BuildValue("s#iii",
+ iov[0].iov_base, ret,
+ pid, uid, gid);
+ free(iov[0].iov_base);
+ return r;
+ }
+}
+
+
--- /dev/null
+#!/usr/bin/python
+
+import os
+import re
+import struct
+
+acdir = "/home/ftp/pub/Linux/PLD/dists/ac/PLD/SRPMS/SRPMS"
+thdir = "/home/ftp/pub/Linux/PLD/dists/th/PLD/SRPMS/RPMS/"
+
+thpkg = []
+acpkg = []
+
+ign = '^(xorg-.*|X11-.*|XcursorTheme-.*)$'
+re_c = re.compile(ign)
+
+re_n = re.compile('^(.*)-([^-]*)-([^-]*)$')
+
+def getname(file):
+ #f = os.popen('rpm --nomd5 --nodigest --nosignature -qp --queryformat "%{NAME}" ' + file, "r")
+ #name = f.read()
+ #f.close()
+ #f = open(file, 'rb')
+ #rpmlead = f.read(96)
+ #f.close()
+ #data = struct.unpack("6B2h66s2h16s", rpmlead)
+ #name = data[8].strip()
+ #print name
+ m = re_n.match(file)
+ name = m.group(1).strip()
+ return name
+
+for rpm in os.listdir(acdir):
+ if re_c.match(rpm):
+ continue
+ acpkg.append(getname(rpm))
+
+for rpm in os.listdir(thdir):
+ if re_c.match(rpm):
+ continue
+ thpkg.append(getname(rpm))
+
+thpkg.sort()
+acpkg.sort()
+
+print "*****************************************************"
+print "Packages in AC repo that are not in TH repo:"
+for pkg in acpkg:
+ if pkg not in thpkg:
+ print pkg
+
+print
+print
+print "*****************************************************"
+print "Packages in TH repo that are not in AC repo:"
+for pkg in thpkg:
+ if pkg not in acpkg:
+ print pkg
--- /dev/null
+#!/bin/sh
+
+dir="$1"
+cd $dir || exit 1
+
+for f in *.rpm ; do
+ g=$(rpm --qf '%{GROUP}' -qp $f)
+ level=".."
+ a="$g"
+ b=
+ while [ "$a" != "$b" ]; do
+ b="$a"
+ a=${a#*/}
+ level="${level}/.."
+ done
+ [ -d "../by-group/$g" ] || mkdir -p "../by-group/$g"
+ ln -sf "$level/RPMS/$f" "../by-group/$g/$f"
+done
+
+# remove dangling symlinks...
+symlinks -dr $dir/../by-group
+# and empty directories
+find $dir/../by-group -depth -type d -empty -exec rmdir {} \;
--- /dev/null
+#!/bin/sh
+# stat(1) each file in .info to see if they exist
+
+REPODIR=${1:-/home/pld/admins/th/ftp/test}
+
+# expand files from .info file
+expand_info() {
+ awk -F ':' -vD="$REPODIR/" '
+ /file:/ {
+ if (/-debuginfo-/) {
+ print D $2 "/debuginfo/" $3
+ } else {
+ print D $2 "/RPMS/" $3
+ }
+ }
+ ' "$@"
+}
+
+i=0
+nn=
+ls -1 $REPODIR/SRPMS/RPMS | sed -rne "s/^((.+)-[^-]+-[^-]+\.src\.rpm)$/\1.info/p" | \
+while read pkg; do
+ for f in $(expand_info $REPODIR/SRPMS/.metadata/$pkg); do
+ if ! stat $f >/dev/null; then
+ echo "!!!: $pkg : $f" >&2
+ fi
+ done
+done
--- /dev/null
+#!/usr/bin/python
+# arekm, 2008
+# remove
+
+import os
+import re
+import time
+import rpm
+import sys
+
+re_rpm = re.compile(r'.*\.rpm$')
+re_nvr = re.compile('^(.*)-([^-]*)-([^-]*)\.rpm$')
+dir = '/home/pld/admins/th/ftp/.archive/PLD/SRPMS/RPMS'
+
+ts = rpm.TransactionSet("", (rpm.RPMVSF_NOHDRCHK or rpm.RPMVSF_NEEDPAYLOAD))
+
+def compare(f1, f2):
+ try:
+ fd1 = os.open(os.path.join(dir, f1), os.O_RDONLY)
+ except Exception, e:
+ print e
+ # ignore non-files
+ return 0
+ try:
+ fd2 = os.open(os.path.join(dir, f2), os.O_RDONLY)
+ except Exception, e:
+ print e
+ # ignore non-files
+ return 0
+ h1 = ts.hdrFromFdno(fd1)
+ h2 = ts.hdrFromFdno(fd2)
+ os.close(fd1)
+ os.close(fd2)
+
+ l1 = rpm.versionCompare(h1, h2)
+ l2 = rpm.versionCompare(h2, h1)
+
+ if l1 > 0 and l2 > 0:
+ return 0
+
+ return -l1
+
+
+def find_old(files):
+ return sorted(files, compare)
+
+files = {}
+dupes = {}
+
+for file in os.listdir(dir):
+ if not re_rpm.match(file):
+ continue
+
+ m = re_nvr.match(file)
+ if not m:
+ print "problem with: %s" % file
+ sys.exit(1)
+
+ if len(sys.argv) == 0:
+ p = os.path.join(dir, file)
+ mtime = os.stat(p).st_mtime
+ if mtime > time.time() - 3*86400:
+ continue
+
+ name = m.group(1)
+
+ if files.has_key(name):
+ if dupes.has_key(name):
+ dupes[name].append(file)
+ else:
+ dupes[name] = [ files[name] ]
+ dupes[name].append(file)
+ else:
+ files[name] = file
+
+for i in dupes.iterkeys():
+ for old in find_old(dupes[i])[1:]:
+ os.system("/home/pld/admins/th/pld-ftp-admin/scripts/remove.py .archive/PLD %s" % old)
--- /dev/null
+#!/usr/bin/python
+# arekm, 2008
+# remove
+
+import os
+import re
+import time
+import rpm
+import sys
+
+re_info = re.compile(r'.*\.info$')
+re_nvr = re.compile('^(.*)-([^-]*)-([^-]*)\.info$')
+dir = '/home/pld/admins/th/ftp/test/SRPMS/.metadata'
+
+def compare(f1, f2):
+ m1 = re_nvr.match(f1)
+ n1 = m1.group(1)
+ v1 = m1.group(2)
+ r1 = m1.group(3)
+
+ m2 = re_nvr.match(f2)
+ n2 = m2.group(1)
+ v2 = m2.group(2)
+ r2 = m2.group(3)
+
+ l1 = rpm.labelCompare((n1, v1, r1), (n2, v2, r2))
+ l2 = rpm.labelCompare((n2, v2, r2), (n1, v1, r1))
+
+ if l1 > 0 and l2 > 0:
+ return 0
+
+ return -l1
+
+
+def find_old(files):
+ return sorted(files, compare)
+
+files = {}
+dupes = {}
+
+for file in os.listdir(dir):
+ if not re_info.match(file):
+ continue
+
+ m = re_nvr.match(file)
+ if not m:
+ print "problem with: %s" % file
+ sys.exit(1)
+
+ if len(sys.argv) == 0:
+ p = os.path.join(dir, file)
+ mtime = os.stat(p).st_mtime
+ if mtime > time.time() - 3*86400:
+ continue
+
+ name = m.group(1)
+
+ if files.has_key(name):
+ if dupes.has_key(name):
+ dupes[name].append(file)
+ else:
+ dupes[name] = [ files[name] ]
+ dupes[name].append(file)
+ else:
+ files[name] = file
+
+for i in dupes.iterkeys():
+ for old in find_old(dupes[i])[1:]:
+ os.system("/home/pld/admins/th/pld-ftp-admin/scripts/remove.py test %s" % old)
--- /dev/null
+#!/usr/bin/python
+# arekm, 2008
+# remove
+
+import os
+import re
+import time
+import rpm
+import sys
+
+re_rpm = re.compile(r'.*\.rpm$')
+re_nvr = re.compile('^(.*)-([^-]*)-([^-]*)\.rpm$')
+dir = '/home/pld/admins/th/ftp/test/SRPMS/RPMS'
+
+ignore = re.compile('^(kernel-.*)$')
+#|\
+#crash-.*|\
+#dahdi-linux-.*|\
+#e1000e-.*|\
+#igb-.*|\
+#ipset-.*|\
+#iscsitarget-.*|\
+#ixgbe-.*|\
+#kernel-net-wl-.*|\
+#lin_tape-.*|\
+#linux-fusion-.*|\
+#linuxrdac-.*|\
+#lirc-.*|\
+#lttng-modules-.*|\
+#madwifi-ng-.*|\
+#nvidiabl-.*|\
+#open-vm-tools-.*|\
+#openvswitch-.*|\
+#r8168-.*|\
+#spl-.*|\
+#tpm_emulator-.*|\
+#VirtualBox-.*|\
+#vpb-driver-.*|\
+#xorg-driver-video-fglrx-.*|\
+#xorg-driver-video-fglrx-legacy-.*|\
+#xorg-driver-video-nvidia-.*|\
+#xorg-driver-video-nvidia-legacy3-.*|\
+#xorg-driver-video-nvidia-legacy-304xx-.*|\
+#xtables-addons-.*)$')
+
+ts = rpm.TransactionSet("", (rpm.RPMVSF_NOHDRCHK or rpm.RPMVSF_NEEDPAYLOAD))
+
+def compare(f1, f2):
+ try:
+ fd1 = os.open(os.path.join(dir, f1), os.O_RDONLY)
+ except Exception, e:
+ print e
+ # ignore non-files
+ return 0
+ try:
+ fd2 = os.open(os.path.join(dir, f2), os.O_RDONLY)
+ except Exception, e:
+ print e
+ # ignore non-files
+ return 0
+ try:
+ h1 = ts.hdrFromFdno(fd1)
+ except Exception, e:
+ print "hdrFromFdno for %s failed: %s" % (f1, e)
+ os.close(fd1)
+ os.close(fd2)
+ return 0
+
+ try:
+ h2 = ts.hdrFromFdno(fd2)
+ except Exception, e:
+ print "hdrFromFdno for %s failed: %s" % (f2, e)
+ os.close(fd1)
+ os.close(fd2)
+ return 0
+
+ os.close(fd1)
+ os.close(fd2)
+
+ l1 = rpm.versionCompare(h1, h2)
+ l2 = rpm.versionCompare(h2, h1)
+
+ if l1 > 0 and l2 > 0:
+ return 0
+
+ return -l1
+
+
+def find_old(files):
+ return sorted(files, compare)
+
+files = {}
+dupes = {}
+
+for file in os.listdir(dir):
+ if not re_rpm.match(file):
+ continue
+
+ if ignore.match(file):
+ continue
+
+ m = re_nvr.match(file)
+ if not m:
+ print "problem with: %s" % file
+ sys.exit(1)
+
+ if len(sys.argv) == 0:
+ p = os.path.join(dir, file)
+ mtime = os.stat(p).st_mtime
+ if mtime > time.time() - 3*86400:
+ continue
+
+ name = m.group(1)
+
+ if files.has_key(name):
+ if dupes.has_key(name):
+ dupes[name].append(file)
+ else:
+ dupes[name] = [ files[name] ]
+ dupes[name].append(file)
+ else:
+ files[name] = file
+
+for i in dupes.iterkeys():
+ for old in find_old(dupes[i])[1:]:
+ print "removing: %s" % old
+ os.system("/home/pld/admins/th/pld-ftp-admin/scripts/remove.py test %s" % old)
--- /dev/null
+#!/bin/sh
+LC_ALL=C; export LC_ALL
+cd /home/pld/admins/th/ftp/test/SRPMS/.metadata || exit 1
+#for file in `find . -name '*.info' -print`; do
+for file in `find . -name '*.info' -mtime +1 -print`; do
+ dfile=$(basename $file | sed -e 's#^\./##g')
+ if (~/pld-ftp-admin/scripts/test-move.py test ready "$dfile" | grep -q "has only src.rpm built"); then
+ echo "Removing $dfile..."
+ ~/pld-ftp-admin/scripts/remove.py test "$dfile"
+ fi
+done
+for file in `find . -name '*.info' -mtime +100`; do
+ dfile=$(basename $file | sed -e 's#^\./##g')
+ echo "Removing $dfile..."
+ ~/pld-ftp-admin/scripts/remove.py test "$dfile"
+done
--- /dev/null
+#!/bin/sh
+
+export LC_ALL=C
+
+filter_deps() {
+ if [ $1 = "x32" ]; then
+ grep -Ev "(uname\(release\)|-multilib-|\/eclipse\/|statifier|kernel-nopae-source-|kernel-tools-perf-vdso|libreoffice|iceape|iceweasel|icedove|nodejs)"
+ else
+ grep -Ev "(uname\(release\)|-multilib-|\/eclipse\/|statifier|kernel-nopae-source-|kernel-tools-perf-vdso)"
+ fi
+}
+
+# group errors by same error kind
+group_deps() {
+ local t=$(mktemp)
+ cat > $t
+ sed -ne 's/.*req \(.*\) not found.*/\1/p' $t | sort -u | while read dep; do
+ grep -F "req $dep not found" $t
+ done
+ rm -f $t
+}
+
+# convert pkg name to src.rpm name
+# uses poldek
+pkg2src() {
+ local t=$(mktemp)
+ local t3=$(mktemp)
+
+ # save input
+ cat > $t
+
+ # create list of N-V-R.A.rpm -> src-N pairs from error report
+ # error: arcconf-7.0.18786-1: req libstdc++.so.5()(64bit) not found
+ sed -ne 's/error: \(.*\): req .* not found/\1/p' $t | sort -u | \
+ xargs -d '\n' poldek --noignore -Q "$@" --cmd ls -q -s | \
+ sed -rne "s/^([^\t ]+)[\t ]+(.+)-[^-]+-[^-]+\.src\.rpm$/\1\t\2/p" >$t3
+
+ local pkg error message srpm
+ while read error pkg message; do
+ # error: arcconf-7.0.18786-1: req libstdc++.so.5()(64bit) not found
+ srpm=$(awk -vpkg="${pkg%:}" '$1 == pkg {printf("%s.spec", $2)}' $t3)
+ if [ -z "$srpm" ]; then
+ echo >&2 "srpms: No match for [${pkg%:}]"
+ fi
+ echo "$error [$srpm] $pkg $message"
+ done < $t
+
+ rm -f $t $t3
+}
+
+gen_list() {
+ arch=$1
+ shift
+ date
+ poldek -O "auto directory dependencies = yes" \
+ --ignore "*-debuginfo-*" \
+ --ignore "opera-plugin32-*" \
+ --ignore "nspluginwrapper-*" \
+ --ignore "mbrola-voice-*" \
+ --ignore "pysql-*" \
+ --ignore "yasql-*" \
+ --ignore "kde4-kdenetwork-kopete-protocol-skype-*.x86_64" \
+ --ignore "libpurple-protocol-skype-*.x86_64" \
+ --ignore "nagios-plugin-check_cciss-*" \
+ --ignore "libpng1*" \
+ --verify=deps -Q "$@" | filter_deps $arch | group_deps | pkg2src "$@" | sort
+}
+
+gen_list_uniq() {
+ arch=$1
+ shift
+ gen_list $arch -O"unique package names = yes" "$@"
+}
+
+t=$(mktemp)
+ftpdir=$HOME/ftp
+for arch in x86_64 i686 x32 ; do
+ if [ "$arch" = x86_64 ]; then
+ outfext=.txt
+ else
+ outfext=-$arch.txt
+ fi
+ gen_list $arch -s $ftpdir/PLD/$arch/RPMS/ -s $ftpdir/PLD/noarch/RPMS/ > $t && cat $t > $HOME/www/main$outfext
+ gen_list_uniq $arch -s $ftpdir/PLD/$arch/RPMS/ -s $ftpdir/PLD/noarch/RPMS/ -s $ftpdir/ready/$arch/RPMS/ -s $ftpdir/ready/noarch/RPMS/ > $t && cat $t > $HOME/www/main-ready$outfext
+ gen_list_uniq $arch -s $ftpdir/PLD/$arch/RPMS/ -s $ftpdir/PLD/noarch/RPMS/ -s $ftpdir/ready/$arch/RPMS/ -s $ftpdir/ready/noarch/RPMS/ -s $ftpdir/test/$arch/RPMS/ -s $ftpdir/test/noarch/RPMS/ > $t && cat $t > $HOME/www/main-ready-test$outfext
+done
+
+chmod 644 $HOME/www/*.txt
+rm -f $t
--- /dev/null
+#!/usr/bin/python
+
+import os
+import re
+
+import rpm
+
+dirs = ['/home/services/ftp/pld/dists/3.0/PLD/x32/RPMS',
+ '/home/services/ftp/pld/dists/3.0/PLD/i686/RPMS',
+ '/home/services/ftp/pld/dists/3.0/PLD/x86_64/RPMS',
+ '/home/services/ftp/pld/dists/3.0/ready/x32/RPMS',
+ '/home/services/ftp/pld/dists/3.0/ready/i686/RPMS',
+ '/home/services/ftp/pld/dists/3.0/ready/x86_64/RPMS',
+ '/home/services/ftp/pld/dists/3.0/test/x32/RPMS',
+ '/home/services/ftp/pld/dists/3.0/test/i686/RPMS',
+ '/home/services/ftp/pld/dists/3.0/test/x86_64/RPMS']
+
+#dirs = ['/home/services/ftp/pld/dists/3.0/test/x86_64/RPMS']
+
+outname = "/home/pld/admins/th/www/name-srcname.txt"
+
+re_rpm = re.compile(r'.*\.rpm$')
+re_nvr = re.compile('^(.*)-([^-]*)-([^-]*)\.rpm$')
+
+ts = rpm.ts()
+ts.setVSFlags(-1)
+pkgs = {}
+for dir in dirs:
+ for file in os.listdir(dir):
+ if not re_rpm.match(file):
+ continue
+
+ rpm_file = os.path.join(dir, file)
+
+ fdno = os.open(rpm_file, os.O_RDONLY)
+ try:
+ hdr = ts.hdrFromFdno(fdno)
+ except Exception, e:
+ print "hdrFromFdno: %s: %s" % (rpm_file, e)
+ os.close(fdno)
+ continue
+ os.close(fdno)
+
+ name = hdr[rpm.RPMTAG_NAME]
+ sourcerpm = hdr[rpm.RPMTAG_SOURCERPM]
+ m = re_nvr.match(sourcerpm)
+ if not m:
+ print "%s: doesn't match src.rpm file name" % (sourcerpm)
+ continue
+ srcname = m.group(1)
+ pkgs[name] = srcname
+
+f = open(outname + ".tmp", "w")
+for (pkg, spkg) in pkgs.iteritems():
+ f.write("%s:%s\n" % (pkg, spkg))
+f.close()
+os.chmod(outname + ".tmp", 0644)
+os.rename(outname + ".tmp", outname)
+
--- /dev/null
+#!/bin/sh
+date > $HOME/www/freshness.txt.new
+/usr/bin/time -f '\nElapsed time: %E' $HOME/bin/ftp-freshness.py >> $HOME/www/freshness.txt.new 2>&1
+chmod 644 $HOME/www/freshness.txt.new
+mv $HOME/www/freshness.txt.new $HOME/www/freshness.txt
+
--- /dev/null
+#!/usr/bin/python
+# arekm, 2007
+
+import os
+import re
+import struct
+import rpm
+import subprocess
+
+# earlier == more important
+dirs = [ "/home/ftp/pub/Linux/PLD/dists/th/test/SRPMS/RPMS/",
+ "/home/ftp/pub/Linux/PLD/dists/th/ready/SRPMS/RPMS/",
+ "/home/ftp/pub/Linux/PLD/dists/th/PLD/SRPMS/RPMS/" ]
+#dirs = [ "/home/pld/admins/th/1" ]
+specsdir = "/home/pld/admins/th/SPECS"
+
+if os.path.isdir(specsdir):
+ os.chdir(specsdir)
+ cmd = ['git', 'pull']
+else:
+ cmd = ['git', 'clone', '--depth=1', 'git://git.pld-linux.org/SPECS', specsdir]
+
+p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+(out, err) = p.communicate(None)
+
+
+os.chdir(specsdir)
+class Pkgs(object):
+ def __init__(self):
+ self.pkg = {}
+ self.cvs = {}
+ self.cvs_new_nvr = []
+ self.cvs_new_nv = []
+ self.re_n = re.compile('^(.*)-([^-]*)-([^-]*)\.src\.rpm$')
+
+ def __get_from_rpm(self, file_name):
+ m = self.re_n.match(file_name)
+ if not m:
+ return False
+ name = m.group(1).strip()
+ version = m.group(2).strip()
+ release = m.group(3).strip()
+ return (name, version, release)
+
+ def __get_from_cvs(self, name):
+ f = os.popen('rpm --specfile -q --queryformat "%{name}\n%{version}\n%{release}\n" ' + specsdir + '/' + name + '.spec 2> /dev/null', 'r')
+ name = f.readline().strip()
+ version = f.readline().strip()
+ release = f.readline().strip()
+ f.close()
+ return (name, version, release)
+
+ def __update_cvs(self, name):
+ if not self.cvs.has_key(name):
+ self.cvs[name] = self.__get_from_cvs(name)
+
+ def __update_new(self, name):
+ cvs_nvr = self.cvs[name]
+ pkg_nvr = self.pkg[name]
+
+ cvs_rpm_vr = rpm.labelCompare((cvs_nvr[0], cvs_nvr[1], cvs_nvr[2]), (pkg_nvr[0], pkg_nvr[1], pkg_nvr[2]))
+ cvs_rpm_v = rpm.labelCompare((cvs_nvr[0], cvs_nvr[1], ""), (pkg_nvr[0], pkg_nvr[1], ""))
+ rpm_cvs_vr = rpm.labelCompare((pkg_nvr[0], pkg_nvr[1], pkg_nvr[2]), (cvs_nvr[0], cvs_nvr[1], cvs_nvr[2]))
+ rpm_cvs_v = rpm.labelCompare((pkg_nvr[0], pkg_nvr[1], ""), (cvs_nvr[0], cvs_nvr[1], ""))
+
+ if rpm_cvs_v < 0 and cvs_rpm_v > 0:
+ self.cvs_new_nv.append(name)
+ else:
+ if rpm_cvs_vr < 0 and cvs_rpm_vr > 0 and cvs_nvr[1] == pkg_nvr[1]:
+ self.cvs_new_nvr.append(name)
+
+ def prepare(self):
+ self.cvs_new_nvr.sort()
+ self.cvs_new_nvr = list(set(self.cvs_new_nvr))
+ self.cvs_new_nv.sort()
+ self.cvs_new_nv = list(set(self.cvs_new_nv))
+
+ pkgs = list(self.pkg) + list(self.cvs)
+
+ for name in list(set(pkgs)):
+ self.__update_new(name)
+
+ def add_rpm(self, file_name):
+ nvr = self.__get_from_rpm(file_name)
+ if not nvr:
+ return False
+ name = nvr[0]
+ if self.pkg.has_key(name):
+ if rpm.labelCompare(nvr, self.pkg[name]) > 0:
+ del self.pkg[name]
+ self.pkg[name] = nvr
+ else:
+ self.pkg[name] = nvr
+ self.__update_cvs(name)
+
+ def print_nvr(self):
+ print "*** VERSION-RELEASE COMPARE FOR THE SAME VERSIONS ONLY ***"
+ for name in self.cvs_new_nvr:
+ self.cvs_new_nvr.sort()
+ cvs_nvr = self.cvs[name]
+ pkg_nvr = self.pkg[name]
+ print "GIT: [%s.spec] %s-%s-%s vs FTP: %s-%s-%s" % (name, cvs_nvr[0], cvs_nvr[1], cvs_nvr[2], pkg_nvr[0], pkg_nvr[1], pkg_nvr[2])
+
+ def print_nv(self):
+ print "*** VERSION COMPARE ONLY ***"
+ self.cvs_new_nv.sort()
+ for name in self.cvs_new_nv:
+ cvs_nvr = self.cvs[name]
+ pkg_nvr = self.pkg[name]
+ print "GIT: [%s.spec] %s-%s-%s vs FTP: %s-%s-%s" % (name, cvs_nvr[0], cvs_nvr[1], cvs_nvr[2], pkg_nvr[0], pkg_nvr[1], pkg_nvr[2])
+
+p = Pkgs()
+
+for d in dirs:
+ for rpm_file_name in os.listdir(d):
+ p.add_rpm(rpm_file_name)
+
+p.prepare()
+
+p.print_nv()
+print "\n\n"
+p.print_nvr()
--- /dev/null
+#!/bin/sh
+# check for packages on ftp whose .spec does not exist (anymore)
+# this is extremely heavy on cvs server, so you run it once per month or so
+# Author: Elan Ruusamäe <glen@pld-linux.org>
+
+export LC_ALL=C
+ftpdir=$HOME/ftp
+wwwdir=$HOME/www
+CVSROOT=:pserver:cvs@cvs.pld-linux.org:/cvsroot
+d=$-
+
+orphaned_pkgs() {
+ set -$d
+ [ -s $t/pkgs.desc ] || /usr/bin/poldek --skip-installed "$@" --cmd "desc *" > $t/pkgs.desc
+ [ -s $t/pkgs.lst ] || sed -n 's/^Source package: \(.*\)-[^-]\+-[^-]\+$/\1/p' $t/pkgs.desc | sort -u > $t/pkgs.lst
+ # {w32codec,acroread,...}-installer pkgs
+ sed -i -e 's,-installer$,,' $t/pkgs.lst
+ for pkg in $(cat $t/pkgs.lst); do
+ # use awk to match package without any regexp fuzz
+ awk -vpkg=$pkg.spec -vm=1 '$1 == pkg{m=0} END{exit m}' $t/cvs.lst || echo Obsolete: $pkg
+ done
+}
+
+# generate list of .specs on ftp. needs cvsnt client
+cvs_pkgs() {
+ set -$d
+ [ -s $t/cvs.raw ] || cvs -d $CVSROOT -Q ls -e packages > $t/cvs.raw 2>/dev/null
+ [ -s $t/cvs.dirs ] || awk -F/ '$1 == "D" { print $2 } ' $t/cvs.raw > $t/cvs.dirs
+ [ -s $t/cvs.specs ] || {
+ while read pkg; do
+ cvs -d $CVSROOT -Q ls -e packages/$pkg/$pkg.spec 2>/dev/null
+ done < $t/cvs.dirs > $t/cvs.lst.tmp && mv $t/cvs.lst.tmp $t/cvs.specs
+ }
+ [ -s $t/cvs.lst ] || awk -F/ '$1 == "" { print $2 } ' $t/cvs.specs > $t/cvs.lst
+}
+
+
+set -e
+t=$(mktemp -d)
+#t=/home/pld/admins/th/tmp/tmp.KOCrX7BtOy
+
+cvs_pkgs
+orphaned_pkgs -s $ftpdir/PLD/i686/RPMS/ -s $ftpdir/PLD/noarch/RPMS/ > $t/orphaned.txt && cat $t/orphaned.txt > $wwwdir/main-orphaned4.txt
+
+chmod 644 $wwwdir/*.txt
+#rm -rf $t
--- /dev/null
+#!/bin/sh
+# check for packages on local system with PLD-doc/PLD-update-TODO
+# Author: Elan Ruusamäe <glen@pld-linux.org>
+# Date: 2012-04-05
+
+export LC_ALL=C
+CVSROOT=:pserver:cvs@cvs.pld-linux.org:/cvsroot
+d=$-
+
+# generate list of package basenames from rpmdb
+rpm_pkgs() {
+ set -$d
+
+ [ -s $t/rpm.db ] || rpm -qa --qf '%{SOURCERPM} %{VERSION}\n' > $t/rpm.db
+
+ # translate pkg names to basenames
+ [ -s $t/rpm.basenames ] || sed -re 's,^(.+)-[^-]+-[^-]+ ,\1 ,' $t/rpm.db > $t/rpm.basenames
+ # uniq
+ [ -s $t/rpm.lst ] || sort -u $t/rpm.basenames > $t/rpm.lst
+}
+
+# fetch PLD-update-TODO
+cvs_todo() {
+ set -$d
+
+ [ -s $t/PLD-doc/PLD-update-TODO ] || (cd $t; cvs -d $CVSROOT -Q co PLD-doc/PLD-update-TODO)
+
+ # reformat for easier parsing
+ # amaya(13) [OLD] 9.54 [NEW] 11.0
+ # vim [OLD] 7.3.401 [NEW] 7.3.515
+ [ -s $t/rpm.todo ] || sed -rne 's,^([^( ]+).*?\[NEW\] (.+)$,\1 \2,p' $t/PLD-doc/PLD-update-TODO > $t/rpm.todo
+
+ # TODO: should uniq as well:
+ # $ grep links2 PLD-doc/PLD-update-TODO
+ # links2(22) [OLD] 2.2 [NEW] 2.6
+ # links2(25) [OLD] 2.1pre28 [NEW] 2.6
+}
+
+rpm_diff() {
+# set -$d
+
+ rpm_pkgs
+ cvs_todo
+
+ [ -s $t/rpm.diffs ] || {
+ set +e
+ while read pkg v2; do
+ v1=$(awk -vpkg=$pkg '$1 == pkg {print $2}' $t/rpm.lst)
+ [ "$v1" ] || continue
+
+ cmp=$(rpmvercmp $v1 $v2)
+ if [ $? -eq 2 ]; then
+ echo "$pkg $cmp"
+ fi
+ done < $t/rpm.todo
+ set -e
+ }
+}
+
+set -e
+t=$(mktemp -d)
+#t=.
+
+rpm_diff
+
+rm -rf $t